Skip to content

Commit

Permalink
hwloc/linux.h: replace hwloc_parse_cpumap_file() with hwloc_linux_rea…
Browse files Browse the repository at this point in the history
…d_path_as_cpumask()

Take a filename instead of FILE (and internally use open instead of fopen).

Signed-off-by: Brice Goglin <[email protected]>
  • Loading branch information
bgoglin committed Dec 14, 2016
1 parent 32e32fa commit e7f5962
Show file tree
Hide file tree
Showing 11 changed files with 32 additions and 126 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ Version 2.0.0
+ hwloc_obj_cpuset_snprintf() is deprecated in favor of hwloc_bitmap_snprintf().
+ Functions diff_load_xml*(), diff_export_xml*() and diff_destroy() in
hwloc/diff.h do not need a topology as first parameter anymore.
+ hwloc_parse_cpumap_file () superseded by hwloc_linux_read_path_as_cpumask()
in hwloc/linux.h.
* Tools
- lstopo and hwloc-info have a new --filter option matching the new filtering API.
- hwloc-distances was removed and replaced with lstopo --distances.
Expand Down
4 changes: 2 additions & 2 deletions doc/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -695,10 +695,10 @@ man3_glibc_sched_DATA = \
man3_linuxdir = $(man3dir)
man3_linux_DATA = \
$(DOX_MAN_DIR)/man3/hwlocality_linux.3 \
$(DOX_MAN_DIR)/man3/hwloc_linux_parse_cpumap_file.3 \
$(DOX_MAN_DIR)/man3/hwloc_linux_set_tid_cpubind.3 \
$(DOX_MAN_DIR)/man3/hwloc_linux_get_tid_cpubind.3 \
$(DOX_MAN_DIR)/man3/hwloc_linux_get_tid_last_cpu_location.3
$(DOX_MAN_DIR)/man3/hwloc_linux_get_tid_last_cpu_location.3 \
$(DOX_MAN_DIR)/man3/hwloc_linux_read_path_as_cpumask.3

man3_linux_libnumadir = $(man3dir)
man3_linux_libnuma_DATA = \
Expand Down
78 changes: 12 additions & 66 deletions hwloc/topology-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,6 @@ hwloc__read_fd_as_cpumask(int fd, hwloc_bitmap_t set)
return 0;
}

/* FIXME: export to API? */
static __hwloc_inline int
hwloc__read_path_as_cpumask(const char *maskpath, hwloc_bitmap_t set, int fsroot_fd)
{
Expand Down Expand Up @@ -707,6 +706,18 @@ hwloc__alloc_read_path_as_cpumask(const char *maskpath, int fsroot_fd)
return set;
}

int
hwloc_linux_read_path_as_cpumask(const char *maskpath, hwloc_bitmap_t set)
{
int fd, err;
fd = open(maskpath, O_RDONLY);
if (fd < 0)
return -1;
err = hwloc__read_fd_as_cpumask(fd, set);
close(fd);
return err;
}


/*****************************
******* CpuBind Hooks *******
Expand Down Expand Up @@ -1977,71 +1988,6 @@ struct hwloc_linux_cpuinfo_proc {
unsigned infos_count;
};

/* FIXME drop from API */
int
hwloc_linux_parse_cpumap_file(FILE *file, hwloc_bitmap_t set)
{
unsigned long *maps;
unsigned long map;
int nr_maps = 0;
static int _nr_maps_allocated = 8; /* Only compute the power-of-two above the kernel cpumask size once.
* Actually, it may increase multiple times if first read cpumaps start with zeroes.
*/
int nr_maps_allocated = _nr_maps_allocated;
int i;

maps = malloc(nr_maps_allocated * sizeof(*maps));
if (!maps)
return -1;

/* reset to zero first */
hwloc_bitmap_zero(set);

/* parse the whole mask */
while (fscanf(file, "%lx,", &map) == 1) /* read one kernel cpu mask and the ending comma */
{
if (nr_maps == nr_maps_allocated) {
unsigned long *tmp = realloc(maps, 2*nr_maps_allocated * sizeof(*maps));
if (!tmp) {
free(maps);
return -1;
}
maps = tmp;
nr_maps_allocated *= 2;
}

if (!map && !nr_maps)
/* ignore the first map if it's empty */
continue;

maps[nr_maps++] = map;
}

/* convert into a set */
#if KERNEL_CPU_MASK_BITS == HWLOC_BITS_PER_LONG
for(i=0; i<nr_maps; i++)
hwloc_bitmap_set_ith_ulong(set, i, maps[nr_maps-1-i]);
#else
for(i=0; i<(nr_maps+1)/2; i++) {
unsigned long mask;
mask = maps[nr_maps-2*i-1];
if (2*i+1<nr_maps)
mask |= maps[nr_maps-2*i-2] << KERNEL_CPU_MASK_BITS;
hwloc_bitmap_set_ith_ulong(set, i, mask);
}
#endif

free(maps);

/* Only update the static value with the final one,
* to avoid sharing intermediate values that we modify,
* in case there's ever multiple concurrent calls.
*/
if (nr_maps_allocated > _nr_maps_allocated)
_nr_maps_allocated = nr_maps_allocated;
return 0;
}

static void
hwloc_find_linux_cpuset_mntpnt(char **cgroup_mntpnt, char **cpuset_mntpnt, const char *root_path)
{
Expand Down
9 changes: 1 addition & 8 deletions include/hwloc/cuda.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_CUDA_DEVICE_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
int domainid, busid, deviceid;

if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domainid, &busid, &deviceid))
Expand All @@ -108,15 +107,9 @@ hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
}

sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domainid, busid, deviceid);
sysfile = fopen(path, "r");
if (!sysfile)
return -1;

if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));

fclose(sysfile);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
Expand Down
9 changes: 1 addition & 8 deletions include/hwloc/cudart.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_CUDART_DEVICE_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
int domain, bus, dev;

if (hwloc_cudart_get_device_pci_ids(topology, idx, &domain, &bus, &dev))
Expand All @@ -105,15 +104,9 @@ hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse
}

sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", domain, bus, dev);
sysfile = fopen(path, "r");
if (!sysfile)
return -1;

if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));

fclose(sysfile);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
Expand Down
11 changes: 1 addition & 10 deletions include/hwloc/intel-mic.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_un
#define HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX];
DIR *sysdir = NULL;
FILE *sysfile = NULL;
struct dirent *dirent;
unsigned pcibus, pcidev, pcifunc;

Expand All @@ -81,17 +80,9 @@ hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_un
while ((dirent = readdir(sysdir)) != NULL) {
if (sscanf(dirent->d_name, "pci_%02x:%02x.%02x", &pcibus, &pcidev, &pcifunc) == 3) {
sprintf(path, "/sys/class/mic/mic%d/pci_%02x:%02x.%02x/local_cpus", idx, pcibus, pcidev, pcifunc);
sysfile = fopen(path, "r");
if (!sysfile) {
closedir(sysdir);
return -1;
}

if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));

fclose(sysfile);
break;
}
}
Expand Down
16 changes: 9 additions & 7 deletions include/hwloc/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ extern "C" {
* @{
*/

/** \brief Convert a linux kernel cpumap file \p file into hwloc CPU set.
*
* Might be used when reading CPU set from sysfs attributes such as topology
* and caches for processors, or local_cpus for devices.
*/
HWLOC_DECLSPEC int hwloc_linux_parse_cpumap_file(FILE *file, hwloc_cpuset_t set);

/** \brief Bind a thread \p tid on cpus given in cpuset \p set
*
* The behavior is exactly the same as the Linux sched_setaffinity system call,
Expand Down Expand Up @@ -66,6 +59,15 @@ HWLOC_DECLSPEC int hwloc_linux_get_tid_cpubind(hwloc_topology_t topology, pid_t
*/
HWLOC_DECLSPEC int hwloc_linux_get_tid_last_cpu_location(hwloc_topology_t topology, pid_t tid, hwloc_bitmap_t set);

/** \brief Convert a linux kernel cpumask file \p path into a hwloc bitmap \p set.
*
* Might be used when reading CPU set from sysfs attributes such as topology
* and caches for processors, or local_cpus for devices.
*
* \note This function ignores the HWLOC_FSROOT environment variable.
*/
HWLOC_DECLSPEC int hwloc_linux_read_path_as_cpumask(const char *path, hwloc_bitmap_t set);

/** @} */


Expand Down
9 changes: 1 addition & 8 deletions include/hwloc/nvml.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_NVML_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_NVML_DEVICE_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
nvmlReturn_t nvres;
nvmlPciInfo_t pci;

Expand All @@ -76,15 +75,9 @@ hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
}

sprintf(path, "/sys/bus/pci/devices/%04x:%02x:%02x.0/local_cpus", pci.domain, pci.bus, pci.device);
sysfile = fopen(path, "r");
if (!sysfile)
return -1;

if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));

fclose(sysfile);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
Expand Down
9 changes: 1 addition & 8 deletions include/hwloc/opencl.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse
/* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */
#define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];
FILE *sysfile = NULL;
cl_device_topology_amd amdtopo;
cl_int clret;

Expand All @@ -89,15 +88,9 @@ hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse
}

sprintf(path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus", amdtopo.pcie.bus, amdtopo.pcie.device, amdtopo.pcie.function);
sysfile = fopen(path, "r");
if (!sysfile)
return -1;

if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));

fclose(sysfile);
#else
/* Non-Linux + AMD OpenCL systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
Expand Down
9 changes: 1 addition & 8 deletions include/hwloc/openfabrics-verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
get the local cpus */
#define HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX 128
char path[HWLOC_OPENFABRICS_VERBS_SYSFS_PATH_MAX];
FILE *sysfile = NULL;

if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
Expand All @@ -76,15 +75,9 @@ hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,

sprintf(path, "/sys/class/infiniband/%s/device/local_cpus",
ibv_get_device_name(ibdev));
sysfile = fopen(path, "r");
if (!sysfile)
return -1;

if (hwloc_linux_parse_cpumap_file(sysfile, set) < 0
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));

fclose(sysfile);
#else
/* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
Expand Down
2 changes: 1 addition & 1 deletion include/hwloc/rename.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,10 @@ extern "C" {

/* linux.h */

#define hwloc_linux_parse_cpumap_file HWLOC_NAME(linux_parse_cpumap_file)
#define hwloc_linux_set_tid_cpubind HWLOC_NAME(linux_set_tid_cpubind)
#define hwloc_linux_get_tid_cpubind HWLOC_NAME(linux_get_tid_cpubind)
#define hwloc_linux_get_tid_last_cpu_location HWLOC_NAME(linux_get_tid_last_cpu_location)
#define hwloc_linux_read_path_as_cpumask HWLOC_NAME(linux_read_file_cpumask)

/* openfabrics-verbs.h */

Expand Down

0 comments on commit e7f5962

Please sign in to comment.