-
Notifications
You must be signed in to change notification settings - Fork 8
/
queue.man
710 lines (498 loc) · 35.8 KB
/
queue.man
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
QUEUE(3) OpenBSD Programmer's Manual QUEUE(3)
NNAAMMEE
SSLLIISSTT__EENNTTRRYY, SSLLIISSTT__HHEEAADD, SSLLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR, SSLLIISSTT__FFIIRRSSTT, SSLLIISSTT__NNEEXXTT,
SSLLIISSTT__EENNDD, SSLLIISSTT__EEMMPPTTYY, SSLLIISSTT__FFOORREEAACCHH, SSLLIISSTT__IINNIITT, SSLLIISSTT__IINNSSEERRTT__AAFFTTEERR,
SSLLIISSTT__IINNSSEERRTT__HHEEAADD, SSLLIISSTT__RREEMMOOVVEE__HHEEAADD, LLIISSTT__EENNTTRRYY, LLIISSTT__HHEEAADD,
LLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR, LLIISSTT__FFIIRRSSTT, LLIISSTT__NNEEXXTT, LLIISSTT__EENNDD, LLIISSTT__EEMMPPTTYY,
LLIISSTT__FFOORREEAACCHH, LLIISSTT__IINNIITT, LLIISSTT__IINNSSEERRTT__AAFFTTEERR, LLIISSTT__IINNSSEERRTT__BBEEFFOORREE,
LLIISSTT__IINNSSEERRTT__HHEEAADD, LLIISSTT__RREEMMOOVVEE, SSIIMMPPLLEEQQ__EENNTTRRYY, SSIIMMPPLLEEQQ__HHEEAADD,
SSIIMMPPLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR, SSIIMMPPLLEEQQ__FFIIRRSSTT, SSIIMMPPLLEEQQ__NNEEXXTT, SSIIMMPPLLEEQQ__EENNDD,
SSIIMMPPLLEEQQ__EEMMPPTTYY, SSIIMMPPLLEEQQ__FFOORREEAACCHH, SSIIMMPPLLEEQQ__IINNIITT, SSIIMMPPLLEEQQ__IINNSSEERRTT__HHEEAADD,
SSIIMMPPLLEEQQ__IINNSSEERRTT__TTAAIILL, SSIIMMPPLLEEQQ__IINNSSEERRTT__AAFFTTEERR, SSIIMMPPLLEEQQ__RREEMMOOVVEE__HHEEAADD,
TTAAIILLQQ__EENNTTRRYY, TTAAIILLQQ__HHEEAADD, TTAAIILLQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR, TTAAIILLQQ__FFIIRRSSTT, TTAAIILLQQ__NNEEXXTT,
TTAAIILLQQ__EENNDD, TTAAIILLQQ__LLAASSTT, TTAAIILLQQ__PPRREEVV, TTAAIILLQQ__EEMMPPTTYY, TTAAIILLQQ__FFOORREEAACCHH,
TTAAIILLQQ__FFOORREEAACCHH__RREEVVEERRSSEE, TTAAIILLQQ__IINNIITT, TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR,
TTAAIILLQQ__IINNSSEERRTT__BBEEFFOORREE, TTAAIILLQQ__IINNSSEERRTT__HHEEAADD, TTAAIILLQQ__IINNSSEERRTT__TTAAIILL, TTAAIILLQQ__RREEMMOOVVEE,
CCIIRRCCLLEEQQ__EENNTTRRYY, CCIIRRCCLLEEQQ__HHEEAADD, CCIIRRCCLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR, CCIIRRCCLLEEQQ__FFIIRRSSTT,
CCIIRRCCLLEEQQ__LLAASSTT, CCIIRRCCLLEEQQ__EENNDD, CCIIRRCCLLEEQQ__NNEEXXTT, CCIIRRCCLLEEQQ__PPRREEVV, CCIIRRCCLLEEQQ__EEMMPPTTYY,
CCIIRRCCLLEEQQ__FFOORREEAACCHH, CCIIRRCCLLEEQQ__IINNIITT, CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR,
CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE, CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD, CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL,
CCIIRRCCLLEEQQ__RREEMMOOVVEE - implementations of singly-linked lists, doubly-linked
lists, simple queues, tail queues, and circular queues
SSYYNNOOPPSSIISS
##iinncclluuddee <<ssyyss//qquueeuuee..hh>>
SSLLIISSTT__EENNTTRRYY(_T_Y_P_E);
SSLLIISSTT__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
SSLLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR(_S_L_I_S_T___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
SSLLIISSTT__FFIIRRSSTT(_S_L_I_S_T___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
SSLLIISSTT__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
SSLLIISSTT__EENNDD(_S_L_I_S_T___H_E_A_D _*_h_e_a_d);
_b_o_o_l
SSLLIISSTT__EEMMPPTTYY(_S_L_I_S_T___H_E_A_D _*_h_e_a_d);
SSLLIISSTT__FFOORREEAACCHH(_V_A_R_N_A_M_E, _S_L_I_S_T___H_E_A_D _*_h_e_a_d, _S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSLLIISSTT__IINNIITT(_S_L_I_S_T___H_E_A_D _*_h_e_a_d);
_v_o_i_d
SSLLIISSTT__IINNSSEERRTT__AAFFTTEERR(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSLLIISSTT__IINNSSEERRTT__HHEEAADD(_S_L_I_S_T___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSLLIISSTT__RREEMMOOVVEE__HHEEAADD(_S_L_I_S_T___H_E_A_D _*_h_e_a_d, _S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
LLIISSTT__EENNTTRRYY(_T_Y_P_E);
LLIISSTT__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
LLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR(_L_I_S_T___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
LLIISSTT__FFIIRRSSTT(_L_I_S_T___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
LLIISSTT__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
LLIISSTT__EENNDD(_L_I_S_T___H_E_A_D _*_h_e_a_d);
_b_o_o_l
LLIISSTT__EEMMPPTTYY(_L_I_S_T___H_E_A_D _*_h_e_a_d);
LLIISSTT__FFOORREEAACCHH(_V_A_R_N_A_M_E, _L_I_S_T___H_E_A_D _*_h_e_a_d, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
LLIISSTT__IINNIITT(_L_I_S_T___H_E_A_D _*_h_e_a_d);
_v_o_i_d
LLIISSTT__IINNSSEERRTT__AAFFTTEERR(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
LLIISSTT__IINNSSEERRTT__BBEEFFOORREE(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
LLIISSTT__IINNSSEERRTT__HHEEAADD(_L_I_S_T___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
LLIISSTT__RREEMMOOVVEE(_s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
SSIIMMPPLLEEQQ__EENNTTRRYY(_T_Y_P_E);
SSIIMMPPLLEEQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
SSIIMMPPLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR(_S_I_M_P_L_E_Q___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
SSIIMMPPLLEEQQ__FFIIRRSSTT(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
SSIIMMPPLLEEQQ__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
SSIIMMPPLLEEQQ__EENNDD(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d);
_v_o_i_d
SSIIMMPPLLEEQQ__IINNIITT(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d);
_v_o_i_d
SSIIMMPPLLEEQQ__IINNSSEERRTT__HHEEAADD(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSIIMMPPLLEEQQ__IINNSSEERRTT__TTAAIILL(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSIIMMPPLLEEQQ__IINNSSEERRTT__AAFFTTEERR(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSIIMMPPLLEEQQ__RREEMMOOVVEE__HHEEAADD(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
TTAAIILLQQ__EENNTTRRYY(_T_Y_P_E);
TTAAIILLQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
TTAAIILLQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR(_T_A_I_L_Q___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
TTAAIILLQQ__FFIIRRSSTT(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
TTAAIILLQQ__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
TTAAIILLQQ__EENNDD(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
TTAAIILLQQ__LLAASSTT(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _H_E_A_D_N_A_M_E _N_A_M_E);
TTAAIILLQQ__PPRREEVV(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _H_E_A_D_N_A_M_E _N_A_M_E, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_b_o_o_l
TTAAIILLQQ__EEMMPPTTYY(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
TTAAIILLQQ__FFOORREEAACCHH(_V_A_R_N_A_M_E, _T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
TTAAIILLQQ__FFOORREEAACCHH__RREEVVEERRSSEE(_V_A_R_N_A_M_E, _T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__IINNIITT(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
_v_o_i_d
TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m,
_s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__IINNSSEERRTT__BBEEFFOORREE(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__IINNSSEERRTT__HHEEAADD(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__IINNSSEERRTT__TTAAIILL(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__RREEMMOOVVEE(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
CCIIRRCCLLEEQQ__EENNTTRRYY(_T_Y_P_E);
CCIIRRCCLLEEQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
CCIIRRCCLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR(_C_I_R_C_L_E_Q___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__FFIIRRSSTT(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__LLAASSTT(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__EENNDD(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__PPRREEVV(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_b_o_o_l
CCIIRRCCLLEEQQ__EEMMPPTTYY(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
CCIIRRCCLLEEQQ__FFOORREEAACCHH(_V_A_R_N_A_M_E, _C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
CCIIRRCCLLEEQQ__FFOORREEAACCHH__RREEVVEERRSSEE(_V_A_R_N_A_M_E, _C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNIITT(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m,
_s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m,
_s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__RREEMMOOVVEE(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
DDEESSCCRRIIPPTTIIOONN
These macros define and operate on five types of data structures: singly-
linked lists, simple queues, lists, tail queues, and circular queues.
All five structures support the following functionality:
1. Insertion of a new entry at the head of the list.
2. Insertion of a new entry after any element in the list.
3. Removal of an entry from the head of the list.
4. Forward traversal through the list.
Singly-linked lists are the simplest of the five data structures and sup-
port only the above functionality. Singly-linked lists are ideal for ap-
plications with large datasets and few or no removals, or for implement-
ing a LIFO queue.
Simple queues add the following functionality:
1. Entries can be added at the end of a list.
However:
1. All list insertions must specify the head of the list.
2. Each head entry requires two pointers rather than one.
3. Code size is about 15% greater and operations run about 20%
slower than singly-linked lists.
Simple queues are ideal for applications with large datasets and few or
no removals, or for implementing a FIFO queue.
All doubly linked types of data structures (lists, tail queues, and cir-
cle queues) additionally allow:
1. Insertion of a new entry before any element in the list.
2. Removal of any entry in the list.
However:
1. Each elements requires two pointers rather than one.
2. Code size and execution time of operations (except for re-
moval) is about twice that of the singly-linked data-struc-
tures.
Lists are the simplest of the doubly linked data structures and support
only the above functionality over singly-linked lists.
Tail queues add the following functionality:
1. Entries can be added at the end of a list.
2. They may be traversed backwards, at a cost.
However:
1. All list insertions and removals must specify the head of the
list.
2. Each head entry requires two pointers rather than one.
3. Code size is about 15% greater and operations run about 20%
slower than singly-linked lists.
Circular queues add the following functionality:
1. Entries can be added at the end of a list.
2. They may be traversed backwards, from tail to head.
However:
1. All list insertions and removals must specify the head of the
list.
2. Each head entry requires two pointers rather than one.
3. The termination condition for traversal is more complex.
4. Code size is about 40% greater and operations run about 45%
slower than lists.
In the macro definitions, _T_Y_P_E is the name tag of a user defined struc-
ture that must contain a field of type SLIST_ENTRY, LIST_ENTRY,
SIMPLEQ_ENTRY, TAILQ_ENTRY, or CIRCLEQ_ENTRY, named _N_A_M_E. The argument
_H_E_A_D_N_A_M_E is the name tag of a user defined structure that must be de-
clared using the macros SSLLIISSTT__HHEEAADD(), LLIISSTT__HHEEAADD(), SSIIMMPPLLEEQQ__HHEEAADD(),
TTAAIILLQQ__HHEEAADD(), or CCIIRRCCLLEEQQ__HHEEAADD(). See the examples below for further ex-
planation of how these macros are used.
SSIINNGGLLYY__LLIINNKKEEDD LLIISSTTSS
A singly-linked list is headed by a structure defined by the SSLLIISSTT__HHEEAADD()
macro. This structure contains a single pointer to the first element on
the list. The elements are singly linked for minimum space and pointer
manipulation overhead at the expense of O(n) removal for arbitrary ele-
ments. New elements can be added to the list after an existing element
or at the head of the list. A _S_L_I_S_T___H_E_A_D structure is declared as fol-
lows:
SLIST_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the list. A pointer
to the head of the list can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The _H_E_A_D_N_A_M_E facility is often not used, leading to the following bizarre
code:
SLIST_HEAD(, TYPE) head, *headp;
The SSLLIISSTT__EENNTTRRYY() macro declares a structure that connects the elements
in the list.
The SSLLIISSTT__IINNIITT() macro initializes the list referenced by _h_e_a_d.
The list can also be initialized statically by using the
SSLLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro like this:
SLIST_HEAD(HEADNAME, TYPE) head = SLIST_HEAD_INITIALIZER(head);
The SSLLIISSTT__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head of
the list.
The SSLLIISSTT__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the ele-
ment _l_i_s_t_e_l_m.
The SSLLIISSTT__RREEMMOOVVEE__HHEEAADD() macro removes the first element of the list
pointed by _h_e_a_d.
The SSLLIISSTT__FFIIRRSSTT(), and SSLLIISSTT__NNEEXXTT() macros can be used to traverse the
list:
for (np = SLIST_FIRST(&head); np != NULL; np = SLIST_NEXT(np, NAME))
Or, for simplicity, one can use the SSLLIISSTT__FFOORREEAACCHH() macro:
SLIST_FOREACH(np, head, NAME)
The SSLLIISSTT__EEMMPPTTYY() macro should be used to check whether a simple list is
empty.
LLIISSTTSS
A list is headed by a structure defined by the LLIISSTT__HHEEAADD() macro. This
structure contains a single pointer to the first element on the list.
The elements are doubly linked so that an arbitrary element can be re-
moved without traversing the list. New elements can be added to the list
after an existing element, before an existing element, or at the head of
the list. A _L_I_S_T___H_E_A_D structure is declared as follows:
LIST_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the list. A pointer
to the head of the list can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The _H_E_A_D_N_A_M_E facility is often not used, leading to the following bizarre
code:
LIST_HEAD(, TYPE) head, *headp;
The LLIISSTT__EENNTTRRYY() macro declares a structure that connects the elements in
the list.
The LLIISSTT__IINNIITT() macro initializes the list referenced by _h_e_a_d.
The list can also be initialized statically by using the
LLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro like this:
LIST_HEAD(HEADNAME, TYPE) head = LIST_HEAD_INITIALIZER(head);
The LLIISSTT__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head of
the list.
The LLIISSTT__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the ele-
ment _l_i_s_t_e_l_m.
The LLIISSTT__IINNSSEERRTT__BBEEFFOORREE() macro inserts the new element _e_l_m before the el-
ement _l_i_s_t_e_l_m.
The LLIISSTT__RREEMMOOVVEE() macro removes the element _e_l_m from the list.
The LLIISSTT__FFIIRRSSTT(), and LLIISSTT__NNEEXXTT() macros can be used to traverse the
list:
for (np = LIST_FIRST(&head); np != NULL; np = LIST_NEXT(np, NAME))
Or, for simplicity, one can use the LLIISSTT__FFOORREEAACCHH() macro:
LIST_FOREACH(np, head, NAME)
The LLIISSTT__EEMMPPTTYY() macro should be used to check whether a list is empty.
LLIISSTT EEXXAAMMPPLLEE
LIST_HEAD(listhead, entry) head;
struct listhead *headp; /* List head. */
struct entry {
...
LIST_ENTRY(entry) entries; /* List. */
...
} *n1, *n2, *np;
LIST_INIT(&head); /* Initialize the list. */
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
LIST_INSERT_HEAD(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
LIST_INSERT_AFTER(n1, n2, entries);
n2 = malloc(sizeof(struct entry)); /* Insert before. */
LIST_INSERT_BEFORE(n1, n2, entries);
/* Forward traversal. */
for (np = head.lh_first; np != NULL; np = np->entries.le_next)
np-> ...
while (head.lh_first != NULL) /* Delete. */
LIST_REMOVE(head.lh_first, entries);
SSIIMMPPLLEE QQUUEEUUEESS
A simple queue is headed by a structure defined by the SSIIMMPPLLEEQQ__HHEEAADD()
macro. This structure contains a pair of pointers, one to the first ele-
ment in the simple queue and the other to the last element in the simple
queue. The elements are singly linked. New elements can be added to the
queue after an existing element, at the head of the queue or at the tail
of the queue. A _S_I_M_P_L_E_Q___H_E_A_D structure is declared as follows:
SIMPLEQ_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the queue. A pointer
to the head of the queue can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The SSIIMMPPLLEEQQ__EENNTTRRYY() macro declares a structure that connects the elements
in the queue.
The SSIIMMPPLLEEQQ__IINNIITT() macro initializes the queue referenced by _h_e_a_d.
The queue can also be initialized statically by using the
SSIIMMPPLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro like this:
SIMPLEQ_HEAD(HEADNAME, TYPE) head = SIMPLEQ_HEAD_INITIALIZER(head);
The SSIIMMPPLLEEQQ__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head
of the queue.
The SSIIMMPPLLEEQQ__IINNSSEERRTT__TTAAIILL() macro inserts the new element _e_l_m at the end of
the queue.
The SSIIMMPPLLEEQQ__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the
element _l_i_s_t_e_l_m.
The SSIIMMPPLLEEQQ__RREEMMOOVVEE__HHEEAADD() macro removes the first element from the queue.
The SSIIMMPPLLEEQQ__FFIIRRSSTT(), and SSIIMMPPLLEEQQ__NNEEXXTT() macros can be used to traverse
the queue. The SSIIMMPPLLEEQQ__FFOORREEAACCHH() is used for queue traversal
SIMPLEQ_FOREACH(np, head, NAME)
The SSIIMMPPLLEEQQ__EEMMPPTTYY() macro should be used to check whether a list is emp-
ty.
SSIIMMPPLLEE QQUUEEUUEE EEXXAAMMPPLLEE
SIMPLEQ_HEAD(listhead, entry) head = SIMPLEQ_HEAD_INITIALIZER(head);
struct entry {
...
SIMPLEQ_ENTRY(entry) entries; /* List. */
...
} *n1, *n2, *np;
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
SIMPLEQ_INSERT_HEAD(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
SIMPLEQ_INSERT_AFTER(n1, n2, entries);
n2 = malloc(sizeof(struct entry)); /* Insert at the tail. */
SIMPLEQ_INSERT_TAIL(&head, n1, entries);
/* Forward traversal. */
for (np = SIMPLEQ_FIRST(&head); np != NULL; np = SIMPLEQ_NEXT(np, entries))
np-> ...
/* Delete. */
while (SIMPLEQ_FIRST(&head) != NULL)
SIMPLEQ_REMOVE_HEAD(&head, n1, entries);
TTAAIILL QQUUEEUUEESS
A tail queue is headed by a structure defined by the TTAAIILLQQ__HHEEAADD() macro.
This structure contains a pair of pointers, one to the first element in
the tail queue and the other to the last element in the tail queue. The
elements are doubly linked so that an arbitrary element can be removed
without traversing the tail queue. New elements can be added to the
queue after an existing element, before an existing element, at the head
of the queue, or at the end the queue. A _T_A_I_L_Q___H_E_A_D structure is de-
clared as follows:
TAILQ_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the tail queue. A
pointer to the head of the tail queue can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The TTAAIILLQQ__EENNTTRRYY() macro declares a structure that connects the elements
in the tail queue.
The TTAAIILLQQ__IINNIITT() macro initializes the tail queue referenced by _h_e_a_d.
The tail queue can also be initialized statically by using the
TTAAIILLQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro.
The TTAAIILLQQ__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head of
the tail queue.
The TTAAIILLQQ__IINNSSEERRTT__TTAAIILL() macro inserts the new element _e_l_m at the end of
the tail queue.
The TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the ele-
ment _l_i_s_t_e_l_m.
The TTAAIILLQQ__IINNSSEERRTT__BBEEFFOORREE() macro inserts the new element _e_l_m before the
element _l_i_s_t_e_l_m.
The TTAAIILLQQ__RREEMMOOVVEE() macro removes the element _e_l_m from the tail queue.
The TTAAIILL__FFIIRRSSTT(), TTAAIILLQQ__NNEEXXTT(), TTAAIILLQQ__LLAASSTT() and TTAAIILLQQ__PPRREEVV() macros can
be used to traverse a tail queue. The TTAAIILLQQ__FFOORREEAACCHH() is used for tail
queue traversal
TAILQ_FOREACH(np, head, NAME)
The TTAAIILLQQ__FFOORREEAACCHH__RREEVVEERRSSEE() acts like TTAAIILLQQ__FFOORREEAACCHH() but traverses the
tail queue in reverse.
The TTAAIILLQQ__EEMMPPTTYY() macro should be used to check whether a tail queue is
empty.
TTAAIILL QQUUEEUUEE EEXXAAMMPPLLEE
TAILQ_HEAD(tailhead, entry) head;
struct tailhead *headp; /* Tail queue head. */
struct entry {
...
TAILQ_ENTRY(entry) entries; /* Tail queue. */
...
} *n1, *n2, *np;
TAILQ_INIT(&head); /* Initialize the queue. */
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
TAILQ_INSERT_HEAD(&head, n1, entries);
n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
TAILQ_INSERT_TAIL(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
TAILQ_INSERT_AFTER(&head, n1, n2, entries);
n2 = malloc(sizeof(struct entry)); /* Insert before. */
TAILQ_INSERT_BEFORE(n1, n2, entries);
/* Forward traversal. */
for (np = TAILQ_FIRST(&head); np; np = TAILQ_NEXT(&head, entries))
np-> ...
/* Delete. */
while (np = TAILQ_FIRST(&head))
TAILQ_REMOVE(&head, np, entries);
CCIIRRCCUULLAARR QQUUEEUUEESS
A circular queue is headed by a structure defined by the CCIIRRCCLLEEQQ__HHEEAADD()
macro. This structure contains a pair of pointers, one to the first ele-
ment in the circular queue and the other to the last element in the cir-
cular queue. The elements are doubly linked so that an arbitrary element
can be removed without traversing the queue. New elements can be added
to the queue after an existing element, before an existing element, at
the head of the queue, or at the end of the queue. A _C_I_R_C_L_E_Q___H_E_A_D struc-
ture is declared as follows:
CIRCLEQ_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the circular queue. A
pointer to the head of the circular queue can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The CCIIRRCCLLEEQQ__EENNTTRRYY() macro declares a structure that connects the elements
in the circular queue.
The CCIIRRCCLLEEQQ__IINNIITT() macro initializes the circular queue referenced by
_h_e_a_d.
The circular queue can also be initialized statically by using the
CCIIRRCCLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro.
The CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head
of the circular queue.
The CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL() macro inserts the new element _e_l_m at the end of
the circular queue.
The CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the
element _l_i_s_t_e_l_m.
The CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE() macro inserts the new element _e_l_m before the
element _l_i_s_t_e_l_m.
The CCIIRRCCLLEEQQ__RREEMMOOVVEE() macro removes the element _e_l_m from the circular
queue.
The CCIIRRCCLLEEQQ__FFIIRRSSTT(), CCIIRRCCLLEEQQ__LLAASSTT(), CCIIRRCCLLEEQQ__EENNDD(), CCIIRRCCLLEEQQ__NNEEXXTT() and
CCIIRRCCLLEEQQ__PPRREEVV() macros can be used to traverse a circular queue. The
CCIIRRCCLLEEQQ__FFOORREEAACCHH() is used for circular queue forward traversal
CIRCLEQ_FOREACH(np, head, NAME)
The CCIIRRCCLLEEQQ__FFOORREEAACCHH__RREEVVEERRSSEE() macro acts like CCIIRRCCLLEEQQ__FFOORREEAACCHH() but tra-
verses the circular queue backwards.
The CCIIRRCCLLEEQQ__EEMMPPTTYY() macro should be used to check whether a circular
queue is empty.
CCIIRRCCUULLAARR QQUUEEUUEE EEXXAAMMPPLLEE
CIRCLEQ_HEAD(circleq, entry) head;
struct circleq *headp; /* Circular queue head. */
struct entry {
...
CIRCLEQ_ENTRY entries; /* Circular queue. */
...
} *n1, *n2, *np;
CIRCLEQ_INIT(&head); /* Initialize the circular queue. */
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
CIRCLEQ_INSERT_HEAD(&head, n1, entries);
n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
CIRCLEQ_INSERT_TAIL(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
n2 = malloc(sizeof(struct entry)); /* Insert before. */
CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
/* Forward traversal. */
for (np = CIRCLEQ_FIRST(&head); np != CIRCLEQ_END(&head);
np = CIRCLEQ_NEXT(np, entries))
np-> ...
/* Reverse traversal. */
for (np = CIRCLEQ_LAST(&head); np != CIRCLEQ_END(&head);
np = CIRCLEQ_PREV(np, entries))
np-> ...
/* Delete. */
while (CIRCLEQ_FIRST(&head) != CIRCLEQ_END(&head))
CIRCLEQ_REMOVE(&head, CIRCLEQ_FIRST(&head), entries);
NNOOTTEESS
The SSLLIISSTT__EENNDD(), LLIISSTT__EENNDD(), SSIIMMPPLLEEQQ__EENNDD() and TTAAIILLQQ__EENNDD() macros are
provided for symmetry with CCIIRRCCLLEEQQ__EENNDD(). They expand to NULL and don't
serve any useful purpose.
Trying to free a list in the following way is a common error:
LIST_FOREACH(var, head, entry)
free(var);
free(head);
Since _v_a_r is free'd, the FFOORREEAACCHH() macro refers to a pointer that may
have been reallocated already. Proper code needs a second variable.
for (var = LIST_FIRST(head); var != LIST_END(head); var = nxt) {
nxt = LIST_NEXT(var);
free(var);
}
LIST_INIT(head); /* to put the list back in order */
HHIISSTTOORRYY
The qquueeuuee functions first appeared in 4.4BSD.
OpenBSD 2.9 December 13, 1993 11