2 #include "libtest_tests_internal.h"
7 struct lfds710_list_asu_element
15 struct test_per_thread_state
18 number_elements_per_thread;
20 struct lfds710_list_asu_state
26 struct lfds710_list_asu_element
30 /***** private prototypes *****/
31 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION new_after_thread( void *libtest_threadset_per_thread_state );
37 /****************************************************************************/
38 void libtest_tests_list_asu_new_after( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
43 number_elements_per_thread,
44 number_logical_processors,
48 struct lfds710_list_asu_element
52 struct lfds710_list_asu_state
55 struct lfds710_misc_validation_info
58 struct libtest_logical_processor
61 struct libtest_threadset_per_thread_state
64 struct libtest_threadset_state
71 struct test_per_thread_state
74 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
75 LFDS710_PAL_ASSERT( ms != NULL );
76 LFDS710_PAL_ASSERT( dvs != NULL );
78 /* TRD : run one thread per logical processor
80 we put a single first element into the list and
81 each thread loops, calling lfds710_list_asu_new_element_by_position( LFDS710_LIST_ASU_POSITION_AFTER ),
82 inserting after the single first element
83 data element contain s thread_number and element_number
84 verification should show element_number decreasing on a per thread basis
87 *dvs = LFDS710_MISC_VALIDITY_VALID;
90 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
91 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
92 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
93 per_thread_counters = libshared_memory_alloc_from_unknown_node( ms, sizeof(lfds710_pal_uint_t) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
94 element_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct test_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
96 number_elements_per_thread = number_elements / number_logical_processors;
98 lfds710_list_asu_init_valid_on_current_logical_core( &lasus, NULL );
100 LFDS710_LIST_ASU_SET_KEY_IN_ELEMENT( first_element, NULL );
101 LFDS710_LIST_ASU_SET_VALUE_IN_ELEMENT( first_element, NULL );
102 lfds710_list_asu_insert_at_position( &lasus, &first_element, NULL, LFDS710_LIST_ASU_POSITION_START );
104 for( loop = 0 ; loop < number_logical_processors ; loop++ )
105 for( subloop = 0 ; subloop < number_elements_per_thread ; subloop++ )
107 (element_array+(loop*number_elements_per_thread)+subloop)->thread_number = loop;
108 (element_array+(loop*number_elements_per_thread)+subloop)->element_number = subloop;
111 libtest_threadset_init( &ts, NULL );
115 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
117 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
119 (tpts+loop)->lasus = &lasus;
120 (tpts+loop)->element_array = element_array + (loop*number_elements_per_thread);
121 (tpts+loop)->first_element = &first_element;
122 (tpts+loop)->number_elements_per_thread = number_elements_per_thread;
124 libtest_threadset_add_thread( &ts, &pts[loop], lp, new_after_thread, &tpts[loop] );
129 LFDS710_MISC_BARRIER_STORE;
131 lfds710_misc_force_store();
133 // TRD : run the test
134 libtest_threadset_run( &ts );
136 libtest_threadset_cleanup( &ts );
138 /* TRD : validate the resultant list
139 iterate over each element
140 we expect to find element numbers increment on a per thread basis
143 LFDS710_MISC_BARRIER_LOAD;
145 vi.min_elements = vi.max_elements = (number_elements_per_thread * number_logical_processors) + 1;
147 lfds710_list_asu_query( &lasus, LFDS710_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
149 for( loop = 0 ; loop < number_logical_processors ; loop++ )
150 *(per_thread_counters+loop) = number_elements_per_thread - 1;
152 /* TRD : we have a leading element, after which all inserts occurred
153 we need to get past that element for validation
154 this is why we're not using lfds710_list_asu_get_start_and_then_next()
157 lasue = LFDS710_LIST_ASU_GET_START( lasus );
159 lasue = LFDS710_LIST_ASU_GET_NEXT( *lasue );
161 while( *dvs == LFDS710_MISC_VALIDITY_VALID and lasue != NULL )
163 element = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
165 if( element->thread_number >= number_logical_processors )
167 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
171 if( element->element_number < per_thread_counters[element->thread_number] )
172 *dvs = LFDS710_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
174 if( element->element_number > per_thread_counters[element->thread_number] )
175 *dvs = LFDS710_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
177 if( element->element_number == per_thread_counters[element->thread_number] )
178 per_thread_counters[element->thread_number]--;
180 lasue = LFDS710_LIST_ASU_GET_NEXT( *lasue );
183 lfds710_list_asu_cleanup( &lasus, NULL );
192 /****************************************************************************/
193 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION new_after_thread( void *libtest_threadset_per_thread_state )
198 struct libtest_threadset_per_thread_state
201 struct test_per_thread_state
204 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
206 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
208 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
209 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
211 libtest_threadset_thread_ready_and_wait( pts );
213 for( loop = 0 ; loop < tpts->number_elements_per_thread ; loop++ )
215 LFDS710_LIST_ASU_SET_KEY_IN_ELEMENT( (tpts->element_array+loop)->lasue, tpts->element_array+loop );
216 LFDS710_LIST_ASU_SET_VALUE_IN_ELEMENT( (tpts->element_array+loop)->lasue, tpts->element_array+loop );
217 lfds710_list_asu_insert_at_position( tpts->lasus, &(tpts->element_array+loop)->lasue, tpts->first_element, LFDS710_LIST_ASU_POSITION_AFTER );
220 LFDS710_MISC_BARRIER_STORE;
222 lfds710_misc_force_store();
224 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);