2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
8 number_elements_per_thread,
11 struct lfds710_stack_state
20 struct lfds710_stack_element
28 /***** private prototypes *****/
29 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_pushing( void *libtest_threadset_per_thread_state );
35 /****************************************************************************/
36 void libtest_tests_stack_pushing( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
41 number_elements_per_thread,
42 number_logical_processors,
45 struct lfds710_list_asu_element
48 struct lfds710_stack_element
51 struct lfds710_stack_state
54 struct lfds710_misc_validation_info
57 struct libtest_logical_processor
60 struct libtest_threadset_per_thread_state
63 struct libtest_threadset_state
70 struct test_per_thread_state
73 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
74 LFDS710_PAL_ASSERT( ms != NULL );
75 LFDS710_PAL_ASSERT( dvs != NULL );
77 /* TRD : we create an empty stack
79 we then create one thread per CPU, where each thread
80 pushes 100,000 elements each as quickly as possible to the stack
82 the data pushed is a counter and a thread ID
84 the threads exit when the stack is full
86 we then validate the stack;
88 checking that the counts increment on a per unique ID basis
89 and that the number of elements we pop equals 100,000 per thread
90 (since each element has an incrementing counter which is
91 unique on a per unique ID basis, we can know we didn't lose
95 *dvs = LFDS710_MISC_VALIDITY_VALID;
98 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
99 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
100 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
101 per_thread_counters = libshared_memory_alloc_from_unknown_node( ms, sizeof(lfds710_pal_uint_t) * number_logical_processors, sizeof(lfds710_pal_uint_t) );
102 te_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct test_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
104 number_elements_per_thread = number_elements / number_logical_processors;
106 // TRD : the main stack
107 lfds710_stack_init_valid_on_current_logical_core( &ss, NULL );
109 libtest_threadset_init( &ts, NULL );
111 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
113 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
115 (tpts+loop)->ss = &ss;
116 (tpts+loop)->thread_number = loop;
117 (tpts+loop)->number_elements_per_thread = number_elements_per_thread;
118 (tpts+loop)->te_array = te_array + loop * number_elements_per_thread;
120 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_pushing, &tpts[loop] );
125 LFDS710_MISC_BARRIER_STORE;
127 lfds710_misc_force_store();
129 // TRD : run the test
130 libtest_threadset_run( &ts );
132 libtest_threadset_cleanup( &ts );
135 LFDS710_MISC_BARRIER_LOAD;
137 for( loop = 0 ; loop < number_logical_processors ; loop++ )
138 *(per_thread_counters+loop) = number_elements_per_thread - 1;
140 vi.min_elements = vi.max_elements = number_elements_per_thread * number_logical_processors;
142 lfds710_stack_query( &ss, LFDS710_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
144 while( *dvs == LFDS710_MISC_VALIDITY_VALID and lfds710_stack_pop(&ss, &se) )
146 te = LFDS710_STACK_GET_VALUE_FROM_ELEMENT( *se );
148 if( te->thread_number >= number_logical_processors )
150 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
154 if( te->datum > per_thread_counters[te->thread_number] )
155 *dvs = LFDS710_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
157 if( te->datum < per_thread_counters[te->thread_number] )
158 *dvs = LFDS710_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
160 if( te->datum == per_thread_counters[te->thread_number] )
161 per_thread_counters[te->thread_number]--;
164 lfds710_stack_cleanup( &ss, NULL );
173 /****************************************************************************/
174 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_pushing( void *libtest_threadset_per_thread_state )
179 struct test_per_thread_state
182 struct libtest_threadset_per_thread_state
185 LFDS710_MISC_BARRIER_LOAD;
187 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
189 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
191 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
193 for( loop = 0 ; loop < tpts->number_elements_per_thread ; loop++ )
195 (tpts->te_array+loop)->thread_number = tpts->thread_number;
196 (tpts->te_array+loop)->datum = loop;
199 libtest_threadset_thread_ready_and_wait( pts );
201 for( loop = 0 ; loop < tpts->number_elements_per_thread ; loop++ )
203 LFDS710_STACK_SET_VALUE_IN_ELEMENT( (tpts->te_array+loop)->se, tpts->te_array+loop );
204 lfds710_stack_push( tpts->ss, &(tpts->te_array+loop)->se );
207 LFDS710_MISC_BARRIER_STORE;
209 lfds710_misc_force_store();
211 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);