2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
10 struct lfds710_queue_bmm_state
14 /***** private prototypes *****/
15 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_simple_dequeuer( void *libtest_threadset_per_thread_state );
21 /****************************************************************************/
22 void libtest_tests_queue_bmm_dequeuing( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
27 power_of_two_number_elements = 1,
29 number_logical_processors;
31 struct lfds710_list_asu_element
34 struct lfds710_queue_bmm_element
37 struct lfds710_queue_bmm_state
40 struct lfds710_misc_validation_info
43 struct libtest_logical_processor
46 struct libtest_threadset_per_thread_state
49 struct libtest_threadset_state
52 struct test_per_thread_state
55 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
56 LFDS710_PAL_ASSERT( ms != NULL );
57 LFDS710_PAL_ASSERT( dvs != NULL );
59 /* TRD : create an empty queue, with the largest possible number of elements
60 do a single-threaded (in the prep function) full enqueue
61 with the value being an incrementing counter
62 then run one thread per CPU
63 where each thread busy-works, dequeuing, and checks the dequeued value is greater than the previously dequeued value
64 run until the queue is empty
67 *dvs = LFDS710_MISC_VALIDITY_VALID;
69 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
72 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
73 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
74 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
75 qbmme_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct lfds710_queue_bmm_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
77 // TRD : need to only use a power of 2 number of elements
78 number_elements >>= 1;
80 while( number_elements != 0 )
82 number_elements >>= 1;
83 power_of_two_number_elements <<= 1;
86 lfds710_queue_bmm_init_valid_on_current_logical_core( &qbmms, qbmme_array, power_of_two_number_elements, NULL );
88 // TRD : fill the queue
89 while( lfds710_queue_bmm_enqueue(&qbmms, NULL, (void *) (counter++)) );
91 libtest_threadset_init( &ts, NULL );
93 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
95 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
96 (tpts+loop)->qbmms = &qbmms;
97 (tpts+loop)->error_flag = LOWERED;
98 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_simple_dequeuer, &tpts[loop] );
102 LFDS710_MISC_BARRIER_STORE;
104 lfds710_misc_force_store();
106 // TRD : run the test
107 libtest_threadset_run( &ts );
109 libtest_threadset_cleanup( &ts );
112 LFDS710_MISC_BARRIER_LOAD;
114 /* TRD : we just check the per-thread error flags and validate the queue
115 most of the checking happened in the threads
118 for( loop = 0 ; loop < number_logical_processors ; loop++ )
119 if( (tpts+loop)->error_flag == RAISED )
120 *dvs = LFDS710_MISC_VALIDITY_INVALID_ORDER;
122 if( *dvs == LFDS710_MISC_VALIDITY_VALID )
124 vi.min_elements = vi.max_elements = 0;
125 lfds710_queue_bmm_query( &qbmms, LFDS710_QUEUE_BMM_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
128 lfds710_queue_bmm_cleanup( &qbmms, NULL );
137 /****************************************************************************/
138 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_simple_dequeuer( void *libtest_threadset_per_thread_state )
145 struct test_per_thread_state
148 struct libtest_threadset_per_thread_state
151 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
153 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
155 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
156 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
158 libtest_threadset_thread_ready_and_wait( pts );
160 while( lfds710_queue_bmm_dequeue(tpts->qbmms, (void *) &key, (void *) &value) )
162 if( value < counter )
163 tpts->error_flag = RAISED;
165 if( value > counter )
169 LFDS710_MISC_BARRIER_STORE;
171 lfds710_misc_force_store();
173 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);