]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libbenchmark/src/libbenchmark_topology_node/libbenchmark_topology_node_compare.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / test_and_benchmark / libbenchmark / src / libbenchmark_topology_node / libbenchmark_topology_node_compare.c
1 /***** includes *****/
2 #include "libbenchmark_topology_node_internal.h"
3
4 /***** enums *****/
5 enum libbenchmark_topology_node_set_type
6 {
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
11 };
12
13
14
15
16
17 /****************************************************************************/
18 int libbenchmark_topology_node_compare_nodes_function( void const *new_key, void const *existing_key )
19 {
20   enum flag
21     finished_flag = LOWERED,
22     not_a_set_flag = LOWERED;
23
24   enum libbenchmark_topology_node_set_type
25     st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET;
26
27   int
28     cr = 0,
29     not_a_set_compare = 0, // TRD : remove compiler warning
30     rv = 0;
31
32   lfds710_pal_uint_t
33     lps_one_count = 0,
34     lps_two_count = 0,
35     shared_count = 0;
36
37   struct lfds710_list_aso_element
38     *lasoe_one,
39     *lasoe_two;
40
41   struct libbenchmark_topology_node_state
42     *new_tns,
43     *existing_tns,
44     *tns_one,
45     *tns_two;
46
47   LFDS710_PAL_ASSERT( new_key != NULL );
48   LFDS710_PAL_ASSERT( existing_key != NULL );
49
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
53
54            so, first, we compare the logical processor list of each node
55
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
61   */
62
63   new_tns = (struct libbenchmark_topology_node_state *) new_key;
64   existing_tns = (struct libbenchmark_topology_node_state *) existing_key;
65
66   if( new_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR and existing_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
67   {
68     if( new_tns->extended_node_info.logical_processor.windows_group_number == existing_tns->extended_node_info.logical_processor.windows_group_number )
69     {
70       if( new_tns->extended_node_info.logical_processor.number > existing_tns->extended_node_info.logical_processor.number )
71         cr = 1;
72
73       if( new_tns->extended_node_info.logical_processor.number < existing_tns->extended_node_info.logical_processor.number )
74         cr = -1;
75     }
76
77     if( new_tns->extended_node_info.logical_processor.windows_group_number < existing_tns->extended_node_info.logical_processor.windows_group_number )
78         cr = -1;
79
80     if( new_tns->extended_node_info.logical_processor.windows_group_number > existing_tns->extended_node_info.logical_processor.windows_group_number )
81         cr = 1;
82
83     if( cr == -1 )
84       not_a_set_compare = -1;
85
86     if( cr == 1 )
87       not_a_set_compare = 1;
88
89     if( cr == 0 )
90       shared_count = 1;
91
92     lps_one_count = lps_two_count = 1;
93   }
94
95   if( new_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR and existing_tns->type != LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
96   {
97     tns_one = new_tns;
98
99     lasoe_two = LFDS710_LIST_ASO_GET_START( existing_tns->logical_processor_children );
100
101     while( lasoe_two != NULL and finished_flag == LOWERED )
102     {
103       tns_two = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_two );
104
105       cr = 0;
106
107       if( tns_one->extended_node_info.logical_processor.windows_group_number == tns_two->extended_node_info.logical_processor.windows_group_number )
108       {
109         if( tns_one->extended_node_info.logical_processor.number > tns_two->extended_node_info.logical_processor.number )
110           cr = 1;
111
112         if( tns_one->extended_node_info.logical_processor.number < tns_two->extended_node_info.logical_processor.number )
113           cr = -1;
114       }
115
116       if( tns_one->extended_node_info.logical_processor.windows_group_number < tns_two->extended_node_info.logical_processor.windows_group_number )
117           cr = -1;
118
119       if( tns_one->extended_node_info.logical_processor.windows_group_number > tns_two->extended_node_info.logical_processor.windows_group_number )
120           cr = 1;
121
122       if( cr == -1 )
123       {
124         finished_flag = RAISED;
125         if( not_a_set_flag == LOWERED )
126         {
127           not_a_set_compare = -1;
128           not_a_set_flag = RAISED;
129         }
130       }
131
132       if( cr == 1 )
133       {
134         lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
135         if( not_a_set_flag == LOWERED )
136         {
137           not_a_set_compare = 1;
138           not_a_set_flag = RAISED;
139         }
140       }
141
142       if( cr == 0 )
143       {
144         shared_count++;
145         finished_flag = RAISED;
146       }
147     }
148
149     lps_one_count = 1;
150     lfds710_list_aso_query( &existing_tns->logical_processor_children, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &lps_two_count );
151   }
152
153   if( new_tns->type != LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR and existing_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
154   {
155     tns_two = existing_tns;
156
157     lasoe_one = LFDS710_LIST_ASO_GET_START( new_tns->logical_processor_children );
158
159     while( lasoe_one != NULL and finished_flag == LOWERED )
160     {
161       tns_one = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_one );
162
163       cr = 0;
164
165       if( tns_one->extended_node_info.logical_processor.windows_group_number == tns_two->extended_node_info.logical_processor.windows_group_number )
166       {
167         if( tns_one->extended_node_info.logical_processor.number > tns_two->extended_node_info.logical_processor.number )
168           cr = 1;
169
170         if( tns_one->extended_node_info.logical_processor.number < tns_two->extended_node_info.logical_processor.number )
171           cr = -1;
172       }
173
174       if( tns_one->extended_node_info.logical_processor.windows_group_number < tns_two->extended_node_info.logical_processor.windows_group_number )
175           cr = -1;
176
177       if( tns_one->extended_node_info.logical_processor.windows_group_number > tns_two->extended_node_info.logical_processor.windows_group_number )
178           cr = 1;
179
180       if( cr == -1 )
181       {
182         lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
183         if( not_a_set_flag == LOWERED )
184         {
185           not_a_set_compare = -1;
186           not_a_set_flag = RAISED;
187         }
188       }
189
190       if( cr == 1 )
191       {
192         finished_flag = RAISED;
193         if( not_a_set_flag == LOWERED )
194         {
195           not_a_set_compare = 1;
196           not_a_set_flag = RAISED;
197         }
198       }
199
200       if( cr == 0 )
201       {
202         shared_count++;
203         finished_flag = RAISED;
204       }
205     }
206
207     lfds710_list_aso_query( &new_tns->logical_processor_children, LFDS710_LIST_ASO_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &lps_one_count );
208     lps_two_count = 1;
209   }
210
211   if( new_tns->type != LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR and existing_tns->type != LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
212   {
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 );
216
217     while( lasoe_one != NULL and lasoe_two != NULL )
218     {
219       tns_one = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_one );
220       tns_two = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_two );
221
222       cr = 0;
223
224       if( tns_one->extended_node_info.logical_processor.windows_group_number == tns_two->extended_node_info.logical_processor.windows_group_number )
225       {
226         if( tns_one->extended_node_info.logical_processor.number > tns_two->extended_node_info.logical_processor.number )
227           cr = 1;
228
229         if( tns_one->extended_node_info.logical_processor.number < tns_two->extended_node_info.logical_processor.number )
230           cr = -1;
231       }
232
233       if( tns_one->extended_node_info.logical_processor.windows_group_number < tns_two->extended_node_info.logical_processor.windows_group_number )
234           cr = -1;
235
236       if( tns_one->extended_node_info.logical_processor.windows_group_number > tns_two->extended_node_info.logical_processor.windows_group_number )
237           cr = 1;
238
239       if( cr == -1 )
240       {
241         lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
242         if( not_a_set_flag == LOWERED )
243         {
244           not_a_set_compare = -1;
245           not_a_set_flag = RAISED;
246         }
247       }
248
249       if( cr == 1 )
250       {
251         lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
252         if( not_a_set_flag == LOWERED )
253         {
254           not_a_set_compare = 1;
255           not_a_set_flag = RAISED;
256         }
257       }
258
259       if( cr == 0 )
260       {
261         shared_count++;
262         lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
263         lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
264       }
265     }
266
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 );
269   }
270
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;
274
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;
278
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;
282
283   // TRD : otherwise, we're LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET, which is the default value
284
285   switch( st )
286   {
287     case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUBSET:
288       rv = -1;
289     break;
290
291     case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SET:
292       rv = libbenchmark_topology_node_compare_node_types_function( new_tns, existing_tns );
293     break;
294
295     case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUPERSET:
296       rv = 1;
297     break;
298
299     case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET:
300       rv = not_a_set_compare;
301     break;
302   }
303
304   return rv;
305 }
306
307
308
309
310
311 /****************************************************************************/
312 int libbenchmark_topology_node_compare_node_types_function( void const *new_key, void const *existing_key )
313 {
314   int
315     rv = 0;
316
317   struct libbenchmark_topology_node_state
318     *new_tns,
319     *existing_tns;
320
321   LFDS710_PAL_ASSERT( new_key != NULL );
322   LFDS710_PAL_ASSERT( existing_key != NULL );
323
324   new_tns = (struct libbenchmark_topology_node_state *) new_key;
325   existing_tns = (struct libbenchmark_topology_node_state *) existing_key;
326
327   if( new_tns->type < existing_tns->type )
328     return -1;
329
330   if( new_tns->type > existing_tns->type )
331     return 1;
332
333   if( new_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_CACHE and existing_tns->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_CACHE )
334   {
335     if( new_tns->extended_node_info.cache.level > existing_tns->extended_node_info.cache.level )
336       rv = 1;
337
338     if( new_tns->extended_node_info.cache.level < existing_tns->extended_node_info.cache.level )
339       rv = -1;
340
341     if( new_tns->extended_node_info.cache.level == existing_tns->extended_node_info.cache.level )
342     {
343       if( new_tns->extended_node_info.cache.type > existing_tns->extended_node_info.cache.type )
344         rv = 1;
345
346       if( new_tns->extended_node_info.cache.type < existing_tns->extended_node_info.cache.type )
347         rv = -1;
348     }
349   }
350
351   return rv;
352 }
353
354
355
356
357
358 /****************************************************************************/
359 int libbenchmark_topology_node_compare_lpsets_function( struct lfds710_list_aso_state *lpset_one, struct lfds710_list_aso_state *lpset_two )
360 {
361   enum flag
362     not_a_set_flag = LOWERED;
363
364   enum libbenchmark_topology_node_set_type
365     st = LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET;
366
367   int
368     cr = 0,
369     rv = 0,
370     not_a_set_compare = 0;
371
372   lfds710_pal_uint_t
373     lps_one_count,
374     lps_two_count,
375     shared_count = 0;
376
377   struct lfds710_list_aso_element
378     *lasoe_one,
379     *lasoe_two;
380
381   struct libbenchmark_topology_node_state
382     *tns_one,
383     *tns_two;
384
385   LFDS710_PAL_ASSERT( lpset_one != NULL );
386   LFDS710_PAL_ASSERT( lpset_two != NULL );
387
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
391            and yet - !
392            I cannot factorize the code with the general topology node compare function
393            ahhhhhhh
394            this function is used only by the compare function in the results API
395   */
396
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 );
400
401   while( lasoe_one != NULL and lasoe_two != NULL )
402   {
403     tns_one = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_one );
404     tns_two = LFDS710_LIST_ASO_GET_VALUE_FROM_ELEMENT( *lasoe_two );
405
406     cr = 0;
407
408     if( tns_one->extended_node_info.logical_processor.windows_group_number == tns_two->extended_node_info.logical_processor.windows_group_number )
409     {
410       if( tns_one->extended_node_info.logical_processor.number > tns_two->extended_node_info.logical_processor.number )
411         cr = 1;
412
413       if( tns_one->extended_node_info.logical_processor.number < tns_two->extended_node_info.logical_processor.number )
414         cr = -1;
415     }
416
417     if( tns_one->extended_node_info.logical_processor.windows_group_number < tns_two->extended_node_info.logical_processor.windows_group_number )
418         cr = -1;
419
420     if( tns_one->extended_node_info.logical_processor.windows_group_number > tns_two->extended_node_info.logical_processor.windows_group_number )
421         cr = 1;
422
423     if( cr == -1 )
424     {
425       lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
426       if( not_a_set_flag == LOWERED )
427       {
428         not_a_set_compare = -1;
429         not_a_set_flag = RAISED;
430       }
431     }
432
433     if( cr == 1 )
434     {
435       lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
436       if( not_a_set_flag == LOWERED )
437       {
438         not_a_set_compare = 1;
439         not_a_set_flag = RAISED;
440       }
441     }
442
443     if( cr == 0 )
444     {
445       shared_count++;
446       lasoe_one = LFDS710_LIST_ASO_GET_NEXT( *lasoe_one );
447       lasoe_two = LFDS710_LIST_ASO_GET_NEXT( *lasoe_two );
448     }
449   }
450
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 );
453
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;
457
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;
461
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;
465
466   switch( st )
467   {
468     case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUBSET:
469       rv = -1;
470     break;
471
472     case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SET:
473       rv = 0;
474     break;
475
476     case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_SUPERSET:
477       rv = 1;
478     break;
479
480     case LIBBENCHMARK_TOPOLOGY_NODE_SET_TYPE_NOT_A_SET:
481       rv = not_a_set_compare;
482     break;
483   }
484
485   return rv;
486 }
487