2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
7 struct lfds710_freelist_state
13 struct lfds710_freelist_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_freelist_without_ea_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_freelist_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 freelist with as many elements as possible elements
65 the creation function runs in a single thread and creates
66 and pushes thofe elements onto the freelist
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 freelist is empty
76 we then check the test elements
77 every element should have been popped
82 *dvs = LFDS710_MISC_VALIDITY_VALID;
84 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
87 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
88 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
89 te_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct test_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
91 lfds710_freelist_init_valid_on_current_logical_core( &fs, NULL, 0, NULL );
93 for( loop = 0 ; loop < number_elements ; loop++ )
95 (te_array+loop)->popped_flag = LOWERED;
96 LFDS710_FREELIST_SET_VALUE_IN_ELEMENT( (te_array+loop)->fe, te_array+loop );
97 lfds710_freelist_push( &fs, &(te_array+loop)->fe, NULL );
100 libtest_threadset_init( &ts, NULL );
104 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
106 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
109 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_popping, &tpts[loop] );
114 LFDS710_MISC_BARRIER_STORE;
116 lfds710_misc_force_store();
118 // TRD : run the test
119 libtest_threadset_run( &ts );
121 libtest_threadset_cleanup( &ts );
124 LFDS710_MISC_BARRIER_LOAD;
126 lfds710_freelist_query( &fs, LFDS710_FREELIST_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
128 // TRD : now we check each element has popped_flag fet to RAISED
129 for( loop = 0 ; loop < number_elements ; loop++ )
130 if( (te_array+loop)->popped_flag == LOWERED )
131 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
134 lfds710_freelist_cleanup( &fs, NULL );
143 /****************************************************************************/
144 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_popping( void *libtest_threadset_per_thread_state )
146 struct lfds710_freelist_element
149 struct test_per_thread_state
152 struct libtest_threadset_per_thread_state
158 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
160 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
162 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
164 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
166 libtest_threadset_thread_ready_and_wait( pts );
168 while( lfds710_freelist_pop(tpts->fs, &fe, NULL) )
170 te = LFDS710_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
171 te->popped_flag = RAISED;
174 LFDS710_MISC_BARRIER_STORE;
176 lfds710_misc_force_store();
178 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);