7 struct lfds700_freelist_state
13 struct lfds700_freelist_element
20 /***** private prototypes *****/
21 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *util_thread_starter_thread_state );
27 /****************************************************************************/
28 void test_lfds700_freelist_rapid_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors )
30 enum lfds700_misc_validity
31 dvs = LFDS700_MISC_VALIDITY_VALID;
35 number_logical_processors;
37 struct lfds700_list_asu_element
40 struct lfds700_freelist_state
43 struct lfds700_misc_prng_state
46 struct lfds700_misc_validation_info
49 struct test_pal_logical_processor
52 struct util_thread_starter_state
61 test_pal_thread_state_t
64 assert( list_of_logical_processors != NULL );
66 /* TRD : in these tests there is a fundamental antagonism between
67 how much checking/memory clean up that we do and the
68 likelyhood of collisions between threads in their lock-free
71 the lock-free operations are very quick; if we do anything
72 much at all between operations, we greatly reduce the chance
75 so we have some tests which do enough checking/clean up that
76 they can tell the freelist is valid and don't leak memory
77 and here, this test now is one of those which does minimal
78 checking - in fact, the nature of the test is that you can't
79 do any real checking - but goes very quickly
81 what we do is create a small freelist and then run one thread
82 per CPU, where each thread simply pushes and then immediately
85 the test runs for ten seconds
87 after the test is done, the only check we do is to traverse
88 the freelist, checking for loops and ensuring the number of
92 internal_display_test_name( "Rapid popping and pushing (10 seconds)" );
94 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
96 lfds700_misc_prng_init( &ps );
98 lfds700_freelist_init_valid_on_current_logical_core( &fs, NULL );
100 ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
102 for( loop = 0 ; loop < number_logical_processors ; loop++ )
105 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
107 // TRD : we need one element per thread
108 te_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
110 for( loop = 0 ; loop < number_logical_processors ; loop++ )
112 LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( (te_array+loop)->fe, te_array+loop );
113 lfds700_freelist_push( &fs, &(te_array+loop)->fe, &ps );
116 util_thread_starter_new( &tts, number_logical_processors );
118 LFDS700_MISC_BARRIER_STORE;
120 lfds700_misc_force_store();
125 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
127 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
128 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_rapid_popping_and_pushing, ts+loop );
132 util_thread_starter_run( tts );
134 for( loop = 0 ; loop < number_logical_processors ; loop++ )
135 test_pal_thread_wait( thread_handles[loop] );
137 util_thread_starter_delete( tts );
139 free( thread_handles );
141 LFDS700_MISC_BARRIER_LOAD;
143 vi.min_elements = vi.max_elements = number_logical_processors;
145 lfds700_freelist_query( &fs, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
147 lfds700_freelist_cleanup( &fs, NULL );
149 util_aligned_free( te_array );
153 // TRD : print the test result
154 internal_display_test_result( 1, "freelist", dvs );
163 /****************************************************************************/
164 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *util_thread_starter_thread_state )
169 struct lfds700_freelist_element
172 struct lfds700_misc_prng_state
178 struct util_thread_starter_thread_state
185 LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
187 assert( util_thread_starter_thread_state != NULL );
189 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
190 ts = (struct test_state *) tsts->thread_user_state;
192 lfds700_misc_prng_init( &ps );
194 util_thread_starter_ready_and_wait( tsts );
196 current_time = start_time = time( NULL );
198 while( current_time < start_time + TEST_DURATION_IN_SECONDS )
200 lfds700_freelist_pop( ts->fs, &fe, &ps );
201 lfds700_freelist_push( ts->fs, fe, &ps );
203 if( time_loop++ == TIME_LOOP_COUNT )
206 time( ¤t_time );
210 LFDS700_MISC_BARRIER_STORE;
212 lfds700_misc_force_store();
214 return( (test_pal_thread_return_t) EXIT_SUCCESS );