| @@ -1,24 +1,24 @@ | | | @@ -1,24 +1,24 @@ |
1 | .\" $NetBSD: gcq.3,v 1.2 2009/05/27 17:47:46 snj Exp $ | | 1 | .\" $NetBSD: gcq.3,v 1.3 2009/05/27 19:23:28 wiz Exp $ |
2 | .\" | | 2 | .\" |
3 | .\" Not (c) 2007 Matthew Orgass | | 3 | .\" Not (c) 2007 Matthew Orgass |
4 | .\" This file is public domain, meaning anyone can make any use of part or all | | 4 | .\" This file is public domain, meaning anyone can make any use of part or all |
5 | .\" of this file including copying into other works without credit. Any use, | | 5 | .\" of this file including copying into other works without credit. Any use, |
6 | .\" modified or not, is solely the responsibility of the user. If this file | | 6 | .\" modified or not, is solely the responsibility of the user. If this file |
7 | .\" is part of a collection then use in the collection is governed by the | | 7 | .\" is part of a collection then use in the collection is governed by the |
8 | .\" terms of the collection. | | 8 | .\" terms of the collection. |
9 | .\" | | 9 | .\" |
10 | .Dd May 1, 2007 | | 10 | .Dd May 1, 2007 |
11 | .Dt gcq 3 | | 11 | .Dt GCQ 3 |
12 | .Os | | 12 | .Os |
13 | .Sh NAME | | 13 | .Sh NAME |
14 | .Nm GCQ_INIT , | | 14 | .Nm GCQ_INIT , |
15 | .Nm GCQ_INIT_HEAD , | | 15 | .Nm GCQ_INIT_HEAD , |
16 | .Nm gcq_init , | | 16 | .Nm gcq_init , |
17 | .Nm gcq_init_head , | | 17 | .Nm gcq_init_head , |
18 | .Nm gcq_q , | | 18 | .Nm gcq_q , |
19 | .Nm gcq_hq , | | 19 | .Nm gcq_hq , |
20 | .Nm gcq_head , | | 20 | .Nm gcq_head , |
21 | .Nm gcq_remove , | | 21 | .Nm gcq_remove , |
22 | .Nm gcq_onlist , | | 22 | .Nm gcq_onlist , |
23 | .Nm gcq_empty , | | 23 | .Nm gcq_empty , |
24 | .Nm gcq_linked , | | 24 | .Nm gcq_linked , |
| @@ -222,76 +222,76 @@ | | | @@ -222,76 +222,76 @@ |
222 | .Fn GCQ_FOREACH_RO_REV_TYPED var nvar head tvar type name | | 222 | .Fn GCQ_FOREACH_RO_REV_TYPED var nvar head tvar type name |
223 | .Fn GCQ_FOREACH_DEQUEUED_TYPED var nvar head tvar type name | | 223 | .Fn GCQ_FOREACH_DEQUEUED_TYPED var nvar head tvar type name |
224 | .Fn GCQ_FOREACH_DEQUEUED_REV_TYPED var nvar head tvar type name | | 224 | .Fn GCQ_FOREACH_DEQUEUED_REV_TYPED var nvar head tvar type name |
225 | .Fn GCQ_FIND var head cond | | 225 | .Fn GCQ_FIND var head cond |
226 | .Fn GCQ_FIND_REV var head cond | | 226 | .Fn GCQ_FIND_REV var head cond |
227 | .Fn GCQ_FIND_TYPED var head tvar type name cond | | 227 | .Fn GCQ_FIND_TYPED var head tvar type name cond |
228 | .Fn GCQ_FIND_REV_TYPED var head tvar type name cond | | 228 | .Fn GCQ_FIND_REV_TYPED var head tvar type name cond |
229 | .Fn GCQ_ASSERT cond | | 229 | .Fn GCQ_ASSERT cond |
230 | .Sh DESCRIPTION | | 230 | .Sh DESCRIPTION |
231 | The generic circular queue is a doubly linked list designed for efficient | | 231 | The generic circular queue is a doubly linked list designed for efficient |
232 | merge operations and unconditional removal. | | 232 | merge operations and unconditional removal. |
233 | All basic operations can be performed with or without use of a separate head, | | 233 | All basic operations can be performed with or without use of a separate head, |
234 | allowing easy replacement of any pointers where efficient removal is desired. | | 234 | allowing easy replacement of any pointers where efficient removal is desired. |
235 | The meaning of the data type will not change; direct use and defined | | 235 | The meaning of the data type will not change; direct use and defined |
236 | operations can be mixed when convenient. | | 236 | operations can be mixed when convenient. |
237 | The basic type is: | | 237 | The basic type is: |
238 | .Bd -literal -offset indent | | 238 | .Bd -literal -offset indent |
239 | struct gcq { | | 239 | struct gcq { |
240 | struct gcq *q_next; | | 240 | struct gcq *q_next; |
241 | struct gcq *q_prev; | | 241 | struct gcq *q_prev; |
242 | }; | | 242 | }; |
243 | .Ed | | 243 | .Ed |
244 | .Pp | | 244 | .Pp |
245 | The structure must first be initialized such that the | | 245 | The structure must first be initialized such that the |
246 | .Va q_next | | 246 | .Va q_next |
247 | and | | 247 | and |
248 | .Va q_prev | | 248 | .Va q_prev |
249 | members point to the beginning of the | | 249 | members point to the beginning of the |
250 | .Vt struct gcq . | | 250 | .Vt struct gcq . |
251 | This can be done with | | 251 | This can be done with |
252 | .Fn gcq_init | | 252 | .Fn gcq_init |
253 | and | | 253 | and |
254 | .Fn gcq_init_head | | 254 | .Fn gcq_init_head |
255 | or with constant initializers | | 255 | or with constant initializers |
256 | .Fn GCQ_INIT | | 256 | .Fn GCQ_INIT |
257 | and | | 257 | and |
258 | .Fn GCQ_INIT_HEAD . | | 258 | .Fn GCQ_INIT_HEAD . |
259 | A | | 259 | A |
260 | .Vt struct gcq | | 260 | .Vt struct gcq |
261 | should | | 261 | should |
262 | .Em never | | 262 | .Em never |
263 | be given | | 263 | be given |
264 | .Dv NULL | | 264 | .Dv NULL |
265 | values. | | 265 | values. |
266 | .Pp | | 266 | .Pp |
267 | The structure containing the | | 267 | The structure containing the |
268 | .Vt struct gcq | | 268 | .Vt struct gcq |
269 | can be retrieved by pointer arithmetic in the | | 269 | can be retrieved by pointer arithmetic in the |
270 | .Fn GCQ_ITEM | | 270 | .Fn GCQ_ITEM |
271 | macro. | | 271 | macro. |
272 | List traversal normally requires knowledge of the list head to safely | | 272 | List traversal normally requires knowledge of the list head to safely |
273 | retrieve list items. | | 273 | retrieve list items. |
274 | .Pp | | 274 | .Pp |
275 | Capitalized operation names are macros and should be assumed to cause multiple | | 275 | Capitalized operation names are macros and should be assumed to cause multiple |
276 | evaluation of arguments. | | 276 | evaluation of arguments. |
277 | .Li TYPED | | 277 | .Li TYPED |
278 | variants of macros set a typed pointer variable instead of or in addition to | | 278 | variants of macros set a typed pointer variable instead of or in addition to |
279 | .Vt struct gcq * | | 279 | .Vt struct gcq * |
280 | arguments. | | 280 | arguments. |
281 | Additional type specific inlines and macros around some GCQ operations can be | | 281 | Additional type specific inlines and macros around some GCQ operations can be |
282 | useful. | | 282 | useful. |
283 | .Pp | | 283 | .Pp |
284 | A few assertions are provided when | | 284 | A few assertions are provided when |
285 | .Dv DIAGNOSTIC | | 285 | .Dv DIAGNOSTIC |
286 | is defined in the kernel or | | 286 | is defined in the kernel or |
287 | .Dv _DIAGNOSTIC | | 287 | .Dv _DIAGNOSTIC |
288 | is defined in userland. | | 288 | is defined in userland. |
289 | If | | 289 | If |
290 | .Dv GCQ_USE_ASSERT | | 290 | .Dv GCQ_USE_ASSERT |
291 | is defined prior to header inclusions | | 291 | is defined prior to header inclusions |
292 | then | | 292 | then |
293 | .Fn assert | | 293 | .Fn assert |
294 | will be used for assertions and | | 294 | will be used for assertions and |
295 | .Dv NDEBUG | | 295 | .Dv NDEBUG |
296 | can be used to turn them off. | | 296 | can be used to turn them off. |
297 | .Fn GCQ_ASSERT | | 297 | .Fn GCQ_ASSERT |
| @@ -301,232 +301,232 @@ None of the operations accept | | | @@ -301,232 +301,232 @@ None of the operations accept |
301 | arguments, however this is not tested by assertion. | | 301 | arguments, however this is not tested by assertion. |
302 | .Pp | | 302 | .Pp |
303 | The head is separately named for type checking but contains only a | | 303 | The head is separately named for type checking but contains only a |
304 | .Vt struct gcq , | | 304 | .Vt struct gcq , |
305 | a pointer to which can be retrieved via | | 305 | a pointer to which can be retrieved via |
306 | .Fn gcq_hq . | | 306 | .Fn gcq_hq . |
307 | The reverse operation is performed by | | 307 | The reverse operation is performed by |
308 | .Fn gcq_head , | | 308 | .Fn gcq_head , |
309 | turning the supplied | | 309 | turning the supplied |
310 | .Vt struct gcq * | | 310 | .Vt struct gcq * |
311 | into | | 311 | into |
312 | .Vt struct gcq_head * . | | 312 | .Vt struct gcq_head * . |
313 | .Fn gcq_q | | 313 | .Fn gcq_q |
314 | returns its | | 314 | returns its |
315 | .Vt struct gcq * | | 315 | .Vt struct gcq * |
316 | argument and is used for type checking in | | 316 | argument and is used for type checking in |
317 | .Fn GCQ_ITEM . | | 317 | .Fn GCQ_ITEM . |
318 | There are no functions for retrieving the raw | | 318 | There are no functions for retrieving the raw |
319 | .Va q_prev | | 319 | .Va q_prev |
320 | and | | 320 | and |
321 | .Va q_next | | 321 | .Va q_next |
322 | pointers as these are usually clearer when used directly (if at all). | | 322 | pointers as these are usually clearer when used directly (if at all). |
323 | .Pp | | 323 | .Pp |
324 | .Fn gcq_remove | | 324 | .Fn gcq_remove |
325 | returns the element removed and is always a valid operation after | | 325 | returns the element removed and is always a valid operation after |
326 | initialization. | | 326 | initialization. |
327 | .Fn gcq_onlist | | 327 | .Fn gcq_onlist |
328 | returns | | 328 | returns |
329 | .Dv false | | 329 | .Dv false |
330 | if the structure links to itself and | | 330 | if the structure links to itself and |
331 | .Dv true | | 331 | .Dv true |
332 | otherwise. | | 332 | otherwise. |
333 | .Fn gcq_empty | | 333 | .Fn gcq_empty |
334 | is the negation of this operation performed on a head. | | 334 | is the negation of this operation performed on a head. |
335 | .Fn gcq_linked | | 335 | .Fn gcq_linked |
336 | tests if | | 336 | tests if |
337 | .Li "prev->q_next == next && next->q_prev == prev" . | | 337 | .Li "prev-\*[Gt]q_next == next \*[Am]\*[Am] next-\*[Gt]q_prev == prev" . |
338 | .Pp | | 338 | .Pp |
339 | .Fn gcq_tie | | 339 | .Fn gcq_tie |
340 | ties | | 340 | ties |
341 | .Va src | | 341 | .Va src |
342 | after | | 342 | after |
343 | .Va dst | | 343 | .Va dst |
344 | such that that if the old lists are DST, DST2 and SRC, SRC2, the new list is | | 344 | such that that if the old lists are DST, DST2 and SRC, SRC2, the new list is |
345 | DST, SRC, SRC2, DST2. | | 345 | DST, SRC, SRC2, DST2. |
346 | If | | 346 | If |
347 | .Va dst | | 347 | .Va dst |
348 | and | | 348 | and |
349 | .Va src | | 349 | .Va src |
350 | are on the same list then any elements between but not including | | 350 | are on the same list then any elements between but not including |
351 | .Va dst | | 351 | .Va dst |
352 | and | | 352 | and |
353 | .Va src | | 353 | .Va src |
354 | are cut from the list. | | 354 | are cut from the list. |
355 | If | | 355 | If |
356 | .Li dst == src | | 356 | .Li dst == src |
357 | then the result is the same as | | 357 | then the result is the same as |
358 | .Fn gcq_remove . | | 358 | .Fn gcq_remove . |
359 | .Fn gcq_tie | | 359 | .Fn gcq_tie |
360 | is equivalent to | | 360 | is equivalent to |
361 | .Fn gcq_tie_after | | 361 | .Fn gcq_tie_after |
362 | except that the latter must only be used with arguments on separate lists or | | 362 | except that the latter must only be used with arguments on separate lists or |
363 | not on lists and asserts that | | 363 | not on lists and asserts that |
364 | .Li "src != dst && dst->q_prev != src" . | | 364 | .Li "src != dst \*[Am]\*[Am] dst-\*[Gt]q_prev != src" . |
365 | .Fn gcq_tie_before | | 365 | .Fn gcq_tie_before |
366 | performs the same operation on | | 366 | performs the same operation on |
367 | .Li dst->q_prev . | | 367 | .Li dst-\*[Gt]q_prev . |
368 | .Pp | | 368 | .Pp |
369 | .Fn gcq_merge | | 369 | .Fn gcq_merge |
370 | moves any elements on list | | 370 | moves any elements on list |
371 | .Va src | | 371 | .Va src |
372 | (but not | | 372 | (but not |
373 | .Va src | | 373 | .Va src |
374 | itself) to list | | 374 | itself) to list |
375 | .Va dst . | | 375 | .Va dst . |
376 | It is normally used with two heads via | | 376 | It is normally used with two heads via |
377 | .Fn gcq_merge_head | | 377 | .Fn gcq_merge_head |
378 | or | | 378 | or |
379 | .Fn gcq_merge_tail . | | 379 | .Fn gcq_merge_tail . |
380 | If | | 380 | If |
381 | .Dv GCQ_UNCONDITIONAL_MERGE | | 381 | .Dv GCQ_UNCONDITIONAL_MERGE |
382 | is defined prior to header inclusion then the merge operations will always | | 382 | is defined prior to header inclusion then the merge operations will always |
383 | perform a tie then remove | | 383 | perform a tie then remove |
384 | .Va src | | 384 | .Va src |
385 | from the new list, which may reduce code size slightly. | | 385 | from the new list, which may reduce code size slightly. |
386 | .Pp | | 386 | .Pp |
387 | .Fn gcq_clear | | 387 | .Fn gcq_clear |
388 | initializes all elements currently linked with | | 388 | initializes all elements currently linked with |
389 | .Va q | | 389 | .Va q |
390 | and is normally used with a head as | | 390 | and is normally used with a head as |
391 | .Fn gcq_remove_all . | | 391 | .Fn gcq_remove_all . |
392 | .Pp | | 392 | .Pp |
393 | .Fn gcq_insert_after | | 393 | .Fn gcq_insert_after |
394 | and | | 394 | and |
395 | .Fn gcq_insert_before | | 395 | .Fn gcq_insert_before |
396 | are slightly optimized versions of | | 396 | are slightly optimized versions of |
397 | .Fn gcq_tie | | 397 | .Fn gcq_tie |
398 | for the case where | | 398 | for the case where |
399 | .Va off | | 399 | .Va off |
400 | is not on a list and include assertions to this effect, which are also useful | | 400 | is not on a list and include assertions to this effect, which are also useful |
401 | to detect missing initialization. | | 401 | to detect missing initialization. |
402 | .Fn gcq_insert_head | | 402 | .Fn gcq_insert_head |
403 | and | | 403 | and |
404 | .Fn gcq_insert_tail | | 404 | .Fn gcq_insert_tail |
405 | are the same operations applied to a head. | | 405 | are the same operations applied to a head. |
406 | .Pp | | 406 | .Pp |
407 | .Fn GCQ_GOT_FIRST | | 407 | .Fn GCQ_GOT_FIRST |
408 | and | | 408 | and |
409 | .Fn GCQ_GOT_LAST | | 409 | .Fn GCQ_GOT_LAST |
410 | set | | 410 | set |
411 | .Va var | | 411 | .Va var |
412 | to a pointer to the first or last | | 412 | to a pointer to the first or last |
413 | .Vt struct gcq | | 413 | .Vt struct gcq |
414 | in the list | | 414 | in the list |
415 | or | | 415 | or |
416 | .Dv NULL | | 416 | .Dv NULL |
417 | if the list is empty and return | | 417 | if the list is empty and return |
418 | .Dv false | | 418 | .Dv false |
419 | if empty and | | 419 | if empty and |
420 | .Dv true | | 420 | .Dv true |
421 | otherwise. | | 421 | otherwise. |
422 | The boolean return is to emphasise that it is not normally safe and useful to | | 422 | The boolean return is to emphasise that it is not normally safe and useful to |
423 | directly pass the raw first/next/etc. pointer to another function. | | 423 | directly pass the raw first/next/etc. pointer to another function. |
424 | The macros are written such that the | | 424 | The macros are written such that the |
425 | .Dv NULL | | 425 | .Dv NULL |
426 | values will be optimized out if not otherwise used. | | 426 | values will be optimized out if not otherwise used. |
427 | .Li DEQUEUED | | 427 | .Li DEQUEUED |
428 | variants also remove the member from the list. | | 428 | variants also remove the member from the list. |
429 | .Li COND | | 429 | .Li COND |
430 | variants take an additional condition that is evaluated when the macro would | | 430 | variants take an additional condition that is evaluated when the macro would |
431 | otherwise return | | 431 | otherwise return |
432 | .Dv true . | | 432 | .Dv true . |
433 | If the condition is false | | 433 | If the condition is false |
434 | .Va var | | 434 | .Va var |
435 | or | | 435 | or |
436 | .Va tvar | | 436 | .Va tvar |
437 | is set to | | 437 | is set to |
438 | .Dv NULL | | 438 | .Dv NULL |
439 | and no dequeue is performed. | | 439 | and no dequeue is performed. |
440 | .Pp | | 440 | .Pp |
441 | .Fn GCQ_GOT_NEXT | | 441 | .Fn GCQ_GOT_NEXT |
442 | and variants take pointers to the current position, list head, and starting | | 442 | and variants take pointers to the current position, list head, and starting |
443 | point as arguments. | | 443 | point as arguments. |
444 | The list head will be skipped when it is reached unless it is equal to the | | 444 | The list head will be skipped when it is reached unless it is equal to the |
445 | starting point; upon reaching the starting point | | 445 | starting point; upon reaching the starting point |
446 | .Va var | | 446 | .Va var |
447 | will be set to | | 447 | will be set to |
448 | .Dv NULL | | 448 | .Dv NULL |
449 | and the macro will return | | 449 | and the macro will return |
450 | .Dv false . | | 450 | .Dv false . |
451 | The next and prev macros also assert that | | 451 | The next and prev macros also assert that |
452 | .Va current | | 452 | .Va current |
453 | is on the list unless it is equal to | | 453 | is on the list unless it is equal to |
454 | .Va start . | | 454 | .Va start . |
455 | These macros are the only provided method for iterating through the list from | | 455 | These macros are the only provided method for iterating through the list from |
456 | an arbitrary point. | | 456 | an arbitrary point. |
457 | Traversal macros are only provided for list heads, however | | 457 | Traversal macros are only provided for list heads, however |
458 | .Fn gcq_head | | 458 | .Fn gcq_head |
459 | can be used to treat any item as a head. | | 459 | can be used to treat any item as a head. |
460 | .Pp | | 460 | .Pp |
461 | Foreach variants contain an embedded | | 461 | Foreach variants contain an embedded |
462 | .Li for | | 462 | .Li for |
463 | statement for iterating over a list. | | 463 | statement for iterating over a list. |
464 | Those containing | | 464 | Those containing |
465 | .Li REV | | 465 | .Li REV |
466 | use the | | 466 | use the |
467 | .Va q_prev | | 467 | .Va q_prev |
468 | pointer for traversal, others use | | 468 | pointer for traversal, others use |
469 | .Va q_next . | | 469 | .Va q_next . |
470 | The plain | | 470 | The plain |
471 | .Fn GCQ_FOREACH | | 471 | .Fn GCQ_FOREACH |
472 | uses a single variable. | | 472 | uses a single variable. |
473 | .Li NVAR | | 473 | .Li NVAR |
474 | variants save the next pointer at the top of the loop so that the current | | 474 | variants save the next pointer at the top of the loop so that the current |
475 | element can be removed without adjusting | | 475 | element can be removed without adjusting |
476 | .Va var . | | 476 | .Va var . |
477 | This is useful when | | 477 | This is useful when |
478 | .Va var | | 478 | .Va var |
479 | is passed to a function that might remove it but will not otherwise modify | | 479 | is passed to a function that might remove it but will not otherwise modify |
480 | the list. | | 480 | the list. |
481 | When the head is reached both | | 481 | When the head is reached both |
482 | .Va var | | 482 | .Va var |
483 | and | | 483 | and |
484 | .Va nvar | | 484 | .Va nvar |
485 | elements are left pointing to the list head. | | 485 | elements are left pointing to the list head. |
486 | .Li FOREACH | | 486 | .Li FOREACH |
487 | asserts that | | 487 | asserts that |
488 | .Va var , | | 488 | .Va var , |
489 | and | | 489 | and |
490 | .Li NVAR | | 490 | .Li NVAR |
491 | asserts that | | 491 | asserts that |
492 | .Va nvar | | 492 | .Va nvar |
493 | does not point to itself when starting the next loop. | | 493 | does not point to itself when starting the next loop. |
494 | This assertion takes place after the variable is tested against the head so | | 494 | This assertion takes place after the variable is tested against the head so |
495 | it is safe to remove all elements from the list. | | 495 | it is safe to remove all elements from the list. |
496 | .Li RO | | 496 | .Li RO |
497 | variants also set | | 497 | variants also set |
498 | .Va nvar | | 498 | .Va nvar |
499 | but assert that the two variables are linked at the end of each iteration. | | 499 | but assert that the two variables are linked at the end of each iteration. |
500 | This is useful when calling a function that is not supposed to remove the | | 500 | This is useful when calling a function that is not supposed to remove the |
501 | element passed. | | 501 | element passed. |
502 | .Li DEQUEUED | | 502 | .Li DEQUEUED |
503 | variants are like | | 503 | variants are like |
504 | .Li NVAR | | 504 | .Li NVAR |
505 | but remove each element before the code block is executed. | | 505 | but remove each element before the code block is executed. |
506 | .Li TYPED | | 506 | .Li TYPED |
507 | variants are equivalent to the untyped versions except that they take three | | 507 | variants are equivalent to the untyped versions except that they take three |
508 | extra arguments: a typed pointer, the type name, and the member name of the | | 508 | extra arguments: a typed pointer, the type name, and the member name of the |
509 | .Vt struct gcq | | 509 | .Vt struct gcq |
510 | used in this list. | | 510 | used in this list. |
511 | .Va tvar | | 511 | .Va tvar |
512 | is set to | | 512 | is set to |
513 | .Dv NULL | | 513 | .Dv NULL |
514 | when the head is reached. | | 514 | when the head is reached. |
515 | .Pp | | 515 | .Pp |
516 | .Fn GCQ_FIND | | 516 | .Fn GCQ_FIND |
517 | is a foreach loop that does nothing except break when the supplied condition | | 517 | is a foreach loop that does nothing except break when the supplied condition |
518 | is true. | | 518 | is true. |
519 | .Li REV | | 519 | .Li REV |
520 | and | | 520 | and |
521 | .Li TYPED | | 521 | .Li TYPED |
522 | variants are available. | | 522 | variants are available. |
523 | .\" .Sh EXAMPLES | | 523 | .\" .Sh EXAMPLES |
524 | .Sh SEE ALSO | | 524 | .Sh SEE ALSO |
525 | .Xr gcc 1 , | | 525 | .Xr gcc 1 , |
526 | .Xr assert 3 , | | | |
527 | .Xr _DIAGASSERT 3 , | | 526 | .Xr _DIAGASSERT 3 , |
| | | 527 | .Xr assert 3 , |
528 | .Xr queue 3 , | | 528 | .Xr queue 3 , |
529 | .Xr KASSERT 9 | | 529 | .Xr KASSERT 9 |
530 | .Sh HISTORY | | 530 | .Sh HISTORY |
531 | GCQ appeared in | | 531 | GCQ appeared in |
532 | .Nx 5.0 . | | 532 | .Nx 5.0 . |