]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_end.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_end.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
27 /***** private prototypes *****/
28 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_end_thread( void *util_thread_starter_thread_state );
29
30
31
32
33
34 /****************************************************************************/
35 void test_lfds700_list_asu_new_end( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
36 {
37   enum lfds700_misc_validity
38     dvs = LFDS700_MISC_VALIDITY_VALID;
39
40   lfds700_pal_uint_t
41     loop,
42     number_elements,
43     number_logical_processors,
44     *per_thread_counters,
45     subloop;
46
47   struct lfds700_list_asu_element
48     *lasue = NULL;
49
50   struct lfds700_list_asu_state
51     lasus;
52
53   struct lfds700_misc_validation_info
54     vi;
55
56   struct test_pal_logical_processor
57     *lp;
58
59   struct util_thread_starter_state
60     *tts;
61
62   struct test_element
63     *element_array,
64     *element;
65
66   struct test_state
67     *ts;
68
69   test_pal_thread_state_t
70     *thread_handles;
71
72   assert( list_of_logical_processors != NULL );
73   // TRD : memory_in_megabytes can be any value in its range
74
75   /* TRD : run one thread per logical processor
76            run for 250k elements
77            each thread loops, calling lfds700_list_asu_new_element_by_position( LFDS700_LIST_ASU_POSITION_END )
78            data element contain a thread_number and element_number
79            verification should show element_number increasing on a per thread basis
80   */
81
82   internal_display_test_name( "New end" );
83
84   lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
85
86   lfds700_list_asu_init_valid_on_current_logical_core( &lasus, NULL, NULL );
87
88   number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
89
90   element_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
91
92   for( loop = 0 ; loop < number_logical_processors ; loop++ )
93     for( subloop = 0 ; subloop < number_elements ; subloop++ )
94     {
95       (element_array+(loop*number_elements)+subloop)->thread_number = loop;
96       (element_array+(loop*number_elements)+subloop)->element_number = subloop;
97     }
98
99   ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
100
101   for( loop = 0 ; loop < number_logical_processors ; loop++ )
102   {
103     (ts+loop)->lasus = &lasus;
104     (ts+loop)->element_array = element_array + (loop*number_elements);
105     (ts+loop)->number_elements = number_elements;
106   }
107
108   thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
109
110   util_thread_starter_new( &tts, number_logical_processors );
111
112   LFDS700_MISC_BARRIER_STORE;
113
114   lfds700_misc_force_store();
115
116   loop = 0;
117   lasue = NULL;
118
119   while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
120   {
121     lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
122     util_thread_starter_start( tts, &thread_handles[loop], loop, lp, new_end_thread, ts+loop );
123     loop++;
124   }
125
126   util_thread_starter_run( tts );
127
128   for( loop = 0 ; loop < number_logical_processors ; loop++ )
129     test_pal_thread_wait( thread_handles[loop] );
130
131   util_thread_starter_delete( tts );
132
133   free( thread_handles );
134
135   free( ts );
136
137   /* TRD : validate the resultant list
138            iterate over each element
139            we expect to find element numbers increment on a per thread basis
140   */
141
142   LFDS700_MISC_BARRIER_LOAD;
143
144   vi.min_elements = vi.max_elements = number_elements * number_logical_processors;
145
146   lfds700_list_asu_query( &lasus, LFDS700_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
147
148   per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
149
150   for( loop = 0 ; loop < number_logical_processors ; loop++ )
151     *(per_thread_counters+loop) = 0;
152
153   lasue = NULL;
154
155   while( dvs == LFDS700_MISC_VALIDITY_VALID and LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(lasus, lasue) )
156   {
157     element = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
158
159     if( element->thread_number >= number_logical_processors )
160     {
161       dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
162       break;
163     }
164
165     if( element->element_number > per_thread_counters[element->thread_number] )
166       dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
167
168     if( element->element_number < per_thread_counters[element->thread_number] )
169       dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
170
171     if( element->element_number == per_thread_counters[element->thread_number] )
172       per_thread_counters[element->thread_number]++;
173   }
174
175   free( per_thread_counters );
176
177   lfds700_list_asu_cleanup( &lasus, NULL );
178
179   util_aligned_free( element_array );
180
181   internal_display_test_result( 1, "list_asu", dvs );
182
183   return;
184 }
185
186
187
188
189
190 /****************************************************************************/
191 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_end_thread( void *util_thread_starter_thread_state )
192 {
193   lfds700_pal_uint_t
194     loop;
195
196   struct lfds700_misc_prng_state
197     ps;
198
199   struct test_state
200     *ts;
201
202   struct util_thread_starter_thread_state
203     *tsts;
204
205   LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
206
207   assert( util_thread_starter_thread_state != NULL );
208
209   tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
210   ts = (struct test_state *) tsts->thread_user_state;
211
212   lfds700_misc_prng_init( &ps );
213
214   util_thread_starter_ready_and_wait( tsts );
215
216   for( loop = 0 ; loop < ts->number_elements ; loop++ )
217   {
218     LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
219     LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
220     lfds700_list_asu_insert_at_position( ts->lasus, &(ts->element_array+loop)->lasue, NULL, LFDS700_LIST_ASU_POSITION_END, &ps );
221   }
222
223   LFDS700_MISC_BARRIER_STORE;
224
225   lfds700_misc_force_store();
226
227   return( (test_pal_thread_return_t) EXIT_SUCCESS );
228 }
229