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
68typedef 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
76typedef 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
89void
90s_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
103void
104s_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
114void
115s_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
132s_list_entry_t *
133s_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
155void
156s_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
177s_list_entry_t *
178s_list_peek_head(
179    s_list_t *s_list)
180{
181    return s_list->head;
182}
183
184
185__inline
186s_list_entry_t *
187s_list_peek_tail(
188    s_list_t *s_list)
189{
190    return s_list->tail;
191}
192
193
194__inline
195s_list_entry_t *
196s_list_next_entry(
197    s_list_entry_t *s_entry)
198{
199    return s_entry->next;
200}
201
202
203__inline
204unsigned long
205s_list_entry_cnt(
206    s_list_t *s_list)
207{
208    return s_list->cnt;
209}
210
211
212__inline
213char
214s_list_is_empty(
215    s_list_t *s_list)
216{
217    return s_list->cnt == 0;
218}
219
220
221__inline
222void
223s_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
241void
242s_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
259void
260s_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
402typedef 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
411typedef 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
424void
425d_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
438void
439d_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
449void
450d_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
473d_list_entry_t *
474d_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
500void
501d_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
523d_list_entry_t *
524d_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
551d_list_entry_t *
552d_list_peek_head(
553    d_list_t *d_list)
554{
555    return d_list->head;
556}
557
558
559__inline
560d_list_entry_t *
561d_list_peek_tail(
562    d_list_t *d_list)
563{
564    return d_list->tail;
565}
566
567
568__inline
569d_list_entry_t *
570d_list_next_entry(
571    d_list_entry_t *d_entry)
572{
573    return d_entry->next;
574}
575
576
577__inline
578void
579d_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
600void
601d_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
627d_list_entry_t *
628d_list_prev_entry(
629    d_list_entry_t *d_entry)
630{
631    return d_entry->prev;
632}
633
634
635__inline
636unsigned long
637d_list_entry_cnt(
638    d_list_t *d_list)
639{
640    return d_list->cnt;
641}
642
643
644__inline
645char
646d_list_is_empty(
647    d_list_t *d_list)
648{
649    return d_list->cnt == 0;
650}
651
652
653__inline
654void
655d_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
676void
677d_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
906typedef void *q_list_entry_t;
907
908typedef 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
925void
926q_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
942void
943q_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
953void
954q_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
976q_list_entry_t
977q_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
1002void
1003q_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
1025q_list_entry_t
1026q_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
1055q_list_entry_t
1056q_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
1068q_list_entry_t
1069q_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
1084unsigned long
1085q_list_entry_cnt(
1086    q_list_t *q_list)
1087{
1088    return q_list->cnt;
1089}
1090
1091
1092__inline
1093char
1094q_list_is_empty(
1095    q_list_t *q_list)
1096{
1097    return q_list->cnt == 0;
1098}
1099
1100
1101__inline
1102char
1103q_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