2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
12 number_logical_processors,
16 struct lfds710_ringbuffer_state
27 /***** private prototypes *****/
28 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_reader_writer( void *libtest_threadset_per_thread_state );
34 /****************************************************************************/
35 void libtest_tests_ringbuffer_reading_and_writing( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
37 enum lfds710_misc_validity
38 local_dvs[2] = { LFDS710_MISC_VALIDITY_VALID, LFDS710_MISC_VALIDITY_VALID };
44 number_logical_processors,
47 struct lfds710_list_asu_element
50 struct lfds710_ringbuffer_element
53 struct lfds710_ringbuffer_state
56 struct lfds710_misc_validation_info
59 struct libtest_logical_processor
62 struct libtest_threadset_per_thread_state
65 struct libtest_threadset_state
71 struct test_per_thread_state
74 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
75 LFDS710_PAL_ASSERT( ms != NULL );
76 LFDS710_PAL_ASSERT( dvs != NULL );
78 /* TRD : we create a single ringbuffer
80 the ringbuffers starts empty
82 we create one thread per CPU
83 where each thread busy-works writing
84 and then immediately reading
87 the user data in each written element is a combination
88 of the thread number and the counter
90 while a thread runs, it keeps track of the
91 counters for the other threads and throws an error
92 if it sees the number stay the same or decrease
95 *dvs = LFDS710_MISC_VALIDITY_VALID;
97 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
100 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
101 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
102 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 );
103 re_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct test_element) + sizeof(struct lfds710_ringbuffer_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
104 te_array = (struct test_element *) ( re_array + number_elements );
107 vi.max_elements = number_elements;
109 lfds710_ringbuffer_init_valid_on_current_logical_core( &rs, re_array, number_elements, NULL );
111 // TRD : populate the ringbuffer
112 for( loop = 1 ; loop < number_elements ; loop++ )
114 te_array[loop].thread_number = 0;
115 te_array[loop].datum = (lfds710_pal_uint_t) -1 ;
116 lfds710_ringbuffer_write( &rs, NULL, &te_array[loop], NULL, NULL, NULL );
119 libtest_threadset_init( &ts, NULL );
123 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
125 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
127 (tpts+loop)->rs = &rs;
128 (tpts+loop)->thread_number = loop;
129 (tpts+loop)->counter = 0;
130 (tpts+loop)->number_logical_processors = number_logical_processors;
131 (tpts+loop)->error_flag = LOWERED;
132 (tpts+loop)->per_thread_counters = counters + loop * number_logical_processors;
134 for( subloop = 0 ; subloop < number_logical_processors ; subloop++ )
135 *((tpts+loop)->per_thread_counters+subloop) = 0;
137 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_reader_writer, &tpts[loop] );
142 // TRD : run the test
143 libtest_threadset_run( &ts );
145 libtest_threadset_cleanup( &ts );
148 LFDS710_MISC_BARRIER_LOAD;
150 lfds710_ringbuffer_query( &rs, LFDS710_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) local_dvs );
152 if( local_dvs[0] != LFDS710_MISC_VALIDITY_VALID )
155 if( local_dvs[1] != LFDS710_MISC_VALIDITY_VALID )
158 if( *dvs == LFDS710_MISC_VALIDITY_VALID )
159 for( loop = 0 ; loop < number_logical_processors ; loop++ )
160 if( (tpts+loop)->error_flag == RAISED )
161 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
163 lfds710_ringbuffer_cleanup( &rs, NULL );
172 /****************************************************************************/
173 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_reader_writer( void *libtest_threadset_per_thread_state )
181 struct test_per_thread_state
184 struct libtest_threadset_per_thread_state
191 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
193 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
195 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
196 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
198 libtest_threadset_thread_ready_and_wait( pts );
200 current_time = start_time = time( NULL );
202 while( current_time < start_time + TEST_DURATION_IN_SECONDS )
204 lfds710_ringbuffer_read( tpts->rs, NULL, (void **) &te );
206 if( te->thread_number >= tpts->number_logical_processors )
207 tpts->error_flag = RAISED;
210 if( te->datum < tpts->per_thread_counters[te->thread_number] )
211 tpts->error_flag = RAISED;
213 if( te->datum >= tpts->per_thread_counters[te->thread_number] )
214 tpts->per_thread_counters[te->thread_number] = te->datum+1;
217 te->thread_number = tpts->thread_number;
218 te->datum = tpts->counter++;
220 lfds710_ringbuffer_write( tpts->rs, NULL, te, NULL, NULL, NULL );
222 if( time_loop++ == TIME_LOOP_COUNT )
225 time( ¤t_time );
229 LFDS710_MISC_BARRIER_STORE;
231 lfds710_misc_force_store();
233 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);