Home | History | Annotate | Line # | Download | only in libpthread
pthread_queue.h revision 1.1.2.1
      1 /*	$Id: pthread_queue.h,v 1.1.2.1 2001/07/13 02:04:33 nathanw Exp $	*/
      2 
      3 /*
      4  * Copyright
      5  */
      6 
      7 /* pthread_queue.h
      8  * Definition of a queue interface for the pthread library.
      9  * Style modeled on the sys/queue.h macros; implementation taken from
     10  * the tail queue, with the added property of static initializability
     11  * (and a corresponding extra cost in the _INSERT_TAIL() function.
     12 */
     13 
     14 
     15 
     16 /*
     17  * Queue definitions.
     18  */
     19 #define PTQ_HEAD(name, type)						\
     20 struct name {								\
     21 	struct type *ptqh_first;/* first element */			\
     22 	struct type **ptqh_last;/* addr of last next element */		\
     23 }
     24 
     25 #define PTQ_HEAD_INITIALIZER { NULL, NULL }
     26 
     27 
     28 #define PTQ_ENTRY(type)						\
     29 struct {								\
     30 	struct type *ptqe_next;	/* next element */			\
     31 	struct type **ptqe_prev;/* address of previous next element */	\
     32 }
     33 
     34 /*
     35  * Queue functions.
     36  */
     37 
     38 #define	PTQ_INIT(head) do {						\
     39 	(head)->ptqh_first = NULL;					\
     40 	(head)->ptqh_last = &(head)->ptqh_first;			\
     41 } while (/*CONSTCOND*/0)
     42 
     43 #define PTQ_INSERT_HEAD(head, elm, field) do {			\
     44 	if (((elm)->field.ptqe_next = (head)->ptqh_first) != NULL)	\
     45 		(head)->ptqh_first->field.ptqe_prev =			\
     46 		    &(elm)->field.ptqe_next;				\
     47 	else								\
     48 		(head)->ptqh_last = &(elm)->field.ptqe_next;		\
     49 	(head)->ptqh_first = (elm);					\
     50 	(elm)->field.ptqe_prev = &(head)->ptqh_first;			\
     51 } while (/*CONSTCOND*/0)
     52 
     53 #define PTQ_INSERT_TAIL(head, elm, field) do {				\
     54 	(elm)->field.ptqe_next = NULL;					\
     55 	if ((head)->ptqh_last == NULL)					\
     56 		(head)->ptqh_last = &(head)->ptqh_first;		\
     57 	(elm)->field.ptqe_prev = (head)->ptqh_last;			\
     58 	*(head)->ptqh_last = (elm);					\
     59 	(head)->ptqh_last = &(elm)->field.ptqe_next;			\
     60 } while (/*CONSTCOND*/0)
     61 
     62 #define PTQ_INSERT_AFTER(head, listelm, elm, field) do {		\
     63 	if (((elm)->field.ptqe_next = (listelm)->field.ptqe_next) != NULL)\
     64 		(elm)->field.ptqe_next->field.ptqe_prev = 		\
     65 		    &(elm)->field.ptqe_next;				\
     66 	else								\
     67 		(head)->ptqh_last = &(elm)->field.ptqe_next;		\
     68 	(listelm)->field.ptqe_next = (elm);				\
     69 	(elm)->field.ptqe_prev = &(listelm)->field.ptqe_next;		\
     70 } while (/*CONSTCOND*/0)
     71 
     72 #define	PTQ_INSERT_BEFORE(listelm, elm, field) do {			\
     73 	(elm)->field.ptqe_prev = (listelm)->field.ptqe_prev;		\
     74 	(elm)->field.ptqe_next = (listelm);				\
     75 	*(listelm)->field.ptqe_prev = (elm);				\
     76 	(listelm)->field.ptqe_prev = &(elm)->field.ptqe_next;		\
     77 } while (/*CONSTCOND*/0)
     78 
     79 #define PTQ_REMOVE(head, elm, field) do {				\
     80 	if (((elm)->field.ptqe_next) != NULL)				\
     81 		(elm)->field.ptqe_next->field.ptqe_prev = 		\
     82 		    (elm)->field.ptqe_prev;				\
     83 	else								\
     84 		(head)->ptqh_last = (elm)->field.ptqe_prev;		\
     85 	*(elm)->field.ptqe_prev = (elm)->field.ptqe_next;		\
     86 } while (/*CONSTCOND*/0)
     87 
     88 /*
     89  * Queue access methods.
     90  */
     91 #define	PTQ_EMPTY(head)		((head)->ptqh_first == NULL)
     92 #define	PTQ_FIRST(head)		((head)->ptqh_first)
     93 #define	PTQ_NEXT(elm, field)		((elm)->field.ptqe_next)
     94 
     95 #define PTQ_LAST(head, headname) \
     96 	(*(((struct headname *)((head)->ptqh_last))->ptqh_last))
     97 #define PTQ_PREV(elm, headname, field) \
     98 	(*(((struct headname *)((elm)->field.ptqe_prev))->ptqh_last))
     99 
    100 #define PTQ_FOREACH(var, head, field)					\
    101 	for ((var) = ((head)->ptqh_first);				\
    102 		(var);							\
    103 		(var) = ((var)->field.ptqe_next))
    104 
    105 #define PTQ_FOREACH_REVERSE(var, head, headname, field)		\
    106 	for ((var) = (*(((struct headname *)((head)->ptqh_last))->ptqh_last));	\
    107 		(var);							\
    108 		(var) = (*(((struct headname *)((var)->field.ptqe_prev))->ptqh_last)))
    109