remove double export of xseg symbols
[archipelago] / xseg / xtypes / xpool.c
1 #include <xtypes/xpool.h>
2
3 static inline int __validate_idx(struct xpool *xp, xpool_index idx) 
4 {
5         struct xpool_node *node = XPTR(&xp->mem)+idx;
6         return (idx < xp->size && node->prev != NoIndex);
7 }
8
9 void __xpool_clear(struct xpool *xp)
10 {
11         uint64_t i;
12         uint64_t size = xp->size;
13         struct xpool_node *mem = XPTR(&xp->mem);
14
15         xp->list = NoIndex;
16         for (i = 1; i < size; i++) {
17                 mem[i-1].prev = NoIndex;
18                 mem[i-1].next = i;
19         }
20         mem[size-1].prev = NoIndex;
21         mem[size-1].next = NoIndex;
22         xp->free = 0;
23 }
24
25 void xpool_clear(struct xpool *xp, uint32_t who)
26 {
27         xlock_acquire(&xp->lock, who);
28         __xpool_clear(xp);
29         xlock_release(&xp->lock);
30 }
31
32 void xpool_init(struct xpool *xp, uint64_t size, struct xpool_node* mem)
33 {
34         xp->size = size;
35         XPTRSET(&xp->mem, mem);
36         xlock_release(&xp->lock);
37         __xpool_clear(xp);
38 }
39
40 xpool_index __xpool_add(struct xpool *xp, xpool_data data)
41 {
42         struct xpool_node *new, *list, *prev;
43         xpool_index idx;
44
45         idx = xp->free;
46         if (idx == NoIndex){
47                 return NoIndex;
48         }
49         new = XPTR(&xp->mem) + idx;
50         xp->free = new->next;
51         new->data = data;
52
53         if (xp->list != NoIndex) {
54                 list = XPTR(&xp->mem) + xp->list;
55                 new->next = xp->list;
56                 new->prev = list->prev;
57
58                 prev = XPTR(&xp->mem) + list->prev;
59                 prev->next = idx;
60                 list->prev = idx;
61         } else {
62                 new->next = idx;
63                 new->prev = idx;
64                 xp->list =idx;
65         }
66         /*
67         idx = xp->list;
68         list = XPTR(&xp->mem) + idx;
69         printf("xpool data: %llu(%llu), ", xp->list, list->data );
70         do {
71         idx = list->next;
72         list = XPTR(&xp->mem) + idx;
73         printf("%llu(%llu), ", idx, list->data);
74         }while(idx != xp->list);
75         printf("\n");
76         */
77         
78         return idx;
79 }
80
81 xpool_index xpool_add(struct xpool *xp, xpool_data data, uint32_t who)
82 {
83         xpool_index idx;
84         xlock_acquire(&xp->lock, who);
85         idx = __xpool_add(xp, data);
86         xlock_release(&xp->lock);
87         return idx;
88 }
89 /*
90 xpool_index xpool_add(struct xpool *xp, xpool_data data)
91 {
92         struct xpool_node *new, *list, *free, *next, *prev;
93         //acquire lock
94         xlock_acquire(&xp->lock, 1);
95         free = XPTR(&xp->free);
96         list = XPTR(&xp->list);
97         new = free;
98         if (new == NULL){
99                 xlock_release(&xp->lock);
100                 return NoIndex;
101         }
102         free = XPTR(&new->next);
103         XPTRSET(&xp->free, free);
104         if (list) {
105                 //new->next = xp->list;
106                 XPTRSET(&new->next, list);
107
108                 prev = XPTR(&list->prev);
109                 XPTRSET(&new->prev, prev);
110                 //new->prev = xp->list->prev;
111
112                 next = XPTR(&prev->next);
113                 XPTRSET(&prev->next, new);
114                 //xp->list->prev->next = new;
115                 
116                 XPTRSET(&list->prev, new);
117                 //xp->list->prev = new;
118         } else {
119                 XPTRSET(&new->next ,new);
120                 //new->next = new;
121                 XPTRSET(&new->prev, new);
122                 //new->prev = new;
123                 XPTRSET(&xp->list, new);
124                 //xp->list = new;
125         }
126         new->data = data;
127         //release lock
128         xlock_release(&xp->lock);
129         return (new - XPTR(&xp->mem));
130 }
131 */
132 /*
133 xpool_index xpool_remove(struct xpool *xp, xpool_index idx, xpool_data *data)
134 {
135         struct xpool_node *node, *list, *free, *prev, *next;
136         //acquire lock
137         xlock_acquire(&xp->lock, 1);
138         if (!__validate_idx(xp, idx)){ // idx < xp->size && node->prev != NULL
139                 xlock_release(&xp->lock);
140                 return NoIndex;
141         }
142         node = XPTR(&xp->mem) + idx;
143         *data = node->data;
144         list = XPTR(&xp->list);
145         free = XPTR(&xp->free);
146         next = XPTR(&node->next);
147         prev = XPTR(&node->prev);
148         if (node == list){
149                 if (node == next)
150                         XPTRSET(&xp->list, NULL);
151                         //xp->list = NULL;
152                 else
153                         XPTRSET(&xp->list, next);
154                         //xp->list = node->next;
155         }
156         XPTRSET(&prev->next, next);
157         //node->prev->next = node->next;
158         XPTRSET(&next->prev, prev);
159         //node->next->prev = node->prev;
160         XPTRSET(&node->prev, NULL);
161         //node->prev = NULL;
162         XPTRSET(&node->next, free);
163         //node->next = xp->free;
164         free = node;
165         XPTRSET(&xp->free, free);
166         //xp->free = node;
167         
168         //release lock
169         xlock_release(&xp->lock);
170         return idx;
171 }
172 */
173 xpool_index __xpool_remove(struct xpool *xp, xpool_index idx, xpool_data *data)
174 {
175         struct xpool_node *node, *prev, *next;
176         if (!__validate_idx(xp, idx)){ // idx < xp->size && node->prev != NULL
177                 return NoIndex;
178         }
179         node = XPTR(&xp->mem) + idx;
180         *data = node->data;
181
182         if (idx == xp->list){
183                 if ( idx == node->next)
184                         xp->list = NoIndex;
185                 else
186                         xp->list = node->next;
187         }
188         prev = XPTR(&xp->mem) + node->prev;
189         prev->next = node->next;
190         
191         next = XPTR(&xp->mem) + node->next;
192         next->prev = node->prev;
193
194         node->prev = NoIndex;
195         node->next = xp->free;
196         xp->free = idx;
197         return idx;
198 }
199
200 xpool_index xpool_remove(struct xpool *xp, xpool_index idx, xpool_data *data, uint32_t who)
201 {
202         xpool_index ret;
203         xlock_acquire(&xp->lock, who);
204         ret = __xpool_remove(xp, idx, data);
205         xlock_release(&xp->lock);
206         return ret;
207 }
208
209 xpool_index __xpool_peek(struct xpool *xp, xpool_data *data)
210 {
211         struct xpool_node *list;
212         xpool_index ret;
213         if (xp->list == NoIndex){
214                 return NoIndex;
215         }
216         ret = xp->list;
217         list = XPTR(&xp->mem) + xp->list;
218         *data = list->data;
219         return ret;
220 }
221
222 xpool_index xpool_peek(struct xpool *xp, xpool_data *data, uint32_t who)
223 {
224         xpool_index ret;
225         xlock_acquire(&xp->lock, who);
226         ret = __xpool_peek(xp, data);
227         xlock_release(&xp->lock);
228         return ret;
229 }
230
231 xpool_index __xpool_peek_idx(struct xpool *xp, xpool_index idx, xpool_data *data)
232 {
233         struct xpool_node *node;
234         if (!__validate_idx(xp, idx)){
235                 return NoIndex;
236         }
237         node = XPTR(&xp->mem) + idx;
238         *data = node->data;
239         return idx;
240 }
241
242 xpool_index xpool_peek_idx(struct xpool *xp, xpool_index idx, xpool_data *data, uint32_t who)
243 {
244         xpool_index ret;
245         xlock_acquire(&xp->lock, who);
246         ret = __xpool_peek_idx(xp,idx,data);
247         xlock_release(&xp->lock);
248         return ret;
249 }
250
251 xpool_index __xpool_peek_and_fwd(struct xpool *xp, xpool_data *data)
252 {
253         struct xpool_node *list;
254         xpool_index ret;
255         if (xp->list == NoIndex){
256                 return NoIndex;
257         }
258         ret = xp->list;
259         list = XPTR(&xp->mem) + xp->list;
260         *data = list->data;
261         xp->list = list->next;
262         return ret;
263 }
264
265 xpool_index xpool_peek_and_fwd(struct xpool *xp, xpool_data *data, uint32_t who)
266 {
267         xpool_index ret;
268         xlock_acquire(&xp->lock, who);
269         ret = __xpool_peek_and_fwd(xp,data);
270         xlock_release(&xp->lock);
271         return ret;
272 }
273
274 /*
275 xpool_index xpool_peek_and_fwd(struct xpool *xp, xpool_data *data)
276 {
277         struct xpool_node *list, *next;
278         //acquire lock
279         xlock_acquire(&xp->lock, 1);
280         list = XPTR(&xp->list);
281         if (!list){
282                 xlock_release(&xp->lock);
283                 return NoIndex;
284         }
285         *data = list->data;
286         next = XPTR(&list->next);
287         XPTRSET(&xp->list, next);
288         //xp->list = xp->list->next;
289         //release lock
290         xlock_release(&xp->lock);
291         return (list - XPTR(&xp->mem));
292 }
293 */
294
295 xpool_index __xpool_set_idx(struct xpool *xp, xpool_index idx, xpool_data data)
296 {
297         struct xpool_node *node;
298         if (!__validate_idx(xp, idx)){
299                 return NoIndex;
300         }
301         node = XPTR(&xp->mem) + idx;
302         node->data = data;
303         return idx;
304 }
305
306 xpool_index xpool_set_idx(struct xpool *xp, xpool_index idx, xpool_data data, uint32_t who)
307 {
308         xpool_index ret;
309         xlock_acquire(&xp->lock, who);
310         ret = __xpool_set_idx(xp, idx, data);
311         xlock_release(&xp->lock);
312         return ret;
313 }
314
315
316 #ifdef __KERNEL__
317 #include <linux/module.h>
318 #include <xtypes/xpool_exports.h>
319 #endif