Skip to content

Commit 31bd148

Browse files
authored
Merge pull request #603 from bgoglin/generic-infos
generic hwloc_infos structure and API * store array+count of info attributes in a new hwloc_infos structure, use that everywhere in the API (object info, cpukind info, internally, etc) * add hwloc_modify_infos() for a clean/flexible/official way to modify these infos * improve tests and hwloc-annotate.
2 parents 37b590b + 6acac76 commit 31bd148

38 files changed

+829
-494
lines changed

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ Version 3.0.0
3434
or "Memory" (for Linux DAX and CXL devices, etc).
3535
+ The "Backend" info attribute of OS devices is now in the topology
3636
root object together with other backends.
37+
+ The array and count of info attributes are now embedded in the new
38+
struct hwloc_infos_s.
39+
- hwloc_infos_s structures may be modified with hwloc_modify_infos().
40+
- hwloc_cpukinds_get_info() and hwloc_cpukinds_register() now manipulate
41+
infos as such a structure.
3742
* Tools
3843
+ lstopo has a new --osf option to tune the displaying of object
3944
attributes and units.

doc/Makefile.am

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,14 @@ man3_object_info_attrsdir = $(man3dir)
349349
man3_object_info_attrs_DATA = \
350350
$(DOX_MAN_DIR)/man3/hwlocality_info_attr.3 \
351351
$(DOX_MAN_DIR)/man3/hwloc_obj_get_info_by_name.3 \
352-
$(DOX_MAN_DIR)/man3/hwloc_obj_add_info.3
352+
$(DOX_MAN_DIR)/man3/hwloc_get_info_by_name.3 \
353+
$(DOX_MAN_DIR)/man3/hwloc_obj_add_info.3 \
354+
$(DOX_MAN_DIR)/man3/hwloc_modify_infos.3 \
355+
$(DOX_MAN_DIR)/man3/hwloc_modify_infos_op_e.3 \
356+
$(DOX_MAN_DIR)/man3/HWLOC_MODIFY_INFOS_OP_ADD.3 \
357+
$(DOX_MAN_DIR)/man3/HWLOC_MODIFY_INFOS_OP_ADD_UNIQUE.3 \
358+
$(DOX_MAN_DIR)/man3/HWLOC_MODIFY_INFOS_OP_REPLACE.3 \
359+
$(DOX_MAN_DIR)/man3/HWLOC_MODIFY_INFOS_OP_REMOVE.3
353360

354361
man3_cpubindingdir = $(man3dir)
355362
man3_cpubinding_DATA = \

doc/hwloc.doxy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,7 @@ Each object contains a list of such pairs that may be consulted
19701970
manually (looking at the object <tt>infos</tt> array field)
19711971
or using the hwloc_obj_get_info_by_name().
19721972
The user may additionally add new name-value pairs to any object using
1973-
hwloc_obj_add_info() or the \ref cli_hwloc_annotate program.
1973+
hwloc_obj_add_info(), hwloc_modify_infos() or the \ref cli_hwloc_annotate program.
19741974

19751975
Here is a non-exhaustive list of attributes that may be automatically
19761976
added by hwloc.
@@ -3970,7 +3970,7 @@ and <tt>hwloc_topology_set_userdata_import_callback()</tt>.
39703970
Each object may also contain some <em>info</em> attributes
39713971
(name and value strings) that are setup by hwloc during discovery
39723972
and that may be extended by the user with
3973-
<tt>hwloc_obj_add_info()</tt> (see also \ref attributes).
3973+
<tt>hwloc_obj_add_info()</tt> or <tt>hwloc_modify_infos()</tt> (see also \ref attributes).
39743974
Contrary to the <tt>userdata</tt> field which is unique, multiple info
39753975
attributes may exist for each object, even with the same name.
39763976
These attributes are always exported to XML.

hwloc/cpukinds.c

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright © 2020-2022 Inria. All rights reserved.
2+
* Copyright © 2020-2023 Inria. All rights reserved.
33
* See COPYING in top-level directory.
44
*/
55

@@ -28,7 +28,7 @@ hwloc_internal_cpukinds_destroy(struct hwloc_topology *topology)
2828
for(i=0; i<topology->nr_cpukinds; i++) {
2929
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
3030
hwloc_bitmap_free(kind->cpuset);
31-
hwloc__free_infos(kind->infos, kind->nr_infos);
31+
hwloc__free_infos(&kind->infos);
3232
}
3333
free(topology->cpukinds);
3434
topology->cpukinds = NULL;
@@ -59,8 +59,8 @@ hwloc_internal_cpukinds_dup(hwloc_topology_t new, hwloc_topology_t old)
5959
goto failed;
6060
}
6161
if (hwloc__tma_dup_infos(tma,
62-
&kinds[i].infos, &kinds[i].nr_infos,
63-
old->cpukinds[i].infos, old->cpukinds[i].nr_infos) < 0) {
62+
&kinds[i].infos,
63+
&old->cpukinds[i].infos) < 0) {
6464
assert(!tma || !tma->dontfree); /* this tma cannot fail to allocate */
6565
hwloc_bitmap_free(kinds[i].cpuset);
6666
new->nr_cpukinds = i;
@@ -85,7 +85,7 @@ hwloc_internal_cpukinds_restrict(hwloc_topology_t topology)
8585
hwloc_bitmap_and(kind->cpuset, kind->cpuset, hwloc_get_root_obj(topology)->cpuset);
8686
if (hwloc_bitmap_iszero(kind->cpuset)) {
8787
hwloc_bitmap_free(kind->cpuset);
88-
hwloc__free_infos(kind->infos, kind->nr_infos);
88+
hwloc__free_infos(&kind->infos);
8989
memmove(kind, kind+1, (topology->nr_cpukinds - i - 1)*sizeof(*kind));
9090
i--;
9191
topology->nr_cpukinds--;
@@ -106,29 +106,29 @@ hwloc__cpukind_check_duplicate_info(struct hwloc_internal_cpukind_s *kind,
106106
const char *name, const char *value)
107107
{
108108
unsigned i;
109-
for(i=0; i<kind->nr_infos; i++)
110-
if (!strcmp(kind->infos[i].name, name)
111-
&& !strcmp(kind->infos[i].value, value))
109+
for(i=0; i<kind->infos.count; i++)
110+
if (!strcmp(kind->infos.array[i].name, name)
111+
&& !strcmp(kind->infos.array[i].value, value))
112112
return 1;
113113
return 0;
114114
}
115115

116116
static __hwloc_inline void
117117
hwloc__cpukind_add_infos(struct hwloc_internal_cpukind_s *kind,
118-
const struct hwloc_info_s *infos, unsigned nr_infos)
118+
const struct hwloc_infos_s *infos)
119119
{
120120
unsigned i;
121-
for(i=0; i<nr_infos; i++) {
122-
if (hwloc__cpukind_check_duplicate_info(kind, infos[i].name, infos[i].value))
121+
for(i=0; i<infos->count; i++) {
122+
if (hwloc__cpukind_check_duplicate_info(kind, infos->array[i].name, infos->array[i].value))
123123
continue;
124-
hwloc__add_info(&kind->infos, &kind->nr_infos, infos[i].name, infos[i].value);
124+
hwloc__add_info(&kind->infos, infos->array[i].name, infos->array[i].value);
125125
}
126126
}
127127

128128
int
129129
hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
130130
int forced_efficiency,
131-
const struct hwloc_info_s *infos, unsigned nr_infos,
131+
const struct hwloc_infos_s *infos,
132132
unsigned long flags)
133133
{
134134
struct hwloc_internal_cpukind_s *kinds;
@@ -184,8 +184,9 @@ hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuse
184184
kinds[newnr].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
185185
kinds[newnr].forced_efficiency = forced_efficiency;
186186
hwloc_bitmap_and(kinds[newnr].cpuset, cpuset, kinds[i].cpuset);
187-
hwloc__cpukind_add_infos(&kinds[newnr], kinds[i].infos, kinds[i].nr_infos);
188-
hwloc__cpukind_add_infos(&kinds[newnr], infos, nr_infos);
187+
hwloc__cpukind_add_infos(&kinds[newnr], &kinds[i].infos);
188+
if (infos)
189+
hwloc__cpukind_add_infos(&kinds[newnr], infos);
189190
/* remove cpuset PUs from the existing kind that we just split */
190191
hwloc_bitmap_andnot(kinds[i].cpuset, kinds[i].cpuset, kinds[newnr].cpuset);
191192
/* clear cpuset PUs that were taken care of */
@@ -196,7 +197,8 @@ hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuse
196197
} else if (res == HWLOC_BITMAP_CONTAINS
197198
|| res == HWLOC_BITMAP_EQUAL) {
198199
/* append new info to existing smaller (or equal) kind */
199-
hwloc__cpukind_add_infos(&kinds[i], infos, nr_infos);
200+
if (infos)
201+
hwloc__cpukind_add_infos(&kinds[i], infos);
200202
if ((flags & HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY)
201203
|| kinds[i].forced_efficiency == HWLOC_CPUKIND_EFFICIENCY_UNKNOWN)
202204
kinds[i].forced_efficiency = forced_efficiency;
@@ -218,7 +220,8 @@ hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuse
218220
kinds[newnr].cpuset = cpuset;
219221
kinds[newnr].efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
220222
kinds[newnr].forced_efficiency = forced_efficiency;
221-
hwloc__cpukind_add_infos(&kinds[newnr], infos, nr_infos);
223+
if (infos)
224+
hwloc__cpukind_add_infos(&kinds[newnr], infos);
222225
newnr++;
223226
} else {
224227
hwloc_bitmap_free(cpuset);
@@ -231,7 +234,7 @@ hwloc_internal_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t cpuse
231234
int
232235
hwloc_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t _cpuset,
233236
int forced_efficiency,
234-
unsigned nr_infos, struct hwloc_info_s *infos,
237+
struct hwloc_infos_s *infos,
235238
unsigned long flags)
236239
{
237240
hwloc_bitmap_t cpuset;
@@ -254,7 +257,7 @@ hwloc_cpukinds_register(hwloc_topology_t topology, hwloc_cpuset_t _cpuset,
254257
if (forced_efficiency < 0)
255258
forced_efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
256259

257-
err = hwloc_internal_cpukinds_register(topology, cpuset, forced_efficiency, infos, nr_infos, HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY);
260+
err = hwloc_internal_cpukinds_register(topology, cpuset, forced_efficiency, infos, HWLOC_CPUKINDS_REGISTER_FLAG_OVERWRITE_FORCED_EFFICIENCY);
258261
if (err < 0)
259262
return err;
260263

@@ -317,8 +320,8 @@ hwloc__cpukinds_summarize_info(struct hwloc_topology *topology,
317320

318321
for(i=0; i<topology->nr_cpukinds; i++) {
319322
struct hwloc_internal_cpukind_s *kind = &topology->cpukinds[i];
320-
for(j=0; j<kind->nr_infos; j++) {
321-
struct hwloc_info_s *info = &kind->infos[j];
323+
for(j=0; j<kind->infos.count; j++) {
324+
struct hwloc_info_s *info = &kind->infos.array[j];
322325
if (!strcmp(info->name, "FrequencyMaxMHz")) {
323326
summary->summaries[i].max_freq = atoi(info->value);
324327
} else if (!strcmp(info->name, "FrequencyBaseMHz")) {
@@ -598,7 +601,7 @@ hwloc_cpukinds_get_info(hwloc_topology_t topology,
598601
unsigned id,
599602
hwloc_bitmap_t cpuset,
600603
int *efficiencyp,
601-
unsigned *nr_infosp, struct hwloc_info_s **infosp,
604+
struct hwloc_infos_s **infosp,
602605
unsigned long flags)
603606
{
604607
struct hwloc_internal_cpukind_s *kind;
@@ -621,10 +624,8 @@ hwloc_cpukinds_get_info(hwloc_topology_t topology,
621624
if (efficiencyp)
622625
*efficiencyp = kind->efficiency;
623626

624-
if (nr_infosp && infosp) {
625-
*nr_infosp = kind->nr_infos;
626-
*infosp = kind->infos;
627-
}
627+
if (infosp)
628+
*infosp = &kind->infos;
628629
return 0;
629630
}
630631

hwloc/diff.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,10 @@ hwloc_diff_trees(hwloc_topology_t topo1, hwloc_obj_t obj1,
212212
}
213213

214214
/* infos */
215-
if (obj1->infos_count != obj2->infos_count)
215+
if (obj1->infos.count != obj2->infos.count)
216216
goto out_too_complex;
217-
for(i=0; i<obj1->infos_count; i++) {
218-
struct hwloc_info_s *info1 = &obj1->infos[i], *info2 = &obj2->infos[i];
217+
for(i=0; i<obj1->infos.count; i++) {
218+
struct hwloc_info_s *info1 = &obj1->infos.array[i], *info2 = &obj2->infos.array[i];
219219
if (strcmp(info1->name, info2->name))
220220
goto out_too_complex;
221221
if (strcmp(info1->value, info2->value)) {
@@ -424,10 +424,10 @@ int hwloc_topology_diff_build(hwloc_topology_t topo1,
424424
|| ic1->efficiency != ic2->efficiency
425425
|| ic1->forced_efficiency != ic2->forced_efficiency
426426
|| ic1->ranking_value != ic2->ranking_value
427-
|| ic1->nr_infos != ic2->nr_infos)
427+
|| ic1->infos.count != ic2->infos.count)
428428
goto roottoocomplex;
429-
for(j=0; j<ic1->nr_infos; j++) {
430-
struct hwloc_info_s *info1 = &ic1->infos[j], *info2 = &ic2->infos[j];
429+
for(j=0; j<ic1->infos.count; j++) {
430+
struct hwloc_info_s *info1 = &ic1->infos.array[j], *info2 = &ic2->infos.array[j];
431431
if (strcmp(info1->name, info2->name)
432432
|| strcmp(info1->value, info2->value)) {
433433
goto roottoocomplex;
@@ -494,8 +494,8 @@ hwloc_apply_diff_one(hwloc_topology_t topology,
494494
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
495495
unsigned i;
496496
int found = 0;
497-
for(i=0; i<obj->infos_count; i++) {
498-
struct hwloc_info_s *info = &obj->infos[i];
497+
for(i=0; i<obj->infos.count; i++) {
498+
struct hwloc_info_s *info = &obj->infos.array[i];
499499
if (!strcmp(info->name, name)
500500
&& !strcmp(info->value, oldvalue)) {
501501
free(info->value);

hwloc/topology-darwin.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,17 +320,20 @@ static int hwloc__darwin_cpukinds_register(struct hwloc_topology *topology,
320320
int got_efficiency = kinds->nr ? 1 : 0;
321321

322322
for(i=0; i<kinds->nr; i++) {
323+
struct hwloc_infos_s infos;
323324
struct hwloc_info_s infoattr;
324-
unsigned nr_info = 0;
325325
int efficiency;
326326
hwloc_debug_2args_bitmap("building cpukind with perflevel %u compatible `%s' and cpuset %s\n",
327327
kinds->kinds[i].perflevel,
328328
kinds->kinds[i].compatible,
329329
kinds->kinds[i].cpuset);
330+
infos.count = 0;
330331
if (kinds->kinds[i].compatible) {
331332
infoattr.name = (char *) "DarwinCompatible";
332333
infoattr.value = kinds->kinds[i].compatible;
333-
nr_info = 1;
334+
infos.array = &infoattr;
335+
infos.count = 1;
336+
infos.allocated = 0;
334337
}
335338
if (kinds->kinds[i].perflevel >= 0) {
336339
/* perflevel0 always refers to the highest performance core type in the system. */
@@ -339,7 +342,7 @@ static int hwloc__darwin_cpukinds_register(struct hwloc_topology *topology,
339342
efficiency = HWLOC_CPUKIND_EFFICIENCY_UNKNOWN;
340343
got_efficiency = 0;
341344
}
342-
hwloc_internal_cpukinds_register(topology, kinds->kinds[i].cpuset, efficiency, &infoattr, nr_info, 0);
345+
hwloc_internal_cpukinds_register(topology, kinds->kinds[i].cpuset, efficiency, &infos, 0);
343346
free(kinds->kinds[i].compatible);
344347
/* the cpuset is given to the callee */
345348
}

0 commit comments

Comments
 (0)