2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
7 struct lfds710_stack_state
13 struct lfds710_stack_element
20 /***** private prototypes *****/
21 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_popping( void *libtest_threadset_per_thread_state );
27 /****************************************************************************/
28 void libtest_tests_stack_popping( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
33 number_logical_processors;
35 struct lfds710_stack_state
38 struct lfds710_list_asu_element
41 struct lfds710_misc_validation_info
44 struct libtest_logical_processor
47 struct libtest_threadset_per_thread_state
50 struct libtest_threadset_state
56 struct test_per_thread_state
59 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
60 LFDS710_PAL_ASSERT( ms != NULL );
61 LFDS710_PAL_ASSERT( dvs != NULL );
63 /* TRD : we create a stack with as many elements as possible elements
65 the creation function runs in a single thread and creates
66 and pushes those elements onto the stack
68 each element contains a void pointer to the container test element
70 we then run one thread per CPU
71 where each thread loops, popping as quickly as possible
72 each test element has a flag which indicates it has been popped
74 the threads run till the source stack is empty
76 we then check the test elements
77 every element should have been popped
82 *dvs = LFDS710_MISC_VALIDITY_VALID;
85 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
86 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
87 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
88 te_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct test_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
90 lfds710_stack_init_valid_on_current_logical_core( &ss, NULL );
92 for( loop = 0 ; loop < number_elements ; loop++ )
94 (te_array+loop)->popped_flag = LOWERED;
95 LFDS710_STACK_SET_VALUE_IN_ELEMENT( (te_array+loop)->se, te_array+loop );
96 lfds710_stack_push( &ss, &(te_array+loop)->se );
99 libtest_threadset_init( &ts, NULL );
103 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
105 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
108 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_popping, &tpts[loop] );
113 LFDS710_MISC_BARRIER_STORE;
115 lfds710_misc_force_store();
117 // TRD : run the test
118 libtest_threadset_run( &ts );
120 libtest_threadset_cleanup( &ts );
123 LFDS710_MISC_BARRIER_LOAD;
125 lfds710_stack_query( &ss, LFDS710_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
127 // TRD : now we check each element has popped_flag set to RAISED
128 for( loop = 0 ; loop < number_elements ; loop++ )
129 if( (te_array+loop)->popped_flag == LOWERED )
130 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
133 lfds710_stack_cleanup( &ss, NULL );
142 /****************************************************************************/
143 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_popping( void *libtest_threadset_per_thread_state )
145 struct lfds710_stack_element
148 struct test_per_thread_state
151 struct libtest_threadset_per_thread_state
157 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
159 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
161 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
163 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
165 libtest_threadset_thread_ready_and_wait( pts );
167 while( lfds710_stack_pop(tpts->ss, &se) )
169 te = LFDS710_STACK_GET_VALUE_FROM_ELEMENT( *se );
170 te->popped_flag = RAISED;
173 LFDS710_MISC_BARRIER_STORE;
175 lfds710_misc_force_store();
177 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);