Skip to content

Commit 56386eb

Browse files
committed
core: add an "allocated" private field in struct hwloc_infos_s
To properly preallocate the array when adding elements. Signed-off-by: Brice Goglin <[email protected]>
1 parent 669a1c0 commit 56386eb

File tree

8 files changed

+61
-26
lines changed

8 files changed

+61
-26
lines changed

hwloc/topology-darwin.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ static int hwloc__darwin_cpukinds_register(struct hwloc_topology *topology,
333333
infoattr.value = kinds->kinds[i].compatible;
334334
infos.array = &infoattr;
335335
infos.count = 1;
336+
infos.allocated = 0;
336337
}
337338
if (kinds->kinds[i].perflevel >= 0) {
338339
/* perflevel0 always refers to the highest performance core type in the system. */

hwloc/topology-linux.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4434,6 +4434,7 @@ hwloc_linux_cpukinds_register(struct hwloc_linux_cpukinds *cpukinds,
44344434
infoattr.value = value;
44354435
infos.array = &infoattr;
44364436
infos.count = 1;
4437+
infos.allocated = 0;
44374438
snprintf(value, sizeof(value), "%lu", cpukinds->sets[i].value);
44384439
/* value (at least cpu_capacity) may be > INT_MAX, too large for a forced_efficiency, hence use i instead */
44394440
hwloc_internal_cpukinds_register(topology, cpukinds->sets[i].cpuset,
@@ -4624,6 +4625,7 @@ look_sysfscpukinds(struct hwloc_topology *topology,
46244625
infoattr.value = (char *) "IntelAtom";
46254626
infos.array = &infoattr;
46264627
infos.count = 1;
4628+
infos.allocated = 0;
46274629
hwloc_internal_cpukinds_register(topology, atom_pmu_set, HWLOC_CPUKIND_EFFICIENCY_UNKNOWN, &infos, 0);
46284630
/* the cpuset is given to the callee */
46294631
} else {
@@ -4636,6 +4638,7 @@ look_sysfscpukinds(struct hwloc_topology *topology,
46364638
infoattr.value = (char *) "IntelCore";
46374639
infos.array = &infoattr;
46384640
infos.count = 1;
4641+
infos.allocated = 0;
46394642
hwloc_internal_cpukinds_register(topology, core_pmu_set, HWLOC_CPUKIND_EFFICIENCY_UNKNOWN, &infos, 0);
46404643
/* the cpuset is given to the callee */
46414644
} else {
@@ -5394,6 +5397,7 @@ hwloc_linux_parse_cpuinfo(struct hwloc_linux_backend_data_s *data,
53945397
Lprocs[curproc].Pproc = Pproc;
53955398
Lprocs[curproc].infos.array = NULL;
53965399
Lprocs[curproc].infos.count = 0;
5400+
Lprocs[curproc].infos.allocated = 0;
53975401
getprocnb_end() else {
53985402

53995403
/* architecture specific or default routine for parsing cpumodel */
@@ -5780,6 +5784,7 @@ hwloc_linuxfs_look_cpu(struct hwloc_backend *backend, struct hwloc_disc_status *
57805784
*/
57815785
global_infos.array = NULL;
57825786
global_infos.count = 0;
5787+
global_infos.allocated = 0;
57835788
numprocs = hwloc_linux_parse_cpuinfo(data, "/proc/cpuinfo", &Lprocs, &global_infos);
57845789
if (numprocs < 0)
57855790
numprocs = 0;
@@ -6915,6 +6920,7 @@ hwloc__get_firmware_dmi_memory_info_one(struct hwloc_topology *topology,
69156920

69166921
infos.array = NULL;
69176922
infos.count = 0;
6923+
infos.allocated = 0;
69186924

69196925
/* start after the header */
69206926
foff = header->length;

hwloc/topology-x86.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,7 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long
14421442
infoattr.value = (char *) "IntelAtom";
14431443
_infos.array = &infoattr;
14441444
_infos.count = 1;
1445+
_infos.allocated = 0;
14451446
hwloc_internal_cpukinds_register(topology, atomset, HWLOC_CPUKIND_EFFICIENCY_UNKNOWN, &_infos, 0);
14461447
/* the cpuset is given to the callee */
14471448
} else {
@@ -1455,6 +1456,7 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, unsigned long
14551456
infoattr.value = (char *) "IntelCore";
14561457
_infos.array = &infoattr;
14571458
_infos.count = 1;
1459+
_infos.allocated = 0;
14581460
hwloc_internal_cpukinds_register(topology, coreset, HWLOC_CPUKIND_EFFICIENCY_UNKNOWN, &_infos, 0);
14591461
/* the cpuset is given to the callee */
14601462
} else {

hwloc/topology-xml.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,7 @@ hwloc__xml_import_cpukind(hwloc_topology_t topology,
14641464

14651465
infos.array = NULL;
14661466
infos.count = 0;
1467+
infos.allocated = 0;
14671468

14681469
while (1) {
14691470
char *attrname, *attrvalue;

hwloc/topology.c

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -471,20 +471,37 @@ void hwloc__free_infos(struct hwloc_infos_s *infos)
471471
free(infos->array);
472472
}
473473

474-
int hwloc__add_info(struct hwloc_infos_s *infos, const char *name, const char *value)
474+
static int hwloc__realloc_infos(struct hwloc_infos_s *infos, unsigned nr)
475475
{
476-
unsigned count = infos->count;
477-
struct hwloc_info_s *array = infos->array;
476+
struct hwloc_info_s *tmparray;
477+
unsigned alloccount;
478+
479+
if (infos->allocated > infos->count + nr)
480+
return 0;
481+
478482
#define OBJECT_INFO_ALLOC 8
479483
/* nothing allocated initially, (re-)allocate by multiple of 8 */
480-
unsigned alloccount = (count + 1 + (OBJECT_INFO_ALLOC-1)) & ~(OBJECT_INFO_ALLOC-1);
481-
if (count != alloccount) {
482-
struct hwloc_info_s *tmparray = realloc(array, alloccount*sizeof(*array));
483-
if (!tmparray)
484-
/* failed to allocate, ignore this info */
485-
goto out_with_array;
486-
infos->array = array = tmparray;
487-
}
484+
alloccount = (infos->count + nr + (OBJECT_INFO_ALLOC-1)) & ~(OBJECT_INFO_ALLOC-1);
485+
tmparray = realloc(infos->array, alloccount*sizeof(*tmparray));
486+
if (!tmparray)
487+
return -1;
488+
489+
infos->array = tmparray;
490+
infos->allocated = alloccount;
491+
return 0;
492+
}
493+
494+
int hwloc__add_info(struct hwloc_infos_s *infos, const char *name, const char *value)
495+
{
496+
unsigned count;
497+
struct hwloc_info_s *array;
498+
499+
if (hwloc__realloc_infos(infos, 1) < 0)
500+
return -1;
501+
502+
count = infos->count;
503+
array = infos->array;
504+
488505
array[count].name = strdup(name);
489506
if (!array[count].name)
490507
goto out_with_array;
@@ -526,21 +543,19 @@ int hwloc__add_info_nodup(struct hwloc_infos_s *infos,
526543
int hwloc__move_infos(struct hwloc_infos_s *dst_infos,
527544
struct hwloc_infos_s *src_infos)
528545
{
529-
unsigned dst_count = dst_infos->count;
530-
struct hwloc_info_s *dst_array = dst_infos->array;
531-
unsigned src_count = src_infos->count;
532-
struct hwloc_info_s *src_array = src_infos->array;
546+
struct hwloc_info_s *dst_array, *src_array;
547+
unsigned dst_count, src_count;
533548
unsigned i;
534-
#define OBJECT_INFO_ALLOC 8
535-
/* nothing allocated initially, (re-)allocate by multiple of 8 */
536-
unsigned alloccount = (dst_count + src_count + (OBJECT_INFO_ALLOC-1)) & ~(OBJECT_INFO_ALLOC-1);
537-
if (dst_count != alloccount) {
538-
struct hwloc_info_s *tmp_array = realloc(dst_array, alloccount*sizeof(*dst_array));
539-
if (!tmp_array)
540-
/* Failed to realloc, ignore the appended infos */
541-
goto drop;
542-
dst_array = tmp_array;
543-
}
549+
550+
src_count = src_infos->count;
551+
src_array = src_infos->array;
552+
553+
if (hwloc__realloc_infos(dst_infos, src_count) < 0)
554+
goto drop;
555+
556+
dst_count = dst_infos->count;
557+
dst_array = dst_infos->array;
558+
544559
for(i=0; i<src_count; i++, dst_count++) {
545560
dst_array[dst_count].name = src_array[i].name;
546561
dst_array[dst_count].value = src_array[i].value;
@@ -561,6 +576,7 @@ int hwloc__move_infos(struct hwloc_infos_s *dst_infos,
561576
free(src_array);
562577
src_infos->array = NULL;
563578
src_infos->count = 0;
579+
src_infos->allocated = 0;
564580
return -1;
565581
}
566582

@@ -576,7 +592,7 @@ int hwloc__tma_dup_infos(struct hwloc_tma *tma,
576592
{
577593
struct hwloc_info_s *newa;
578594
unsigned i, j;
579-
newa = hwloc_tma_calloc(tma, oldi->count * sizeof(*newa));
595+
newa = hwloc_tma_calloc(tma, oldi->allocated * sizeof(*newa));
580596
if (!newa)
581597
return -1;
582598
for(i=0; i<oldi->count; i++) {
@@ -587,6 +603,7 @@ int hwloc__tma_dup_infos(struct hwloc_tma *tma,
587603
}
588604
newi->array = newa;
589605
newi->count = oldi->count;
606+
newi->allocated = oldi->allocated;
590607
return 0;
591608

592609
failed:
@@ -597,6 +614,7 @@ int hwloc__tma_dup_infos(struct hwloc_tma *tma,
597614
}
598615
newi->array = NULL;
599616
newi->count = 0;
617+
newi->allocated = 0;
600618
return -1;
601619
}
602620

include/hwloc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ struct hwloc_info_s {
433433
struct hwloc_infos_s {
434434
struct hwloc_info_s *array; /**< \brief Array of string pairs */
435435
unsigned count; /**< \brief Number of elements in the array. */
436+
unsigned allocated; /**< \private Internal use only (number of allocated elements in the array). */
436437
};
437438

438439
/** \brief Structure of a topology object

tests/hwloc/cpukinds.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ int main(void)
9191
info.value = (char*) "BigCore";
9292
infos.array = &info;
9393
infos.count = 1;
94+
infos.allocated = 0;
9495
err = hwloc_cpukinds_register(topology, cpuset, 1000, &infos, 0);
9596
assert(!err);
9697
/* PU 6-9 (third package) are small and less efficient */
@@ -100,6 +101,7 @@ int main(void)
100101
info.value = (char*) "SmallCore";
101102
infos.array = &info;
102103
infos.count = 1;
104+
infos.allocated = 0;
103105
err = hwloc_cpukinds_register(topology, cpuset, 10, &infos, 0);
104106
assert(!err);
105107

@@ -165,6 +167,7 @@ int main(void)
165167
info.value = (char*) "this, that and those";
166168
infos.array = &info;
167169
infos.count = 1;
170+
infos.allocated = 0;
168171
err = hwloc_cpukinds_register(topology, cpuset, -1, &infos, 0);
169172
assert(!err);
170173

utils/hwloc/hwloc-annotate.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ static void apply(hwloc_topology_t topology, hwloc_obj_t obj)
9292
free(obj->infos.array);
9393
obj->infos.array = NULL;
9494
obj->infos.count = 0;
95+
obj->infos.allocated = 0;
9596
}
9697
if (clearuserdata) {
9798
hwloc_utils_userdata_free(obj);
@@ -119,6 +120,7 @@ static void apply(hwloc_topology_t topology, hwloc_obj_t obj)
119120
if (!j) {
120121
free(obj->infos.array);
121122
obj->infos.array = NULL;
123+
obj->infos.allocated = 0;
122124
}
123125
}
124126
if (infovalue)
@@ -774,6 +776,7 @@ int main(int argc, char *argv[])
774776
info.value = ckivalue;
775777
infos.count = 1;
776778
infos.array = &info;
779+
infos.allocated = 0;
777780
if (hwloc_cpukinds_register(topology, ckcpuset, ckefficiency,
778781
ckiname ? &infos : NULL,
779782
ckflags) < 0) {

0 commit comments

Comments
 (0)