BRL-CAD
list.h
Go to the documentation of this file.
1 /* L I S T . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #ifndef BU_LIST_H
22 #define BU_LIST_H
23 
24 #include "common.h"
25 
26 #include "bu/defines.h"
27 #include "bu/magic.h"
28 
30 
31 /*----------------------------------------------------------------------*/
32 /** @addtogroup list */
33 /** @{*/
34 /** @file libbu/list.c
35  *
36  * @brief Support routines for doubly-linked lists.
37  *
38  * These macros assume that all user-provided structures will have a
39  * "struct bu_list" as their first element (often named "l" [ell]).
40  * Thus, a pointer to the bu_list struct is a "pun" for the
41  * user-provided structure as well, and the pointers can be converted
42  * back and forth safely with type casts.
43  *
44  * Furthermore, the head of the linked list could be a full instance
45  * of the user-provided structure (although the storage-conscious
46  * programmer could make the head just an bu_list structure, with
47  * careful type casting). This results in a doubly-linked circular
48  * list, with the head having the same shape as all the list members.
49  * The application is free to make use of this symmetry and store data
50  * values in the head, or the extra storage in the head can be
51  * ignored.
52  *
53  * Where a macro expects an argument "p", it should be a pointer to a
54  * user-provided structure.
55  *
56  * Where a macro expects an argument "hp", it should be a pointer to a
57  * "struct bu_list" located in the list head, e.g., &(head.l).
58  *
59  * Where a macro expects an argument "old", "new", or "cur", it should
60  * be a pointer to the "struct bu_list" located either in a
61  * user-provided structure, e.g. &((p)->l), or for the case of "old"
62  * it may also be in the list head.
63  *
64  @code
65  --- BEGIN EXAMPLE ---
66 
67  // make bu_list the first element in your structure
68  struct my_structure {
69  struct bu_list l;
70  int my_data;
71  };
72 
73  // your actual list
74  struct my_structure *my_list = NULL;
75 
76  // allocate and initialize your list head
77  BU_GET(my_list, struct my_structure);
78  BU_LIST_INIT(&(my_list->l));
79  my_list->my_data = -1;
80 
81  // add a new element to your list
82  struct my_structure *new_entry;
83  BU_GET(new_entry, struct my_structure);
84  new_entry->my_data = rand();
85  BU_LIST_PUSH(&(my_list->l), &(new_entry->l));
86 
87  // iterate over your list, remove all items
88  struct my_structure *entry;
89  while (BU_LIST_WHILE(entry, my_structure, &(my_list->l))) {
90  bu_log("Entry value is %d\n", entry->my_data);
91  BU_LIST_DEQUEUE(&(entry->l));
92  BU_PUT(entry, struct my_structure);
93  }
94  BU_PUT(my_list, struct my_structure);
95 
96  --- END EXAMPLE ---
97  @endcode
98  *
99  * Dequeueing the head of a list is a valid and well defined operation
100  * which should be performed with caution. Unless a pointer to some
101  * other element of the list is retained by the application, the rest
102  * of the linked list can no longer be referred to.
103  *
104  * The "magic" field of the list header _must_ be set to the constant
105  * BU_LIST_HEAD_MAGIC, but the "magic" field of all list members
106  * should be established by user code, to identify the type of
107  * structure that the bu_list structure is embedded in. It is
108  * permissible for one list to contain an arbitrarily mixed set of
109  * user "magic" numbers, as long as the head is properly marked.
110  *
111  * There is a dual set of terminology used in some of the macros:
112  *
113  * FIRST/ LAST - from the point of view of the list head
114  * NEXT / PREV - from the point of view of a list member
115  * forw / back - the actual pointer names
116  */
117 
118 struct bu_list {
119  uint32_t magic; /**< @brief Magic # for mem id/check */
120  struct bu_list *forw; /**< @brief "forward", "next" */
121  struct bu_list *back; /**< @brief "back", "last" */
122 };
123 typedef struct bu_list bu_list_t;
124 #define BU_LIST_NULL ((struct bu_list *)0)
125 
126 /**
127  * macro for setting the magic number of a non-head list node
128  */
129 #define BU_LIST_MAGIC_SET(_l, _magic) {(_l)->magic = (_magic);}
130 
131 /**
132  * macro for testing whether a list node's magic number is equal to a
133  * specific magic number
134  */
135 #define BU_LIST_MAGIC_EQUAL(_l, _magic) ((_l)->magic == (_magic))
136 
137 /**
138  * there is no reliable way to assert the integrity of an arbitrary
139  * bu_list struct since the magic can be anything, therefore there is
140  * no BU_CK_LIST(). we can, however, check for a valid head node.
141  */
142 #define BU_CK_LIST_HEAD(_p) BU_CKMAG((_p), BU_LIST_HEAD_MAGIC, "bu_list")
143 
144 /**
145  * initializes a bu_list struct as a circular list without allocating
146  * any memory. call BU_LIST_MAGIC_SET() to change the list type.
147  */
148 #define BU_LIST_INIT(_hp) { \
149  (_hp)->forw = (_hp)->back = (_hp); \
150  (_hp)->magic = BU_LIST_HEAD_MAGIC; /* used by circ. macros */ }
151 
152 /**
153  * initializes a bu_list struct node with a particular non-head node
154  * magic number without allocating any memory.
155  */
156 #define BU_LIST_INIT_MAGIC(_hp, _magic) { \
157  BU_LIST_INIT((_hp)); \
158  BU_LIST_MAGIC_SET((_hp), (_magic)); \
159  }
160 
161 /**
162  * macro suitable for declaration statement zero-initialization of a
163  * bu_list struct, but not suitably for validation with
164  * BU_CK_LIST_HEAD() as the list pointers are NULL. does not allocate
165  * memory.
166  */
167 #define BU_LIST_INIT_ZERO { 0, BU_LIST_NULL, BU_LIST_NULL }
168 
169 /**
170  * returns truthfully whether a bu_list has been initialized via
171  * BU_LIST_INIT(). lists initialized with BU_LIST_INIT_ZERO or
172  * zero-allocated will not return true as their forward/backward
173  * pointers reference nothing.
174  */
175 #define BU_LIST_IS_INITIALIZED(_hp) (((struct bu_list *)(_hp) != BU_LIST_NULL) && LIKELY((_hp)->forw != BU_LIST_NULL))
176 
177 
178 /**
179  * Insert "new" item in front of "old" item. Often, "old" is the
180  * head. To put the new item at the tail of the list, insert before
181  * the head, e.g. * BU_LIST_INSERT(&(head.l), &((p)->l));
182  */
183 #define BU_LIST_INSERT(old, new) { \
184  BU_ASSERT((void *)(old) != (void *)NULL); \
185  BU_ASSERT((void *)(new) != (void *)NULL); \
186  (new)->back = (old)->back; \
187  (old)->back = (new); \
188  (new)->forw = (old); \
189  BU_ASSERT((void *)((new)->back) != (void *)NULL); \
190  (new)->back->forw = (new); }
191 
192 /**
193  * Append "new" item after "old" item. Often, "old" is the head. To
194  * put the new item at the head of the list, append after the head,
195  * e.g. * BU_LIST_APPEND(&(head.l), &((p)->l));
196  */
197 #define BU_LIST_APPEND(old, new) { \
198  BU_ASSERT((void *)(old) != (void *)NULL); \
199  BU_ASSERT((void *)(new) != (void *)NULL); \
200  (new)->forw = (old)->forw; \
201  (new)->back = (old); \
202  (old)->forw = (new); \
203  BU_ASSERT((void *)((old)->forw) != (void *)NULL); \
204  (new)->forw->back = (new); }
205 
206 /**
207  * Dequeue "cur" item from anywhere in doubly-linked list
208  */
209 #define BU_LIST_DEQUEUE(cur) { \
210  BU_ASSERT((void *)(cur) != (void *)NULL); \
211  if (LIKELY((cur)->forw != NULL)) (cur)->forw->back = (cur)->back; \
212  if (LIKELY((cur)->back != NULL)) (cur)->back->forw = (cur)->forw; \
213  (cur)->forw = (cur)->back = BU_LIST_NULL; /* sanity */ }
214 
215 /**
216  * Dequeue "cur" but do not fix its links
217  */
218 #define BU_LIST_DQ(cur) {\
219  BU_ASSERT((void *)(cur) != (void *)NULL); \
220  if (LIKELY((cur)->forw != NULL)) (cur)->forw->back = (cur)->back; \
221  if (LIKELY((cur)->back != NULL)) (cur)->back->forw = (cur)->forw; }
222 
223 #define BU_LIST_DQ_T(cur, type) (\
224  (cur)->forw->back = (cur)->back, \
225  (cur)->back->forw = (cur)->forw, \
226  (type *)(cur))
227 
228 /**
229  * This version of BU_LIST_DEQUEUE uses the comma operator in order to
230  * return a typecast version of the dequeued pointer
231  */
232 #define BU_LIST_DEQUEUE_T(cur, type) (\
233  (cur)->forw->back = (cur)->back, \
234  (cur)->back->forw = (cur)->forw, \
235  (cur)->forw = (cur)->back = BU_LIST_NULL, \
236  (type *)(cur))
237 
238 
239 /**
240  * The Stack Discipline
241  *
242  * BU_LIST_PUSH places p at the tail of hp. BU_LIST_POP sets p to
243  * last element in hp's list (else NULL) and, if p is non-null,
244  * dequeues it.
245  */
246 #define BU_LIST_PUSH(hp, p) \
247  BU_LIST_APPEND(hp, (struct bu_list *)(p))
248 
249 #define BU_LIST_POP(structure, hp, p) \
250  { \
251  if (BU_LIST_NON_EMPTY(hp)) { \
252  (p) = ((struct structure *)((hp)->forw)); \
253  BU_LIST_DEQUEUE((struct bu_list *)(p)); \
254  } else { \
255  (p) = (struct structure *) 0; \
256  } \
257  }
258 
259 #define BU_LIST_POP_T(hp, type) \
260  (type *)bu_list_pop(hp)
261 
262 /**
263  * "Bulk transfer" all elements from the list headed by src_hd onto
264  * the list headed by dest_hd, without examining every element in the
265  * list. src_hd is left with a valid but empty list.
266  *
267  * BU_LIST_INSERT_LIST places src_hd elements at head of dest_hd list,
268  * BU_LIST_APPEND_LIST places src_hd elements at end of dest_hd list.
269  */
270 #define BU_LIST_INSERT_LIST(dest_hp, src_hp) \
271  if (LIKELY(BU_LIST_NON_EMPTY(src_hp))) { \
272  struct bu_list *_first = (src_hp)->forw; \
273  struct bu_list *_last = (src_hp)->back; \
274  (dest_hp)->forw->back = _last; \
275  _last->forw = (dest_hp)->forw; \
276  (dest_hp)->forw = _first; \
277  _first->back = (dest_hp); \
278  (src_hp)->forw = (src_hp)->back = (src_hp); \
279  }
280 
281 #define BU_LIST_APPEND_LIST(dest_hp, src_hp) \
282  if (LIKELY(BU_LIST_NON_EMPTY(src_hp))) {\
283  struct bu_list *_first = (src_hp)->forw; \
284  struct bu_list *_last = (src_hp)->back; \
285  _first->back = (dest_hp)->back; \
286  (dest_hp)->back->forw = _first; \
287  (dest_hp)->back = _last; \
288  _last->forw = (dest_hp); \
289  (src_hp)->forw = (src_hp)->back = (src_hp); \
290  }
291 
292 /**
293  * Test if a doubly linked list is empty, given head pointer
294  */
295 #define BU_LIST_IS_EMPTY(hp) ((hp)->forw == (hp))
296 #define BU_LIST_NON_EMPTY(hp) ((hp)->forw != (hp))
297 #define BU_LIST_NON_EMPTY_P(p, structure, hp) \
298  (((p)=(struct structure *)((hp)->forw)) != (struct structure *)(hp))
299 #define BU_LIST_IS_CLEAR(hp) ((hp)->magic == 0 && \
300  (hp)->forw == BU_LIST_NULL && \
301  (hp)->back == BU_LIST_NULL)
302 
303 /* Return re-cast pointer to first element on list.
304  * No checking is performed to see if list is empty.
305  */
306 #define BU_LIST_LAST(structure, hp) \
307  ((struct structure *)((hp)->back))
308 #define BU_LIST_BACK(structure, hp) \
309  ((struct structure *)((hp)->back))
310 #define BU_LIST_PREV(structure, hp) \
311  ((struct structure *)((hp)->back))
312 #define BU_LIST_FIRST(structure, hp) \
313  ((struct structure *)((hp)->forw))
314 #define BU_LIST_FORW(structure, hp) \
315  ((struct structure *)((hp)->forw))
316 #define BU_LIST_NEXT(structure, hp) \
317  ((struct structure *)((hp)->forw))
318 
319 /**
320  * Boolean test to see if current list element is the head
321  */
322 #define BU_LIST_IS_HEAD(p, hp) \
323  (((struct bu_list *)(p)) == (struct bu_list *)(hp))
324 #define BU_LIST_NOT_HEAD(p, hp) \
325  (!BU_LIST_IS_HEAD(p, hp))
326 
327 /**
328  * Boolean test to see if previous list element is the head
329  */
330 #define BU_LIST_PREV_IS_HEAD(p, hp)\
331  (((struct bu_list *)(p))->back == (struct bu_list *)(hp))
332 #define BU_LIST_PREV_NOT_HEAD(p, hp)\
333  (!BU_LIST_PREV_IS_HEAD(p, hp))
334 
335 /**
336  * Boolean test to see if the next list element is the head
337  */
338 #define BU_LIST_NEXT_IS_HEAD(p, hp) \
339  (((struct bu_list *)(p))->forw == (struct bu_list *)(hp))
340 #define BU_LIST_NEXT_NOT_HEAD(p, hp) \
341  (!BU_LIST_NEXT_IS_HEAD(p, hp))
342 
343 #define BU_LIST_EACH(hp, p, type) \
344  for ((p)=(type *)BU_LIST_FIRST(bu_list, hp); \
345  (p) && BU_LIST_NOT_HEAD(p, hp); \
346  (p)=(type *)BU_LIST_PNEXT(bu_list, p)) \
347 
348 #define BU_LIST_REVEACH(hp, p, type) \
349  for ((p)=(type *)BU_LIST_LAST(bu_list, hp); \
350  (p) && BU_LIST_NOT_HEAD(p, hp); \
351  (p)=(type *)BU_LIST_PREV(bu_list, ((struct bu_list *)(p)))) \
352 
353 #define BU_LIST_TAIL(hp, start, p, type) \
354  for ((p)=(type *)start; \
355  (p) && BU_LIST_NOT_HEAD(p, hp); \
356  (p)=(type *)BU_LIST_PNEXT(bu_list, (p)))
357 
358 /**
359  * Intended as innards for a for loop to visit all nodes on list, e.g.:
360  *
361  * for (BU_LIST_FOR(p, structure, hp)) {
362  * work_on(p);
363  * }
364  */
365 #define BU_LIST_FOR(p, structure, hp) \
366  (p)=BU_LIST_FIRST(structure, hp); \
367  (p) && BU_LIST_NOT_HEAD(p, hp); \
368  (p)=BU_LIST_PNEXT(structure, p)
369 
370 #define BU_LIST_FOR_BACKWARDS(p, structure, hp) \
371  (p)=BU_LIST_LAST(structure, hp); \
372  (p) && BU_LIST_NOT_HEAD(p, hp); \
373  (p)=BU_LIST_PLAST(structure, p)
374 
375 /**
376  * Process all the list members except hp and the actual head. Useful
377  * when starting somewhere besides the head.
378  */
379 #define BU_LIST_FOR_CIRC(p, structure, hp) \
380  (p)=BU_LIST_PNEXT_CIRC(structure, hp); \
381  (p) && BU_LIST_NOT_HEAD(p, hp); \
382  (p)=BU_LIST_PNEXT_CIRC(structure, p)
383 
384 /**
385  * Intended as innards for a for loop to visit elements of two lists
386  * in tandem, e.g.:
387  *
388  * for (BU_LIST_FOR2(p1, p2, structure, hp1, hp2)) {
389  * process(p1, p2);
390  * }
391  */
392 #define BU_LIST_FOR2(p1, p2, structure, hp1, hp2) \
393  (p1)=BU_LIST_FIRST(structure, hp1), \
394  (p2)=BU_LIST_FIRST(structure, hp2); \
395  (p1) && BU_LIST_NOT_HEAD((struct bu_list *)(p1), (hp1)) && \
396  (p2) && BU_LIST_NOT_HEAD((struct bu_list *)(p2), (hp2)); \
397  (p1)=BU_LIST_NEXT(structure, (struct bu_list *)(p1)), \
398  (p2)=BU_LIST_NEXT(structure, (struct bu_list *)(p2))
399 
400 /**
401  * Innards for a while loop that constantly picks off the first
402  * element. Useful mostly for a loop that will dequeue every list
403  * element, e.g.:
404  *
405  * while (BU_LIST_WHILE(p, structure, hp)) {
406  *@n BU_LIST_DEQUEUE(&(p->l));
407  *@n free((char *)p);
408  *@n }
409  */
410 #define BU_LIST_WHILE(p, structure, hp) \
411  (((p)=(struct structure *)((hp)->forw)) != (struct structure *)(hp))
412 
413 /**
414  * Return the magic number of the first (or last) item on a list
415  */
416 #define BU_LIST_FIRST_MAGIC(hp) ((hp)->forw->magic)
417 #define BU_LIST_LAST_MAGIC(hp) ((hp)->back->magic)
418 
419 /**
420  * Return pointer to next (or previous) element, which may be the head
421  */
422 #define BU_LIST_PNEXT(structure, p) \
423  ((struct structure *)(((struct bu_list *)(p))->forw))
424 #define BU_LIST_PLAST(structure, p) \
425  ((struct structure *)(((struct bu_list *)(p))->back))
426 
427 /**
428  * Return pointer two links away, which may include the head
429  */
430 #define BU_LIST_PNEXT_PNEXT(structure, p) \
431  ((struct structure *)(((struct bu_list *)(p))->forw->forw))
432 #define BU_LIST_PNEXT_PLAST(structure, p) \
433  ((struct structure *)(((struct bu_list *)(p))->forw->back))
434 #define BU_LIST_PLAST_PNEXT(structure, p) \
435  ((struct structure *)(((struct bu_list *)(p))->back->forw))
436 #define BU_LIST_PLAST_PLAST(structure, p) \
437  ((struct structure *)(((struct bu_list *)(p))->back->back))
438 
439 /**
440  * Return pointer to circular next element; i.e., ignoring the list head
441  */
442 #define BU_LIST_PNEXT_CIRC(structure, p) \
443  ((BU_LIST_FIRST_MAGIC((struct bu_list *)(p)) == BU_LIST_HEAD_MAGIC) ? \
444  BU_LIST_PNEXT_PNEXT(structure, (struct bu_list *)(p)) : \
445  BU_LIST_PNEXT(structure, p))
446 
447 /**
448  * Return pointer to circular last element; i.e., ignoring the list head
449  */
450 #define BU_LIST_PPREV_CIRC(structure, p) \
451  ((BU_LIST_LAST_MAGIC((struct bu_list *)(p)) == BU_LIST_HEAD_MAGIC) ? \
452  BU_LIST_PLAST_PLAST(structure, (struct bu_list *)(p)) : \
453  BU_LIST_PLAST(structure, p))
454 
455 /**
456  * Support for membership on multiple linked lists.
457  *
458  * When a structure of type '_type' contains more than one bu_list
459  * structure within it (such as the NMG edgeuse), this macro can be
460  * used to convert a pointer '_ptr2' to a "midway" bu_list structure
461  * (an element called '_name2' in structure '_type') back into a
462  * pointer to the overall enclosing structure. Examples:
463  *
464  * eu = BU_LIST_MAIN_PTR(edgeuse, midway, l2);
465  *
466  * eu1 = BU_LIST_MAIN_PTR(edgeuse, BU_LIST_FIRST(bu_list, &eg1->eu_hd2), l2);
467  *
468  * Files using BU_LIST_MAIN_PTR will need to include stddef.h
469  */
470 #define BU_LIST_MAIN_PTR(_type, _ptr2, _name2) \
471  ((struct _type *)(((char *)(_ptr2)) - (bu_offsetof(struct _type, _name2) + bu_offsetof(struct bu_list, magic))))
472 
473 /**
474  * Creates and initializes a bu_list head structure
475  */
476 BU_EXPORT extern struct bu_list *bu_list_new(void);
477 
478 /**
479  * Returns the results of BU_LIST_POP
480  */
481 BU_EXPORT extern struct bu_list *bu_list_pop(struct bu_list *hp);
482 
483 /**
484  * Returns the number of elements on a bu_list brand linked list.
485  */
486 BU_EXPORT extern int bu_list_len(const struct bu_list *hd);
487 
488 /**
489  * Reverses the order of elements in a bu_list linked list.
490  */
491 BU_EXPORT extern void bu_list_reverse(struct bu_list *hd);
492 
493 /**
494  * Given a list of structures allocated with bu_malloc() or
495  * bu_calloc() enrolled on a bu_list head, walk the list and free the
496  * structures. This routine can only be used when the structures have
497  * no interior pointers.
498  */
499 BU_EXPORT extern void bu_list_free(struct bu_list *hd);
500 
501 /**
502  * Simple parallel-safe routine for appending a data structure to the
503  * end of a bu_list doubly-linked list.
504  *
505  * @par Issues:
506  * Only one semaphore shared by all list heads.
507  * @n No portable way to notify waiting thread(s) that are sleeping
508  */
509 BU_EXPORT extern void bu_list_parallel_append(struct bu_list *headp,
510  struct bu_list *itemp);
511 
512 /**
513  * Simple parallel-safe routine for dequeueing one data structure from
514  * the head of a bu_list doubly-linked list.
515  * If the list is empty, wait until some other thread puts something on
516  * the list.
517  *
518  * @par Issues:
519  * No portable way to not spin and burn CPU time while waiting
520  * @n for something to show up on the list.
521  */
522 BU_EXPORT extern struct bu_list *bu_list_parallel_dequeue(struct bu_list *headp);
523 
524 /**
525  * Generic bu_list doubly-linked list checker.
526  */
527 BU_EXPORT extern void bu_ck_list(const struct bu_list *hd,
528  const char *str);
529 
530 /**
531  * bu_list doubly-linked list checker which checks the magic number for
532  * all elements in the linked list
533  */
534 BU_EXPORT extern void bu_ck_list_magic(const struct bu_list *hd,
535  const char *str,
536  const uint32_t magic);
537 
538 
539 /**
540  * Creates and initializes a bu_list head structure
541  */
542 BU_EXPORT extern struct bu_list *bu_list_new(void);
543 
544 /**
545  * Returns the results of BU_LIST_POP
546  */
547 BU_EXPORT extern struct bu_list *bu_list_pop(struct bu_list *hp);
548 
549 /**
550  * Returns the number of elements on a bu_list brand linked list.
551  */
552 BU_EXPORT extern int bu_list_len(const struct bu_list *hd);
553 
554 /**
555  * Reverses the order of elements in a bu_list linked list.
556  */
557 BU_EXPORT extern void bu_list_reverse(struct bu_list *hd);
558 
559 /**
560  * Given a list of structures allocated with bu_malloc() or
561  * bu_calloc() enrolled on a bu_list head, walk the list and free the
562  * structures. This routine can only be used when the structures have
563  * no interior pointers.
564  */
565 BU_EXPORT extern void bu_list_free(struct bu_list *hd);
566 
567 /**
568  * Simple parallel-safe routine for appending a data structure to the
569  * end of a bu_list doubly-linked list.
570  *
571  * @par Issues:
572  * Only one semaphore shared by all list heads.
573  * @n No portable way to notify waiting thread(s) that are sleeping
574  */
575 BU_EXPORT extern void bu_list_parallel_append(struct bu_list *headp,
576  struct bu_list *itemp);
577 
578 /**
579  * Simple parallel-safe routine for dequeueing one data structure from
580  * the head of a bu_list doubly-linked list.
581  * If the list is empty, wait until some other thread puts something on
582  * the list.
583  *
584  * @par Issues:
585  * No portable way to not spin and burn CPU time while waiting
586  * @n for something to show up on the list.
587  */
588 BU_EXPORT extern struct bu_list *bu_list_parallel_dequeue(struct bu_list *headp);
589 
590 /**
591  * Generic bu_list doubly-linked list checker.
592  */
593 BU_EXPORT extern void bu_ck_list(const struct bu_list *hd,
594  const char *str);
595 
596 /**
597  * bu_list doubly-linked list checker which checks the magic number for
598  * all elements in the linked list
599  */
600 BU_EXPORT extern void bu_ck_list_magic(const struct bu_list *hd,
601  const char *str,
602  const uint32_t magic);
603 
604 /** @} */
605 
607 
608 #endif /* BU_LIST_H */
609 
610 /*
611  * Local Variables:
612  * mode: C
613  * tab-width: 8
614  * indent-tabs-mode: t
615  * c-file-style: "stroustrup"
616  * End:
617  * ex: shiftwidth=4 tabstop=8
618  */
struct bu_list * bu_list_parallel_dequeue(struct bu_list *headp)
Definition: list.c:98
Definition: list.h:118
Header file for the BRL-CAD common definitions.
struct bu_list * bu_list_pop(struct bu_list *hp)
Definition: list.c:41
#define __BEGIN_DECLS
Definition: common.h:73
struct bu_list * back
"back", "last"
Definition: list.h:121
void bu_ck_list(const struct bu_list *hd, const char *str)
Definition: list.c:116
oldeumate l2 magic
Definition: nmg_mod.c:3843
uint32_t magic
Magic # for mem id/check.
Definition: list.h:119
void bu_list_parallel_append(struct bu_list *headp, struct bu_list *itemp)
Definition: list.c:90
void bu_list_reverse(struct bu_list *hd)
int bu_list_len(const struct bu_list *hd)
#define __END_DECLS
Definition: common.h:74
struct bu_list * bu_list_new(void)
Definition: list.c:30
struct bu_list * forw
"forward", "next"
Definition: list.h:120
void bu_list_free(struct bu_list *hd)
Definition: list.c:79
void bu_ck_list_magic(const struct bu_list *hd, const char *str, const uint32_t magic)
Definition: list.c:157