11 struct lfds700_freelist_state
20 struct lfds700_freelist_element
28 /***** private prototypes *****/
29 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_pushing( void *util_thread_starter_thread_state );
35 /****************************************************************************/
36 void test_lfds700_freelist_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
38 enum lfds700_misc_validity
39 dvs = LFDS700_MISC_VALIDITY_VALID;
44 number_logical_processors,
47 struct lfds700_list_asu_element
50 struct lfds700_freelist_element
53 struct lfds700_freelist_state
56 struct lfds700_misc_prng_state
59 struct lfds700_misc_validation_info
62 struct test_pal_logical_processor
65 struct util_thread_starter_state
75 test_pal_thread_state_t
78 assert( list_of_logical_processors != NULL );
79 // TRD : memory_in_megabytes can be any value in its range
81 /* TRD : we create an empty freelist
83 we then create one thread per CPU, where each thread
84 pushes 100,000 elements each as quickly as possible to the freelist
86 the data pushed is a counter and a thread ID
88 the threads exit when the freelist is full
90 we then validate the freelist;
92 checking that the counts increment on a per unique ID basis
93 and that the number of elements we pop equals 100,000 per thread
94 (since each element has an incrementing counter which is
95 unique on a per unique ID basis, we can know we didn't lose
99 internal_display_test_name( "Pushing" );
101 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
103 lfds700_misc_prng_init( &ps );
105 number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
107 // TRD : the main freelist
108 lfds700_freelist_init_valid_on_current_logical_core( &fs, NULL );
110 ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
112 for( loop = 0 ; loop < number_logical_processors ; loop++ )
115 (ts+loop)->thread_number = loop;
116 (ts+loop)->number_elements = number_elements;
119 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
121 util_thread_starter_new( &tts, number_logical_processors );
123 LFDS700_MISC_BARRIER_STORE;
125 lfds700_misc_force_store();
130 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
132 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
133 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_pushing, ts+loop );
137 util_thread_starter_run( tts );
139 for( loop = 0 ; loop < number_logical_processors ; loop++ )
140 test_pal_thread_wait( thread_handles[loop] );
142 util_thread_starter_delete( tts );
144 free( thread_handles );
146 LFDS700_MISC_BARRIER_LOAD;
148 per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
150 for( loop = 0 ; loop < number_logical_processors ; loop++ )
151 *(per_thread_counters+loop) = number_elements - 1;
153 vi.min_elements = vi.max_elements = number_elements * number_logical_processors;
155 lfds700_freelist_query( &fs, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
157 while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_freelist_pop(&fs, &fe, &ps) )
159 te = LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
161 if( first_te == NULL )
164 if( te->thread_number >= number_logical_processors )
166 dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
170 if( te->datum > per_thread_counters[te->thread_number] )
171 dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
173 if( te->datum < per_thread_counters[te->thread_number] )
174 dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
176 if( te->datum == per_thread_counters[te->thread_number] )
177 per_thread_counters[te->thread_number]--;
181 for( loop = 0 ; loop < number_logical_processors ; loop++ )
182 util_aligned_free( (ts+loop)->te_array );
184 free( per_thread_counters );
188 lfds700_freelist_cleanup( &fs, NULL );
190 // TRD : print the test result
191 internal_display_test_result( 1, "freelist", dvs );
200 /****************************************************************************/
201 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_pushing( void *util_thread_starter_thread_state )
206 struct lfds700_misc_prng_state
212 struct util_thread_starter_thread_state
215 LFDS700_MISC_BARRIER_LOAD;
217 assert( util_thread_starter_thread_state != NULL );
219 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
220 ts = (struct test_state *) tsts->thread_user_state;
222 lfds700_misc_prng_init( &ps );
224 ts->te_array = util_aligned_malloc( sizeof(struct test_element) * ts->number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
226 for( loop = 0 ; loop < ts->number_elements ; loop++ )
228 (ts->te_array+loop)->thread_number = ts->thread_number;
229 (ts->te_array+loop)->datum = loop;
232 util_thread_starter_ready_and_wait( tsts );
234 for( loop = 0 ; loop < ts->number_elements ; loop++ )
236 LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( (ts->te_array+loop)->fe, ts->te_array+loop );
237 lfds700_freelist_push( ts->fs, &(ts->te_array+loop)->fe, &ps );
240 LFDS700_MISC_BARRIER_STORE;
242 lfds700_misc_force_store();
244 return( (test_pal_thread_return_t) EXIT_SUCCESS );