7 /****************************************************************************/
8 void test_lfds610_slist( void )
14 test_slist_new_delete_get();
15 test_slist_get_set_user_data();
16 test_slist_delete_all_elements();
25 /****************************************************************************/
26 void test_slist_new_delete_get( void )
32 struct lfds610_slist_state
35 struct lfds610_slist_element
38 struct slist_test_state
45 total_create_count = 0,
46 total_delete_count = 0,
49 enum lfds610_data_structure_validity
50 dvs = LFDS610_VALIDITY_VALID;
52 /* TRD : two threads per CPU
53 first simply alternates between new_head() and new_next() (next on element created by head)
54 second calls get_next, if NULL, then calls get_head, and deletes the element
55 both threads keep count of created and deleted
56 validate is to reconcile created, deleted and remaining in list
59 internal_display_test_name( "New head/next, delete and get next" );
61 cpu_count = abstraction_cpu_count();
63 lfds610_slist_new( &ss, NULL, NULL );
65 sts = malloc( sizeof(struct slist_test_state) * cpu_count * 2 );
67 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
70 (sts+loop)->create_count = 0;
71 (sts+loop)->delete_count = 0;
74 thread_handles = malloc( sizeof(thread_state_t) * cpu_count * 2 );
76 for( loop = 0 ; loop < cpu_count ; loop++ )
78 abstraction_thread_start( &thread_handles[loop], loop, slist_test_internal_thread_new_delete_get_new_head_and_next, sts+loop );
79 abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_test_internal_thread_new_delete_get_delete_and_get, sts+loop+cpu_count );
82 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
83 abstraction_thread_wait( thread_handles[loop] );
85 free( thread_handles );
88 for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
90 total_create_count += (sts+loop)->create_count;
91 total_delete_count += (sts+loop)->delete_count;
94 while( NULL != lfds610_slist_get_head_and_then_next(ss, &se) )
97 if( total_create_count - total_delete_count - element_count != 0 )
98 dvs = LFDS610_VALIDITY_INVALID_TEST_DATA;
102 lfds610_slist_delete( ss );
104 internal_display_test_result( 1, "slist", dvs );
113 /****************************************************************************/
114 thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_new_head_and_next( void *slist_test_state )
116 struct slist_test_state
122 struct lfds610_slist_element
125 assert( slist_test_state != NULL );
127 sts = (struct slist_test_state *) slist_test_state;
129 lfds610_slist_use( sts->ss );
133 while( time(NULL) < start_time + 1 )
135 if( sts->create_count % 2 == 0 )
136 se = lfds610_slist_new_head( sts->ss, NULL );
138 lfds610_slist_new_next( se, NULL );
143 return( (thread_return_t) EXIT_SUCCESS );
150 /****************************************************************************/
151 thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_delete_and_get( void *slist_test_state )
153 struct slist_test_state
159 struct lfds610_slist_element
162 assert( slist_test_state != NULL );
164 sts = (struct slist_test_state *) slist_test_state;
166 lfds610_slist_use( sts->ss );
170 while( time(NULL) < start_time + 1 )
173 lfds610_slist_get_head( sts->ss, &se );
175 lfds610_slist_get_next( se, &se );
179 if( 1 == lfds610_slist_logically_delete_element(sts->ss, se) )
184 return( (thread_return_t) EXIT_SUCCESS );
191 /****************************************************************************/
192 void test_slist_get_set_user_data( void )
198 struct lfds610_slist_state
201 struct lfds610_slist_element
204 struct slist_test_state
214 *per_thread_counters,
215 *per_thread_drop_flags;
217 enum lfds610_data_structure_validity
218 dvs = LFDS610_VALIDITY_VALID;
220 /* TRD : create a list of (cpu_count*10) elements, user data 0
222 each thread loops, setting user_data to ((thread_number << (sizeof(lfds610_atom_t)*8-8)) | count)
223 validation is to scan list, count on a per thread basis should go down only once
226 internal_display_test_name( "Get and set user data" );
228 cpu_count = abstraction_cpu_count();
230 lfds610_slist_new( &ss, NULL, NULL );
232 for( loop = 0 ; loop < cpu_count * 10 ; loop++ )
233 lfds610_slist_new_head( ss, NULL );
235 sts = malloc( sizeof(struct slist_test_state) * cpu_count );
237 for( loop = 0 ; loop < cpu_count ; loop++ )
240 (sts+loop)->thread_and_count = (lfds610_atom_t) loop << (sizeof(lfds610_atom_t)*8-8);
243 thread_handles = malloc( sizeof(thread_state_t) * cpu_count );
245 for( loop = 0 ; loop < cpu_count ; loop++ )
246 abstraction_thread_start( &thread_handles[loop], loop, slist_test_internal_thread_get_set_user_data, sts+loop );
248 for( loop = 0 ; loop < cpu_count ; loop++ )
249 abstraction_thread_wait( thread_handles[loop] );
251 free( thread_handles );
254 per_thread_counters = malloc( sizeof(lfds610_atom_t) * cpu_count );
255 per_thread_drop_flags = malloc( sizeof(lfds610_atom_t) * cpu_count );
257 for( loop = 0 ; loop < cpu_count ; loop++ )
259 *(per_thread_counters+loop) = 0;
260 *(per_thread_drop_flags+loop) = 0;
263 while( dvs == LFDS610_VALIDITY_VALID and NULL != lfds610_slist_get_head_and_then_next(ss, &se) )
265 lfds610_slist_get_user_data_from_element( se, (void **) &thread_and_count );
267 thread = thread_and_count >> (sizeof(lfds610_atom_t)*8-8);
268 count = (thread_and_count << 8) >> 8;
270 if( thread >= cpu_count )
272 dvs = LFDS610_VALIDITY_INVALID_TEST_DATA;
276 if( per_thread_counters[thread] == 0 )
278 per_thread_counters[thread] = count;
282 per_thread_counters[thread]++;
284 if( count < per_thread_counters[thread] and per_thread_drop_flags[thread] == 1 )
286 dvs = LFDS610_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
290 if( count < per_thread_counters[thread] and per_thread_drop_flags[thread] == 0 )
292 per_thread_drop_flags[thread] = 1;
293 per_thread_counters[thread] = count;
297 if( count < per_thread_counters[thread] )
298 dvs = LFDS610_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
300 if( count >= per_thread_counters[thread] )
301 per_thread_counters[thread] = count;
304 free( per_thread_drop_flags );
305 free( per_thread_counters );
309 lfds610_slist_delete( ss );
311 internal_display_test_result( 1, "slist", dvs );
320 /****************************************************************************/
321 thread_return_t CALLING_CONVENTION slist_test_internal_thread_get_set_user_data( void *slist_test_state )
323 struct slist_test_state
329 struct lfds610_slist_element
332 assert( slist_test_state != NULL );
334 sts = (struct slist_test_state *) slist_test_state;
336 lfds610_slist_use( sts->ss );
340 while( time(NULL) < start_time + 1 )
343 lfds610_slist_get_head( sts->ss, &se );
345 lfds610_slist_set_user_data_in_element( se, (void *) sts->thread_and_count++ );
347 lfds610_slist_get_next( se, &se );
350 return( (thread_return_t) EXIT_SUCCESS );
357 /****************************************************************************/
358 void test_slist_delete_all_elements( void )
360 struct lfds610_slist_state
363 struct lfds610_slist_element
372 enum lfds610_data_structure_validity
373 dvs = LFDS610_VALIDITY_VALID;
375 /* TRD : this test creates a list of 100,000 elements
376 then simply calls delete_all_elements()
377 we then count the number of elements remaining
381 internal_display_test_name( "Delete all elements" );
383 lfds610_slist_new( &ss, NULL, NULL );
385 for( loop = 0 ; loop < 1000000 ; loop++ )
386 lfds610_slist_new_head( ss, NULL );
388 lfds610_slist_single_threaded_physically_delete_all_elements( ss );
390 while( NULL != lfds610_slist_get_head_and_then_next(ss, &se) )
393 if( element_count != 0 )
394 dvs = LFDS610_VALIDITY_INVALID_TEST_DATA;
396 lfds610_slist_delete( ss );
398 internal_display_test_result( 1, "slist", dvs );