2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
13 struct lfds710_ringbuffer_state
17 /***** private prototypes *****/
18 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_simple_reader( void *libtest_threadset_per_thread_state );
24 /****************************************************************************/
25 void libtest_tests_ringbuffer_reading( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
27 enum lfds710_misc_validity
28 local_dvs[2] = { LFDS710_MISC_VALIDITY_VALID, LFDS710_MISC_VALIDITY_VALID };
33 number_logical_processors,
36 struct lfds710_list_asu_element
39 struct lfds710_ringbuffer_element
42 struct lfds710_ringbuffer_state
45 struct lfds710_misc_validation_info
48 struct libtest_logical_processor
51 struct libtest_threadset_per_thread_state
54 struct libtest_threadset_state
57 struct test_per_thread_state
60 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
61 LFDS710_PAL_ASSERT( ms != NULL );
62 LFDS710_PAL_ASSERT( dvs != NULL );
64 /* TRD : we create a single ringbuffer
65 with 1,000,000 elements
66 we populate the ringbuffer, where the
67 user data is an incrementing counter
69 we create one thread per CPU
70 where each thread busy-works,
71 reading until the ringbuffer is empty
73 each thread keep track of the number of reads it manages
74 and that each user data it reads is greater than the
75 previous user data that was read
78 *dvs = LFDS710_MISC_VALIDITY_VALID;
80 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
83 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
84 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
85 re_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct lfds710_ringbuffer_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
88 vi.max_elements = number_elements - 1;
90 lfds710_ringbuffer_init_valid_on_current_logical_core( &rs, re_array, number_elements, NULL );
92 // TRD : init the ringbuffer contents for the test
93 for( loop = 1 ; loop < number_elements ; loop++ )
94 lfds710_ringbuffer_write( &rs, NULL, (void *) (lfds710_pal_uint_t) loop, NULL, NULL, NULL );
96 libtest_threadset_init( &ts, NULL );
100 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
102 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
103 (tpts+loop)->rs = &rs;
104 (tpts+loop)->read_count = 0;
105 (tpts+loop)->error_flag = LOWERED;
107 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_simple_reader, &tpts[loop] );
112 // TRD : run the test
113 libtest_threadset_run( &ts );
115 libtest_threadset_cleanup( &ts );
118 LFDS710_MISC_BARRIER_LOAD;
120 lfds710_ringbuffer_query( &rs, LFDS710_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) local_dvs );
122 if( local_dvs[0] != LFDS710_MISC_VALIDITY_VALID )
125 if( local_dvs[1] != LFDS710_MISC_VALIDITY_VALID )
128 if( *dvs == LFDS710_MISC_VALIDITY_VALID )
130 // TRD : check for raised error flags
131 for( loop = 0 ; loop < number_logical_processors ; loop++ )
132 if( (tpts+loop)->error_flag == RAISED )
133 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
135 // TRD : check thread reads total to 1,000,000
136 for( loop = 0 ; loop < number_logical_processors ; loop++ )
137 total_read += (tpts+loop)->read_count;
139 if( total_read < number_elements - 1 )
140 *dvs = LFDS710_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
142 if( total_read > number_elements - 1 )
143 *dvs = LFDS710_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
146 lfds710_ringbuffer_cleanup( &rs, NULL );
155 /****************************************************************************/
156 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_simple_reader( void *libtest_threadset_per_thread_state )
162 struct test_per_thread_state
165 struct libtest_threadset_per_thread_state
168 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
170 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
172 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
173 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
175 lfds710_ringbuffer_read( tpts->rs, NULL, (void **) &prev_value );
178 libtest_threadset_thread_ready_and_wait( pts );
180 while( lfds710_ringbuffer_read(tpts->rs, NULL, (void **) &value) )
182 if( value <= prev_value )
183 tpts->error_flag = RAISED;
190 LFDS710_MISC_BARRIER_STORE;
192 lfds710_misc_force_store();
194 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);