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