]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libtest/src/libtest_tests/libtest_tests_freelist_without_ea_popping.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_freelist_without_ea_popping.c
1 /***** includes *****/
2 #include "libtest_tests_internal.h"
3
4 /***** structs *****/
5 struct test_per_thread_state
6 {
7   struct lfds710_freelist_state
8     *fs;
9 };
10
11 struct test_element
12 {
13   struct lfds710_freelist_element
14     fe;
15
16   enum flag
17     popped_flag;
18 };
19
20 /***** private prototypes *****/
21 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_popping( void *libtest_threadset_per_thread_state );
22
23
24
25
26
27 /****************************************************************************/
28 void libtest_tests_freelist_without_ea_popping( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
29 {
30   lfds710_pal_uint_t
31     loop = 0,
32     number_elements,
33     number_logical_processors;
34
35   struct lfds710_freelist_state
36     fs;
37
38   struct lfds710_list_asu_element
39     *lasue = NULL;
40
41   struct lfds710_misc_validation_info
42     vi = { 0, 0 };
43
44   struct libtest_logical_processor
45     *lp;
46
47   struct libtest_threadset_per_thread_state
48     *pts;
49
50   struct libtest_threadset_state
51     ts;
52
53   struct test_element
54     *te_array;
55
56   struct test_per_thread_state
57     *tpts;
58
59   LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
60   LFDS710_PAL_ASSERT( ms != NULL );
61   LFDS710_PAL_ASSERT( dvs != NULL );
62
63   /* TRD : we create a freelist with as many elements as possible elements
64
65            the creation function runs in a single thread and creates
66            and pushes thofe elements onto the freelist
67
68            each element contains a void pointer to the container test element
69
70            we then run one thread per CPU
71            where each thread loops, popping as quickly as possible
72            each test element has a flag which indicates it has been popped
73
74            the threads run till the source freelist is empty
75
76            we then check the test elements
77            every element should have been popped
78
79            then tidy up
80   */
81
82   *dvs = LFDS710_MISC_VALIDITY_VALID;
83
84   lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
85
86   // TRD : allocate
87   tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
88   pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
89   te_array = libshared_memory_alloc_largest_possible_array_from_unknown_node( ms, sizeof(struct test_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES, &number_elements );
90
91   lfds710_freelist_init_valid_on_current_logical_core( &fs, NULL, 0, NULL );
92
93   for( loop = 0 ; loop < number_elements ; loop++ )
94   {
95     (te_array+loop)->popped_flag = LOWERED;
96     LFDS710_FREELIST_SET_VALUE_IN_ELEMENT( (te_array+loop)->fe, te_array+loop );
97     lfds710_freelist_push( &fs, &(te_array+loop)->fe, NULL );
98   }
99
100   libtest_threadset_init( &ts, NULL );
101
102   loop = 0;
103
104   while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
105   {
106     lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
107     tpts[loop].fs = &fs;
108
109     libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_popping, &tpts[loop] );
110
111     loop++;
112   }
113
114   LFDS710_MISC_BARRIER_STORE;
115
116   lfds710_misc_force_store();
117
118   // TRD : run the test
119   libtest_threadset_run( &ts );
120
121   libtest_threadset_cleanup( &ts );
122
123   // TRD : validate
124   LFDS710_MISC_BARRIER_LOAD;
125
126   lfds710_freelist_query( &fs, LFDS710_FREELIST_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
127
128   // TRD : now we check each element has popped_flag fet to RAISED
129   for( loop = 0 ; loop < number_elements ; loop++ )
130     if( (te_array+loop)->popped_flag == LOWERED )
131       *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
132
133   // TRD : cleanup
134   lfds710_freelist_cleanup( &fs, NULL );
135
136   return;
137 }
138
139
140
141
142
143 /****************************************************************************/
144 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_popping( void *libtest_threadset_per_thread_state )
145 {
146   struct lfds710_freelist_element
147     *fe;
148
149   struct test_per_thread_state
150     *tpts;
151
152   struct libtest_threadset_per_thread_state
153     *pts;
154
155   struct test_element
156     *te;
157
158   LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
159
160   LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
161
162   pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
163
164   tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
165
166   libtest_threadset_thread_ready_and_wait( pts );
167
168   while( lfds710_freelist_pop(tpts->fs, &fe, NULL) )
169   {
170     te = LFDS710_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
171     te->popped_flag = RAISED;
172   }
173
174   LFDS710_MISC_BARRIER_STORE;
175
176   lfds710_misc_force_store();
177
178   return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);
179 }
180