]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_after.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.0.0 / test / src / test_lfds700_list_addonly_singlylinked_unordered_new_after.c
1 /***** includes *****/
2 #include "internal.h"
3
4 /***** structs *****/
5 struct test_element
6 {
7   struct lfds700_list_asu_element
8     lasue;
9
10   lfds700_pal_uint_t
11     element_number,
12     thread_number;
13 };
14
15 struct test_state
16 {
17   lfds700_pal_uint_t
18     number_elements;
19
20   struct lfds700_list_asu_state
21     *lasus;
22
23   struct test_element
24     *element_array;
25
26   struct lfds700_list_asu_element
27     *first_element;
28 };
29
30 /***** private prototypes *****/
31 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_after_thread( void *util_thread_starter_thread_state );
32
33
34
35
36
37 /****************************************************************************/
38 void test_lfds700_list_asu_new_after( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
39 {
40   enum lfds700_misc_validity
41     dvs = LFDS700_MISC_VALIDITY_VALID;
42
43   lfds700_pal_uint_t
44     loop,
45     number_elements,
46     number_logical_processors,
47     *per_thread_counters,
48     subloop;
49
50   struct lfds700_list_asu_element
51     *lasue,
52     first_element;
53
54   struct lfds700_list_asu_state
55     lasus;
56
57   struct lfds700_misc_prng_state
58     ps;
59
60   struct lfds700_misc_validation_info
61     vi;
62
63   struct test_pal_logical_processor
64     *lp;
65
66   struct util_thread_starter_state
67     *tts;
68
69   struct test_element
70     *element_array,
71     *element;
72
73   struct test_state
74     *ts;
75
76   test_pal_thread_state_t
77     *thread_handles;
78
79   assert( list_of_logical_processors != NULL );
80   // TRD : memory_in_megabytes can be any value in its range
81
82   /* TRD : run one thread per logical processor
83            run for 250k elements
84            we put a single first element into the list and
85            each thread loops, calling lfds700_list_asu_new_element_by_position( LFDS700_LIST_ASU_POSITION_AFTER ),
86            inserting after the single first element
87            data element contain s thread_number and element_number
88            verification should show element_number decreasing on a per thread basis
89   */
90
91   internal_display_test_name( "New after" );
92
93   lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
94
95   lfds700_misc_prng_init( &ps );
96
97   lfds700_list_asu_init_valid_on_current_logical_core( &lasus, NULL, NULL );
98
99   LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( first_element, NULL );
100   LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( first_element, NULL );
101   lfds700_list_asu_insert_at_position( &lasus, &first_element, NULL, LFDS700_LIST_ASU_POSITION_START, &ps );
102
103   number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
104
105   element_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
106
107   for( loop = 0 ; loop < number_logical_processors ; loop++ )
108     for( subloop = 0 ; subloop < number_elements ; subloop++ )
109     {
110       (element_array+(loop*number_elements)+subloop)->thread_number = loop;
111       (element_array+(loop*number_elements)+subloop)->element_number = subloop;
112     }
113
114   ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
115
116   for( loop = 0 ; loop < number_logical_processors ; loop++ )
117   {\
118     (ts+loop)->lasus = &lasus;
119     (ts+loop)->element_array = element_array + (loop*number_elements);
120     (ts+loop)->first_element = &first_element;
121     (ts+loop)->number_elements = number_elements;
122   }
123
124   thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
125
126   util_thread_starter_new( &tts, number_logical_processors );
127
128   LFDS700_MISC_BARRIER_STORE;
129
130   lfds700_misc_force_store();
131
132   loop = 0;
133   lasue = NULL;
134
135   while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
136   {
137     lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
138     util_thread_starter_start( tts, &thread_handles[loop], loop, lp, new_after_thread, ts+loop );
139     loop++;
140   }
141
142   util_thread_starter_run( tts );
143
144   for( loop = 0 ; loop < number_logical_processors ; loop++ )
145     test_pal_thread_wait( thread_handles[loop] );
146
147   util_thread_starter_delete( tts );
148
149   free( thread_handles );
150
151   free( ts );
152
153   /* TRD : validate the resultant list
154            iterate over each element
155            we expect to find element numbers increment on a per thread basis
156   */
157
158   LFDS700_MISC_BARRIER_LOAD;
159
160   vi.min_elements = vi.max_elements = number_elements * number_logical_processors + 1;
161
162   lfds700_list_asu_query( &lasus, LFDS700_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
163
164   per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
165
166   for( loop = 0 ; loop < number_logical_processors ; loop++ )
167     *(per_thread_counters+loop) = number_elements - 1;
168
169   /* TRD : we have a leading element, after which all inserts occurred
170            we need to get past that element for validation
171            this is why we're not using lfds700_list_asu_get_start_and_then_next()
172   */
173
174   lasue = LFDS700_LIST_ASU_GET_START( lasus );
175
176   lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
177
178   while( dvs == LFDS700_MISC_VALIDITY_VALID and lasue != NULL )
179   {
180     element = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
181
182     if( element->thread_number >= number_logical_processors )
183     {
184       dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
185       break;
186     }
187
188     if( element->element_number < per_thread_counters[element->thread_number] )
189       dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
190
191     if( element->element_number > per_thread_counters[element->thread_number] )
192       dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
193
194     if( element->element_number == per_thread_counters[element->thread_number] )
195       per_thread_counters[element->thread_number]--;
196
197     lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
198   }
199
200   free( per_thread_counters );
201
202   lfds700_list_asu_cleanup( &lasus, NULL );
203
204   util_aligned_free( element_array );
205
206   internal_display_test_result( 1, "list_asu", dvs );
207
208   return;
209 }
210
211
212
213
214
215 /****************************************************************************/
216 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_after_thread( void *util_thread_starter_thread_state )
217 {
218   lfds700_pal_uint_t
219     loop;
220
221   struct lfds700_misc_prng_state
222     ps;
223
224   struct test_state
225     *ts;
226
227   struct util_thread_starter_thread_state
228     *tsts;
229
230   LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
231
232   assert( util_thread_starter_thread_state != NULL );
233
234   tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
235   ts = (struct test_state *) tsts->thread_user_state;
236
237   lfds700_misc_prng_init( &ps );
238
239   util_thread_starter_ready_and_wait( tsts );
240
241   for( loop = 0 ; loop < ts->number_elements ; loop++ )
242   {
243     LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
244     LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
245     lfds700_list_asu_insert_at_position( ts->lasus, &(ts->element_array+loop)->lasue, ts->first_element, LFDS700_LIST_ASU_POSITION_AFTER, &ps );
246   }
247
248   LFDS700_MISC_BARRIER_STORE;
249
250   lfds700_misc_force_store();
251
252   return( (test_pal_thread_return_t) EXIT_SUCCESS );
253 }
254