7 /****************************************************************************/
8 void test_lfds600_slist( void )
17 struct lfds600_slist_thread_start_state
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
34 cpu_count = abstraction_cpu_count();
40 // TRD : 1. one head writer per CPU
43 "1. one head writer per CPU\n"
44 "==========================\n" );
46 lfds600_slist_new( &stss.ss, NULL, NULL );
47 stss.iteration_modulo = 1;
51 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
53 for( loop = 0 ; loop < cpu_count ; loop++ )
54 abstraction_thread_start( &thread_handles[loop], loop, lfds600_slist_internal_thread_head_writer, &stss );
56 for( loop = 0 ; loop < cpu_count ; loop++ )
57 abstraction_thread_wait( thread_handles[loop] );
59 lfds600_slist_delete( stss.ss );
61 free( thread_handles );
63 // TRD : 2. make one element, then one after writer per CPU
66 "2. make one element, then one after writer per CPU\n"
67 "==================================================\n" );
69 lfds600_slist_new( &stss.ss, NULL, NULL );
70 stss.iteration_modulo = 1;
71 stss.se = lfds600_slist_new_head( stss.ss, (void *) NULL );
74 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
76 for( loop = 0 ; loop < cpu_count ; loop++ )
77 abstraction_thread_start( &thread_handles[loop], loop, lfds600_slist_internal_thread_after_writer, &stss );
79 for( loop = 0 ; loop < cpu_count ; loop++ )
80 abstraction_thread_wait( thread_handles[loop] );
82 lfds600_slist_delete( stss.ss );
84 free( thread_handles );
86 // TRD : 3. make a list, then one list traverser per CPU
89 "3. make a list, then one list traverser per CPU\n"
90 "===============================================\n" );
92 lfds600_slist_new( &stss.ss, NULL, NULL );
93 stss.iteration_modulo = 1;
97 // TRD : small list so we get collisions
98 for( loop = 0 ; loop < 10 ; loop++ )
99 lfds600_slist_new_head( stss.ss, (void *) 0 );
101 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
103 for( loop = 0 ; loop < cpu_count ; loop++ )
104 abstraction_thread_start( &thread_handles[loop], loop, lfds600_slist_internal_thread_traverser, &stss );
106 for( loop = 0 ; loop < cpu_count ; loop++ )
107 abstraction_thread_wait( thread_handles[loop] );
109 lfds600_slist_delete( stss.ss );
111 free( thread_handles );
113 // TRD : 4. one head writer and one list traverser per CPU
116 "4. one head writer and one list traverser per CPU\n"
117 "=================================================\n" );
119 lfds600_slist_new( &stss.ss, NULL, NULL );
120 stss.iteration_modulo = 1;
124 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
126 for( loop = 0 ; loop < cpu_count ; loop++ )\
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 );
132 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
133 abstraction_thread_wait( thread_handles[loop] );
135 lfds600_slist_delete( stss.ss );
137 free( thread_handles );
139 // TRD : 5. make one element, then one after writer and one list traverser per CPU
142 "5. make one element, then one after writer and one list traverser per CPU\n"
143 "=========================================================================\n" );
145 lfds600_slist_new( &stss.ss, NULL, NULL );
146 stss.iteration_modulo = 1;
147 stss.se = lfds600_slist_new_head( stss.ss, (void *) NULL );
150 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
152 for( loop = 0 ; loop < cpu_count ; loop++ )\
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 );
158 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
159 abstraction_thread_wait( thread_handles[loop] );
161 lfds600_slist_delete( stss.ss );
163 free( thread_handles );
165 // TRD : 6. make a list, then one 100% deleter-traverser per CPU
168 "6. make a list, then one 100%% deleter-traverser per CPU\n"
169 "=======================================================\n" );
171 lfds600_slist_new( &stss.ss, NULL, NULL );
172 stss.iteration_modulo = 1;
176 for( loop = 0 ; loop < 10000 ; loop++ )
177 lfds600_slist_new_head( stss.ss, (void *) 0 );
179 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
181 for( loop = 0 ; loop < cpu_count ; loop++ )
182 abstraction_thread_start( &thread_handles[loop], loop, lfds600_slist_internal_thread_deleter_traverser, &stss );
184 for( loop = 0 ; loop < cpu_count ; loop++ )
185 abstraction_thread_wait( thread_handles[loop] );
187 lfds600_slist_delete( stss.ss );
189 free( thread_handles );
191 // TRD : 7. make a list, then one 25% deleter-traverser per CPU
194 "7. make a list, then one 25%% deleter-traverser per CPU\n"
195 "======================================================\n" );
197 lfds600_slist_new( &stss.ss, NULL, NULL );
198 stss.iteration_modulo = 4;
202 for( loop = 0 ; loop < 10000 ; loop++ )
203 lfds600_slist_new_head( stss.ss, (void *) 0 );
205 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
207 for( loop = 0 ; loop < cpu_count ; loop++ )
208 abstraction_thread_start( &thread_handles[loop], loop, lfds600_slist_internal_thread_deleter_traverser, &stss );
210 for( loop = 0 ; loop < cpu_count ; loop++ )
211 abstraction_thread_wait( thread_handles[loop] );
213 lfds600_slist_delete( stss.ss );
215 free( thread_handles );
217 // TRD : 8. one head writer and one 100% deleter-traverse per CPU
220 "8. one head writer and one 100%% deleter-traverse per CPU\n"
221 "========================================================\n" );
223 lfds600_slist_new( &stss.ss, NULL, NULL );
224 stss.iteration_modulo = 1;
228 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
230 for( loop = 0 ; loop < cpu_count ; loop++ )
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 );
236 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
237 abstraction_thread_wait( thread_handles[loop] );
239 lfds600_slist_delete( stss.ss );
241 free( thread_handles );
243 // TRD : 9. one head writer and one 25% deleter-traverse per CPU
246 "9. one head writer and one 25%% deleter-traverse per CPU\n"
247 "=======================================================\n" );
249 lfds600_slist_new( &stss.ss, NULL, NULL );
250 stss.iteration_modulo = 4;
254 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
256 for( loop = 0 ; loop < cpu_count ; loop++ )
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 );
262 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
263 abstraction_thread_wait( thread_handles[loop] );
265 lfds600_slist_delete( stss.ss );
267 free( thread_handles );
269 // TRD : 10. make one element, then one after writer and one 100% deleter-traverser per CPU
272 "10. make one element, then one after writer and one 100%% deleter-traverser per CPU\n"
273 "==================================================================================\n" );
275 lfds600_slist_new( &stss.ss, NULL, NULL );
276 stss.iteration_modulo = 1;
277 stss.se = lfds600_slist_new_head( stss.ss, (void *) NULL );
280 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
282 for( loop = 0 ; loop < cpu_count ; loop++ )
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 );
288 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
289 abstraction_thread_wait( thread_handles[loop] );
291 lfds600_slist_delete( stss.ss );
293 free( thread_handles );
295 // TRD : 11. make one element, then one after writer and one 25% deleter-traverser per CPU
298 "11. make one element, then one after writer and one 25%% deleter-traverser per CPU\n"
299 "=================================================================================\n" );
301 lfds600_slist_new( &stss.ss, NULL, NULL );
302 stss.iteration_modulo = 4;
303 stss.se = lfds600_slist_new_head( stss.ss, (void *) NULL );
306 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
308 for( loop = 0 ; loop < cpu_count ; loop++ )
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 );
314 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
315 abstraction_thread_wait( thread_handles[loop] );
317 lfds600_slist_delete( stss.ss );
319 free( thread_handles );
321 // TRD : 12. one head writer, one after writer, one traverser and one 25% deleter-traverser per CPU
324 "12. one head writer, one after writer, one traverser and one 25%% deleter-traverser per CPU\n"
325 "==========================================================================================\n" );
327 lfds600_slist_new( &stss.ss, NULL, NULL );
328 stss.iteration_modulo = 4;
329 stss.se = lfds600_slist_new_head( stss.ss, (void *) NULL );
332 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 4 );
334 for( loop = 0 ; loop < cpu_count ; loop++ )
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 );
342 for( loop = 0 ; loop < cpu_count * 4 ; loop++ )
343 abstraction_thread_wait( thread_handles[loop] );
345 lfds600_slist_delete( stss.ss );
347 free( thread_handles );
356 /****************************************************************************/
357 thread_return_t CALLING_CONVENTION lfds600_slist_internal_thread_head_writer( void *lfds600_slist_thread_start_state )
359 struct lfds600_slist_thread_start_state
368 assert( lfds600_slist_thread_start_state != NULL );
370 stss = (struct lfds600_slist_thread_start_state *) lfds600_slist_thread_start_state;
374 while( time(NULL) < start_time + stss->duration )
375 if( lfds600_slist_new_head(stss->ss, (void *) 0) )
378 printf( "head writer count = %lu\n", count );
380 return( (thread_return_t) EXIT_SUCCESS );
387 /****************************************************************************/
388 thread_return_t CALLING_CONVENTION lfds600_slist_internal_thread_after_writer( void *lfds600_slist_thread_start_state )
390 struct lfds600_slist_thread_start_state
399 assert( lfds600_slist_thread_start_state != NULL );
401 stss = (struct lfds600_slist_thread_start_state *) lfds600_slist_thread_start_state;
405 while( time(NULL) < start_time + stss->duration )
406 if( lfds600_slist_new_next(stss->se, (void *) 0) )
409 printf( "after writer count = %lu\n", count );
411 return( (thread_return_t) EXIT_SUCCESS );
418 /****************************************************************************/
419 thread_return_t CALLING_CONVENTION lfds600_slist_internal_thread_traverser( void *lfds600_slist_thread_start_state )
421 struct lfds600_slist_thread_start_state
431 struct lfds600_slist_element
434 assert( lfds600_slist_thread_start_state != NULL );
436 stss = (struct lfds600_slist_thread_start_state *) lfds600_slist_thread_start_state;
440 lfds600_slist_get_head( stss->ss, &se );
442 while( time(NULL) < start_time + stss->duration )
444 if( !(iteration % stss->iteration_modulo) )
446 lfds600_slist_get_next( se, &se );
452 lfds600_slist_get_head( stss->ss, &se );
459 printf( "traverser count = %lu\n", count );
461 return( (thread_return_t) EXIT_SUCCESS );
468 /****************************************************************************/
469 thread_return_t CALLING_CONVENTION lfds600_slist_internal_thread_deleter_traverser( void *lfds600_slist_thread_start_state )
471 struct lfds600_slist_thread_start_state
481 struct lfds600_slist_element
484 assert( lfds600_slist_thread_start_state != NULL );
486 stss = (struct lfds600_slist_thread_start_state *) lfds600_slist_thread_start_state;
490 lfds600_slist_get_head( stss->ss, &se );
492 while( time(NULL) < start_time + stss->duration )
494 if( se != NULL and !(iteration % stss->iteration_modulo) )
496 lfds600_slist_delete_element( stss->ss, se );
501 lfds600_slist_get_next( se, &se );
504 lfds600_slist_get_head( stss->ss, &se );
509 printf( "deleter-traverser count = %lu\n", count );
511 return( (thread_return_t) EXIT_SUCCESS );