]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.0.0/test/src/test_lfds700_stack_popping.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.0.0 / test / src / test_lfds700_stack_popping.c
1 /***** includes *****/
2 #include "internal.h"
3
4 /***** structs *****/
5 struct test_state
6 {
7   struct lfds700_stack_state
8     *ss;
9 };
10
11 struct test_element
12 {
13   struct lfds700_stack_element
14     se;
15
16   enum flag
17     popped_flag;
18 };
19
20 /***** private prototypes *****/
21 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state );
22
23
24
25
26
27 /****************************************************************************/
28 void test_lfds700_stack_popping( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
29 {
30   enum lfds700_misc_validity
31     dvs = LFDS700_MISC_VALIDITY_VALID;
32
33   lfds700_pal_uint_t
34     loop,
35     number_elements,
36     number_logical_processors;
37
38   struct lfds700_misc_prng_state
39     ps;
40
41   struct lfds700_list_asu_element
42     *lasue;
43
44   struct lfds700_stack_state
45     ss;
46
47   struct lfds700_misc_validation_info
48     vi = { 0, 0 };
49
50   struct test_pal_logical_processor
51     *lp;
52
53   struct util_thread_starter_state
54     *tts;
55
56   struct test_element
57     *te_array;
58
59   struct test_state
60     *ts;
61
62   test_pal_thread_state_t
63     *thread_handles;
64
65   assert( list_of_logical_processors != NULL );
66   // TRD : memory_in_megabytes can be any value in its range
67
68   /* TRD : we create a stack
69
70            we then populate the stack with 1,000,000 elements
71            each void pointer of data points to the containing test element
72
73            we then run one thread per CPU
74            where each thread loops, popping as quickly as possible
75            upon popping, a flag is set in the containing test element
76
77            the threads run till the source stack is empty
78
79            we then check the poppged flag, all should be raised
80
81            then tidy up
82
83            no CAS+GC code, as we only pop
84   */
85
86   internal_display_test_name( "Popping" );
87
88   lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
89
90   lfds700_misc_prng_init( &ps );
91
92   lfds700_stack_init_valid_on_current_logical_core( &ss, NULL );
93
94   number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct test_element) ;
95
96   te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
97
98   for( loop = 0 ; loop < number_elements ; loop++ )
99   {
100     (te_array+loop)->popped_flag = LOWERED;
101     LFDS700_STACK_SET_VALUE_IN_ELEMENT( (te_array+loop)->se, te_array+loop );
102     lfds700_stack_push( &ss, &(te_array+loop)->se, &ps );
103   }
104
105   ts = util_aligned_malloc( sizeof(struct test_state) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
106
107   for( loop = 0 ; loop < number_logical_processors ; loop++ )
108     (ts+loop)->ss = &ss;
109
110   thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
111
112   util_thread_starter_new( &tts, number_logical_processors );
113
114   LFDS700_MISC_BARRIER_STORE;
115
116   lfds700_misc_force_store();
117
118   loop = 0;
119   lasue = NULL;
120
121   while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
122   {
123     lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
124     util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_popping, ts+loop );
125     loop++;
126   }
127
128   util_thread_starter_run( tts );
129
130   for( loop = 0 ; loop < number_logical_processors ; loop++ )
131     test_pal_thread_wait( thread_handles[loop] );
132
133   util_thread_starter_delete( tts );
134
135   free( thread_handles );
136
137   LFDS700_MISC_BARRIER_LOAD;
138
139   lfds700_stack_query( &ss, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, (void *) &dvs );
140
141   // TRD : now we check each element has popped_flag set to RAISED
142   for( loop = 0 ; loop < number_elements ; loop++ )
143     if( (te_array+loop)->popped_flag == LOWERED )
144       dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
145
146   // TRD : cleanup
147   lfds700_stack_cleanup( &ss, NULL );
148   util_aligned_free( te_array );
149   util_aligned_free( ts );
150
151   // TRD : print the test result
152   internal_display_test_result( 1, "stack", dvs );
153
154   return;
155 }
156
157
158
159
160
161 /****************************************************************************/
162 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state )
163 {
164   struct lfds700_misc_prng_state
165     ps;
166
167   struct lfds700_stack_element
168     *se;
169
170   struct test_element
171     *te;
172
173   struct test_state
174     *ts;
175
176   struct util_thread_starter_thread_state
177     *tsts;
178
179   LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
180
181   assert( util_thread_starter_thread_state != NULL );
182
183   tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
184   ts = (struct test_state *) tsts->thread_user_state;
185
186   lfds700_misc_prng_init( &ps );
187
188   util_thread_starter_ready_and_wait( tsts );
189
190   while( lfds700_stack_pop(ts->ss, &se, &ps) )
191   {
192     te = LFDS700_STACK_GET_VALUE_FROM_ELEMENT( *se );
193     te->popped_flag = RAISED;
194   }
195
196   LFDS700_MISC_BARRIER_STORE;
197
198   lfds700_misc_force_store();
199
200   return( (test_pal_thread_return_t) EXIT_SUCCESS );
201 }
202