2 #include "libbenchmark_benchmarks_freelist_internal.h"
5 struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state
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 )
24 number_logical_processors,
25 number_logical_processors_in_numa_node,
26 largest_number_logical_processors_in_numa_node = 0;
28 struct lfds710_list_asu_element
32 struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state
35 struct libbenchmark_datastructure_freelist_pthread_mutex_element
38 struct libbenchmark_datastructure_freelist_pthread_mutex_state
41 struct libbenchmark_threadset_per_numa_state
45 struct libbenchmark_threadset_per_thread_state
48 struct libbenchmark_topology_node_state
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 );
57 libbenchmark_threadset_init( tsets, ts, logical_processor_set, ms, libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_thread, NULL );
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) )
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;
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
83 the loop over the threads, and give each one the freelist state as it's user state
86 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
88 pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
91 number_logical_processors_in_numa_node = 0;
93 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
95 pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
97 libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
99 if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
100 number_logical_processors_in_numa_node++;
103 if( number_logical_processors_in_numa_node > largest_number_logical_processors_in_numa_node )
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 );
112 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
114 pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
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)
121 number_logical_processors_in_numa_node = 0;
123 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
125 pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
127 libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
129 if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
130 number_logical_processors_in_numa_node++;
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] );
140 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
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;
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
154 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_numa_states,lasue) )
156 pns = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
159 number_logical_processors_in_numa_node = 0;
161 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue_lp) )
163 pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue_lp );
165 libbenchmark_topology_query( ts, LIBBENCHMARK_TOPOLOGY_QUERY_GET_NUMA_NODE_FOR_LOGICAL_PROCESSOR, pts->tns_lp, &numa_node_for_lp );
167 if( LIBBENCHMARK_TOPOLOGY_NODE_GET_NUMA_ID(*numa_node_for_lp) == pns->numa_node_id )
168 number_logical_processors_in_numa_node++;
171 if( number_logical_processors_in_numa_node > largest_number_logical_processors_in_numa_node )
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 );
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] );
185 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
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;
194 tsets->users_threadset_state = fs;
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 )
206 int long long unsigned
209 time_units_per_second;
215 struct libbenchmark_datastructure_freelist_pthread_mutex_state
218 struct libbenchmark_datastructure_freelist_pthread_mutex_element
221 struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state
224 struct libbenchmark_threadset_per_thread_state
227 LFDS710_MISC_BARRIER_LOAD;
229 LFDS710_PAL_ASSERT( libbenchmark_threadset_per_thread_state != NULL );
231 pts = (struct libbenchmark_threadset_per_thread_state *) libbenchmark_threadset_per_thread_state;
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 );
236 LIBBENCHMARK_PAL_TIME_UNITS_PER_SECOND( &time_units_per_second );
238 libbenchmark_threadset_thread_ready_and_wait( pts );
240 LIBBENCHMARK_PAL_GET_HIGHRES_TIME( ¤t_time );
242 end_time = current_time + time_units_per_second * libbenchmark_globals_benchmark_duration_in_seconds;
244 while( current_time < end_time )
246 libbenchmark_datastructure_freelist_pthread_mutex_pop( fs, &fe );
247 libbenchmark_datastructure_freelist_pthread_mutex_push( fs, fe );
250 if( time_loop++ == TIME_LOOP_COUNT )
253 LIBBENCHMARK_PAL_GET_HIGHRES_TIME( ¤t_time );
257 ptbs->operation_count = operation_count;
259 LFDS710_MISC_BARRIER_STORE;
261 lfds710_misc_force_store();
263 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);
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 )
276 struct libbenchmark_datastructure_freelist_pthread_mutex_state
279 struct lfds710_list_asu_element
282 struct libbenchmark_benchmark_freelist_pthread_mutex_push1_pop1_per_thread_benchmark_state
285 struct libbenchmark_threadset_per_thread_state
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 );
293 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(tsets->list_of_per_thread_states,lasue) )
295 pts = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
297 ptbs = LIBBENCHMARK_THREADSET_PER_THREAD_STATE_GET_USERS_PER_THREAD_STATE( *pts );
299 libbenchmark_results_put_result( rs,
300 LIBBENCHMARK_DATASTRUCTURE_ID_FREELIST,
301 LIBBENCHMARK_BENCHMARK_ID_PUSH1_THEN_POP1,
302 LIBBENCHMARK_LOCK_ID_PTHREAD_MUTEX,
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 );
310 fs = tsets->users_threadset_state;
312 libbenchmark_datastructure_freelist_pthread_mutex_cleanup( fs, NULL );