13 struct lfds700_ringbuffer_state
17 /***** private prototypes *****/
18 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_reader( void *util_thread_starter_thread_state );
24 /****************************************************************************/
25 void test_lfds700_ringbuffer_reading( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
27 enum lfds700_misc_validity
28 dvs[2] = { LFDS700_MISC_VALIDITY_VALID, LFDS700_MISC_VALIDITY_VALID };
32 number_elements_with_dummy_element,
33 number_elements_without_dummy_element,
34 number_logical_processors,
37 struct lfds700_list_asu_element
40 struct lfds700_misc_prng_state
43 struct lfds700_ringbuffer_element
46 struct lfds700_ringbuffer_state
49 struct lfds700_misc_validation_info
52 struct test_pal_logical_processor
55 struct util_thread_starter_state
61 test_pal_thread_state_t
64 assert( list_of_logical_processors != NULL );
65 // TRD : memory_in_megabytes can be any value in its range
67 /* TRD : we create a single ringbuffer
68 with 1,000,000 elements
69 we populate the ringbuffer, where the
70 user data is an incrementing counter
72 we create one thread per CPU
73 where each thread busy-works,
74 reading until the ringbuffer is empty
76 each thread keep track of the number of reads it manages
77 and that each user data it reads is greater than the
78 previous user data that was read
81 internal_display_test_name( "Reading" );
83 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
85 lfds700_misc_prng_init( &ps );
87 number_elements_with_dummy_element = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct lfds700_ringbuffer_element);
88 number_elements_without_dummy_element = number_elements_with_dummy_element - 1;
91 vi.max_elements = number_elements_without_dummy_element;
93 re_array = util_aligned_malloc( sizeof(struct lfds700_ringbuffer_element) * number_elements_with_dummy_element, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
95 lfds700_ringbuffer_init_valid_on_current_logical_core( &rs, re_array, number_elements_with_dummy_element, &ps, NULL );
97 // TRD : init the ringbuffer contents for the test
98 for( loop = 0 ; loop < number_elements_without_dummy_element ; loop++ )
99 lfds700_ringbuffer_write( &rs, NULL, (void *) (size_t) loop, NULL, NULL, NULL, &ps );
101 ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
103 for( loop = 0 ; loop < number_logical_processors ; loop++ )
106 (ts+loop)->read_count = 0;
107 (ts+loop)->error_flag = LOWERED;
110 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
112 util_thread_starter_new( &tts, number_logical_processors );
114 LFDS700_MISC_BARRIER_STORE;
116 lfds700_misc_force_store();
121 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
123 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
124 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_simple_reader, ts+loop );
128 util_thread_starter_run( tts );
130 for( loop = 0 ; loop < number_logical_processors ; loop++ )
131 test_pal_thread_wait( thread_handles[loop] );
133 util_thread_starter_delete( tts );
135 free( thread_handles );
137 LFDS700_MISC_BARRIER_LOAD;
139 lfds700_ringbuffer_query( &rs, LFDS700_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) dvs );
141 // TRD : check for raised error flags
142 for( loop = 0 ; loop < number_logical_processors ; loop++ )
143 if( (ts+loop)->error_flag == RAISED )
144 dvs[0] = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
146 // TRD : check thread reads total to 1,000,000
147 for( loop = 0 ; loop < number_logical_processors ; loop++ )
148 total_read += (ts+loop)->read_count;
150 if( total_read < number_elements_without_dummy_element )
151 dvs[0] = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
153 if( total_read > number_elements_without_dummy_element )
154 dvs[0] = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
158 lfds700_ringbuffer_cleanup( &rs, NULL );
160 util_aligned_free( re_array );
162 internal_display_test_result( 2, "queue", dvs[0], "freelist", dvs[1] );
171 /****************************************************************************/
172 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_reader( void *util_thread_starter_thread_state )
178 struct lfds700_misc_prng_state
184 struct util_thread_starter_thread_state
187 LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
189 assert( util_thread_starter_thread_state != NULL );
191 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
192 ts = (struct test_state *) tsts->thread_user_state;
194 lfds700_misc_prng_init( &ps );
196 lfds700_ringbuffer_read( ts->rs, NULL, (void **) &prev_value, &ps );
199 util_thread_starter_ready_and_wait( tsts );
201 while( lfds700_ringbuffer_read(ts->rs, NULL, (void **) &value, &ps) )
203 if( value <= prev_value )
204 ts->error_flag = RAISED;
211 LFDS700_MISC_BARRIER_STORE;
213 lfds700_misc_force_store();
215 return( (test_pal_thread_return_t) EXIT_SUCCESS );