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_popping( void *util_thread_starter_thread_state );
27 /****************************************************************************/
28 void test_lfds700_stack_popping( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
30 enum lfds700_misc_validity
31 dvs = LFDS700_MISC_VALIDITY_VALID;
36 number_logical_processors;
38 struct lfds700_misc_prng_state
41 struct lfds700_list_asu_element
44 struct lfds700_stack_state
47 struct lfds700_misc_validation_info
50 struct test_pal_logical_processor
53 struct util_thread_starter_state
62 test_pal_thread_state_t
65 assert( list_of_logical_processors != NULL );
66 // TRD : memory_in_megabytes can be any value in its range
68 /* TRD : we create a stack
70 we then populate the stack with 1,000,000 elements
71 each void pointer of data points to the containing test element
73 we then run one thread per CPU
74 where each thread loops, popping as quickly as possible
75 upon popping, a flag is set in the containing test element
77 the threads run till the source stack is empty
79 we then check the poppged flag, all should be raised
83 no CAS+GC code, as we only pop
86 internal_display_test_name( "Popping" );
88 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
90 lfds700_misc_prng_init( &ps );
92 lfds700_stack_init_valid_on_current_logical_core( &ss, NULL );
94 number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct test_element) ;
96 te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
98 for( loop = 0 ; loop < number_elements ; loop++ )
100 (te_array+loop)->popped_flag = LOWERED;
101 LFDS700_STACK_SET_VALUE_IN_ELEMENT( (te_array+loop)->se, te_array+loop );
102 lfds700_stack_push( &ss, &(te_array+loop)->se, &ps );
105 ts = util_aligned_malloc( sizeof(struct test_state) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
107 for( loop = 0 ; loop < number_logical_processors ; loop++ )
110 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
112 util_thread_starter_new( &tts, number_logical_processors );
114 LFDS700_MISC_BARRIER_STORE;
116 lfds700_misc_force_store();
121 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
123 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
124 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_popping, ts+loop );
128 util_thread_starter_run( tts );
130 for( loop = 0 ; loop < number_logical_processors ; loop++ )
131 test_pal_thread_wait( thread_handles[loop] );
133 util_thread_starter_delete( tts );
135 free( thread_handles );
137 LFDS700_MISC_BARRIER_LOAD;
139 lfds700_stack_query( &ss, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, (void *) &dvs );
141 // TRD : now we check each element has popped_flag set to RAISED
142 for( loop = 0 ; loop < number_elements ; loop++ )
143 if( (te_array+loop)->popped_flag == LOWERED )
144 dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
147 lfds700_stack_cleanup( &ss, NULL );
148 util_aligned_free( te_array );
149 util_aligned_free( ts );
151 // TRD : print the test result
152 internal_display_test_result( 1, "stack", dvs );
161 /****************************************************************************/
162 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state )
164 struct lfds700_misc_prng_state
167 struct lfds700_stack_element
176 struct util_thread_starter_thread_state
179 LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
181 assert( util_thread_starter_thread_state != NULL );
183 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
184 ts = (struct test_state *) tsts->thread_user_state;
186 lfds700_misc_prng_init( &ps );
188 util_thread_starter_ready_and_wait( tsts );
190 while( lfds700_stack_pop(ts->ss, &se, &ps) )
192 te = LFDS700_STACK_GET_VALUE_FROM_ELEMENT( *se );
193 te->popped_flag = RAISED;
196 LFDS700_MISC_BARRIER_STORE;
198 lfds700_misc_force_store();
200 return( (test_pal_thread_return_t) EXIT_SUCCESS );