]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libbenchmark/src/libbenchmark_benchmarks_freelist_push1_then_pop1/libbenchmark_benchmarks_freelist_pthread_mutex_push1_then_pop1.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / test_and_benchmark / libbenchmark / src / libbenchmark_benchmarks_freelist_push1_then_pop1 / libbenchmark_benchmarks_freelist_pthread_mutex_push1_then_pop1.c
1 /***** includes *****/
2 #include "libbenchmark_benchmarks_freelist_internal.h"
3
4 /***** structs *****/
5 struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state
6 {
7   lfds710_pal_uint_t
8     operation_count;
9 };
10
11
12
13
14
15 /****************************************************************************/
16 void libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_init( struct libbenchmark_topology_state *ts,
17                                                                     struct lfds710_list_aso_state *logical_processor_set,
18                                                                     struct libshared_memory_state *ms,
19                                                                     enum libbenchmark_topology_numa_mode numa_mode,
20                                                                     struct libbenchmark_threadset_state *tsets )
21 {
22   lfds710_pal_uint_t
23     loop,
24     number_logical_processors,
25     number_logical_processors_in_numa_node,
26     largest_number_logical_processors_in_numa_node = 0;
27
28   struct lfds710_list_asu_element
29     *lasue = NULL,
30     *lasue_lp = NULL;
31
32   struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state
33     *ptbs;
34
35   struct libbenchmark_datastructure_freelist_pthread_mutex_element
36     *fe;
37
38   struct libbenchmark_datastructure_freelist_pthread_mutex_state
39     *fs = NULL;
40
41   struct libbenchmark_threadset_per_numa_state
42     *pns,
43     *largest_pns = NULL;
44
45   struct libbenchmark_threadset_per_thread_state
46     *pts;
47
48   struct libbenchmark_topology_node_state
49     *numa_node_for_lp;
50
51   LFDS710_PAL_ASSERT( ts != NULL );
52   LFDS710_PAL_ASSERT( logical_processor_set != NULL );
53   LFDS710_PAL_ASSERT( ms != NULL );
54   // TRD : numa_mode can be any value in its range
55   LFDS710_PAL_ASSERT( tsets != NULL );
56
57   libbenchmark_threadset_init( tsets, ts, logical_processor_set, ms, libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_thread, NULL );
58
59   switch( numa_mode )
60   {
61     case LIBBENCHMARK_TOPOLOGY_NUMA_MODE_SMP:
62       fs = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_datastructure_freelist_pthread_mutex_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
63       libbenchmark_datastructure_freelist_pthread_mutex_init( fs, NULL );
64       lfds710_list_aso_query( logical_processor_set, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void *) &number_logical_processors );
65       fe = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_datastructure_freelist_pthread_mutex_element) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
66       for( loop = 0 ; loop < number_logical_processors ; loop++ )
67         libbenchmark_datastructure_freelist_pthread_mutex_push( fs, &fe[loop] );
68       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
69       {
70         pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
71         ptbs = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
72         pts->users_per_thread_state = ptbs;
73       }
74     break;
75
76     case LIBBENCHMARK_TOPOLOGY_NUMA_MODE_NUMA:
77       /* TRD : init the freelist from the NUMA node with most processors from the current set
78                or, if equal threads, with lowest NUMA
79                iterate over the NUMA node list
80                for each NUMA node, allocate one freelist element per thread on that node
81                and push those elements onto the stack
82
83                the loop over the threads, and give each one the freelist state as it's user state
84       */
85
86       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
87       {
88         pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
89
90         lasue_lp = NULL;
91         number_logical_processors_in_numa_node = 0;
92
93         while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
94         {
95           pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
96
97           libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
98
99           if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
100             number_logical_processors_in_numa_node++;
101         }
102
103         if( number_logical_processors_in_numa_node > largest_number_logical_processors_in_numa_node )
104           largest_pns = pns;
105       }
106
107       fs = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct libbenchmark_datastructure_freelist_pthread_mutex_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
108       libbenchmark_datastructure_freelist_pthread_mutex_init( fs, NULL );
109
110       lasue = NULL;
111
112       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
113       {
114         pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
115
116         /* TRD : for each NUMA node, figure out how many LPs in the current set are in that NUMA node
117                  and allocate then the correct number of elements from this NUMA node (1 per LP)
118         */
119
120         lasue_lp = NULL;
121         number_logical_processors_in_numa_node = 0;
122
123         while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
124         {
125           pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
126
127           libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
128
129           if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
130             number_logical_processors_in_numa_node++;
131         }
132
133         fe = libshared_memory_alloc_from_specific_node( ms, pns->numa_node_id, sizeof(struct libbenchmark_datastructure_freelist_pthread_mutex_element) * number_logical_processors_in_numa_node, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
134         for( loop = 0 ; loop < number_logical_processors_in_numa_node ; loop++ )
135           libbenchmark_datastructure_freelist_pthread_mutex_push( fs, &fe[loop] );
136       }
137
138       lasue = NULL;
139
140       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
141       {
142         pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
143         ptbs = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
144         pts->users_per_thread_state = ptbs;
145       }
146     break;
147
148     case LIBBENCHMARK_TOPOLOGY_NUMA_MODE_NUMA_BUT_NOT_USED:
149       /* TRD : freelist state in the NUMA node with most threads from the current set
150                or, if equal threads, with lowest NUMA
151                all elements alloced from that node as well
152       */
153
154       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
155       {
156         pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
157
158         lasue_lp = NULL;
159         number_logical_processors_in_numa_node = 0;
160
161         while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
162         {
163           pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
164
165           libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
166
167           if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
168             number_logical_processors_in_numa_node++;
169         }
170
171         if( number_logical_processors_in_numa_node > largest_number_logical_processors_in_numa_node )
172           largest_pns = pns;
173       }
174
175       fs = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct libbenchmark_datastructure_freelist_pthread_mutex_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
176       libbenchmark_datastructure_freelist_pthread_mutex_init( fs, NULL );
177
178       lfds710_list_aso_query( logical_processor_set, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void *) &number_logical_processors );
179       fe = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct libbenchmark_datastructure_freelist_pthread_mutex_element) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
180       for( loop = 0 ; loop < number_logical_processors ; loop++ )
181         libbenchmark_datastructure_freelist_pthread_mutex_push( fs, &fe[loop] );
182
183       lasue = NULL;
184
185       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
186       {
187         pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
188         ptbs = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
189         pts->users_per_thread_state = ptbs;
190       }
191     break;
192   }
193
194   tsets->users_threadset_state = fs;
195
196   return;
197 }
198
199
200
201
202
203 /****************************************************************************/
204 libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_thread( void *libbenchmark_threadset_per_thread_state )
205 {
206   int long long unsigned
207     current_time = 0,
208     end_time,
209     time_units_per_second;
210
211   lfds710_pal_uint_t
212     operation_count = 0,
213     time_loop = 0;
214
215   struct libbenchmark_datastructure_freelist_pthread_mutex_state
216     *fs;
217
218   struct libbenchmark_datastructure_freelist_pthread_mutex_element
219     *fe;
220
221   struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state
222     *ptbs;
223
224   struct libbenchmark_threadset_per_thread_state
225     *pts;
226
227   LFDS710_MISC_BARRIER_LOAD;
228
229   LFDS710_PAL_ASSERT( libbenchmark_threadset_per_thread_state != NULL );
230
231   pts = (struct libbenchmark_threadset_per_thread_state *) libbenchmark_threadset_per_thread_state;
232
233   ptbs = LIBBENCHMARK_THREADSET_PER_THREAD_STATE_GET_USERS_PER_THREAD_STATE( *pts );
234   fs = LIBBENCHMARK_THREADSET_PER_THREAD_STATE_GET_USERS_OVERALL_STATE( *pts );
235
236   LIBBENCHMARK_PAL_TIME_UNITS_PER_SECOND( &time_units_per_second );
237
238   libbenchmark_threadset_thread_ready_and_wait( pts );
239
240   LIBBENCHMARK_PAL_GET_HIGHRES_TIME( &current_time );
241
242   end_time = current_time + time_units_per_second * libbenchmark_globals_benchmark_duration_in_seconds;
243
244   while( current_time < end_time )
245   {
246     libbenchmark_datastructure_freelist_pthread_mutex_pop( fs, &fe );
247     libbenchmark_datastructure_freelist_pthread_mutex_push( fs, fe );
248     operation_count++;
249
250     if( time_loop++ == TIME_LOOP_COUNT )
251     {
252       time_loop = 0;
253       LIBBENCHMARK_PAL_GET_HIGHRES_TIME( &current_time );
254     }
255   }
256
257   ptbs->operation_count = operation_count;
258
259   LFDS710_MISC_BARRIER_STORE;
260
261   lfds710_misc_force_store();
262
263   return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);
264 }
265
266
267
268
269
270 /****************************************************************************/
271 void libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_cleanup( struct lfds710_list_aso_state *logical_processor_set,
272                                                                        enum libbenchmark_topology_numa_mode numa_mode,
273                                                                        struct libbenchmark_results_state *rs,
274                                                                        struct libbenchmark_threadset_state *tsets )
275 {
276   struct libbenchmark_datastructure_freelist_pthread_mutex_state
277     *fs;
278
279   struct lfds710_list_asu_element
280     *lasue = NULL;
281
282   struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state
283     *ptbs;
284
285   struct libbenchmark_threadset_per_thread_state
286     *pts;
287
288   LFDS710_PAL_ASSERT( logical_processor_set != NULL );
289   // TRD : numa_mode can be any value in its range
290   LFDS710_PAL_ASSERT( rs != NULL );
291   LFDS710_PAL_ASSERT( tsets != NULL );
292
293   while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
294   {
295     pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
296
297     ptbs = LIBBENCHMARK_THREADSET_PER_THREAD_STATE_GET_USERS_PER_THREAD_STATE( *pts );
298
299     libbenchmark_results_put_result( rs,
300                                      LIBBENCHMARK_DATASTRUCTURE_ID_FREELIST,
301                                      LIBBENCHMARK_BENCHMARK_ID_PUSH1_THEN_POP1,
302                                      LIBBENCHMARK_LOCK_ID_PTHREAD_MUTEX,
303                                      numa_mode,
304                                      logical_processor_set,
305                                      LIBBENCHMARK_TOPOLOGY_NODE_GET_LOGICAL_PROCESSOR_NUMBER( *pts->tns_lp ),
306                                      LIBBENCHMARK_TOPOLOGY_NODE_GET_WINDOWS_GROUP_NUMBER( *pts->tns_lp ),
307                                      ptbs->operation_count );
308   }
309
310   fs = tsets->users_threadset_state;
311
312   libbenchmark_datastructure_freelist_pthread_mutex_cleanup( fs, NULL );
313
314   return;
315 }
316