]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libtest/src/libtest_tests/libtest_tests_ringbuffer_reading.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / test_and_benchmark / libtest / src / libtest_tests / libtest_tests_ringbuffer_reading.c
1 /***** includes *****/
2 #include "libtest_tests_internal.h"
3
4 /***** structs *****/
5 struct test_per_thread_state
6 {
7   enum flag
8     error_flag;
9
10   lfds710_pal_uint_t
11     read_count;
12
13   struct lfds710_ringbuffer_state
14     *rs;
15 };
16
17 /***** private prototypes *****/
18 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_simple_reader( void *libtest_threadset_per_thread_state );
19
20
21
22
23
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 )
26 {
27   enum lfds710_misc_validity
28     local_dvs[2] = { LFDS710_MISC_VALIDITY_VALID, LFDS710_MISC_VALIDITY_VALID };
29
30   lfds710_pal_uint_t
31     loop,
32     number_elements,
33     number_logical_processors,
34     total_read = 0;
35
36   struct lfds710_list_asu_element
37     *lasue = NULL;
38
39   struct lfds710_ringbuffer_element
40     *re_array;
41
42   struct lfds710_ringbuffer_state
43     rs;
44
45   struct lfds710_misc_validation_info
46     vi;
47
48   struct libtest_logical_processor
49     *lp;
50
51   struct libtest_threadset_per_thread_state
52     *pts;
53
54   struct libtest_threadset_state
55     ts;
56
57   struct test_per_thread_state
58     *tpts;
59
60   LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
61   LFDS710_PAL_ASSERT( ms != NULL );
62   LFDS710_PAL_ASSERT( dvs != NULL );
63
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
68
69            we create one thread per CPU
70            where each thread busy-works,
71            reading until the ringbuffer is empty
72
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
76   */
77
78   *dvs = LFDS710_MISC_VALIDITY_VALID;
79
80   lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
81
82   // TRD : allocate
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 );
86
87   vi.min_elements = 0;
88   vi.max_elements = number_elements - 1;
89
90   lfds710_ringbuffer_init_valid_on_current_logical_core( &rs, re_array, number_elements, NULL );
91
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 );
95
96   libtest_threadset_init( &ts, NULL );
97
98   loop = 0;
99
100   while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
101   {
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;
106
107     libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_simple_reader, &tpts[loop] );
108
109     loop++;
110   }
111
112   // TRD : run the test
113   libtest_threadset_run( &ts );
114
115   libtest_threadset_cleanup( &ts );
116
117   // TRD : validate
118   LFDS710_MISC_BARRIER_LOAD;
119
120   lfds710_ringbuffer_query( &rs, LFDS710_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) local_dvs );
121
122   if( local_dvs[0] != LFDS710_MISC_VALIDITY_VALID )
123     *dvs = local_dvs[0];
124
125   if( local_dvs[1] != LFDS710_MISC_VALIDITY_VALID )
126     *dvs = local_dvs[1];
127
128   if( *dvs == LFDS710_MISC_VALIDITY_VALID )
129   {
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;
134
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;
138
139     if( total_read < number_elements - 1 )
140       *dvs = LFDS710_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
141
142     if( total_read > number_elements - 1 )
143       *dvs = LFDS710_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
144   }
145
146   lfds710_ringbuffer_cleanup( &rs, NULL );
147
148   return;
149 }
150
151
152
153
154
155 /****************************************************************************/
156 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_simple_reader( void *libtest_threadset_per_thread_state )
157 {
158   lfds710_pal_uint_t
159     *prev_value,
160     *value;
161
162   struct test_per_thread_state
163     *tpts;
164
165   struct libtest_threadset_per_thread_state
166     *pts;
167
168   LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
169
170   LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
171
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 );
174
175   lfds710_ringbuffer_read( tpts->rs, NULL, (void **) &prev_value );
176   tpts->read_count++;
177
178   libtest_threadset_thread_ready_and_wait( pts );
179
180   while( lfds710_ringbuffer_read(tpts->rs, NULL, (void **) &value) )
181   {
182     if( value <= prev_value )
183       tpts->error_flag = RAISED;
184
185     prev_value = value;
186
187     tpts->read_count++;
188   }
189
190   LFDS710_MISC_BARRIER_STORE;
191
192   lfds710_misc_force_store();
193
194   return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);
195 }
196