2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
10 struct lfds710_queue_umm_state
16 struct lfds710_queue_umm_element
20 /***** private prototypes *****/
21 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_simple_dequeuer( void *libtest_threadset_per_thread_state );
27 /****************************************************************************/
28 void libtest_tests_queue_umm_dequeuing( 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_list_asu_element
38 struct lfds710_queue_umm_element LFDS710_PAL_ALIGN(LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES)
41 struct lfds710_queue_umm_state
44 struct lfds710_misc_validation_info
47 struct libtest_logical_processor
50 struct libtest_threadset_per_thread_state
53 struct libtest_threadset_state
59 struct test_per_thread_state
62 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
63 LFDS710_PAL_ASSERT( ms != NULL );
64 LFDS710_PAL_ASSERT( dvs != NULL );
66 /* TRD : create a queue, add 1,000,000 elements
68 use a single thread to enqueue every element
69 each elements user data is an incrementing counter
71 then run one thread per CPU
72 where each busy-works dequeuing
74 when an element is dequeued, we check (on a per-thread basis) the
75 value dequeued is greater than the element previously dequeued
78 *dvs = LFDS710_MISC_VALIDITY_VALID;
81 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
82 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
83 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
84 te_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct test_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
86 lfds710_queue_umm_init_valid_on_current_logical_core( &qs, &qe_dummy, NULL );
88 for( loop = 0 ; loop < number_elements ; loop++ )
90 LFDS710_QUEUE_UMM_SET_VALUE_IN_ELEMENT( (te_array+loop)->qe, loop );
91 lfds710_queue_umm_enqueue( &qs, &(te_array+loop)->qe );
94 libtest_threadset_init( &ts, NULL );
98 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
100 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
101 (tpts+loop)->qs = &qs;
102 (tpts+loop)->error_flag = LOWERED;
103 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_simple_dequeuer, &tpts[loop] );
107 LFDS710_MISC_BARRIER_STORE;
109 lfds710_misc_force_store();
111 // TRD : run the test
112 libtest_threadset_run( &ts );
114 libtest_threadset_cleanup( &ts );
117 LFDS710_MISC_BARRIER_LOAD;
119 // TRD : check queue is empty
120 lfds710_queue_umm_query( &qs, LFDS710_QUEUE_UMM_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
122 // TRD : check for raised error flags
123 for( loop = 0 ; loop < number_logical_processors ; loop++ )
124 if( (tpts+loop)->error_flag == RAISED )
125 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
127 lfds710_queue_umm_cleanup( &qs, NULL );
136 /****************************************************************************/
137 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_simple_dequeuer( void *libtest_threadset_per_thread_state )
143 struct lfds710_queue_umm_element
146 struct test_per_thread_state
149 struct libtest_threadset_per_thread_state
152 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
154 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
156 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
157 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
159 lfds710_queue_umm_dequeue( tpts->qs, &qe );
160 prev_value = LFDS710_QUEUE_UMM_GET_VALUE_FROM_ELEMENT( *qe );
162 libtest_threadset_thread_ready_and_wait( pts );
164 while( lfds710_queue_umm_dequeue(tpts->qs, &qe) )
166 value = LFDS710_QUEUE_UMM_GET_VALUE_FROM_ELEMENT( *qe );
168 if( value <= prev_value )
169 tpts->error_flag = RAISED;
174 LFDS710_MISC_BARRIER_STORE;
176 lfds710_misc_force_store();
178 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);