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
s_list_init(s_list_t * s_list,s_list_entry_t * head_entry,s_list_entry_t * tail_entry,unsigned long entry_cnt)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
s_list_clear(s_list_t * s_list)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
s_list_push_head(s_list_t * s_list,s_list_entry_t * s_entry)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 *
s_list_pop_head(s_list_t * s_list)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
s_list_push_tail(s_list_t * s_list,s_list_entry_t * s_entry)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 *
s_list_peek_head(s_list_t * s_list)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 *
s_list_peek_tail(s_list_t * s_list)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 *
s_list_next_entry(s_list_entry_t * s_entry)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
s_list_entry_cnt(s_list_t * s_list)205 s_list_entry_cnt(
206     s_list_t *s_list)
207 {
208     return s_list->cnt;
209 }
210 
211 
212 __inline
213 char
s_list_is_empty(s_list_t * s_list)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
s_list_add_head(s_list_t * s_list,s_list_t * s_list_head)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
s_list_add_tail(s_list_t * s_list,s_list_t * s_list_tail)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
s_list_split(s_list_t * s_list,s_list_t * s_list_head,s_list_entry_t * split_entry,unsigned long entry_cnt)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
d_list_init(d_list_t * d_list,d_list_entry_t * head_entry,d_list_entry_t * tail_entry,unsigned long entry_cnt)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
d_list_clear(d_list_t * d_list)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
d_list_push_head(d_list_t * d_list,d_list_entry_t * d_entry)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 *
d_list_pop_head(d_list_t * d_list)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
d_list_push_tail(d_list_t * d_list,d_list_entry_t * d_entry)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 *
d_list_pop_tail(d_list_t * d_list)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 *
d_list_peek_head(d_list_t * d_list)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 *
d_list_peek_tail(d_list_t * d_list)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 *
d_list_next_entry(d_list_entry_t * d_entry)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
d_list_remove_entry(d_list_t * d_list,d_list_entry_t * d_entry)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
d_list_insert_entry(d_list_t * d_list,d_list_entry_t * d_entry_prev,d_list_entry_t * d_entry_next,d_list_entry_t * d_entry)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 *
d_list_prev_entry(d_list_entry_t * d_entry)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
d_list_entry_cnt(d_list_t * d_list)637 d_list_entry_cnt(
638     d_list_t *d_list)
639 {
640     return d_list->cnt;
641 }
642 
643 
644 __inline
645 char
d_list_is_empty(d_list_t * d_list)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
d_list_add_head(d_list_t * d_list,d_list_t * d_list_head)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
d_list_add_tail(d_list_t * d_list,d_list_t * d_list_tail)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
q_list_init(q_list_t * q_list,q_list_entry_t q_list_arr[],unsigned long max_cnt)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
q_list_clear(q_list_t * q_list)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
q_list_push_head(q_list_t * q_list,q_list_entry_t q_entry)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
q_list_pop_head(q_list_t * q_list)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
q_list_push_tail(q_list_t * q_list,q_list_entry_t q_entry)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
q_list_pop_tail(q_list_t * q_list)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
q_list_peek_head(q_list_t * q_list)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
q_list_peek_tail(q_list_t * q_list)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
q_list_entry_cnt(q_list_t * q_list)1085 q_list_entry_cnt(
1086     q_list_t *q_list)
1087 {
1088     return q_list->cnt;
1089 }
1090 
1091 
1092 __inline
1093 char
q_list_is_empty(q_list_t * q_list)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
q_list_is_full(q_list_t * q_list)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