7 struct lfds700_list_asu_element
20 struct lfds700_list_asu_state
26 struct lfds700_list_asu_element
30 /***** private prototypes *****/
31 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_after_thread( void *util_thread_starter_thread_state );
37 /****************************************************************************/
38 void test_lfds700_list_asu_new_after( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
40 enum lfds700_misc_validity
41 dvs = LFDS700_MISC_VALIDITY_VALID;
46 number_logical_processors,
50 struct lfds700_list_asu_element
54 struct lfds700_list_asu_state
57 struct lfds700_misc_prng_state
60 struct lfds700_misc_validation_info
63 struct test_pal_logical_processor
66 struct util_thread_starter_state
76 test_pal_thread_state_t
79 assert( list_of_logical_processors != NULL );
80 // TRD : memory_in_megabytes can be any value in its range
82 /* TRD : run one thread per logical processor
84 we put a single first element into the list and
85 each thread loops, calling lfds700_list_asu_new_element_by_position( LFDS700_LIST_ASU_POSITION_AFTER ),
86 inserting after the single first element
87 data element contain s thread_number and element_number
88 verification should show element_number decreasing on a per thread basis
91 internal_display_test_name( "New after" );
93 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
95 lfds700_misc_prng_init( &ps );
97 lfds700_list_asu_init_valid_on_current_logical_core( &lasus, NULL, NULL );
99 LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( first_element, NULL );
100 LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( first_element, NULL );
101 lfds700_list_asu_insert_at_position( &lasus, &first_element, NULL, LFDS700_LIST_ASU_POSITION_START, &ps );
103 number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
105 element_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
107 for( loop = 0 ; loop < number_logical_processors ; loop++ )
108 for( subloop = 0 ; subloop < number_elements ; subloop++ )
110 (element_array+(loop*number_elements)+subloop)->thread_number = loop;
111 (element_array+(loop*number_elements)+subloop)->element_number = subloop;
114 ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
116 for( loop = 0 ; loop < number_logical_processors ; loop++ )
118 (ts+loop)->lasus = &lasus;
119 (ts+loop)->element_array = element_array + (loop*number_elements);
120 (ts+loop)->first_element = &first_element;
121 (ts+loop)->number_elements = number_elements;
124 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
126 util_thread_starter_new( &tts, number_logical_processors );
128 LFDS700_MISC_BARRIER_STORE;
130 lfds700_misc_force_store();
135 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
137 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
138 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, new_after_thread, ts+loop );
142 util_thread_starter_run( tts );
144 for( loop = 0 ; loop < number_logical_processors ; loop++ )
145 test_pal_thread_wait( thread_handles[loop] );
147 util_thread_starter_delete( tts );
149 free( thread_handles );
153 /* TRD : validate the resultant list
154 iterate over each element
155 we expect to find element numbers increment on a per thread basis
158 LFDS700_MISC_BARRIER_LOAD;
160 vi.min_elements = vi.max_elements = number_elements * number_logical_processors + 1;
162 lfds700_list_asu_query( &lasus, LFDS700_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
164 per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
166 for( loop = 0 ; loop < number_logical_processors ; loop++ )
167 *(per_thread_counters+loop) = number_elements - 1;
169 /* TRD : we have a leading element, after which all inserts occurred
170 we need to get past that element for validation
171 this is why we're not using lfds700_list_asu_get_start_and_then_next()
174 lasue = LFDS700_LIST_ASU_GET_START( lasus );
176 lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
178 while( dvs == LFDS700_MISC_VALIDITY_VALID and lasue != NULL )
180 element = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
182 if( element->thread_number >= number_logical_processors )
184 dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
188 if( element->element_number < per_thread_counters[element->thread_number] )
189 dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
191 if( element->element_number > per_thread_counters[element->thread_number] )
192 dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
194 if( element->element_number == per_thread_counters[element->thread_number] )
195 per_thread_counters[element->thread_number]--;
197 lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
200 free( per_thread_counters );
202 lfds700_list_asu_cleanup( &lasus, NULL );
204 util_aligned_free( element_array );
206 internal_display_test_result( 1, "list_asu", dvs );
215 /****************************************************************************/
216 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_after_thread( void *util_thread_starter_thread_state )
221 struct lfds700_misc_prng_state
227 struct util_thread_starter_thread_state
230 LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
232 assert( util_thread_starter_thread_state != NULL );
234 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
235 ts = (struct test_state *) tsts->thread_user_state;
237 lfds700_misc_prng_init( &ps );
239 util_thread_starter_ready_and_wait( tsts );
241 for( loop = 0 ; loop < ts->number_elements ; loop++ )
243 LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
244 LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
245 lfds700_list_asu_insert_at_position( ts->lasus, &(ts->element_array+loop)->lasue, ts->first_element, LFDS700_LIST_ASU_POSITION_AFTER, &ps );
248 LFDS700_MISC_BARRIER_STORE;
250 lfds700_misc_force_store();
252 return( (test_pal_thread_return_t) EXIT_SUCCESS );