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