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