]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libtest/src/libtest_tests/libtest_tests_stack_rapid_popping_and_pushing.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_stack_rapid_popping_and_pushing.c
1 /***** includes *****/
2 #include "libtest_tests_internal.h"
3
4 /***** structs *****/
5 struct test_per_thread_state
6 {
7   struct lfds710_stack_state
8     *ss;
9 };
10
11 struct test_element
12 {
13   struct lfds710_stack_element
14     se;
15
16   lfds710_pal_uint_t
17     datum;
18 };
19
20 /***** private prototypes *****/
21 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *libtest_threadset_per_thread_state );
22
23
24
25
26
27 /****************************************************************************/
28 void libtest_tests_stack_rapid_popping_and_pushing( 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     index = 0,
32     loop,
33     number_logical_processors;
34
35   struct lfds710_list_asu_element
36     *lasue = NULL;
37
38   struct lfds710_misc_validation_info
39     vi = { 0, 0 };
40
41   struct lfds710_stack_state
42     ss;
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 : in these tests there is a fundamental antagonism between
64            how much checking/memory clean up that we do and the
65            likelyhood of collisions between threads in their lock-free
66            operations
67
68            the lock-free operations are very quick; if we do anything
69            much at all between operations, we greatly reduce the chance
70            of threads colliding
71
72            so we have some tests which do enough checking/clean up that
73            they can tell the stack is valid and don't leak memory
74            and here, this test now is one of those which does minimal
75            checking - in fact, the nature of the test is that you can't
76            do any real checking - but goes very quickly
77
78            what we do is create a small stack and then run one thread
79            per CPU, where each thread simply pushes and then immediately
80            pops
81
82            the test runs for ten seconds
83
84            after the test is done, the only check we do is to traverse
85            the stack, checking for loops and ensuring the number of
86            elements is correct
87   */
88
89   // TRD : allocate
90   lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
91   tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
92   pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
93   te_array = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_element) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
94
95   lfds710_stack_init_valid_on_current_logical_core( &ss, NULL );
96
97   for( loop = 0 ; loop < number_logical_processors ; loop++ )
98     tpts[loop].ss = &ss;
99
100   for( loop = 0 ; loop < number_logical_processors ; loop++ )
101   {
102     LFDS710_STACK_SET_VALUE_IN_ELEMENT( te_array[loop].se, &te_array[loop] );
103     lfds710_stack_push( &ss, &te_array[loop].se );
104   }
105
106   // TRD : get the threads ready
107   libtest_threadset_init( &ts, NULL );
108
109   while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
110   {
111     lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
112     libtest_threadset_add_thread( &ts, &pts[index], lp, thread_rapid_popping_and_pushing, &tpts[index] );
113     index++;
114   }
115
116   // TRD : run the test
117   libtest_threadset_run( &ts );
118
119   libtest_threadset_cleanup( &ts );
120
121   // TRD : validate
122   LFDS710_MISC_BARRIER_LOAD;
123
124   vi.min_elements = vi.max_elements = number_logical_processors;
125
126   lfds710_stack_query( &ss, LFDS710_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
127
128   lfds710_stack_cleanup( &ss, NULL );
129
130   return;
131 }
132
133
134
135
136
137 /****************************************************************************/
138 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *libtest_threadset_per_thread_state )
139 {
140   lfds710_pal_uint_t
141     time_loop = 0;
142
143   struct lfds710_stack_element
144     *se;
145
146   struct libtest_threadset_per_thread_state
147     *pts;
148
149   struct test_per_thread_state
150     *tpts;
151
152   time_t
153     current_time,
154     start_time;
155
156   LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
157
158   LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
159
160   pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
161   tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
162
163   libtest_threadset_thread_ready_and_wait( pts );
164
165   current_time = start_time = time( NULL );
166
167   while( current_time < start_time + TEST_DURATION_IN_SECONDS )
168   {
169     lfds710_stack_pop( tpts->ss, &se );
170     lfds710_stack_push( tpts->ss, se );
171
172     if( time_loop++ == TIME_LOOP_COUNT )
173     {
174       time_loop = 0;
175       time( &current_time );
176     }
177   }
178
179   LFDS710_MISC_BARRIER_STORE;
180
181   lfds710_misc_force_store();
182
183   return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);
184 }
185