2 #include "libbenchmark_topology_node_internal.h"
5 enum libbenchmark_topology_node_set_type
7 LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUBSET,
8 LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SET,
9 LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUPERSET,
10 LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET
17 /****************************************************************************/
18 int libbenchmark_topology_node_compare_nodes_function( void const *new_key, void const *existing_key )
21 finished_flag = LOWERED,
22 not_a_set_flag = LOWERED;
24 enum libbenchmark_topology_node_set_type
25 st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET;
29 not_a_set_compare = 0, // TRD : remove compiler warning
37 struct lfds710_list_aso_element
41 struct libbenchmark_topology_node_state
47 LFDS710_PAL_ASSERT( new_key != NULL );
48 LFDS710_PAL_ASSERT( existing_key != NULL );
50 /* TRD : we compare the range of logic processors serviced by the nodes
51 the basic rule for cache/bus/memory arrangment is that the number of logical processors supported by a node
52 remains the same width or gets wider, as we go up the tree
54 so, first, we compare the logical processor list of each node
56 if the set in new_node is a subset of existing_node, then we are less than
57 if the set in new_node is the set of existing_node, then we compare on type (we know the ordering of types)
58 if the set in new_node is a superset of existing_node, then we are greater than
59 if the set in new_node is not a subset, set or superset of existing_node then we scan the logical processor
60 numbers and the first of new_node or existing_node to -have- the lowest number the other does -not-, is less than
63 new_tns = (struct libbenchmark_topology_node_state *) new_key;
64 existing_tns = (struct libbenchmark_topology_node_state *) existing_key;
66 if( new_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR and existing_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
68 if( new_tns->extended_node_info.logical_processor.windows_group_number == existing_tns->extended_node_info.logical_processor.windows_group_number )
70 if( new_tns->extended_node_info.logical_processor.number > existing_tns->extended_node_info.logical_processor.number )
73 if( new_tns->extended_node_info.logical_processor.number < existing_tns->extended_node_info.logical_processor.number )
77 if( new_tns->extended_node_info.logical_processor.windows_group_number < existing_tns->extended_node_info.logical_processor.windows_group_number )
80 if( new_tns->extended_node_info.logical_processor.windows_group_number > existing_tns->extended_node_info.logical_processor.windows_group_number )
84 not_a_set_compare = -1;
87 not_a_set_compare = 1;
92 lps_one_count = lps_two_count = 1;
95 if( new_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR and existing_tns->type != LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
99 lasoe_two = LFDS710_LIST_ASO_GET_START( existing_tns->logical_processor_children );
101 while( lasoe_two != NULL and finished_flag == LOWERED )
103 tns_two = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_two );
107 if( tns_one->extended_node_info.logical_processor.windows_group_number == tns_two->extended_node_info.logical_processor.windows_group_number )
109 if( tns_one->extended_node_info.logical_processor.number > tns_two->extended_node_info.logical_processor.number )
112 if( tns_one->extended_node_info.logical_processor.number < tns_two->extended_node_info.logical_processor.number )
116 if( tns_one->extended_node_info.logical_processor.windows_group_number < tns_two->extended_node_info.logical_processor.windows_group_number )
119 if( tns_one->extended_node_info.logical_processor.windows_group_number > tns_two->extended_node_info.logical_processor.windows_group_number )
124 finished_flag = RAISED;
125 if( not_a_set_flag == LOWERED )
127 not_a_set_compare = -1;
128 not_a_set_flag = RAISED;
134 lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
135 if( not_a_set_flag == LOWERED )
137 not_a_set_compare = 1;
138 not_a_set_flag = RAISED;
145 finished_flag = RAISED;
150 lfds710_list_aso_query( &existing_tns->logical_processor_children, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &lps_two_count );
153 if( new_tns->type != LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR and existing_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
155 tns_two = existing_tns;
157 lasoe_one = LFDS710_LIST_ASO_GET_START( new_tns->logical_processor_children );
159 while( lasoe_one != NULL and finished_flag == LOWERED )
161 tns_one = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_one );
165 if( tns_one->extended_node_info.logical_processor.windows_group_number == tns_two->extended_node_info.logical_processor.windows_group_number )
167 if( tns_one->extended_node_info.logical_processor.number > tns_two->extended_node_info.logical_processor.number )
170 if( tns_one->extended_node_info.logical_processor.number < tns_two->extended_node_info.logical_processor.number )
174 if( tns_one->extended_node_info.logical_processor.windows_group_number < tns_two->extended_node_info.logical_processor.windows_group_number )
177 if( tns_one->extended_node_info.logical_processor.windows_group_number > tns_two->extended_node_info.logical_processor.windows_group_number )
182 lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
183 if( not_a_set_flag == LOWERED )
185 not_a_set_compare = -1;
186 not_a_set_flag = RAISED;
192 finished_flag = RAISED;
193 if( not_a_set_flag == LOWERED )
195 not_a_set_compare = 1;
196 not_a_set_flag = RAISED;
203 finished_flag = RAISED;
207 lfds710_list_aso_query( &new_tns->logical_processor_children, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &lps_one_count );
211 if( new_tns->type != LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR and existing_tns->type != LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
213 // TRD : count the number of shared logical processors
214 lasoe_one = LFDS710_LIST_ASO_GET_START( new_tns->logical_processor_children );
215 lasoe_two = LFDS710_LIST_ASO_GET_START( existing_tns->logical_processor_children );
217 while( lasoe_one != NULL and lasoe_two != NULL )
219 tns_one = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_one );
220 tns_two = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_two );
224 if( tns_one->extended_node_info.logical_processor.windows_group_number == tns_two->extended_node_info.logical_processor.windows_group_number )
226 if( tns_one->extended_node_info.logical_processor.number > tns_two->extended_node_info.logical_processor.number )
229 if( tns_one->extended_node_info.logical_processor.number < tns_two->extended_node_info.logical_processor.number )
233 if( tns_one->extended_node_info.logical_processor.windows_group_number < tns_two->extended_node_info.logical_processor.windows_group_number )
236 if( tns_one->extended_node_info.logical_processor.windows_group_number > tns_two->extended_node_info.logical_processor.windows_group_number )
241 lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
242 if( not_a_set_flag == LOWERED )
244 not_a_set_compare = -1;
245 not_a_set_flag = RAISED;
251 lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
252 if( not_a_set_flag == LOWERED )
254 not_a_set_compare = 1;
255 not_a_set_flag = RAISED;
262 lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
263 lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
267 lfds710_list_aso_query( &new_tns->logical_processor_children, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &lps_one_count );
268 lfds710_list_aso_query( &existing_tns->logical_processor_children, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &lps_two_count );
271 // TRD : same number of logical processors, and they're fully shared
272 if( lps_one_count == lps_two_count and shared_count == lps_one_count )
273 st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SET;
275 // TRD : smaller number of logical processors, but they're all shared
276 if( lps_one_count < lps_two_count and shared_count == lps_one_count )
277 st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUBSET;
279 // TRD : larger number of logical processors, but lps_two is fully represented in lps_one
280 if( lps_one_count > lps_two_count and shared_count == lps_two_count )
281 st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUPERSET;
283 // TRD : otherwise, we're LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET, which is the default value
287 case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUBSET:
291 case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SET:
292 rv = libbenchmark_topology_node_compare_node_types_function( new_tns, existing_tns );
295 case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUPERSET:
299 case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET:
300 rv = not_a_set_compare;
311 /****************************************************************************/
312 int libbenchmark_topology_node_compare_node_types_function( void const *new_key, void const *existing_key )
317 struct libbenchmark_topology_node_state
321 LFDS710_PAL_ASSERT( new_key != NULL );
322 LFDS710_PAL_ASSERT( existing_key != NULL );
324 new_tns = (struct libbenchmark_topology_node_state *) new_key;
325 existing_tns = (struct libbenchmark_topology_node_state *) existing_key;
327 if( new_tns->type < existing_tns->type )
330 if( new_tns->type > existing_tns->type )
333 if( new_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_CACHE and existing_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_CACHE )
335 if( new_tns->extended_node_info.cache.level > existing_tns->extended_node_info.cache.level )
338 if( new_tns->extended_node_info.cache.level < existing_tns->extended_node_info.cache.level )
341 if( new_tns->extended_node_info.cache.level == existing_tns->extended_node_info.cache.level )
343 if( new_tns->extended_node_info.cache.type > existing_tns->extended_node_info.cache.type )
346 if( new_tns->extended_node_info.cache.type < existing_tns->extended_node_info.cache.type )
358 /****************************************************************************/
359 int libbenchmark_topology_node_compare_lpsets_function( struct lfds710_list_aso_state *lpset_one, struct lfds710_list_aso_state *lpset_two )
362 not_a_set_flag = LOWERED;
364 enum libbenchmark_topology_node_set_type
365 st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET;
370 not_a_set_compare = 0;
377 struct lfds710_list_aso_element
381 struct libbenchmark_topology_node_state
385 LFDS710_PAL_ASSERT( lpset_one != NULL );
386 LFDS710_PAL_ASSERT( lpset_two != NULL );
388 /* TRD : this function is utterly annoying
389 it is word for word identical to one of the compare cases in the general topology node compare function
390 except the compare result for IS_A_SET is 0 rather than a call to the type comparer
392 I cannot factorize the code with the general topology node compare function
394 this function is used only by the compare function in the results API
397 // TRD : first, count the number of shared logical processors
398 lasoe_one = LFDS710_LIST_ASO_GET_START( *lpset_one );
399 lasoe_two = LFDS710_LIST_ASO_GET_START( *lpset_two );
401 while( lasoe_one != NULL and lasoe_two != NULL )
403 tns_one = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_one );
404 tns_two = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_two );
408 if( tns_one->extended_node_info.logical_processor.windows_group_number == tns_two->extended_node_info.logical_processor.windows_group_number )
410 if( tns_one->extended_node_info.logical_processor.number > tns_two->extended_node_info.logical_processor.number )
413 if( tns_one->extended_node_info.logical_processor.number < tns_two->extended_node_info.logical_processor.number )
417 if( tns_one->extended_node_info.logical_processor.windows_group_number < tns_two->extended_node_info.logical_processor.windows_group_number )
420 if( tns_one->extended_node_info.logical_processor.windows_group_number > tns_two->extended_node_info.logical_processor.windows_group_number )
425 lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
426 if( not_a_set_flag == LOWERED )
428 not_a_set_compare = -1;
429 not_a_set_flag = RAISED;
435 lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
436 if( not_a_set_flag == LOWERED )
438 not_a_set_compare = 1;
439 not_a_set_flag = RAISED;
446 lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
447 lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
451 lfds710_list_aso_query( lpset_one, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &lps_one_count );
452 lfds710_list_aso_query( lpset_two, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &lps_two_count );
454 // TRD : same number of logical processors, and they're fully shared
455 if( lps_one_count == lps_two_count and shared_count == lps_one_count )
456 st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SET;
458 // TRD : smaller number of logical processors, but they're all shared
459 if( lps_one_count < lps_two_count and shared_count == lps_one_count )
460 st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUBSET;
462 // TRD : larger number of logical processors, but lps_two is fully represented in lps_one
463 if( lps_one_count > lps_two_count and shared_count == lps_two_count )
464 st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUPERSET;
468 case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUBSET:
472 case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SET:
476 case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUPERSET:
480 case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET:
481 rv = not_a_set_compare;