1 #include "internal.h"
\r
7 /****************************************************************************/
\r
8 void test_lfds601_slist( void )
\r
17 struct lfds601_slist_thread_start_state
\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
34 cpu_count = abstraction_cpu_count();
\r
40 // TRD : 1. one head writer per CPU
\r
43 "1. one head writer per CPU\n"
\r
44 "==========================\n" );
\r
46 lfds601_slist_new( &stss.ss, NULL, NULL );
\r
47 stss.iteration_modulo = 1;
\r
51 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
\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
56 for( loop = 0 ; loop < cpu_count ; loop++ )
\r
57 abstraction_thread_wait( thread_handles[loop] );
\r
59 lfds601_slist_delete( stss.ss );
\r
61 free( thread_handles );
\r
63 // TRD : 2. make one element, then one after writer per CPU
\r
66 "2. make one element, then one after writer per CPU\n"
\r
67 "==================================================\n" );
\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
74 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
\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
79 for( loop = 0 ; loop < cpu_count ; loop++ )
\r
80 abstraction_thread_wait( thread_handles[loop] );
\r
82 lfds601_slist_delete( stss.ss );
\r
84 free( thread_handles );
\r
86 // TRD : 3. make a list, then one list traverser per CPU
\r
89 "3. make a list, then one list traverser per CPU\n"
\r
90 "===============================================\n" );
\r
92 lfds601_slist_new( &stss.ss, NULL, NULL );
\r
93 stss.iteration_modulo = 1;
\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
101 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
\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
106 for( loop = 0 ; loop < cpu_count ; loop++ )
\r
107 abstraction_thread_wait( thread_handles[loop] );
\r
109 lfds601_slist_delete( stss.ss );
\r
111 free( thread_handles );
\r
113 // TRD : 4. one head writer and one list traverser per CPU
\r
116 "4. one head writer and one list traverser per CPU\n"
\r
117 "=================================================\n" );
\r
119 lfds601_slist_new( &stss.ss, NULL, NULL );
\r
120 stss.iteration_modulo = 1;
\r
124 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
\r
126 for( loop = 0 ; loop < cpu_count ; loop++ )\
\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
132 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
\r
133 abstraction_thread_wait( thread_handles[loop] );
\r
135 lfds601_slist_delete( stss.ss );
\r
137 free( thread_handles );
\r
139 // TRD : 5. make one element, then one after writer and one list traverser per CPU
\r
142 "5. make one element, then one after writer and one list traverser per CPU\n"
\r
143 "=========================================================================\n" );
\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
150 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
\r
152 for( loop = 0 ; loop < cpu_count ; loop++ )\
\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
158 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
\r
159 abstraction_thread_wait( thread_handles[loop] );
\r
161 lfds601_slist_delete( stss.ss );
\r
163 free( thread_handles );
\r
165 // TRD : 6. make a list, then one 100% deleter-traverser per CPU
\r
168 "6. make a list, then one 100%% deleter-traverser per CPU\n"
\r
169 "=======================================================\n" );
\r
171 lfds601_slist_new( &stss.ss, NULL, NULL );
\r
172 stss.iteration_modulo = 1;
\r
176 for( loop = 0 ; loop < 10000 ; loop++ )
\r
177 lfds601_slist_new_head( stss.ss, (void *) 0 );
\r
179 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
\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
184 for( loop = 0 ; loop < cpu_count ; loop++ )
\r
185 abstraction_thread_wait( thread_handles[loop] );
\r
187 lfds601_slist_delete( stss.ss );
\r
189 free( thread_handles );
\r
191 // TRD : 7. make a list, then one 25% deleter-traverser per CPU
\r
194 "7. make a list, then one 25%% deleter-traverser per CPU\n"
\r
195 "======================================================\n" );
\r
197 lfds601_slist_new( &stss.ss, NULL, NULL );
\r
198 stss.iteration_modulo = 4;
\r
202 for( loop = 0 ; loop < 10000 ; loop++ )
\r
203 lfds601_slist_new_head( stss.ss, (void *) 0 );
\r
205 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 1 );
\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
210 for( loop = 0 ; loop < cpu_count ; loop++ )
\r
211 abstraction_thread_wait( thread_handles[loop] );
\r
213 lfds601_slist_delete( stss.ss );
\r
215 free( thread_handles );
\r
217 // TRD : 8. one head writer and one 100% deleter-traverse per CPU
\r
220 "8. one head writer and one 100%% deleter-traverse per CPU\n"
\r
221 "========================================================\n" );
\r
223 lfds601_slist_new( &stss.ss, NULL, NULL );
\r
224 stss.iteration_modulo = 1;
\r
226 stss.duration = 10;
\r
228 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
\r
230 for( loop = 0 ; loop < cpu_count ; loop++ )
\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
236 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
\r
237 abstraction_thread_wait( thread_handles[loop] );
\r
239 lfds601_slist_delete( stss.ss );
\r
241 free( thread_handles );
\r
243 // TRD : 9. one head writer and one 25% deleter-traverse per CPU
\r
246 "9. one head writer and one 25%% deleter-traverse per CPU\n"
\r
247 "=======================================================\n" );
\r
249 lfds601_slist_new( &stss.ss, NULL, NULL );
\r
250 stss.iteration_modulo = 4;
\r
254 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
\r
256 for( loop = 0 ; loop < cpu_count ; loop++ )
\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
262 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
\r
263 abstraction_thread_wait( thread_handles[loop] );
\r
265 lfds601_slist_delete( stss.ss );
\r
267 free( thread_handles );
\r
269 // TRD : 10. make one element, then one after writer and one 100% deleter-traverser per CPU
\r
272 "10. make one element, then one after writer and one 100%% deleter-traverser per CPU\n"
\r
273 "==================================================================================\n" );
\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
280 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
\r
282 for( loop = 0 ; loop < cpu_count ; loop++ )
\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
288 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
\r
289 abstraction_thread_wait( thread_handles[loop] );
\r
291 lfds601_slist_delete( stss.ss );
\r
293 free( thread_handles );
\r
295 // TRD : 11. make one element, then one after writer and one 25% deleter-traverser per CPU
\r
298 "11. make one element, then one after writer and one 25%% deleter-traverser per CPU\n"
\r
299 "=================================================================================\n" );
\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
306 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 2 );
\r
308 for( loop = 0 ; loop < cpu_count ; loop++ )
\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
314 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
\r
315 abstraction_thread_wait( thread_handles[loop] );
\r
317 lfds601_slist_delete( stss.ss );
\r
319 free( thread_handles );
\r
321 // TRD : 12. one head writer, one after writer, one traverser and one 25% deleter-traverser per CPU
\r
324 "12. one head writer, one after writer, one traverser and one 25%% deleter-traverser per CPU\n"
\r
325 "==========================================================================================\n" );
\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
332 thread_handles = (thread_state_t *) malloc( sizeof(thread_state_t) * cpu_count * 4 );
\r
334 for( loop = 0 ; loop < cpu_count ; loop++ )
\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
342 for( loop = 0 ; loop < cpu_count * 4 ; loop++ )
\r
343 abstraction_thread_wait( thread_handles[loop] );
\r
345 lfds601_slist_delete( stss.ss );
\r
347 free( thread_handles );
\r
356 /****************************************************************************/
\r
357 thread_return_t CALLING_CONVENTION lfds601_slist_internal_thread_head_writer( void *lfds601_slist_thread_start_state )
\r
359 struct lfds601_slist_thread_start_state
\r
368 assert( lfds601_slist_thread_start_state != NULL );
\r
370 stss = (struct lfds601_slist_thread_start_state *) lfds601_slist_thread_start_state;
\r
372 time( &start_time );
\r
374 while( time(NULL) < start_time + stss->duration )
\r
375 if( lfds601_slist_new_head(stss->ss, (void *) 0) )
\r
378 printf( "head writer count = %lu\n", count );
\r
380 return( (thread_return_t) EXIT_SUCCESS );
\r
387 /****************************************************************************/
\r
388 thread_return_t CALLING_CONVENTION lfds601_slist_internal_thread_after_writer( void *lfds601_slist_thread_start_state )
\r
390 struct lfds601_slist_thread_start_state
\r
399 assert( lfds601_slist_thread_start_state != NULL );
\r
401 stss = (struct lfds601_slist_thread_start_state *) lfds601_slist_thread_start_state;
\r
403 time( &start_time );
\r
405 while( time(NULL) < start_time + stss->duration )
\r
406 if( lfds601_slist_new_next(stss->se, (void *) 0) )
\r
409 printf( "after writer count = %lu\n", count );
\r
411 return( (thread_return_t) EXIT_SUCCESS );
\r
418 /****************************************************************************/
\r
419 thread_return_t CALLING_CONVENTION lfds601_slist_internal_thread_traverser( void *lfds601_slist_thread_start_state )
\r
421 struct lfds601_slist_thread_start_state
\r
431 struct lfds601_slist_element
\r
434 assert( lfds601_slist_thread_start_state != NULL );
\r
436 stss = (struct lfds601_slist_thread_start_state *) lfds601_slist_thread_start_state;
\r
438 time( &start_time );
\r
440 lfds601_slist_get_head( stss->ss, &se );
\r
442 while( time(NULL) < start_time + stss->duration )
\r
444 if( !(iteration % stss->iteration_modulo) )
\r
446 lfds601_slist_get_next( se, &se );
\r
452 lfds601_slist_get_head( stss->ss, &se );
\r
459 printf( "traverser count = %lu\n", count );
\r
461 return( (thread_return_t) EXIT_SUCCESS );
\r
468 /****************************************************************************/
\r
469 thread_return_t CALLING_CONVENTION lfds601_slist_internal_thread_deleter_traverser( void *lfds601_slist_thread_start_state )
\r
471 struct lfds601_slist_thread_start_state
\r
481 struct lfds601_slist_element
\r
484 assert( lfds601_slist_thread_start_state != NULL );
\r
486 stss = (struct lfds601_slist_thread_start_state *) lfds601_slist_thread_start_state;
\r
488 time( &start_time );
\r
490 lfds601_slist_get_head( stss->ss, &se );
\r
492 while( time(NULL) < start_time + stss->duration )
\r
494 if( se != NULL and !(iteration % stss->iteration_modulo) )
\r
496 lfds601_slist_delete_element( stss->ss, se );
\r
501 lfds601_slist_get_next( se, &se );
\r
504 lfds601_slist_get_head( stss->ss, &se );
\r
509 printf( "deleter-traverser count = %lu\n", count );
\r
511 return( (thread_return_t) EXIT_SUCCESS );
\r