]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libbenchmark/src/libbenchmark_benchmarks_queue_umm_enqueue1_then_dequeue1/libbenchmark_benchmarks_queue_umm_liblfds700_lockfree_enqueue1_dequeue1.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / test_and_benchmark / libbenchmark / src / libbenchmark_benchmarks_queue_umm_enqueue1_then_dequeue1 / libbenchmark_benchmarks_queue_umm_liblfds700_lockfree_enqueue1_dequeue1.c
1 /***** includes *****/
2 #include "libbenchmark_benchmarks_queue_umm_internal.h"
3
4 /***** structs *****/
5 struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_per_thread_benchmark_state
6 {
7   lfds710_pal_uint_t
8     operation_count;
9 };
10
11 struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_overall_benchmark_state
12 {
13   struct lfds700_queue_state
14     *qs;
15 };
16
17
18
19
20
21 /****************************************************************************/
22 void libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_init( struct libbenchmark_topology_state *ts,
23                                                                                   struct lfds710_list_aso_state *logical_processor_set,
24                                                                                   struct libshared_memory_state *ms,
25                                                                                   enum libbenchmark_topology_numa_mode numa_mode,
26                                                                                   struct libbenchmark_threadset_state *tsets )
27 {
28   struct lfds700_misc_prng_state
29     ps;
30
31   lfds710_pal_uint_t
32     loop,
33     number_logical_processors,
34     number_logical_processors_in_numa_node,
35     largest_number_logical_processors_in_numa_node = 0;
36
37   struct lfds710_list_asu_element
38     *lasue = NULL,
39     *lasue_lp = NULL;
40
41   struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_overall_benchmark_state
42     *obs;
43
44   struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_per_thread_benchmark_state
45     *ptbs;
46
47   struct lfds700_queue_element
48     *qe;
49
50   struct lfds700_queue_state
51     *qs = NULL;
52
53   struct libbenchmark_threadset_per_numa_state
54     *pns,
55     *largest_pns = NULL;
56
57   struct libbenchmark_threadset_per_thread_state
58     *pts;
59
60   struct libbenchmark_topology_node_state
61     *numa_node_for_lp;
62
63   LFDS710_PAL_ASSERT( ts != NULL );
64   LFDS710_PAL_ASSERT( logical_processor_set != NULL );
65   LFDS710_PAL_ASSERT( ms != NULL );
66   // TRD : numa_mode can be any value in its range
67   LFDS710_PAL_ASSERT( tsets != NULL );
68
69   lfds700_misc_prng_init( &ps );
70
71   obs = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_overall_benchmark_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
72
73   libbenchmark_threadset_init( tsets, ts, logical_processor_set, ms, libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_thread, NULL );
74
75   switch( numa_mode )
76   {
77     case LIBBENCHMARK_TOPOLOGY_NUMA_MODE_SMP:
78       qs = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct lfds700_queue_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
79       lfds710_list_aso_query( logical_processor_set, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void *) &number_logical_processors );
80       qe = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct lfds700_queue_element) * (number_logical_processors+1), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
81       lfds700_queue_init_valid_on_current_logical_core( qs, &qe[0], &ps, NULL );
82       for( loop = 1 ; loop < (number_logical_processors+1) ; loop++ )
83         lfds700_queue_enqueue( qs, &qe[loop], &ps );
84       // TRD : now the per-thread states
85       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
86       {
87         pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
88         ptbs = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_per_thread_benchmark_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
89         pts->users_per_thread_state = ptbs;
90       }
91     break;
92
93     case LIBBENCHMARK_TOPOLOGY_NUMA_MODE_NUMA:
94       // TRD : get the NUMA node for the queue_umm state
95       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
96       {
97         pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
98
99         lasue_lp = NULL;
100         number_logical_processors_in_numa_node = 0;
101
102         while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
103         {
104           pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
105
106           libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
107
108           if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
109             number_logical_processors_in_numa_node++;
110         }
111
112         if( number_logical_processors_in_numa_node > largest_number_logical_processors_in_numa_node )
113           largest_pns = pns;
114       }
115
116       qs = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct lfds700_queue_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
117       qe = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct lfds700_queue_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
118       lfds700_queue_init_valid_on_current_logical_core( qs, qe, &ps, NULL );
119
120       /* TRD : for each NUMA node, alloc one element per thread in that NUMA node (from the current thread set)
121                the dummy element comes from the same node as the queue_umm state and has already been done
122       */
123
124       lasue = NULL;
125
126       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
127       {
128         pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
129
130         /* TRD : for each NUMA node, figure out how many LPs in the current set are in that NUMA node
131                  and allocate then the correct number of elements from this NUMA node (1 per LP)
132         */
133
134         lasue_lp = NULL;
135         number_logical_processors_in_numa_node = 0;
136
137         while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
138         {
139           pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
140
141           libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
142
143           if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
144             number_logical_processors_in_numa_node++;
145         }
146
147         qe = libshared_memory_alloc_from_specific_node( ms, pns->numa_node_id, sizeof(struct lfds700_queue_element) * number_logical_processors_in_numa_node, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
148         for( loop = 0 ; loop < number_logical_processors_in_numa_node ; loop++ )
149           lfds700_queue_enqueue( qs, &qe[loop], &ps );
150       }
151
152       // TRD : now the per-thread states
153
154       lasue = NULL;
155
156       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
157       {
158         pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
159         ptbs = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_per_thread_benchmark_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
160         pts->users_per_thread_state = ptbs;
161       }
162     break;
163
164     case LIBBENCHMARK_TOPOLOGY_NUMA_MODE_NUMA_BUT_NOT_USED:
165       // TRD : get the NUMA node for the queue_umm state
166       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
167       {
168         pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
169
170         lasue_lp = NULL;
171         number_logical_processors_in_numa_node = 0;
172
173         while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
174         {
175           pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
176
177           libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
178
179           if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
180             number_logical_processors_in_numa_node++;
181         }
182
183         if( number_logical_processors_in_numa_node > largest_number_logical_processors_in_numa_node )
184           largest_pns = pns;
185       }
186
187       qs = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct lfds700_queue_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
188       qe = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct lfds700_queue_element), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
189       lfds700_queue_init_valid_on_current_logical_core( qs, qe, &ps, NULL );
190
191       /* TRD : for each NUMA node, alloc one element per thread in that NUMA node (from the current thread set)
192                the dummy element comes from the same node as the queue_umm state and has already been done
193       */
194
195       lasue = NULL;
196
197       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
198       {
199         pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
200
201         /* TRD : for each NUMA node, figure out how many LPs in the current set are in that NUMA node
202                  and allocate then the correct number of elements from this NUMA node (1 per LP)
203         */
204
205         lasue_lp = NULL;
206         number_logical_processors_in_numa_node = 0;
207
208         while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
209         {
210           pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
211
212           libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
213
214           if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
215             number_logical_processors_in_numa_node++;
216         }
217
218         // TRD : everything allocates from the queue_umm state NUMA node
219         qe = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct lfds700_queue_element) * number_logical_processors_in_numa_node, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
220         for( loop = 0 ; loop < number_logical_processors_in_numa_node ; loop++ )
221           lfds700_queue_enqueue( qs, &qe[loop], &ps );
222       }
223
224       // TRD : now the per-thread states
225
226       lasue = NULL;
227
228       while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
229       {
230         pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
231         ptbs = libshared_memory_alloc_from_specific_node( ms, largest_pns->numa_node_id, sizeof(struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_per_thread_benchmark_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
232         pts->users_per_thread_state = ptbs;
233       }    break;
234   }
235
236   obs->qs = qs;
237   tsets->users_threadset_state = obs;
238
239   return;
240 }
241
242
243
244
245
246 /****************************************************************************/
247 libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_thread( void *libbenchmark_threadset_per_thread_state )
248 {
249   int long long unsigned
250     current_time = 0,
251     end_time,
252     time_units_per_second;
253
254   struct lfds700_misc_prng_state
255     ps;
256
257   lfds710_pal_uint_t
258     operation_count = 0,
259     time_loop = 0;
260
261   struct lfds700_queue_element
262     *qe;
263
264   struct lfds700_queue_state
265     *qs;
266
267   struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_overall_benchmark_state
268     *obs;
269
270   struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_per_thread_benchmark_state
271     *ptbs;
272
273   struct libbenchmark_threadset_per_thread_state
274     *pts;
275
276   LFDS710_MISC_BARRIER_LOAD;
277
278   LFDS710_PAL_ASSERT( libbenchmark_threadset_per_thread_state != NULL );
279
280   pts = (struct libbenchmark_threadset_per_thread_state *) libbenchmark_threadset_per_thread_state;
281
282   ptbs = LIBBENCHMARK_THREADSET_PER_THREAD_STATE_GET_USERS_PER_THREAD_STATE( *pts );
283   obs = LIBBENCHMARK_THREADSET_PER_THREAD_STATE_GET_USERS_OVERALL_STATE( *pts );
284   qs = obs->qs;
285
286   lfds700_misc_prng_init( &ps );
287
288   LIBBENCHMARK_PAL_TIME_UNITS_PER_SECOND( &time_units_per_second );
289
290   libbenchmark_threadset_thread_ready_and_wait( pts );
291
292   LIBBENCHMARK_PAL_GET_HIGHRES_TIME( &current_time );
293
294   end_time = current_time + time_units_per_second * libbenchmark_globals_benchmark_duration_in_seconds;
295
296   while( current_time < end_time )
297   {
298     lfds700_queue_dequeue( qs, &qe, &ps );
299     lfds700_queue_enqueue( qs, qe, &ps );
300     operation_count++;
301
302     if( time_loop++ == TIME_LOOP_COUNT )
303     {
304       time_loop = 0;
305       LIBBENCHMARK_PAL_GET_HIGHRES_TIME( &current_time );
306     }
307   }
308
309   ptbs->operation_count = operation_count;
310
311   LFDS710_MISC_BARRIER_STORE;
312
313   lfds710_misc_force_store();
314
315   return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);
316 }
317
318
319
320
321
322 /****************************************************************************/
323 void libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_cleanup( struct lfds710_list_aso_state *logical_processor_set,
324                                                                                   enum libbenchmark_topology_numa_mode numa_mode,
325                                                                                   struct libbenchmark_results_state *rs,
326                                                                                   struct libbenchmark_threadset_state *tsets )
327 {
328   struct lfds710_list_asu_element
329     *lasue = NULL;
330
331   struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_overall_benchmark_state
332     *obs;
333
334   struct libbenchmark_benchmark_queue_umm_liblfds700_lockfree_enqueue1_dequeue1_per_thread_benchmark_state
335     *ptbs;
336
337   struct libbenchmark_threadset_per_thread_state
338     *pts;
339
340   LFDS710_PAL_ASSERT( logical_processor_set != NULL );
341   // TRD : numa_mode can be any value in its range
342   LFDS710_PAL_ASSERT( rs != NULL );
343   LFDS710_PAL_ASSERT( tsets != NULL );
344
345   while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
346   {
347     pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
348
349     ptbs = LIBBENCHMARK_THREADSET_PER_THREAD_STATE_GET_USERS_PER_THREAD_STATE( *pts );
350
351     libbenchmark_results_put_result( rs,
352                                      LIBBENCHMARK_DATASTRUCTURE_ID_QUEUE_UMM,
353                                      LIBBENCHMARK_BENCHMARK_ID_ENQUEUE_UMM1_THEN_DEQUEUE_UMM1,
354                                      LIBBENCHMARK_LOCK_ID_LIBLFDS700_LOCKFREE,
355                                      numa_mode,
356                                      logical_processor_set,
357                                      LIBBENCHMARK_TOPOLOGY_NODE_GET_LOGICAL_PROCESSOR_NUMBER( *pts->tns_lp ),
358                                      LIBBENCHMARK_TOPOLOGY_NODE_GET_WINDOWS_GROUP_NUMBER( *pts->tns_lp ),
359                                      ptbs->operation_count );
360   }
361
362   obs = tsets->users_threadset_state;
363
364   lfds700_queue_cleanup( obs->qs, NULL );
365
366   return;
367 }
368