Annotation of embedaddon/bird2/lib/slist_test.c, revision 1.1.1.1
1.1 misho 1: /*
2: * BIRD Library -- Safe Linked Lists Tests
3: *
4: * (c) 2015 CZ.NIC z.s.p.o.
5: *
6: * Can be freely distributed and used under the terms of the GNU GPL.
7: */
8:
9: #include "test/birdtest.h"
10:
11: #include "lib/slists.h"
12:
13: #define MAX_NUM 1000
14:
15: static snode nodes[MAX_NUM];
16: static slist lst;
17:
18: static void
19: show_list(void)
20: {
21: bt_debug("\n");
22: bt_debug("list.null is at %p and point to %p \n", &lst.null, lst.null);
23: bt_debug("list.head is at %p and point to %p \n", &lst.head, lst.head);
24: bt_debug("list.tail is at %p and point to %p \n", &lst.tail, lst.tail);
25: bt_debug("list.tail_readers is at %p and point to %p \n", &lst.tail_readers, lst.tail_readers);
26:
27: int i;
28: for (i = 0; i < MAX_NUM; i++)
29: bt_debug("n[%3i] is at %p, .prev (%p) points to %p, .next (%p) points to %p, .readers (%p) points to %p \n",
30: i, &nodes[i], &(nodes[i].prev), nodes[i].prev, &(nodes[i].next), nodes[i].next, &(nodes[i].readers), nodes[i].readers);
31: }
32:
33: static int
34: is_filled_list_well_linked(void)
35: {
36: int i;
37: bt_assert(lst.head == &nodes[0]);
38: bt_assert(lst.tail == &nodes[MAX_NUM-1]);
39: bt_assert((void *) nodes[0].prev == (void *) &lst.head);
40: bt_assert((void *) nodes[MAX_NUM-1].next == (void *) &lst.null);
41:
42: for (i = 0; i < MAX_NUM; i++)
43: {
44: if (i < (MAX_NUM-1))
45: bt_assert(nodes[i].next == &nodes[i+1]);
46:
47: if (i > 0)
48: bt_assert(nodes[i].prev == &nodes[i-1]);
49: }
50:
51: return 1;
52: }
53:
54: static int
55: is_empty_list_well_unlinked(void)
56: {
57: bt_assert(lst.head == SNODE &lst.null);
58: bt_assert(lst.tail == SNODE &lst.head);
59:
60: bt_assert(EMPTY_SLIST(lst));
61:
62: return 1;
63: }
64:
65: static void
66: init_list__(slist *l, struct snode nodes[])
67: {
68: s_init_list(l);
69:
70: int i;
71: for (i = 0; i < MAX_NUM; i++)
72: {
73: nodes[i].next = NULL;
74: nodes[i].prev = NULL;
75: }
76: }
77:
78: static void
79: init_list_(void)
80: {
81: init_list__(&lst, nodes);
82: }
83:
84: static int
85: t_add_tail(void)
86: {
87: int i;
88:
89: init_list_();
90: for (i = 0; i < MAX_NUM; i++)
91: {
92: s_add_tail(&lst, &nodes[i]);
93: bt_debug(".");
94: bt_assert(lst.tail == &nodes[i]);
95: bt_assert(lst.head == &nodes[0]);
96: bt_assert((void *) nodes[i].next == (void *) &lst.null);
97: if (i > 0)
98: {
99: bt_assert(nodes[i-1].next == &nodes[i]);
100: bt_assert(nodes[i].prev == &nodes[i-1]);
101: }
102: }
103:
104: bt_assert(is_filled_list_well_linked());
105:
106: return 1;
107: }
108:
109: static int
110: t_add_head(void)
111: {
112: int i;
113:
114: init_list_();
115: for (i = MAX_NUM-1; i >= 0; i--)
116: {
117: s_add_head(&lst, &nodes[i]);
118: bt_debug(".");
119: bt_assert(lst.head == &nodes[i]);
120: bt_assert(lst.tail == &nodes[MAX_NUM-1]);
121: if (i < MAX_NUM-1)
122: {
123: bt_assert(nodes[i+1].prev == &nodes[i]);
124: bt_assert(nodes[i].next == &nodes[i+1]);
125: }
126: }
127:
128: bt_assert(is_filled_list_well_linked());
129:
130: return 1;
131: }
132:
133: static void
134: insert_node_(snode *n, snode *after)
135: {
136: s_insert_node(n, after);
137: bt_debug(".");
138: }
139:
140: static int
141: t_insert_node(void)
142: {
143: int i;
144:
145: init_list_();
146:
147: // add first node
148: insert_node_(&nodes[0], SNODE &lst.head);
149:
150: // add odd nodes
151: for (i = 2; i < MAX_NUM; i+=2)
152: insert_node_(&nodes[i], &nodes[i-2]);
153:
154: // add even nodes
155: for (i = 1; i < MAX_NUM; i+=2)
156: insert_node_(&nodes[i], &nodes[i-1]);
157:
158: bt_debug("\n");
159: bt_assert(is_filled_list_well_linked());
160:
161: return 1;
162: }
163:
164: static void
165: fill_list2(slist *l, snode nodes[])
166: {
167: int i;
168: for (i = 0; i < MAX_NUM; i++)
169: s_add_tail(l, &nodes[i]);
170: }
171:
172: static void
173: fill_list(void)
174: {
175: fill_list2(&lst, SNODE nodes);
176: }
177:
178:
179: static int
180: t_remove_node(void)
181: {
182: int i;
183:
184: init_list_();
185:
186: /* Fill & Remove & Check */
187: fill_list();
188: for (i = 0; i < MAX_NUM; i++)
189: s_rem_node(&nodes[i]);
190: bt_assert(is_empty_list_well_unlinked());
191:
192: /* Fill & Remove the half of nodes & Check & Remove the rest nodes & Check */
193: fill_list();
194: for (i = 0; i < MAX_NUM; i+=2)
195: s_rem_node(&nodes[i]);
196:
197: int tail_node_index = (MAX_NUM % 2) ? MAX_NUM - 2 : MAX_NUM - 1;
198: bt_assert(lst.head == &nodes[1]);
199: bt_assert(lst.tail == &nodes[tail_node_index]);
200: bt_assert(nodes[tail_node_index].next == SNODE &lst.null);
201:
202: for (i = 1; i < MAX_NUM; i+=2)
203: {
204: if (i > 1)
205: bt_assert(nodes[i].prev == &nodes[i-2]);
206: if (i < tail_node_index)
207: bt_assert(nodes[i].next == &nodes[i+2]);
208: }
209:
210: for (i = 1; i < MAX_NUM; i+=2)
211: s_rem_node(&nodes[i]);
212: bt_assert(is_empty_list_well_unlinked());
213:
214: return 1;
215: }
216:
217: static int
218: t_add_tail_list(void)
219: {
220: snode nodes2[MAX_NUM];
221: slist l2;
222:
223: init_list__(&lst, SNODE &nodes);
224: fill_list2(&lst, SNODE &nodes);
225:
226: init_list__(&l2, SNODE &nodes2);
227: fill_list2(&l2, SNODE &nodes2);
228:
229: s_add_tail_list(&lst, &l2);
230:
231: bt_assert(nodes[MAX_NUM-1].next == &nodes2[0]);
232: bt_assert(nodes2[0].prev == &nodes[MAX_NUM-1]);
233: bt_assert(lst.tail == &nodes2[MAX_NUM-1]);
234:
235: return 1;
236: }
237:
238: void
239: dump(const char *str, slist *a)
240: {
241: snode *x;
242:
243: bt_debug("%s \n", str);
244: for (x = SHEAD(*a); x; x = x->next)
245: {
246: siterator *i, *j;
247: bt_debug("%p", x);
248: j = (siterator *) x;
249: for (i = x->readers; i; i = i->next)
250: {
251: if (i->prev != j)
252: bt_debug(" ???");
253: j = i;
254: bt_debug(" [%p:%p]", i, i->node);
255: }
256: bt_debug("\n");
257: }
258: bt_debug("---\n");
259: }
260:
261: static int
262: t_iterator_walk(void)
263: {
264: snode *node;
265: siterator iter;
266:
267: init_list_();
268: fill_list();
269:
270: int k;
271: int i = 0;
272:
273: show_list();
274:
275: s_init(&iter, &lst);
276: WALK_SLIST(node, lst)
277: {
278: s_get(&iter);
279: s_put(&iter, node);
280: bt_debug("node->readers: %p, iter: %p, nodes[%d].readers: %p, node: %p, nodes[i]: %p, node->next: %p \n",
281: node->readers, &iter, i, nodes[i].readers, node, &(nodes[i]), node->next);
282: bt_assert(node->readers == &iter);
283: bt_assert(node->readers == nodes[i].readers);
284: bt_assert(node == &(nodes[i]));
285: for (k = 0; k < MAX_NUM; k++)
286: if (k != i)
287: bt_assert(nodes[k].readers == NULL);
288:
289: dump("",&lst);
290: i++;
291: }
292:
293: return 1;
294: }
295:
296: static int
297: t_original(void)
298: {
299: slist a, b;
300: snode *x, *y;
301: siterator i, j;
302:
303: s_init_list(&a);
304: s_init_list(&b);
305: x = xmalloc(sizeof(*x));
306: s_add_tail(&a, x);
307: x = xmalloc(sizeof(*x));
308: s_add_tail(&a, x);
309: x = xmalloc(sizeof(*x));
310: s_add_tail(&a, x);
311: dump("1", &a);
312:
313: s_init(&i, &a);
314: s_init(&j, &a);
315: dump("2", &a);
316:
317: x = s_get(&i);
318: bt_debug("Got %p\n", x);
319: dump("3", &a);
320:
321: s_put(&i, x->next);
322: dump("4", &a);
323:
324: y = s_get(&j);
325: while (y)
326: {
327: s_put(&j, y);
328: dump("5*", &a);
329: y = s_get(&j)->next;
330: }
331:
332: dump("5 done", &a);
333:
334: s_rem_node(a.head->next);
335: dump("6 (deletion)", &a);
336:
337: s_put(&i, s_get(&i)->next);
338: dump("6 (relink)", &a);
339:
340: x = xmalloc(sizeof(*x));
341: s_add_tail(&b, x);
342: dump("7 (second list)", &b);
343:
344: s_add_tail_list(&b, &a);
345: dump("8 (after merge)", &b);
346:
347: return 1;
348: }
349:
350: static int
351: t_safe_del_walk(void)
352: {
353: init_list_();
354: fill_list();
355:
356: show_list();
357:
358: snode *node, *node_next;
359: WALK_SLIST_DELSAFE(node,node_next, lst)
360: {
361: bt_debug("Will remove node %p \n", node);
362: s_rem_node(SNODE node);
363: }
364: bt_assert(is_empty_list_well_unlinked());
365:
366: return 1;
367: }
368:
369: int
370: main(int argc, char *argv[])
371: {
372: bt_init(argc, argv);
373:
374: bt_test_suite(t_add_tail, "Adding nodes to tail of list");
375: bt_test_suite(t_add_head, "Adding nodes to head of list");
376: bt_test_suite(t_insert_node, "Inserting nodes to list");
377: bt_test_suite(t_remove_node, "Removing nodes from list");
378: bt_test_suite(t_add_tail_list, "At the tail of a list adding the another list");
379: bt_test_suite(t_iterator_walk, "Iterator walk");
380: bt_test_suite(t_safe_del_walk, "WALK_SLIST_DELSAFE and s_rem_node all nodes");
381: bt_test_suite(t_original, "The original BIRD test suit for SLIST");
382:
383: return bt_exit_value();
384: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>