7 struct lfds700_stack_state
13 struct lfds700_stack_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_stack_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_misc_prng_state
40 struct lfds700_list_asu_element
43 struct lfds700_stack_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 );
65 // TRD : st can be any value in its range
67 /* TRD : in these tests there is a fundamental antagonism between
68 how much checking/memory clean up that we do and the
69 likelyhood of collisions between threads in their lock-free
72 the lock-free operations are very quick; if we do anything
73 much at all between operations, we greatly reduce the chance
76 so we have some tests which do enough checking/clean up that
77 they can tell the stack is valid and don't leak memory
78 and here, this test now is one of those which does minimal
79 checking - in fact, the nature of the test is that you can't
80 do any real checking - but goes very quickly
82 what we do is create a small stack and then run one thread
83 per CPU, where each thread simply pushes and then immediately
86 the test runs for ten seconds
88 after the test is done, the only check we do is to traverse
89 the stack, checking for loops and ensuring the number of
93 internal_display_test_name( "Rapid popping and pushing (%d seconds)", TEST_DURATION_IN_SECONDS );
95 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
97 lfds700_misc_prng_init( &ps );
99 ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
101 lfds700_stack_init_valid_on_current_logical_core( &ss, NULL );
103 for( loop = 0 ; loop < number_logical_processors ; loop++ )
106 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
108 // TRD : we need one element per thread
109 te_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
111 for( loop = 0 ; loop < number_logical_processors ; loop++ )
113 LFDS700_STACK_SET_VALUE_IN_ELEMENT( (te_array+loop)->se, te_array+loop );
114 lfds700_stack_push( &ss, &(te_array+loop)->se, &ps );
117 util_thread_starter_new( &tts, number_logical_processors );
119 LFDS700_MISC_BARRIER_STORE;
121 lfds700_misc_force_store();
126 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
128 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
129 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_rapid_popping_and_pushing, ts+loop );
133 util_thread_starter_run( tts );
135 for( loop = 0 ; loop < number_logical_processors ; loop++ )
136 test_pal_thread_wait( thread_handles[loop] );
138 util_thread_starter_delete( tts );
140 free( thread_handles );
142 LFDS700_MISC_BARRIER_LOAD;
144 vi.min_elements = vi.max_elements = number_logical_processors;
146 lfds700_stack_query( &ss, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
148 lfds700_stack_cleanup( &ss, NULL );
150 util_aligned_free( te_array );
154 // TRD : print the test result
155 internal_display_test_result( 1, "stack", dvs );
164 /****************************************************************************/
165 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *util_thread_starter_thread_state )
170 struct lfds700_misc_prng_state
173 struct lfds700_stack_element
179 struct util_thread_starter_thread_state
186 LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
188 assert( util_thread_starter_thread_state != NULL );
190 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
191 ts = (struct test_state *) tsts->thread_user_state;
193 lfds700_misc_prng_init( &ps );
195 util_thread_starter_ready_and_wait( tsts );
197 current_time = start_time = time( NULL );
199 while( current_time < start_time + TEST_DURATION_IN_SECONDS )
201 lfds700_stack_pop( ts->ss, &se, &ps );
202 lfds700_stack_push( ts->ss, se, &ps );
204 if( time_loop++ == TIME_LOOP_COUNT )
207 time( ¤t_time );
211 LFDS700_MISC_BARRIER_STORE;
213 lfds700_misc_force_store();
215 return( (test_pal_thread_return_t) EXIT_SUCCESS );