]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/test_and_benchmark/libbenchmark/src/libbenchmark_topology/libbenchmark_topology_lpsets.c
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / test_and_benchmark / libbenchmark / src / libbenchmark_topology / libbenchmark_topology_lpsets.c
1 /***** includes *****/
2 #include "libbenchmark_topology_internal.h"
3
4 /***** private prototypes *****/
5 static void libbenchmark_topology_internal_generate_thread_set_one_lp_per_lowest_level_cache( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets );
6 static void libbenchmark_topology_internal_generate_thread_set_one_to_all_lps_per_lowest_level_cache( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets );
7 static void libbenchmark_topology_internal_generate_thread_set_all_lps_per_lowest_level_cache( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets );
8 static void libbenchmark_topology_internal_generate_thread_set_all_lps( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets );
9
10
11
12
13
14 /****************************************************************************/
15 void libbenchmark_topology_generate_deduplicated_logical_processor_sets( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets )
16 {
17   int
18     cr;
19
20   struct lfds710_list_asu_element
21     *local_lasue = NULL,
22     *lasue;
23
24   struct lfds710_list_asu_state
25     throw_lp_sets,
26     local_lp_sets;
27
28   struct libbenchmark_topology_logical_processor_set
29     *local_lps,
30     *lps,
31     *new_lps;
32
33   LFDS710_PAL_ASSERT( ts != NULL );
34   LFDS710_PAL_ASSERT( ms != NULL );
35   LFDS710_PAL_ASSERT( lp_sets != NULL );
36
37   lfds710_list_asu_init_valid_on_current_logical_core( &throw_lp_sets, NULL );
38   lfds710_list_asu_init_valid_on_current_logical_core( &local_lp_sets, NULL );
39
40   // TRD : order is a useful hack - we want the full set to come last after deduplication, this order achieves this
41   libbenchmark_topology_internal_generate_thread_set_one_lp_per_lowest_level_cache( ts, ms, &local_lp_sets );
42   libbenchmark_topology_internal_generate_thread_set_all_lps_per_lowest_level_cache( ts, ms, &local_lp_sets );
43   libbenchmark_topology_internal_generate_thread_set_one_to_all_lps_per_lowest_level_cache( ts, ms, &local_lp_sets );
44   libbenchmark_topology_internal_generate_thread_set_all_lps( ts, ms, &throw_lp_sets );
45
46   /*
47
48   while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(local_lp_sets, local_lasue) )
49   {
50     char
51       *lps_string;
52
53     local_lps = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *local_lasue );
54
55     benchmark_topology_construct_benchmark_logical_processor_set_string( t, local_lps, &lps_string );
56     printf( "%s\n", lps_string );
57   }
58
59   exit( 1 );
60
61   */
62
63   /* TRD : now de-duplicate local_lp_sets
64            dumbo algorithm, loop over every value in local_lp_sets
65            and if not present in lp_sets, add to lp_sets
66
67            algorithmically better to sort and then pass over once, removing duplicates
68            however, this is not a coding test - it's real life - and in this case
69            the extra coding work makes no sense at all
70   */
71
72   lfds710_list_asu_init_valid_on_current_logical_core( lp_sets, NULL );
73
74   while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(local_lp_sets, local_lasue) )
75   {
76     local_lps = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *local_lasue );
77
78     cr = !0;
79     lasue = NULL;
80
81     // TRD : exit loop if cr is 0, which means we found the set exists already
82     while( cr != 0 and LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*lp_sets, lasue) )
83     {
84       lps = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
85       cr = libbenchmark_topology_node_compare_lpsets_function( &local_lps->logical_processors, &lps->logical_processors );
86     }
87
88     // TRD : if we did NOT find this set already, then keep it
89     if( cr != 0 )
90     {
91       new_lps = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_logical_processor_set), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
92       new_lps->logical_processors = local_lps->logical_processors;
93       LFDS710_LIST_ASU_SET_VALUE_IN_ELEMENT( new_lps->lasue, new_lps );
94       lfds710_list_asu_insert_at_end( lp_sets, &new_lps->lasue );
95     }
96   }
97
98   lfds710_list_asu_cleanup( &local_lp_sets, NULL );
99
100   return;
101 }
102
103
104
105
106
107 /****************************************************************************/
108 static void libbenchmark_topology_internal_generate_thread_set_one_lp_per_lowest_level_cache( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets )
109 {
110   lfds710_pal_uint_t
111     loop,
112     lowest_level_type_count = 0,
113     lps_count;
114
115   struct lfds710_btree_au_element
116     *be = NULL,
117     *be_llc = NULL,
118     *be_lp = NULL;
119
120   struct libbenchmark_topology_logical_processor_set
121     *lps;
122
123   struct libbenchmark_topology_node_state
124     *new_tns,
125     *node = NULL,
126     *node_llc = NULL,
127     *node_lp = NULL;
128
129   LFDS710_PAL_ASSERT( ts != NULL );
130   LFDS710_PAL_ASSERT( ms != NULL );
131   LFDS710_PAL_ASSERT( lp_sets != NULL );
132
133   /* TRD : we find the lowest level cache type
134            there are a certain number of these caches in the system
135            each will service a certain number of logical processors
136
137            we create one thread set per lowest level cache type,
138            with the the first thread set having only the first lowest
139            level cache and following sets adding one more lowest level
140            cache at a time, until the final thread set has all the
141            lowest level caches; for each lowest level cache in a thread set,
142            that thread set has the first logical processor of each lowest
143            level cache
144   */
145
146   // TRD : find lowest level memory, bus or cache
147   while( lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be_llc, LFDS710_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
148   {
149     node_llc = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be_llc );
150
151     if( node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_SYSTEM or node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_NUMA or node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_CACHE )
152       break;
153   }
154
155   // TRD : count the number of the lowest level type
156   while( lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be, LFDS710_BTREE_AU_ABSOLUTE_POSITION_LARGEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE) )
157   {
158     node = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be );
159
160     if( 0 == libbenchmark_topology_node_compare_node_types_function(node, node_llc) )
161       lowest_level_type_count++;
162   }
163
164   // TRD : create the thread sets
165   for( loop = 0 ; loop < lowest_level_type_count ; loop++ )
166   {
167     /* TRD : find the first 0 to (loop+1) lowest level types
168              add the smallest LP under that type to the thread set
169     */
170
171     lps = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_logical_processor_set), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
172     lfds710_list_aso_init_valid_on_current_logical_core( &lps->logical_processors, libbenchmark_topology_node_compare_nodes_function, LFDS710_LIST_ASO_INSERT_RESULT_FAILURE_EXISTING_KEY, NULL );
173     lps_count = 0;
174     be = NULL;
175
176     while( lps_count < loop+1 and lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be, LFDS710_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
177     {
178       node = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be );
179
180       // TRD : if we've found a lowest level type...
181       if( 0 == libbenchmark_topology_node_compare_node_types_function(node, node_llc) )
182       {
183         // TRD : now use a temp copy of be and go LARGEST_TO_SMALLEST until we find an LP
184         be_lp = be;
185
186         while( lfds710_btree_au_get_by_relative_position(&be_lp, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE) )
187         {
188           node_lp = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be_lp );
189
190           if( node_lp->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
191             break;
192         }
193
194         // TRD : now add LP
195         new_tns = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_node_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
196         *new_tns = *node_lp;
197         LFDS710_LIST_ASO_SET_KEY_IN_ELEMENT( new_tns->lasoe, new_tns );
198         LFDS710_LIST_ASO_SET_VALUE_IN_ELEMENT( new_tns->lasoe, new_tns );
199         lfds710_list_aso_insert( &lps->logical_processors, &new_tns->lasoe, NULL );
200         lps_count++;
201       }
202     }
203
204     LFDS710_LIST_ASU_SET_KEY_IN_ELEMENT( lps->lasue, lps );
205     LFDS710_LIST_ASU_SET_VALUE_IN_ELEMENT( lps->lasue, lps );
206     lfds710_list_asu_insert_at_end( lp_sets, &lps->lasue );
207   }
208
209   return;
210 }
211
212
213
214
215
216 /****************************************************************************/
217 static void libbenchmark_topology_internal_generate_thread_set_one_to_all_lps_per_lowest_level_cache( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets )
218 {
219   lfds710_pal_uint_t
220     loop,
221     lowest_level_type_count = 0,
222     lp_per_llc = 0,
223     lp_count,
224     lps_count;
225
226   struct lfds710_btree_au_element
227     *be = NULL,
228     *be_llc = NULL,
229     *be_lp = NULL;
230
231   struct libbenchmark_topology_logical_processor_set
232     *lps;
233
234   struct libbenchmark_topology_node_state
235     *new_lp,
236     *node = NULL,
237     *node_llc = NULL,
238     *node_lp = NULL;
239
240   LFDS710_PAL_ASSERT( ts != NULL );
241   LFDS710_PAL_ASSERT( ms != NULL );
242   LFDS710_PAL_ASSERT( lp_sets != NULL );
243
244   /* TRD : we find the lowest level cache type
245            there are a certain number of these caches in the system
246            each will service a certain number of logical processors
247
248            we create one thread set per logical processor under
249            the lowest level type (they will have all have the same
250            number of logical processors)
251
252            each set contains an increasing number of LPs from each
253            lowest level type, e.g. the first set has one LP from
254            each lowest level type, the second has two, enode, until
255          s  all LPs are in use
256   */
257
258   // TRD : find lowest level memory, bus or cache
259   while( lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be_llc, LFDS710_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
260   {
261     node_llc = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be_llc );
262
263     if( node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_SYSTEM or node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_NUMA or node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_CACHE )
264       break;
265   }
266
267   /* TRD : count the number of LPs under the lowest level type
268            since be_llc points at the smallest of the lowest level types
269            we will once we've counted all it's LPs naturally exit the tree
270            since we're walking LFDS710_ADDONLY_UNBALANCED_BTREE_WALK_FROM_LARGEST_TO_SMALLEST
271   */
272   be_lp = be_llc;
273
274   while( lfds710_btree_au_get_by_relative_position(&be_lp, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE) )
275   {
276     node_lp = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be_lp );
277
278     if( node_lp->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
279       lp_per_llc++;
280   }
281
282   // TRD : count the number of the lowest level type
283   while( lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be, LFDS710_BTREE_AU_ABSOLUTE_POSITION_LARGEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE) )
284   {
285     node = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be );
286
287     if( 0 == libbenchmark_topology_node_compare_node_types_function(node, node_llc) )
288       lowest_level_type_count++;
289   }
290
291   // TRD : create the thread sets
292   for( loop = 0 ; loop < lp_per_llc ; loop++ )
293   {
294     /* TRD : visit each lowest level type
295              add from 0 to loop+1 of its LPs to the set
296     */
297
298     lps = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_logical_processor_set), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
299     lfds710_list_aso_init_valid_on_current_logical_core( &lps->logical_processors, libbenchmark_topology_node_compare_nodes_function, LFDS710_LIST_ASO_INSERT_RESULT_FAILURE_EXISTING_KEY, NULL );
300     lps_count = 0;
301
302     be = NULL;
303
304     while( lps_count < lowest_level_type_count*(loop+1) and lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be, LFDS710_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
305     {
306       node = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be );
307
308       // TRD : if we've found a lowest level type...
309       if( 0 == libbenchmark_topology_node_compare_node_types_function(node, node_llc) )
310       {
311         // TRD : now use a temp copy of be and go LARGEST_TO_SMALLEST until we have (loop+1) LPs
312         be_lp = be;
313         lp_count = 0;
314
315         while( lp_count < loop+1 and lfds710_btree_au_get_by_relative_position(&be_lp, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE) )
316         {
317           node_lp = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be_lp );
318
319           if( node_lp->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
320           {
321             new_lp = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_node_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
322             *new_lp = *node_lp;
323             LFDS710_LIST_ASO_SET_KEY_IN_ELEMENT( new_lp->lasoe, new_lp );
324             LFDS710_LIST_ASO_SET_VALUE_IN_ELEMENT( new_lp->lasoe, new_lp );
325             lfds710_list_aso_insert( &lps->logical_processors, &new_lp->lasoe, NULL );
326             lp_count++;
327             lps_count++;
328           }
329         }
330       }
331     }
332
333     LFDS710_LIST_ASU_SET_KEY_IN_ELEMENT( lps->lasue, lps );
334     LFDS710_LIST_ASU_SET_VALUE_IN_ELEMENT( lps->lasue, lps );
335     lfds710_list_asu_insert_at_end( lp_sets, &lps->lasue );
336   }
337
338   return;
339 }
340
341
342
343
344
345 /****************************************************************************/
346 static void libbenchmark_topology_internal_generate_thread_set_all_lps_per_lowest_level_cache( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets )
347 {
348   lfds710_pal_uint_t
349     loop,
350     lowest_level_type_count = 0,
351     lp_per_llc = 0,
352     lps_count;
353
354   struct lfds710_btree_au_element
355     *be = NULL,
356     *be_llc = NULL,
357     *be_lp = NULL;
358
359   struct libbenchmark_topology_logical_processor_set
360     *lps;
361
362   struct libbenchmark_topology_node_state
363     *new_lp,
364     *node = NULL,
365     *node_llc = NULL,
366     *node_lp = NULL;
367
368   LFDS710_PAL_ASSERT( ts != NULL );
369   LFDS710_PAL_ASSERT( ms != NULL );
370   LFDS710_PAL_ASSERT( lp_sets != NULL );
371
372   /* TRD : we find the lowest level cache type
373            there are a certain number of these caches in the system
374            each will service a certain number of logical processors
375
376            each lowest level type has a given number of logical processors
377            (the number is the same for each lowest level type)
378            we create one thread set per lowest level type,
379            where we're adding in full blocks of lowest level type LPs,
380            e.g. the first set has all the LPs of the first lowest level
381            type, the second set has all the LPs of the first and second
382            lowest level types, enode
383   */
384
385   // TRD : find lowest level memory, bus or cache
386   while( lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be_llc, LFDS710_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
387   {
388     node_llc = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be_llc );
389
390     if( node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_SYSTEM or node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_NUMA or node_llc->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_CACHE )
391       break;
392   }
393
394   /* TRD : count the number of LPs under the lowest level type
395            since be_llc points at the smallest of the lowest level types
396            we will once we've counted all it's LPs naturally exit the tree
397            since we're walking LFDS710_ADDONLY_UNBALANCED_BTREE_WALK_FROM_LARGEST_TO_SMALLEST
398   */
399   be_lp = be_llc;
400
401   while( lfds710_btree_au_get_by_relative_position(&be_lp, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE) )
402   {
403     node_lp = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be_lp );
404
405     if( node_lp->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
406       lp_per_llc++;
407   }
408
409   // TRD : count the number of the lowest level type
410   while( lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be, LFDS710_BTREE_AU_ABSOLUTE_POSITION_LARGEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE) )
411   {
412     node = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be );
413
414     if( 0 == libbenchmark_topology_node_compare_node_types_function(node, node_llc) )
415       lowest_level_type_count++;
416   }
417
418   // TRD : create the thread sets
419   for( loop = 0 ; loop < lowest_level_type_count ; loop++ )
420   {
421     /* TRD : find the first 0 to (loop+1) lowest level types
422              add all LPs under those lowest level types to the set
423     */
424
425     lps = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_logical_processor_set), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
426     lfds710_list_aso_init_valid_on_current_logical_core( &lps->logical_processors, libbenchmark_topology_node_compare_nodes_function, LFDS710_LIST_ASO_INSERT_RESULT_FAILURE_EXISTING_KEY, NULL );
427     lps_count = 0;
428     be = NULL;
429
430     while( lps_count < lp_per_llc*(loop+1) and lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be, LFDS710_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
431     {
432       node = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be );
433
434       // TRD : if we've found a lowest level type...
435       if( 0 == libbenchmark_topology_node_compare_node_types_function(node, node_llc) )
436       {
437         // TRD : now use a temp copy of be and go LARGEST_TO_SMALLEST until we exit the tree or find another lowest level type
438         be_lp = be;
439
440         while( lfds710_btree_au_get_by_relative_position(&be_lp, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE) )
441         {
442           node_lp = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be_lp );
443
444           if( node_lp->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
445           {
446             // TRD : now add LP
447             new_lp = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_node_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
448             *new_lp = *node_lp;
449             LFDS710_LIST_ASO_SET_KEY_IN_ELEMENT( new_lp->lasoe, new_lp );
450             LFDS710_LIST_ASO_SET_VALUE_IN_ELEMENT( new_lp->lasoe, new_lp );
451             lfds710_list_aso_insert( &lps->logical_processors, &new_lp->lasoe, NULL );
452             lps_count++;
453           }
454
455           if( node_lp->type == node_llc->type )
456             break;
457         }
458       }
459     }
460
461     LFDS710_LIST_ASU_SET_KEY_IN_ELEMENT( lps->lasue, lps );
462     LFDS710_LIST_ASU_SET_VALUE_IN_ELEMENT( lps->lasue, lps );
463     lfds710_list_asu_insert_at_end( lp_sets, &lps->lasue );
464   }
465
466   return;
467 }
468
469
470
471
472
473 /****************************************************************************/
474 static void libbenchmark_topology_internal_generate_thread_set_all_lps( struct libbenchmark_topology_state *ts, struct libshared_memory_state *ms, struct lfds710_list_asu_state *lp_sets )
475 {
476   struct lfds710_btree_au_element
477     *be = NULL;
478
479   struct libbenchmark_topology_logical_processor_set
480     *lps;
481
482   struct libbenchmark_topology_node_state
483     *new_lp,
484     *node;
485
486   LFDS710_PAL_ASSERT( ts != NULL );
487   LFDS710_PAL_ASSERT( ms != NULL );
488   LFDS710_PAL_ASSERT( lp_sets != NULL );
489
490   lps = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_logical_processor_set), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
491   lfds710_list_aso_init_valid_on_current_logical_core( &lps->logical_processors, libbenchmark_topology_node_compare_nodes_function, LFDS710_LIST_ASO_INSERT_RESULT_FAILURE_EXISTING_KEY, NULL );
492
493   // TRD : iterate over tree - add in every logical processor
494   while( lfds710_btree_au_get_by_absolute_position_and_then_by_relative_position(&ts->topology_tree, &be, LFDS710_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS710_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
495   {
496     node = LFDS710_BTREE_AU_GET_VALUE_FROM_ELEMENT( *be );
497
498     if( node->type == LIBBENCHMARK_TOPOLOGY_NODE_TYPE_LOGICAL_PROCESSOR )
499     {
500       // TRD : now add LP
501       new_lp = libshared_memory_alloc_from_most_free_space_node( ms, sizeof(struct libbenchmark_topology_node_state), LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
502       *new_lp = *node;
503       LFDS710_LIST_ASO_SET_KEY_IN_ELEMENT( new_lp->lasoe, new_lp );
504       LFDS710_LIST_ASO_SET_VALUE_IN_ELEMENT( new_lp->lasoe, new_lp );
505       lfds710_list_aso_insert( &lps->logical_processors, &new_lp->lasoe, NULL );
506     }
507   }
508
509   LFDS710_LIST_ASU_SET_KEY_IN_ELEMENT( lps->lasue, lps );
510   LFDS710_LIST_ASU_SET_VALUE_IN_ELEMENT( lps->lasue, lps );
511   lfds710_list_asu_insert_at_end( lp_sets, &lps->lasue );
512
513   return;
514 }
515