]> pd.if.org Git - liblfds/blob - liblfds/liblfds6.0.1/test/src/test_slist.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds6.0.1 / test / src / test_slist.c
1 #include "internal.h"\r
2 \r
3 \r
4 \r
5 \r
6 \r
7 /****************************************************************************/\r
8 void test_lfds601_slist( void )\r
9 {\r
10   unsigned int\r
11     loop,\r
12     cpu_count;\r
13 \r
14   thread_state_t\r
15     *thread_handles;\r
16 \r
17   struct lfds601_slist_thread_start_state\r
18     stss;\r
19 \r
20   /* TRD : 1. one head writer per CPU\r
21            2. make one element, then one after writer per CPU\r
22            3. make a list, then one list traverser per CPU\r
23            4. one head writer and one list traverser per CPU\r
24            5. make one element, then one after writer and one list traverser per CPU\r
25            6. make a list, then one 100% deleter-traverser per CPU\r
26            7. make a list, then one 25% deleter-traverser per CPU\r
27            8. one head writer and one 100% deleter-traverse per CPU\r
28            9. one head writer and one 25% deleter-traverse per CPU\r
29            10. make one element, then one after writer and one 100% deleter-traverser per CPU\r
30            11. make one element, then one after writer and one 25% deleter-traverser per CPU\r
31            12. one head writer, one after writer, one traverser and one 25% deleter-traverser per CPU\r
32   */\r
33 \r
34   cpu_count = abstraction_cpu_count();\r
35 \r
36   printf( "\n"\r
37           "SList Test\n"\r
38           "==========\n" );\r
39 \r
40   // TRD : 1. one head writer per CPU\r
41 \r
42   printf( "\n"\r
43           "1. one head writer per CPU\n"\r
44           "==========================\n" );\r
45 \r
46   lfds601_slist_new( &stss.ss, NULL, NULL );\r
47   stss.iteration_modulo = 1;\r
48   stss.se = NULL;\r
49   stss.duration = 1;\r
50 \r
51   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );\r
52 \r
53   for( loop = 0 ; loop < cpu_count ; loop++ )\r
54     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_head_writer, &stss );\r
55 \r
56   for( loop = 0 ; loop < cpu_count ; loop++ )\r
57     abstraction_thread_wait( thread_handles[loop] );\r
58 \r
59   lfds601_slist_delete( stss.ss );\r
60 \r
61   free( thread_handles );\r
62 \r
63   // TRD : 2. make one element, then one after writer per CPU\r
64 \r
65   printf( "\n"\r
66           "2. make one element, then one after writer per CPU\n"\r
67           "==================================================\n" );\r
68 \r
69   lfds601_slist_new( &stss.ss, NULL, NULL );\r
70   stss.iteration_modulo = 1;\r
71   stss.se = lfds601_slist_new_head( stss.ss, (void *) NULL );\r
72   stss.duration = 1;\r
73 \r
74   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );\r
75 \r
76   for( loop = 0 ; loop < cpu_count ; loop++ )\r
77     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_after_writer, &stss );\r
78 \r
79   for( loop = 0 ; loop < cpu_count ; loop++ )\r
80     abstraction_thread_wait( thread_handles[loop] );\r
81 \r
82   lfds601_slist_delete( stss.ss );\r
83 \r
84   free( thread_handles );\r
85 \r
86   // TRD : 3. make a list, then one list traverser per CPU\r
87 \r
88   printf( "\n"\r
89           "3. make a list, then one list traverser per CPU\n"\r
90           "===============================================\n" );\r
91 \r
92   lfds601_slist_new( &stss.ss, NULL, NULL );\r
93   stss.iteration_modulo = 1;\r
94   stss.se = NULL;\r
95   stss.duration = 10;\r
96 \r
97   // TRD : small list so we get collisions\r
98   for( loop = 0 ; loop < 10 ; loop++ )\r
99     lfds601_slist_new_head( stss.ss, (void *) 0 );\r
100 \r
101   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );\r
102 \r
103   for( loop = 0 ; loop < cpu_count ; loop++ )\r
104     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_traverser, &stss );\r
105 \r
106   for( loop = 0 ; loop < cpu_count ; loop++ )\r
107     abstraction_thread_wait( thread_handles[loop] );\r
108 \r
109   lfds601_slist_delete( stss.ss );\r
110 \r
111   free( thread_handles );\r
112 \r
113   // TRD : 4. one head writer and one list traverser per CPU\r
114 \r
115   printf( "\n"\r
116           "4. one head writer and one list traverser per CPU\n"\r
117           "=================================================\n" );\r
118 \r
119   lfds601_slist_new( &stss.ss, NULL, NULL );\r
120   stss.iteration_modulo = 1;\r
121   stss.se = NULL;\r
122   stss.duration = 1;\r
123 \r
124   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );\r
125 \r
126   for( loop = 0 ; loop < cpu_count ; loop++ )\\r
127   {\r
128     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_head_writer, &stss );\r
129     abstraction_thread_start( &thread_handles[loop+cpu_count], loop, lfds601_slist_internal_thread_traverser, &stss );\r
130   }\r
131 \r
132   for( loop = 0 ; loop < cpu_count * 2 ; loop++ )\r
133     abstraction_thread_wait( thread_handles[loop] );\r
134 \r
135   lfds601_slist_delete( stss.ss );\r
136 \r
137   free( thread_handles );\r
138 \r
139   // TRD : 5. make one element, then one after writer and one list traverser per CPU\r
140 \r
141   printf( "\n"\r
142           "5. make one element, then one after writer and one list traverser per CPU\n"\r
143           "=========================================================================\n" );\r
144 \r
145   lfds601_slist_new( &stss.ss, NULL, NULL );\r
146   stss.iteration_modulo = 1;\r
147   stss.se = lfds601_slist_new_head( stss.ss, (void *) NULL );\r
148   stss.duration = 1;\r
149 \r
150   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );\r
151 \r
152   for( loop = 0 ; loop < cpu_count ; loop++ )\\r
153   {\r
154     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_after_writer, &stss );\r
155     abstraction_thread_start( &thread_handles[loop+cpu_count], loop, lfds601_slist_internal_thread_traverser, &stss );\r
156   }\r
157 \r
158   for( loop = 0 ; loop < cpu_count * 2 ; loop++ )\r
159     abstraction_thread_wait( thread_handles[loop] );\r
160 \r
161   lfds601_slist_delete( stss.ss );\r
162 \r
163   free( thread_handles );\r
164 \r
165   // TRD : 6. make a list, then one 100% deleter-traverser per CPU\r
166 \r
167   printf( "\n"\r
168           "6. make a list, then one 100%% deleter-traverser per CPU\n"\r
169           "=======================================================\n" );\r
170 \r
171   lfds601_slist_new( &stss.ss, NULL, NULL );\r
172   stss.iteration_modulo = 1;\r
173   stss.se = NULL;\r
174   stss.duration = 1;\r
175 \r
176   for( loop = 0 ; loop < 10000 ; loop++ )\r
177     lfds601_slist_new_head( stss.ss, (void *) 0 );\r
178 \r
179   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );\r
180 \r
181   for( loop = 0 ; loop < cpu_count ; loop++ )\r
182     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_deleter_traverser, &stss );\r
183 \r
184   for( loop = 0 ; loop < cpu_count ; loop++ )\r
185     abstraction_thread_wait( thread_handles[loop] );\r
186 \r
187   lfds601_slist_delete( stss.ss );\r
188 \r
189   free( thread_handles );\r
190 \r
191   // TRD : 7. make a list, then one 25% deleter-traverser per CPU\r
192 \r
193   printf( "\n"\r
194           "7. make a list, then one 25%% deleter-traverser per CPU\n"\r
195           "======================================================\n" );\r
196 \r
197   lfds601_slist_new( &stss.ss, NULL, NULL );\r
198   stss.iteration_modulo = 4;\r
199   stss.se = NULL;\r
200   stss.duration = 1;\r
201 \r
202   for( loop = 0 ; loop < 10000 ; loop++ )\r
203     lfds601_slist_new_head( stss.ss, (void *) 0 );\r
204 \r
205   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );\r
206 \r
207   for( loop = 0 ; loop < cpu_count ; loop++ )\r
208     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_deleter_traverser, &stss );\r
209 \r
210   for( loop = 0 ; loop < cpu_count ; loop++ )\r
211     abstraction_thread_wait( thread_handles[loop] );\r
212 \r
213   lfds601_slist_delete( stss.ss );\r
214 \r
215   free( thread_handles );\r
216 \r
217   // TRD : 8. one head writer and one 100% deleter-traverse per CPU\r
218 \r
219   printf( "\n"\r
220           "8. one head writer and one 100%% deleter-traverse per CPU\n"\r
221           "========================================================\n" );\r
222 \r
223   lfds601_slist_new( &stss.ss, NULL, NULL );\r
224   stss.iteration_modulo = 1;\r
225   stss.se = NULL;\r
226   stss.duration = 10;\r
227 \r
228   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );\r
229 \r
230   for( loop = 0 ; loop < cpu_count ; loop++ )\r
231   {\r
232     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_head_writer, &stss );\r
233     abstraction_thread_start( &thread_handles[loop+cpu_count], loop, lfds601_slist_internal_thread_deleter_traverser, &stss );\r
234   }\r
235 \r
236   for( loop = 0 ; loop < cpu_count * 2 ; loop++ )\r
237     abstraction_thread_wait( thread_handles[loop] );\r
238 \r
239   lfds601_slist_delete( stss.ss );\r
240 \r
241   free( thread_handles );\r
242 \r
243   // TRD : 9. one head writer and one 25% deleter-traverse per CPU\r
244 \r
245   printf( "\n"\r
246           "9. one head writer and one 25%% deleter-traverse per CPU\n"\r
247           "=======================================================\n" );\r
248 \r
249   lfds601_slist_new( &stss.ss, NULL, NULL );\r
250   stss.iteration_modulo = 4;\r
251   stss.se = NULL;\r
252   stss.duration = 1;\r
253 \r
254   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );\r
255 \r
256   for( loop = 0 ; loop < cpu_count ; loop++ )\r
257   {\r
258     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_head_writer, &stss );\r
259     abstraction_thread_start( &thread_handles[loop+cpu_count], loop, lfds601_slist_internal_thread_deleter_traverser, &stss );\r
260   }\r
261 \r
262   for( loop = 0 ; loop < cpu_count * 2 ; loop++ )\r
263     abstraction_thread_wait( thread_handles[loop] );\r
264 \r
265   lfds601_slist_delete( stss.ss );\r
266 \r
267   free( thread_handles );\r
268 \r
269   // TRD : 10. make one element, then one after writer and one 100% deleter-traverser per CPU\r
270 \r
271   printf( "\n"\r
272           "10. make one element, then one after writer and one 100%% deleter-traverser per CPU\n"\r
273           "==================================================================================\n" );\r
274 \r
275   lfds601_slist_new( &stss.ss, NULL, NULL );\r
276   stss.iteration_modulo = 1;\r
277   stss.se = lfds601_slist_new_head( stss.ss, (void *) NULL );\r
278   stss.duration = 10;\r
279 \r
280   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );\r
281 \r
282   for( loop = 0 ; loop < cpu_count ; loop++ )\r
283   {\r
284     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_after_writer, &stss );\r
285     abstraction_thread_start( &thread_handles[loop+cpu_count], loop, lfds601_slist_internal_thread_deleter_traverser, &stss );\r
286   }\r
287 \r
288   for( loop = 0 ; loop < cpu_count * 2 ; loop++ )\r
289     abstraction_thread_wait( thread_handles[loop] );\r
290 \r
291   lfds601_slist_delete( stss.ss );\r
292 \r
293   free( thread_handles );\r
294 \r
295   // TRD : 11. make one element, then one after writer and one 25% deleter-traverser per CPU\r
296 \r
297   printf( "\n"\r
298           "11. make one element, then one after writer and one 25%% deleter-traverser per CPU\n"\r
299           "=================================================================================\n" );\r
300 \r
301   lfds601_slist_new( &stss.ss, NULL, NULL );\r
302   stss.iteration_modulo = 4;\r
303   stss.se = lfds601_slist_new_head( stss.ss, (void *) NULL );\r
304   stss.duration = 1;\r
305 \r
306   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );\r
307 \r
308   for( loop = 0 ; loop < cpu_count ; loop++ )\r
309   {\r
310     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_after_writer, &stss );\r
311     abstraction_thread_start( &thread_handles[loop+cpu_count], loop, lfds601_slist_internal_thread_deleter_traverser, &stss );\r
312   }\r
313 \r
314   for( loop = 0 ; loop < cpu_count * 2 ; loop++ )\r
315     abstraction_thread_wait( thread_handles[loop] );\r
316 \r
317   lfds601_slist_delete( stss.ss );\r
318 \r
319   free( thread_handles );\r
320 \r
321   // TRD : 12. one head writer, one after writer, one traverser and one 25% deleter-traverser per CPU\r
322 \r
323   printf( "\n"\r
324           "12. one head writer, one after writer, one traverser and one 25%% deleter-traverser per CPU\n"\r
325           "==========================================================================================\n" );\r
326 \r
327   lfds601_slist_new( &stss.ss, NULL, NULL );\r
328   stss.iteration_modulo = 4;\r
329   stss.se = lfds601_slist_new_head( stss.ss, (void *) NULL );\r
330   stss.duration = 1;\r
331 \r
332   thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 4 );\r
333 \r
334   for( loop = 0 ; loop < cpu_count ; loop++ )\r
335   {\r
336     abstraction_thread_start( &thread_handles[loop], loop, lfds601_slist_internal_thread_head_writer, &stss );\r
337     abstraction_thread_start( &thread_handles[loop+cpu_count], loop, lfds601_slist_internal_thread_after_writer, &stss );\r
338     abstraction_thread_start( &thread_handles[loop+cpu_count*2], loop, lfds601_slist_internal_thread_traverser, &stss );\r
339     abstraction_thread_start( &thread_handles[loop+cpu_count*3], loop, lfds601_slist_internal_thread_deleter_traverser, &stss );\r
340   }\r
341 \r
342   for( loop = 0 ; loop < cpu_count * 4 ; loop++ )\r
343     abstraction_thread_wait( thread_handles[loop] );\r
344 \r
345   lfds601_slist_delete( stss.ss );\r
346 \r
347   free( thread_handles );\r
348 \r
349   return;\r
350 }\r
351 \r
352 \r
353 \r
354 \r
355 \r
356 /****************************************************************************/\r
357 thread_return_t CALLING_CONVENTION lfds601_slist_internal_thread_head_writer( void *lfds601_slist_thread_start_state )\r
358 {\r
359   struct lfds601_slist_thread_start_state\r
360     *stss;\r
361 \r
362   time_t\r
363     start_time;\r
364 \r
365   unsigned long int\r
366     count = 0;\r
367 \r
368   assert( lfds601_slist_thread_start_state != NULL );\r
369 \r
370   stss = (struct lfds601_slist_thread_start_state *) lfds601_slist_thread_start_state;\r
371 \r
372   time( &start_time );\r
373 \r
374   while( time(NULL) < start_time + stss->duration )\r
375     if( lfds601_slist_new_head(stss->ss, (void *) 0) )\r
376       count++;\r
377 \r
378   printf( "head writer count = %lu\n", count );\r
379 \r
380   return( (thread_return_t) EXIT_SUCCESS );\r
381 }\r
382 \r
383 \r
384 \r
385 \r
386 \r
387 /****************************************************************************/\r
388 thread_return_t CALLING_CONVENTION lfds601_slist_internal_thread_after_writer( void *lfds601_slist_thread_start_state )\r
389 {\r
390   struct lfds601_slist_thread_start_state\r
391     *stss;\r
392 \r
393   time_t\r
394     start_time;\r
395 \r
396   unsigned long int\r
397     count = 0;\r
398 \r
399   assert( lfds601_slist_thread_start_state != NULL );\r
400 \r
401   stss = (struct lfds601_slist_thread_start_state *) lfds601_slist_thread_start_state;\r
402 \r
403   time( &start_time );\r
404 \r
405   while( time(NULL) < start_time + stss->duration )\r
406     if( lfds601_slist_new_next(stss->se, (void *) 0) )\r
407       count++;\r
408 \r
409   printf( "after writer count = %lu\n", count );\r
410 \r
411   return( (thread_return_t) EXIT_SUCCESS );\r
412 }\r
413 \r
414 \r
415 \r
416 \r
417 \r
418 /****************************************************************************/\r
419 thread_return_t CALLING_CONVENTION lfds601_slist_internal_thread_traverser( void *lfds601_slist_thread_start_state )\r
420 {\r
421   struct lfds601_slist_thread_start_state\r
422     *stss;\r
423 \r
424   time_t\r
425     start_time;\r
426 \r
427   unsigned long int\r
428     count = 0,\r
429     iteration = 0;\r
430 \r
431   struct lfds601_slist_element\r
432     *se;\r
433 \r
434   assert( lfds601_slist_thread_start_state != NULL );\r
435 \r
436   stss = (struct lfds601_slist_thread_start_state *) lfds601_slist_thread_start_state;\r
437 \r
438   time( &start_time );\r
439 \r
440   lfds601_slist_get_head( stss->ss, &se );\r
441 \r
442   while( time(NULL) < start_time + stss->duration )\r
443   {\r
444     if( !(iteration % stss->iteration_modulo) )\r
445     {\r
446       lfds601_slist_get_next( se, &se );\r
447       count++;\r
448     }\r
449 \r
450     if( se == NULL )\r
451     {\r
452       lfds601_slist_get_head( stss->ss, &se );\r
453       count++;\r
454     }\r
455 \r
456     iteration++;\r
457   }\r
458 \r
459   printf( "traverser count = %lu\n", count );\r
460 \r
461   return( (thread_return_t) EXIT_SUCCESS );\r
462 }\r
463 \r
464 \r
465 \r
466 \r
467 \r
468 /****************************************************************************/\r
469 thread_return_t CALLING_CONVENTION lfds601_slist_internal_thread_deleter_traverser( void *lfds601_slist_thread_start_state )\r
470 {\r
471   struct lfds601_slist_thread_start_state\r
472     *stss;\r
473 \r
474   time_t\r
475     start_time;\r
476 \r
477   unsigned long int\r
478     count = 0,\r
479     iteration = 0;\r
480 \r
481   struct lfds601_slist_element\r
482     *se;\r
483 \r
484   assert( lfds601_slist_thread_start_state != NULL );\r
485 \r
486   stss = (struct lfds601_slist_thread_start_state *) lfds601_slist_thread_start_state;\r
487 \r
488   time( &start_time );\r
489 \r
490   lfds601_slist_get_head( stss->ss, &se );\r
491 \r
492   while( time(NULL) < start_time + stss->duration )\r
493   {\r
494     if( se != NULL and !(iteration % stss->iteration_modulo) )\r
495     {\r
496       lfds601_slist_delete_element( stss->ss, se );\r
497       count++;\r
498     }\r
499 \r
500     if( se != NULL )\r
501       lfds601_slist_get_next( se, &se );\r
502 \r
503     if( se == NULL )\r
504       lfds601_slist_get_head( stss->ss, &se );\r
505 \r
506     iteration++;\r
507   }\r
508 \r
509   printf( "deleter-traverser count = %lu\n", count );\r
510 \r
511   return( (thread_return_t) EXIT_SUCCESS );\r
512 }\r
513 \r