2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
12 number_logical_processors,
16 struct lfds710_queue_umm_state
22 struct lfds710_queue_umm_element
31 /***** private prototypes *****/
32 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_enqueuer_and_dequeuer( void *libtest_threadset_per_thread_state );
38 /****************************************************************************/
39 void libtest_tests_queue_umm_enqueuing_and_dequeuing( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
44 number_logical_processors,
48 struct lfds710_list_asu_element
51 struct lfds710_queue_umm_state
54 struct lfds710_misc_validation_info
57 struct libtest_logical_processor
60 struct libtest_threadset_per_thread_state
63 struct libtest_threadset_state
69 struct test_per_thread_state
72 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
73 LFDS710_PAL_ASSERT( ms != NULL );
74 LFDS710_PAL_ASSERT( dvs != NULL );
76 /* TRD : create a queue with one element per thread
77 each thread constly dequeues and enqueues from that one queue
78 where when enqueuing sets in the element
79 its thread number and counter
80 and when dequeuing, checks the thread number and counter
81 against previously seen counter for that thread
82 where it should always see a higher number
85 *dvs = LFDS710_MISC_VALIDITY_VALID;
88 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
89 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
90 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
91 per_thread_counters = libshared_memory_alloc_from_unknown_node( ms, sizeof(lfds710_pal_uint_t) * number_logical_processors * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
92 te_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct test_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
94 lfds710_queue_umm_init_valid_on_current_logical_core( &qs, &(te_array+number_logical_processors)->qe, NULL );
96 // TRD : we assume the test will iterate at least once (or we'll have a false negative)
97 for( loop = 0 ; loop < number_logical_processors ; loop++ )
99 (te_array+loop)->thread_number = loop;
100 (te_array+loop)->counter = 0;
101 LFDS710_QUEUE_UMM_SET_VALUE_IN_ELEMENT( (te_array+loop)->qe, te_array+loop );
102 lfds710_queue_umm_enqueue( &qs, &(te_array+loop)->qe );
105 libtest_threadset_init( &ts, NULL );
109 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
111 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
112 (tpts+loop)->qs = &qs;
113 (tpts+loop)->thread_number = loop;
114 (tpts+loop)->counter = 0;
115 (tpts+loop)->error_flag = LOWERED;
116 (tpts+loop)->per_thread_counters = per_thread_counters + loop * number_logical_processors;
117 (tpts+loop)->number_logical_processors = number_logical_processors;
119 for( subloop = 0 ; subloop < number_logical_processors ; subloop++ )
120 *((tpts+loop)->per_thread_counters+subloop) = 0;
122 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_enqueuer_and_dequeuer, &tpts[loop] );
126 LFDS710_MISC_BARRIER_STORE;
128 lfds710_misc_force_store();
130 // TRD : run the test
131 libtest_threadset_run( &ts );
133 libtest_threadset_cleanup( &ts );
136 LFDS710_MISC_BARRIER_LOAD;
138 vi.min_elements = vi.max_elements = number_logical_processors;
140 lfds710_queue_umm_query( &qs, LFDS710_QUEUE_UMM_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
142 for( loop = 0 ; loop < number_logical_processors ; loop++ )
143 if( (tpts+loop)->error_flag == RAISED )
144 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
146 lfds710_queue_umm_cleanup( &qs, NULL );
155 /****************************************************************************/
156 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_enqueuer_and_dequeuer( void *libtest_threadset_per_thread_state )
161 struct lfds710_queue_umm_element
167 struct test_per_thread_state
170 struct libtest_threadset_per_thread_state
177 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
179 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
181 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
182 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
184 libtest_threadset_thread_ready_and_wait( pts );
186 current_time = start_time = time( NULL );
188 while( current_time < start_time + TEST_DURATION_IN_SECONDS )
190 lfds710_queue_umm_dequeue( tpts->qs, &qe );
191 te = LFDS710_QUEUE_UMM_GET_VALUE_FROM_ELEMENT( *qe );
193 if( te->thread_number >= tpts->number_logical_processors )
194 tpts->error_flag = RAISED;
197 if( te->counter < tpts->per_thread_counters[te->thread_number] )
198 tpts->error_flag = RAISED;
200 if( te->counter >= tpts->per_thread_counters[te->thread_number] )
201 tpts->per_thread_counters[te->thread_number] = te->counter+1;
204 te->thread_number = tpts->thread_number;
205 te->counter = ++tpts->counter;
207 LFDS710_QUEUE_UMM_SET_VALUE_IN_ELEMENT( *qe, te );
208 lfds710_queue_umm_enqueue( tpts->qs, qe );
210 if( time_loop++ == TIME_LOOP_COUNT )
213 time( ¤t_time );
217 LFDS710_MISC_BARRIER_STORE;
219 lfds710_misc_force_store();
221 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);