1 : /*
2 : * Copyright (c) 2004-2010 Alex Pankratov. All rights reserved.
3 : *
4 : * Hierarchical memory allocator, 1.2.1
5 : * http://swapped.cc/halloc
6 : */
7 :
8 : /*
9 : * The program is distributed under terms of BSD license.
10 : * You can obtain the copy of the license by visiting:
11 : *
12 : * http://www.opensource.org/licenses/bsd-license.php
13 : */
14 :
15 : #ifndef _LIBP_HLIST_H_
16 : #define _LIBP_HLIST_H_
17 :
18 : #include <assert.h>
19 : #include "macros.h" /* static_inline */
20 :
21 : /*
22 : * weak double-linked list w/ tail sentinel
23 : */
24 : typedef struct hlist_head hlist_head_t;
25 : typedef struct hlist_item hlist_item_t;
26 :
27 : /*
28 : *
29 : */
30 : struct hlist_head
31 : {
32 : hlist_item_t * next;
33 : };
34 :
35 : struct hlist_item
36 : {
37 : hlist_item_t * next;
38 : hlist_item_t ** prev;
39 : };
40 :
41 : /*
42 : * shared tail sentinel
43 : */
44 : struct hlist_item hlist_null;
45 :
46 : /*
47 : *
48 : */
49 : #define __hlist_init(h) { &hlist_null }
50 : #define __hlist_init_item(i) { &hlist_null, &(i).next }
51 :
52 : static_inline void hlist_init(hlist_head_t * h);
53 : static_inline void hlist_init_item(hlist_item_t * i);
54 :
55 : /* static_inline void hlist_purge(hlist_head_t * h); */
56 :
57 : /* static_inline bool_t hlist_empty(const hlist_head_t * h); */
58 :
59 : /* static_inline hlist_item_t * hlist_head(const hlist_head_t * h); */
60 :
61 : /* static_inline hlist_item_t * hlist_next(const hlist_item_t * i); */
62 : /* static_inline hlist_item_t * hlist_prev(const hlist_item_t * i,
63 : const hlist_head_t * h); */
64 :
65 : static_inline void hlist_add(hlist_head_t * h, hlist_item_t * i);
66 :
67 : /* static_inline void hlist_add_prev(hlist_item_t * l, hlist_item_t * i); */
68 : /* static_inline void hlist_add_next(hlist_item_t * l, hlist_item_t * i); */
69 :
70 : static_inline void hlist_del(hlist_item_t * i);
71 :
72 : static_inline void hlist_relink(hlist_item_t * i);
73 : static_inline void hlist_relink_head(hlist_head_t * h);
74 :
75 : #define hlist_for_each(i, h) \
76 : for (i = (h)->next; i != &hlist_null; i = i->next)
77 :
78 : #define hlist_for_each_safe(i, tmp, h) \
79 : for (i = (h)->next, tmp = i->next; \
80 : i!= &hlist_null; \
81 : i = tmp, tmp = i->next)
82 :
83 : /*
84 : * static
85 : */
86 0 : static_inline void hlist_init(hlist_head_t * h)
87 : {
88 0 : assert(h);
89 0 : h->next = &hlist_null;
90 0 : }
91 :
92 0 : static_inline void hlist_init_item(hlist_item_t * i)
93 : {
94 0 : assert(i);
95 0 : i->prev = &i->next;
96 0 : i->next = &hlist_null;
97 0 : }
98 :
99 0 : static_inline void hlist_add(hlist_head_t * h, hlist_item_t * i)
100 : {
101 : hlist_item_t * next;
102 0 : assert(h && i);
103 :
104 0 : next = i->next = h->next;
105 0 : next->prev = &i->next;
106 0 : h->next = i;
107 0 : i->prev = &h->next;
108 0 : }
109 :
110 0 : static_inline void hlist_del(hlist_item_t * i)
111 : {
112 : hlist_item_t * next;
113 0 : assert(i);
114 :
115 0 : next = i->next;
116 0 : next->prev = i->prev;
117 0 : *i->prev = next;
118 :
119 0 : hlist_init_item(i);
120 0 : }
121 :
122 0 : static_inline void hlist_relink(hlist_item_t * i)
123 : {
124 0 : assert(i);
125 0 : *i->prev = i;
126 0 : i->next->prev = &i->next;
127 0 : }
128 :
129 0 : static_inline void hlist_relink_head(hlist_head_t * h)
130 : {
131 0 : assert(h);
132 0 : h->next->prev = &h->next;
133 0 : }
134 :
135 : #endif
136 :
|