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