xref: /titanic_51/usr/src/uts/common/io/bnxe/577xx/include/listq.h (revision d14abf155341d55053c76eeec58b787a456b753b)
1  /*******************************************************************************
2   * The information contained in this file is confidential and proprietary to
3   * ZNK Corporation.  No part of this file may be reproduced or distributed,
4   * in any form or by any means for any purpose, without the express written
5   * permission of ZNK Corporation.
6   *
7   * (c) COPYRIGHT 1998 ZNK Corporation, ALL RIGHTS RESERVED.
8   *
9   * Single link list routines:
10   *    void              s_list_init        (s_list_t *,  *head, *tail, cnt)
11   *    void              s_list_clear       (s_list_t *)
12   *    void              s_list_push_head   (s_list_t *,  s_list_entry_t *)
13   *    s_list_entry_t *  s_list_pop_head    (s_list_t *)
14   *    void              s_list_push_tail   (s_list_t *,  s_list_entry_t *)
15   *    s_list_entry_t *  s_list_peek_head   (s_list_t *)
16   *    s_list_entry_t *  s_list_peek_tail   (s_list_t *)
17   *    s_list_entry_t *  s_list_next_entry  (s_list_entry_t *)
18   *    unsigned long     s_list_entry_cnt   (s_list_t *)
19   *    char              s_list_is_empty    (s_list_t *)
20   *    void              s_list_add_head    (s_list_t *,  s_list_t *)
21   *    void              s_list_add_tail    (s_list_t *,  s_list_t *)
22   *    void              s_list_split       (d_list_t *,  d_list_t *, d_list_entry_t *, ulong)
23   *
24   * Double link list routines:
25   *    void              d_list_init        (d_list_t *,  *head, *tail, cnt)
26   *    void              d_list_clear       (d_list_t *)
27   *    void              d_list_push_head   (d_list_t *,  d_list_entry_t *)
28   *    d_list_entry_t *  d_list_pop_head    (d_list_t *)
29   *    void              d_list_push_tail   (d_list_t *,  d_list_entry_t *)
30   *    d_list_entry_t *  d_list_pop_tail    (d_list_t *)
31   *    d_list_entry_t *  d_list_peek_head   (d_list_t *)
32   *    d_list_entry_t *  d_list_peek_tail   (d_list_t *)
33   *    d_list_entry_t *  d_list_next_entry  (d_list_entry_t *)
34   *    void              d_list_remove_entry(d_list_t *,  d_list_entry_t *)
35   *    void              d_list_insert_entry(d_list_t *,  *prev, *next, *new)
36   *    d_list_entry_t *  d_list_prev_entry  (d_list_entry_t *)
37   *    unsigned long     d_list_entry_cnt   (d_list_t *)
38   *    char              d_list_is_empty    (d_list_t *)
39   *    void              d_list_add_head    (d_list_t *,  d_list_t *)
40   *    void              d_list_add_tail    (d_list_t *,  d_list_t *)
41   *
42   * Array list routines:
43   *    void              q_list_init        (q_list_t *,  q_list_entry *, ulong)
44   *    void              q_list_clear       (q_list_t *)
45   *    void              q_list_push_head   (q_list_t *,  q_list_entry_t)
46   *    q_list_entry_t    q_list_pop_head    (q_list_t *)
47   *    void              q_list_push_tail   (q_list_t *,  q_list_entry_t)
48   *    q_list_entry_t    q_list_pop_tail    (q_list_t *)
49   *    q_list_entry_t    q_list_peek_head   (q_list_t *)
50   *    q_list_entry_t    q_list_peek_tail   (q_list_t *)
51   *    unsigned long     q_list_entry_cnt   (q_list_t *)
52   *    char              q_list_is_empty    (q_list_t *)
53   *    char              q_list_is_full     (q_list_t *)
54   *
55   * History:
56   *    03/30/98 Hav Khauv                Initial version.
57   ******************************************************************************/
58  
59  #ifndef _listq_h_
60  #define _listq_h_
61  
62  
63  
64  /*******************************************************************************
65   * Single link list.
66   ******************************************************************************/
67  
68  typedef struct _s_list_entry_t
69  {
70      struct _s_list_entry_t *next;
71  } s_list_entry_t;
72  
73  #define S_LINK_CAST(_p)                 ((s_list_entry_t *) (_p))
74  
75  
76  typedef struct _s_list_t
77  {
78      s_list_entry_t *head;
79      s_list_entry_t *tail;
80      unsigned long cnt;
81  } s_list_t;
82  
83  
84  
85  #ifdef _INLINE_LISTQ_CALLS
86  
87  
88  __inline
89  void
90  s_list_init(
91      s_list_t *s_list,
92      s_list_entry_t *head_entry,
93      s_list_entry_t *tail_entry,
94      unsigned long entry_cnt)
95  {
96      s_list->head = head_entry;
97      s_list->tail = tail_entry;
98      s_list->cnt = entry_cnt;
99  }
100  
101  
102  __inline
103  void
104  s_list_clear(
105      s_list_t *s_list)
106  {
107      s_list->head = (s_list_entry_t *) 0;
108      s_list->tail = (s_list_entry_t *) 0;
109      s_list->cnt = 0;
110  }
111  
112  
113  __inline
114  void
115  s_list_push_head(
116      s_list_t *s_list,
117      s_list_entry_t *s_entry)
118  {
119      s_entry->next = s_list->head;
120  
121      if(s_list->tail == (s_list_entry_t *) 0)
122      {
123          s_list->tail = s_entry;
124      }
125      s_list->head = s_entry;
126  
127      s_list->cnt++;
128  }
129  
130  
131  __inline
132  s_list_entry_t *
133  s_list_pop_head(
134      s_list_t *s_list)
135  {
136      s_list_entry_t *s_entry;
137  
138      s_entry = s_list->head;
139      if(s_list->head)
140      {
141          s_list->head = s_list->head->next;
142          if(s_list->head == (s_list_entry_t *) 0)
143          {
144              s_list->tail = (s_list_entry_t *) 0;
145          }
146  
147          s_list->cnt--;
148      }
149  
150      return s_entry;
151  }
152  
153  
154  __inline
155  void
156  s_list_push_tail(
157      s_list_t *s_list,
158      s_list_entry_t *s_entry)
159  {
160      s_entry->next = (s_list_entry_t *) 0;
161  
162      if(s_list->tail)
163      {
164          s_list->tail->next = s_entry;
165      }
166      else
167      {
168          s_list->head = s_entry;
169      }
170      s_list->tail = s_entry;
171  
172      s_list->cnt++;
173  }
174  
175  
176  __inline
177  s_list_entry_t *
178  s_list_peek_head(
179      s_list_t *s_list)
180  {
181      return s_list->head;
182  }
183  
184  
185  __inline
186  s_list_entry_t *
187  s_list_peek_tail(
188      s_list_t *s_list)
189  {
190      return s_list->tail;
191  }
192  
193  
194  __inline
195  s_list_entry_t *
196  s_list_next_entry(
197      s_list_entry_t *s_entry)
198  {
199      return s_entry->next;
200  }
201  
202  
203  __inline
204  unsigned long
205  s_list_entry_cnt(
206      s_list_t *s_list)
207  {
208      return s_list->cnt;
209  }
210  
211  
212  __inline
213  char
214  s_list_is_empty(
215      s_list_t *s_list)
216  {
217      return s_list->cnt == 0;
218  }
219  
220  
221  __inline
222  void
223  s_list_add_head(
224      s_list_t *s_list,
225      s_list_t *s_list_head)
226  {
227      if(s_list->cnt == 0)
228      {
229          *s_list = *s_list_head;
230      }
231      else if(s_list_head->cnt)
232      {
233          s_list_head->tail->next = s_list->head;
234          s_list->head = s_list_head->head;
235          s_list->cnt += s_list_head->cnt;
236      }
237  }
238  
239  
240  __inline
241  void
242  s_list_add_tail(
243      s_list_t *s_list,
244      s_list_t *s_list_tail)
245  {
246      if(s_list->cnt == 0)
247      {
248          *s_list = *s_list_tail;
249      }
250      else if(s_list_tail->cnt)
251      {
252          s_list->tail->next = s_list_tail->head;
253          s_list->tail = s_list_tail->tail;
254          s_list->cnt += s_list_tail->cnt;
255      }
256  }
257  
258  __inline
259  void
260  s_list_split(
261      s_list_t * s_list,
262      s_list_t * s_list_head,
263      s_list_entry_t * split_entry,
264      unsigned long entry_cnt)
265  {
266      if (split_entry->next == NULL) {
267          s_list_head->head = s_list->head;
268          s_list_head->tail = split_entry;
269          s_list_head->cnt = entry_cnt;
270  
271          s_list->head = NULL;
272          s_list->tail = NULL;
273          s_list->cnt = 0;
274      } else {
275          s_list_head->head = s_list->head;
276          s_list_head->tail = split_entry;
277          s_list_head->cnt = entry_cnt;
278  
279          s_list->head = split_entry->next;
280          s_list->cnt = s_list->cnt - entry_cnt;
281          split_entry->next = NULL;
282  
283      }
284  }
285  
286  #else
287  
288  
289  #define s_list_init(_s_list, _head_entry, _tail_entry, _entry_cnt) \
290      (_s_list)->head = (_head_entry); \
291      (_s_list)->tail = (_tail_entry); \
292      (_s_list)->cnt = (_entry_cnt)
293  
294  
295  #define s_list_clear(_s_list) \
296      (_s_list)->head = (s_list_entry_t *) 0; \
297      (_s_list)->tail = (s_list_entry_t *) 0; \
298      (_s_list)->cnt = 0
299  
300  
301  #define s_list_push_head(_s_list, _s_entry) \
302      (_s_entry)->next = (_s_list)->head; \
303      if((_s_list)->tail == (s_list_entry_t *) 0) \
304      { \
305          (_s_list)->tail = (_s_entry); \
306      } \
307      (_s_list)->head = (_s_entry); \
308      (_s_list)->cnt++
309  
310  
311  #define s_list_pop_head(_s_list) \
312      (_s_list)->head; \
313      if((_s_list)->head) \
314      { \
315          (_s_list)->head = (_s_list)->head->next; \
316          if((_s_list)->head == (s_list_entry_t *) 0) \
317          { \
318              (_s_list)->tail = (s_list_entry_t *) 0; \
319          } \
320          (_s_list)->cnt--; \
321      }
322  
323  
324  #define s_list_push_tail(_s_list, _s_entry) \
325      (_s_entry)->next = (s_list_entry_t *) 0; \
326      if((_s_list)->tail) \
327      { \
328          (_s_list)->tail->next = (_s_entry); \
329      } \
330      else \
331      { \
332          (_s_list)->head = (_s_entry); \
333      } \
334      (_s_list)->tail = (_s_entry); \
335      (_s_list)->cnt++
336  
337  
338  #define s_list_peek_head(_s_list)       ((_s_list)->head)
339  
340  
341  #define s_list_peek_tail(_s_list)       ((_s_list)->tail)
342  
343  
344  #define s_list_next_entry(_s_entry)     ((_s_entry)->next)
345  
346  
347  #define s_list_entry_cnt(_s_list)       ((_s_list)->cnt)
348  
349  
350  #define s_list_is_empty(_s_list)        ((_s_list)->cnt == 0)
351  
352  
353  #define s_list_add_head(_s_list, _s_list_head) \
354      if((_s_list)->cnt == 0) \
355      { \
356          *(_s_list) = *(_s_list_head); \
357      } \
358      else if((_s_list_head)->cnt) \
359      { \
360          (_s_list_head)->tail->next = (_s_list)->head; \
361          (_s_list)->head = (_s_list_head)->head; \
362          (_s_list)->cnt += (_s_list_head)->cnt; \
363      }
364  
365  #define s_list_add_tail(_s_list, _s_list_tail) \
366      if((_s_list)->cnt == 0) \
367      { \
368          *(_s_list) = *(_s_list_tail); \
369      } \
370      else if((_s_list_tail)->cnt) \
371      { \
372          (_s_list)->tail->next = (_s_list_tail)->head; \
373          (_s_list)->tail = (_s_list_tail)->tail; \
374          (_s_list)->cnt += (_s_list_tail)->cnt; \
375      }
376  
377  #define s_list_split(_s_list, _s_list_head, _split_entry, _entry_cnt) \
378      if ((_split_entry)->next == NULL) { \
379          (_s_list_head)->head = (_s_list)->head; \
380          (_s_list_head)->tail = _split_entry; \
381          (_s_list_head)->cnt = _entry_cnt; \
382          (_s_list)->head = NULL; \
383          (_s_list)->tail = NULL; \
384          (_s_list)->cnt = 0; \
385      } else { \
386          (_s_list_head)->head = (_s_list)->head; \
387          (_s_list_head)->tail = _split_entry; \
388          (_s_list_head)->cnt = (_entry_cnt); \
389          (_s_list)->head = (_split_entry)->next; \
390          (_s_list)->cnt = (_s_list)->cnt - (_entry_cnt); \
391          (_split_entry)->next = NULL; \
392      }
393  
394  #endif
395  
396  
397  
398  /*******************************************************************************
399   * Double link list entry.
400   ******************************************************************************/
401  
402  typedef struct _d_list_entry_t
403  {
404      struct _d_list_entry_t *next;
405      struct _d_list_entry_t *prev;
406  } d_list_entry_t;
407  
408  #define D_LINK_CAST(_p)                 ((d_list_entry_t *) (_p))
409  
410  
411  typedef struct _d_list_t
412  {
413      d_list_entry_t *head;
414      d_list_entry_t *tail;
415      unsigned long cnt;
416  } d_list_t;
417  
418  
419  
420  #ifdef _INLINE_LISTQ_CALLS
421  
422  
423  __inline
424  void
425  d_list_init(
426      d_list_t *d_list,
427      d_list_entry_t *head_entry,
428      d_list_entry_t *tail_entry,
429      unsigned long entry_cnt)
430  {
431      d_list->head = head_entry;
432      d_list->tail = tail_entry;
433      d_list->cnt = entry_cnt;
434  }
435  
436  
437  __inline
438  void
439  d_list_clear(
440      d_list_t *d_list)
441  {
442      d_list->head = (d_list_entry_t *) 0;
443      d_list->tail = (d_list_entry_t *) 0;
444      d_list->cnt = 0;
445  }
446  
447  
448  __inline
449  void
450  d_list_push_head(
451      d_list_t *d_list,
452      d_list_entry_t *d_entry)
453  {
454      d_entry->prev = (d_list_entry_t *) 0;
455      d_entry->next = d_list->head;
456  
457      if(d_list->tail == (d_list_entry_t *) 0)
458      {
459          d_list->tail = d_entry;
460      }
461      else
462      {
463          d_list->head->prev = d_entry;
464      }
465  
466      d_list->head = d_entry;
467  
468      d_list->cnt++;
469  }
470  
471  
472  __inline
473  d_list_entry_t *
474  d_list_pop_head(
475      d_list_t *d_list)
476  {
477      d_list_entry_t *d_entry;
478  
479      d_entry = d_list->head;
480      if(d_list->head)
481      {
482          d_list->head = d_list->head->next;
483          if(d_list->head)
484          {
485              d_list->head->prev = (d_list_entry_t *) 0;
486          }
487          else
488          {
489              d_list->tail = (d_list_entry_t *) 0;
490          }
491  
492          d_list->cnt--;
493      }
494  
495      return d_entry;
496  }
497  
498  
499  __inline
500  void
501  d_list_push_tail(
502      d_list_t *d_list,
503      d_list_entry_t *d_entry)
504  {
505      d_entry->next = (d_list_entry_t *) 0;
506      d_entry->prev = d_list->tail;
507  
508      if(d_list->tail)
509      {
510          d_list->tail->next = d_entry;
511      }
512      else
513      {
514          d_list->head = d_entry;
515      }
516      d_list->tail = d_entry;
517  
518      d_list->cnt++;
519  }
520  
521  
522  __inline
523  d_list_entry_t *
524  d_list_pop_tail(
525      d_list_t *d_list)
526  {
527      d_list_entry_t *d_entry;
528  
529      d_entry = d_list->tail;
530  
531      if(d_list->tail)
532      {
533          d_list->tail = d_list->tail->prev;
534          if(d_list->tail)
535          {
536              d_list->tail->next = (d_list_entry_t *) 0;
537          }
538          else
539          {
540              d_list->head = (d_list_entry_t *) 0;
541          }
542  
543          d_list->cnt--;
544      }
545  
546      return d_entry;
547  }
548  
549  
550  __inline
551  d_list_entry_t *
552  d_list_peek_head(
553      d_list_t *d_list)
554  {
555      return d_list->head;
556  }
557  
558  
559  __inline
560  d_list_entry_t *
561  d_list_peek_tail(
562      d_list_t *d_list)
563  {
564      return d_list->tail;
565  }
566  
567  
568  __inline
569  d_list_entry_t *
570  d_list_next_entry(
571      d_list_entry_t *d_entry)
572  {
573      return d_entry->next;
574  }
575  
576  
577  __inline
578  void
579  d_list_remove_entry(
580      d_list_t *d_list,
581      d_list_entry_t *d_entry)
582  {
583      if(d_list->head == d_entry)
584      {
585          d_list_pop_head(d_list);
586      }
587      else if(d_list->tail == d_entry)
588      {
589          d_list_pop_tail(d_list);
590      }
591      else
592      {
593          d_entry->prev->next = d_entry->next;
594          d_entry->next->prev = d_entry->prev;
595          d_list->cnt--;
596      }
597  }
598  
599  __inline
600  void
601  d_list_insert_entry(
602      d_list_t *d_list,
603      d_list_entry_t *d_entry_prev,
604      d_list_entry_t *d_entry_next,
605      d_list_entry_t *d_entry)
606  {
607      if (d_entry_prev  == NULL)
608      {
609          d_list_push_head(d_list, d_entry);
610      }
611      else if (d_entry_next == NULL)
612      {
613          d_list_push_tail(d_list, d_entry);
614      }
615      else
616      {
617          d_entry->next = d_entry_next;
618          d_entry->prev = d_entry_prev;
619          d_entry_prev->next = d_entry;
620          d_entry_next->prev = d_entry;
621          d_list->cnt++;
622      }
623  }
624  
625  
626  __inline
627  d_list_entry_t *
628  d_list_prev_entry(
629      d_list_entry_t *d_entry)
630  {
631      return d_entry->prev;
632  }
633  
634  
635  __inline
636  unsigned long
637  d_list_entry_cnt(
638      d_list_t *d_list)
639  {
640      return d_list->cnt;
641  }
642  
643  
644  __inline
645  char
646  d_list_is_empty(
647      d_list_t *d_list)
648  {
649      return d_list->cnt == 0;
650  }
651  
652  
653  __inline
654  void
655  d_list_add_head(
656      d_list_t *d_list,
657      d_list_t *d_list_head)
658  {
659      d_list_head->tail->next = d_list->head;
660  
661      if(d_list->head)
662      {
663          d_list->head->prev = d_list_head->tail;
664      }
665      else
666      {
667          d_list->tail = d_list_head->tail;
668      }
669      d_list->head = d_list_head->head;
670  
671      d_list->cnt += d_list_head->cnt;
672  }
673  
674  
675  __inline
676  void
677  d_list_add_tail(
678      d_list_t *d_list,
679      d_list_t *d_list_tail)
680  {
681      d_list_tail->head->prev = d_list->tail;
682  
683      if(d_list->tail)
684      {
685          d_list->tail->next = d_list_tail->head;
686      }
687      else
688      {
689          d_list->head = d_list_tail->head;
690      }
691      d_list->tail = d_list_tail->tail;
692  
693      d_list->cnt += d_list_tail->cnt;
694  }
695  
696  
697  #else
698  
699  
700  #define d_list_init(_d_list, _head_entry, _tail_entry, _entry_cnt) \
701      (_d_list)->head = (_head_entry); \
702      (_d_list)->tail = (_tail_entry); \
703      (_d_list)->cnt = (_entry_cnt)
704  
705  
706  #define d_list_clear(_d_list) \
707      (_d_list)->head = (d_list_entry_t *) 0; \
708      (_d_list)->tail = (d_list_entry_t *) 0; \
709      (_d_list)->cnt = 0
710  
711  
712  #define d_list_push_head(_d_list, _d_entry) \
713      (_d_entry)->prev = (d_list_entry_t *) 0; \
714      (_d_entry)->next = (_d_list)->head; \
715      if((_d_list)->tail == (d_list_entry_t *) 0) \
716      { \
717          (_d_list)->tail = (_d_entry); \
718      } \
719      else \
720      { \
721          (_d_list)->head->prev = (_d_entry); \
722      } \
723      (_d_list)->head = (_d_entry); \
724      (_d_list)->cnt++
725  
726  
727  #define d_list_pop_head(_d_list) \
728      (_d_list)->head; \
729      if((_d_list)->head) \
730      { \
731          (_d_list)->head = (_d_list)->head->next; \
732          if((_d_list)->head) \
733          { \
734              (_d_list)->head->prev = (d_list_entry_t *) 0; \
735          } \
736          else \
737          { \
738              (_d_list)->tail = (d_list_entry_t *) 0; \
739          } \
740          (_d_list)->cnt--; \
741      }
742  
743  
744  #define d_list_push_tail(_d_list, _d_entry) \
745      (_d_entry)->next = (d_list_entry_t *) 0; \
746      (_d_entry)->prev = (_d_list)->tail; \
747      if((_d_list)->tail) \
748      { \
749          (_d_list)->tail->next = (_d_entry); \
750      } \
751      else \
752      { \
753          (_d_list)->head = (_d_entry); \
754      } \
755      (_d_list)->tail = (_d_entry); \
756      (_d_list)->cnt++
757  
758  
759  #define d_list_pop_tail(_d_list) \
760      (_d_list)->tail; \
761      if((_d_list)->tail) \
762      { \
763          (_d_list)->tail = (_d_list)->tail->prev; \
764          if((_d_list)->tail) \
765          { \
766              (_d_list)->tail->next = (d_list_entry_t *) 0; \
767          } \
768          else \
769          { \
770              (_d_list)->head = (d_list_entry_t *) 0; \
771          } \
772          (_d_list)->cnt--; \
773      }
774  
775  
776  #define d_list_peek_head(_d_list)       ((_d_list)->head)
777  
778  
779  #define d_list_peek_tail(_d_list)       ((_d_list)->tail)
780  
781  
782  #define d_list_next_entry(_d_entry)     ((_d_entry)->next)
783  
784  #define d_list_insert_entry(_d_list, _d_entry_prev, _d_entry_next, _d_entry) \
785      if (_d_entry_prev  == NULL ) \
786      { \
787          (_d_entry)->prev = (d_list_entry_t *) 0; \
788          (_d_entry)->next = (_d_list)->head; \
789          if((_d_list)->tail == (d_list_entry_t *) 0) \
790          { \
791              (_d_list)->tail = (_d_entry); \
792          } \
793          (_d_list)->head = (_d_entry); \
794          (_d_list)->cnt++; \
795      } \
796      else if (_d_entry_next == NULL ) \
797      { \
798          (_d_entry)->next = (d_list_entry_t *) 0; \
799          (_d_entry)->prev = (_d_list)->tail; \
800          if((_d_list)->tail) \
801          { \
802              (_d_list)->tail->next = (_d_entry); \
803          } \
804          else \
805          { \
806              (_d_list)->head = (_d_entry); \
807          } \
808          (_d_list)->tail = (_d_entry); \
809          (_d_list)->cnt++; \
810      } \
811      else \
812      { \
813          (_d_entry)->next = (_d_entry_next); \
814          (_d_entry)->prev = (_d_entry_prev); \
815          (_d_entry_prev)->next = (_d_entry); \
816          (_d_entry_next)->prev = (_d_entry); \
817          (_d_list)->cnt++; \
818      }
819  
820  #define d_list_remove_entry(_d_list, _d_entry) \
821      if((_d_list)->head == (_d_entry)) \
822      { \
823          if((_d_list)->head) \
824          { \
825              (_d_list)->head = (_d_list)->head->next; \
826              if((_d_list)->head) \
827              { \
828                  (_d_list)->head->prev = (d_list_entry_t *) 0; \
829              } \
830              else \
831              { \
832                  (_d_list)->tail = (d_list_entry_t *) 0; \
833              } \
834              (_d_list)->cnt--; \
835          } \
836      } \
837      else if((_d_list)->tail == (_d_entry)) \
838      { \
839          if((_d_list)->tail) \
840          { \
841              (_d_list)->tail = (_d_list)->tail->prev; \
842              if((_d_list)->tail) \
843              { \
844                  (_d_list)->tail->next = (d_list_entry_t *) 0; \
845              } \
846              else \
847              { \
848                  (_d_list)->head = (d_list_entry_t *) 0; \
849              } \
850              (_d_list)->cnt--; \
851          } \
852      } \
853      else \
854      { \
855          (_d_entry)->prev->next = (_d_entry)->next; \
856          (_d_entry)->next->prev = (_d_entry)->prev; \
857          (_d_list)->cnt--; \
858      }
859  
860  
861  #define d_list_prev_entry(_d_entry)     ((_d_entry)->prev)
862  
863  
864  #define d_list_entry_cnt(_d_list)       ((_d_list)->cnt)
865  
866  
867  #define d_list_is_empty(_d_list)        ((_d_list)->cnt == 0)
868  
869  
870  #define d_list_add_head(_d_list, _d_list_head) \
871      (_d_list_head)->tail->next = (_d_list)->head; \
872      if((_d_list)->head) \
873      { \
874          (_d_list)->head->prev = (_d_list_head)->tail; \
875      } \
876      else \
877      { \
878          (_d_list)->tail = (_d_list_head)->tail; \
879      } \
880      (_d_list)->head = (_d_list_head)->head; \
881      (_d_list)->cnt += (_d_list_head)->cnt
882  
883  
884  #define d_list_add_tail(_d_list, _d_list_tail) \
885      (_d_list_tail)->head->prev = (_d_list)->tail; \
886      if((_d_list)->tail) \
887      { \
888          (_d_list)->tail->next = (_d_list_tail)->head; \
889      } \
890      else \
891      { \
892          (_d_list)->head = (_d_list_tail)->head; \
893      } \
894      (_d_list)->tail = (_d_list_tail)->tail; \
895      (_d_list)->cnt += (_d_list_tail)->cnt
896  
897  
898  #endif
899  
900  
901  
902  /*******************************************************************************
903   * Array list.
904   ******************************************************************************/
905  
906  typedef void *q_list_entry_t;
907  
908  typedef struct _q_list_t
909  {
910      q_list_entry_t *head;
911      q_list_entry_t *tail;
912      unsigned long cnt;
913  
914      unsigned long max_cnt;
915      q_list_entry_t *first_entry_addr;
916      q_list_entry_t *last_entry_addr;
917  } q_list_t;
918  
919  
920  
921  #ifdef _INLINE_LISTQ_CALLS
922  
923  
924  __inline
925  void
926  q_list_init(
927      q_list_t *q_list,
928      q_list_entry_t q_list_arr[],
929      unsigned long max_cnt)
930  {
931      q_list->max_cnt = max_cnt;
932      q_list->first_entry_addr = q_list_arr;
933      q_list->last_entry_addr = q_list_arr + (max_cnt-1);
934  
935      q_list->head = q_list->first_entry_addr;
936      q_list->tail = q_list->first_entry_addr;
937      q_list->cnt = 0;
938  }
939  
940  
941  __inline
942  void
943  q_list_clear(
944      q_list_t *q_list)
945  {
946      q_list->head = q_list->first_entry_addr;
947      q_list->tail = q_list->first_entry_addr;
948      q_list->cnt = 0;
949  }
950  
951  
952  __inline
953  void
954  q_list_push_head(
955      q_list_t *q_list,
956      q_list_entry_t q_entry)
957  {
958      if(q_list->cnt < q_list->max_cnt)
959      {
960          if(q_list->head == q_list->first_entry_addr)
961          {
962              q_list->head = q_list->last_entry_addr;
963          }
964          else
965          {
966              q_list->head--;
967          }
968  
969          *(q_list->head) = q_entry;
970          q_list->cnt++;
971      }
972  }
973  
974  
975  __inline
976  q_list_entry_t
977  q_list_pop_head(
978      q_list_t *q_list)
979  {
980      q_list_entry_t q_entry;
981  
982      q_entry = q_list->cnt ? *q_list->head : (q_list_entry_t *) 0;
983      if(q_list->cnt)
984      {
985          if(q_list->head == q_list->last_entry_addr)
986          {
987              q_list->head = q_list->first_entry_addr;
988          }
989          else
990          {
991              q_list->head++;
992          }
993  
994          q_list->cnt--;
995      }
996  
997      return q_entry;
998  }
999  
1000  
1001  __inline
1002  void
1003  q_list_push_tail(
1004      q_list_t *q_list,
1005      q_list_entry_t q_entry)
1006  {
1007      if(q_list->cnt < q_list->max_cnt)
1008      {
1009          *q_list->tail = q_entry;
1010          if(q_list->tail == q_list->last_entry_addr)
1011          {
1012              q_list->tail = q_list->first_entry_addr;
1013          }
1014          else
1015          {
1016              q_list->tail++;
1017          }
1018  
1019          q_list->cnt++;
1020      }
1021  }
1022  
1023  
1024  __inline
1025  q_list_entry_t
1026  q_list_pop_tail(
1027      q_list_t *q_list)
1028  {
1029      q_list_entry_t q_entry;
1030  
1031      q_entry = q_list->cnt ?
1032          (q_list->tail == q_list->first_entry_addr ?
1033              *q_list->last_entry_addr : *(q_list->tail-1)) :
1034          (q_list_entry_t *) 0;
1035  
1036      if(q_list->cnt)
1037      {
1038          if(q_list->tail == q_list->first_entry_addr)
1039          {
1040              q_list->tail = q_list->last_entry_addr;
1041          }
1042          else
1043          {
1044              q_list->tail--;
1045          }
1046  
1047          q_list->cnt--;
1048      }
1049  
1050      return q_entry;
1051  }
1052  
1053  
1054  __inline
1055  q_list_entry_t
1056  q_list_peek_head(
1057      q_list_t *q_list)
1058  {
1059      q_list_entry_t q_entry;
1060  
1061      q_entry = q_list->cnt ? *q_list->head : (q_list_entry_t *) 0;
1062  
1063      return q_entry;
1064  }
1065  
1066  
1067  __inline
1068  q_list_entry_t
1069  q_list_peek_tail(
1070      q_list_t *q_list)
1071  {
1072      q_list_entry_t q_entry;
1073  
1074      q_entry = q_list->cnt ?
1075          (q_list->tail == q_list->first_entry_addr ?
1076              *q_list->last_entry_addr : *(q_list->tail - 1)) :
1077          (q_list_entry_t *) 0;
1078  
1079      return q_entry;
1080  }
1081  
1082  
1083  __inline
1084  unsigned long
1085  q_list_entry_cnt(
1086      q_list_t *q_list)
1087  {
1088      return q_list->cnt;
1089  }
1090  
1091  
1092  __inline
1093  char
1094  q_list_is_empty(
1095      q_list_t *q_list)
1096  {
1097      return q_list->cnt == 0;
1098  }
1099  
1100  
1101  __inline
1102  char
1103  q_list_is_full(
1104      q_list_t *q_list)
1105  {
1106      return q_list->cnt == q_list->max_cnt;
1107  }
1108  
1109  
1110  #else
1111  
1112  
1113  #define q_list_init(_q_list, _q_list_arr, _max_cnt) \
1114      (_q_list)->max_cnt = (_max_cnt); \
1115      (_q_list)->first_entry_addr = (_q_list_arr); \
1116      (_q_list)->last_entry_addr = (_q_list_arr) + ((_max_cnt) - 1); \
1117      (_q_list)->head = (_q_list)->first_entry_addr; \
1118      (_q_list)->tail = (_q_list)->first_entry_addr; \
1119      (_q_list)->cnt = 0
1120  
1121  
1122  #define q_list_clear(_q_list) \
1123      (_q_list)->head = (_q_list)->first_entry_addr; \
1124      (_q_list)->tail = (_q_list)->first_entry_addr; \
1125      (_q_list)->cnt = 0
1126  
1127  
1128  #define q_list_push_head(_q_list, _q_entry) \
1129      if((_q_list)->cnt < (_q_list)->max_cnt) \
1130      { \
1131          if((_q_list)->head == (_q_list)->first_entry_addr) \
1132          { \
1133              (_q_list)->head = (_q_list)->last_entry_addr; \
1134          } \
1135          else \
1136          { \
1137              (_q_list)->head--; \
1138          } \
1139          *((_q_list)->head) = (_q_entry); \
1140          (_q_list)->cnt++; \
1141      }
1142  
1143  
1144  #define q_list_pop_head(_q_list) \
1145      (_q_list)->cnt ? *(_q_list)->head : (q_list_entry_t *) 0; \
1146      if((_q_list)->cnt) \
1147      { \
1148          if((_q_list)->head == (_q_list)->last_entry_addr) \
1149          { \
1150              (_q_list)->head = (_q_list)->first_entry_addr; \
1151          } \
1152          else \
1153          { \
1154              (_q_list)->head++; \
1155          } \
1156          (_q_list)->cnt--; \
1157      }
1158  
1159  
1160  #define q_list_push_tail(_q_list, _q_entry) \
1161      if((_q_list)->cnt < (_q_list)->max_cnt) \
1162      { \
1163          *(_q_list)->tail = (_q_entry); \
1164          if((_q_list)->tail == (_q_list)->last_entry_addr) \
1165          { \
1166              (_q_list)->tail = (_q_list)->first_entry_addr; \
1167          } \
1168          else \
1169          { \
1170              (_q_list)->tail++; \
1171          } \
1172          (_q_list)->cnt++; \
1173      }
1174  
1175  
1176  #define q_list_pop_tail(_q_list) \
1177      (_q_list)->cnt ? ((_q_list)->tail == (_q_list)->first_entry_addr ? \
1178          *(_q_list)->last_entry_addr : *((_q_list)->tail-1)) : \
1179          (q_list_entry_t *) 0; \
1180      if((_q_list)->cnt) \
1181      { \
1182          if((_q_list)->tail == (_q_list)->first_entry_addr) \
1183          { \
1184              (_q_list)->tail = (_q_list)->last_entry_addr; \
1185          } \
1186          else \
1187          { \
1188              (_q_list)->tail--; \
1189          } \
1190          (_q_list)->cnt--; \
1191      } \
1192  
1193  
1194  #define q_list_peek_head(_q_list) \
1195      ((_q_list)->cnt ? *(_q_list)->head : (q_list_entry_t *) 0)
1196  
1197  
1198  #define q_list_peek_tail(_q_list) \
1199      ((_q_list)->cnt ? ((_q_list)->tail == (_q_list)->first_entry_addr ? \
1200          *(_q_list)->last_entry_addr : *((_q_list)->tail - 1)) : \
1201          (q_list_entry_t *) 0)
1202  
1203  
1204  #define q_list_entry_cnt(_q_list)   ((_q_list)->cnt)
1205  
1206  
1207  #define q_list_is_empty(_q_list)    ((_q_list)->cnt == 0)
1208  
1209  
1210  #define q_list_is_full(_q_list)     ((_q_list)->cnt == (_q_list)->max_cnt)
1211  
1212  
1213  #endif
1214  
1215  
1216  
1217  
1218  #endif /* _listq_h_ */
1219  
1220