]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libtest/src/libtest_tests/libtest_tests_freelist_without_ea_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_freelist_without_ea_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_freelist_state
8     *fs;
9 };
10
11 struct test_element
12 {
13   struct lfds710_freelist_element
14     fe;
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 *libshared_threads_thread_state );
22
23
24
25
26
27 /****************************************************************************/
28 void libtest_tests_freelist_without_ea_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_freelist_state
42     fs;
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 freelist is valid and don't leak memory
74            and here, this test now is one of thofe 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 freelist 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 feconds
83
84            after the test is done, the only check we do is to traverfe
85            the freelist, checking for loops and ensuring the number of
86            elements is correct
87   */
88
89   *dvs = LFDS710_MISC_VALIDITY_VALID;
90
91   lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
92
93   // TRD : allocate
94   tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
95   pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
96   te_array = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_element) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
97
98   lfds710_freelist_init_valid_on_current_logical_core( &fs, NULL, 0, NULL );
99
100   for( loop = 0 ; loop < number_logical_processors ; loop++ )
101     tpts[loop].fs = &fs;
102
103   for( loop = 0 ; loop < number_logical_processors ; loop++ )
104   {
105     LFDS710_FREELIST_SET_VALUE_IN_ELEMENT( te_array[loop].fe, &te_array[loop] );
106     lfds710_freelist_push( &fs, &te_array[loop].fe, NULL );
107   }
108
109   // TRD : get the threads ready
110   libtest_threadset_init( &ts, NULL );
111
112   while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
113   {
114     lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
115     libtest_threadset_add_thread( &ts, &pts[index], lp, thread_rapid_popping_and_pushing, &tpts[index] );
116     index++;
117   }
118
119   // TRD : run the test
120   libtest_threadset_run( &ts );
121
122   libtest_threadset_cleanup( &ts );
123
124   // TRD : validate
125   LFDS710_MISC_BARRIER_LOAD;
126
127   vi.min_elements = vi.max_elements = number_logical_processors;
128
129   lfds710_freelist_query( &fs, LFDS710_FREELIST_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
130
131   lfds710_freelist_cleanup( &fs, NULL );
132
133   return;
134 }
135
136
137
138
139
140 /****************************************************************************/
141 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *libtest_threadset_per_thread_state )
142 {
143   lfds710_pal_uint_t
144     time_loop = 0;
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   time_t
156     current_time,
157     start_time;
158
159   LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
160
161   LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
162
163   pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
164
165   tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
166
167   libtest_threadset_thread_ready_and_wait( pts );
168
169   current_time = start_time = time( NULL );
170
171   while( current_time < start_time + TEST_DURATION_IN_SECONDS )
172   {
173     lfds710_freelist_pop( tpts->fs, &fe, NULL );
174     lfds710_freelist_push( tpts->fs, fe, NULL );
175
176     if( time_loop++ == TIME_LOOP_COUNT )
177     {
178       time_loop = 0;
179       time( &current_time );
180     }
181   }
182
183   LFDS710_MISC_BARRIER_STORE;
184
185   lfds710_misc_force_store();
186
187   return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);
188 }
189