From 52e2890824bad1bf69b1a3fae22c855640ee801e Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 22 May 2020 20:47:12 +0700 Subject: [PATCH] Update hwloc for MSVC builds. --- src/3rdparty/hwloc/NEWS | 23 ++- src/3rdparty/hwloc/VERSION | 6 +- src/3rdparty/hwloc/include/hwloc.h | 35 ++-- .../hwloc/include/hwloc/autogen/config.h | 6 +- src/3rdparty/hwloc/include/hwloc/helper.h | 46 ++++-- src/3rdparty/hwloc/include/hwloc/opencl.h | 13 +- src/3rdparty/hwloc/include/hwloc/plugins.h | 18 ++- src/3rdparty/hwloc/include/hwloc/rename.h | 11 +- src/3rdparty/hwloc/include/private/private.h | 6 +- src/3rdparty/hwloc/src/bitmap.c | 6 +- src/3rdparty/hwloc/src/components.c | 153 ++++++++++++++++-- src/3rdparty/hwloc/src/distances.c | 2 + src/3rdparty/hwloc/src/pci-common.c | 4 +- src/3rdparty/hwloc/src/topology-noos.c | 29 ++-- src/3rdparty/hwloc/src/topology-synthetic.c | 1 + src/3rdparty/hwloc/src/topology-windows.c | 18 ++- .../hwloc/src/topology-xml-nolibxml.c | 8 +- src/3rdparty/hwloc/src/topology-xml.c | 68 ++++++-- src/3rdparty/hwloc/src/topology.c | 97 +++++++++-- 19 files changed, 435 insertions(+), 115 deletions(-) diff --git a/src/3rdparty/hwloc/NEWS b/src/3rdparty/hwloc/NEWS index 99809e6a..0dfe28df 100644 --- a/src/3rdparty/hwloc/NEWS +++ b/src/3rdparty/hwloc/NEWS @@ -1,5 +1,5 @@ Copyright © 2009 CNRS -Copyright © 2009-2019 Inria. All rights reserved. +Copyright © 2009-2020 Inria. All rights reserved. Copyright © 2009-2013 Université Bordeaux Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. @@ -16,6 +16,27 @@ bug fixes (and other actions) for each version of hwloc since version 0.9. +Version 2.2.0 +------------- +* API + + Add hwloc_bitmap_singlify_by_core() to remove SMT from a given cpuset, + thanks to Florian Reynier for the suggestion. + + Add --enable-32bits-pci-domain to stop ignoring PCI devices with domain + >16bits (e.g. 10000:02:03.4). Enabling this option breaks the library ABI. + Thanks to Dylan Simon for the help. +* Backends + + Add support for Linux cgroups v2. + + Add NUMA support for FreeBSD. + + Add get_last_cpu_location support for FreeBSD. + + Remove support for Intel Xeon Phi (MIC, Knights Corner) co-processors. +* Tools + + Add --uid to filter the hwloc-ps output by uid on Linux. + + Add a GRAPHICAL OUTPUT section in the manpage of lstopo. +* Misc + + Use the native dlopen instead of libltdl, + unless --disable-plugin-dlopen is passed at configure time. + + Version 2.1.0 ------------- * API diff --git a/src/3rdparty/hwloc/VERSION b/src/3rdparty/hwloc/VERSION index 9035ed9c..e182793d 100644 --- a/src/3rdparty/hwloc/VERSION +++ b/src/3rdparty/hwloc/VERSION @@ -8,7 +8,7 @@ # Please update HWLOC_VERSION* in contrib/windows/hwloc_config.h too. major=2 -minor=1 +minor=2 release=0 # greek is used for alpha or beta release tags. If it is non-empty, @@ -22,7 +22,7 @@ greek= # The date when this release was created -date="Sep 30, 2019" +date="Mar 30, 2020" # If snapshot=1, then use the value from snapshot_version as the # entire hwloc version (i.e., ignore major, minor, release, and @@ -41,7 +41,7 @@ snapshot_version=${major}.${minor}.${release}${greek}-git # 2. Version numbers are described in the Libtool current:revision:age # format. -libhwloc_so_version=16:0:1 +libhwloc_so_version=17:0:2 libnetloc_so_version=0:0:0 # Please also update the lines in contrib/windows/libhwloc.vcxproj diff --git a/src/3rdparty/hwloc/include/hwloc.h b/src/3rdparty/hwloc/include/hwloc.h index e106e9cc..01b42fdc 100644 --- a/src/3rdparty/hwloc/include/hwloc.h +++ b/src/3rdparty/hwloc/include/hwloc.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2019 Inria. All rights reserved. + * Copyright © 2009-2020 Inria. All rights reserved. * Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -173,8 +173,12 @@ typedef hwloc_const_bitmap_t hwloc_const_nodeset_t; * may be defined in the future! If you need to compare types, use * hwloc_compare_types() instead. */ -#define HWLOC_OBJ_TYPE_MIN HWLOC_OBJ_MACHINE /**< \private Sentinel value */ typedef enum { + +/** \cond */ +#define HWLOC_OBJ_TYPE_MIN HWLOC_OBJ_MACHINE /* Sentinel value */ +/** \endcond */ + HWLOC_OBJ_MACHINE, /**< \brief Machine. * A set of processors and memory with cache * coherency. @@ -251,7 +255,7 @@ typedef enum { */ HWLOC_OBJ_BRIDGE, /**< \brief Bridge (filtered out by default). - * Any bridge that connects the host or an I/O bus, + * Any bridge (or PCI switch) that connects the host or an I/O bus, * to another I/O bus. * They are not added to the topology unless I/O discovery * is enabled with hwloc_topology_set_flags(). @@ -360,9 +364,8 @@ typedef enum hwloc_obj_osdev_type_e { */ HWLOC_DECLSPEC int hwloc_compare_types (hwloc_obj_type_t type1, hwloc_obj_type_t type2) __hwloc_attribute_const; -enum hwloc_compare_types_e { - HWLOC_TYPE_UNORDERED = INT_MAX /**< \brief Value returned by hwloc_compare_types() when types can not be compared. \hideinitializer */ -}; +/** \brief Value returned by hwloc_compare_types() when types can not be compared. \hideinitializer */ +#define HWLOC_TYPE_UNORDERED INT_MAX /** @} */ @@ -614,7 +617,11 @@ union hwloc_obj_attr_u { } group; /** \brief PCI Device specific Object Attributes */ struct hwloc_pcidev_attr_s { - unsigned short domain; +#ifndef HWLOC_HAVE_32BITS_PCI_DOMAIN + unsigned short domain; /* Only 16bits PCI domains are supported by default */ +#else + unsigned int domain; /* 32bits PCI domain support break the library ABI, hence it's disabled by default */ +#endif unsigned char bus, dev, func; unsigned short class_id; unsigned short vendor_id, device_id, subvendor_id, subdevice_id; @@ -629,7 +636,11 @@ union hwloc_obj_attr_u { hwloc_obj_bridge_type_t upstream_type; union { struct { - unsigned short domain; +#ifndef HWLOC_HAVE_32BITS_PCI_DOMAIN + unsigned short domain; /* Only 16bits PCI domains are supported by default */ +#else + unsigned int domain; /* 32bits PCI domain support break the library ABI, hence it's disabled by default */ +#endif unsigned char secondary_bus, subordinate_bus; } pci; } downstream; @@ -859,7 +870,8 @@ hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type) /** \brief Returns the type of objects at depth \p depth. * - * \p depth should between 0 and hwloc_topology_get_depth()-1. + * \p depth should between 0 and hwloc_topology_get_depth()-1, + * or a virtual depth such as ::HWLOC_TYPE_DEPTH_NUMANODE. * * \return (hwloc_obj_type_t)-1 if depth \p depth does not exist. */ @@ -1355,7 +1367,7 @@ HWLOC_DECLSPEC int hwloc_get_proc_last_cpu_location(hwloc_topology_t topology, h typedef enum { /** \brief Reset the memory allocation policy to the system default. * Depending on the operating system, this may correspond to - * ::HWLOC_MEMBIND_FIRSTTOUCH (Linux), + * ::HWLOC_MEMBIND_FIRSTTOUCH (Linux, FreeBSD), * or ::HWLOC_MEMBIND_BIND (AIX, HP-UX, Solaris, Windows). * This policy is never returned by get membind functions. * The nodeset argument is ignored. @@ -2169,13 +2181,14 @@ HWLOC_DECLSPEC void * hwloc_topology_get_userdata(hwloc_topology_t topology); enum hwloc_restrict_flags_e { /** \brief Remove all objects that became CPU-less. * By default, only objects that contain no PU and no memory are removed. + * This flag may not be used with ::HWLOC_RESTRICT_FLAG_BYNODESET. * \hideinitializer */ HWLOC_RESTRICT_FLAG_REMOVE_CPULESS = (1UL<<0), /** \brief Restrict by nodeset instead of CPU set. * Only keep objects whose nodeset is included or partially included in the given set. - * This flag may not be used with ::HWLOC_RESTRICT_FLAG_BYNODESET. + * This flag may not be used with ::HWLOC_RESTRICT_FLAG_REMOVE_CPULESS. */ HWLOC_RESTRICT_FLAG_BYNODESET = (1UL<<3), diff --git a/src/3rdparty/hwloc/include/hwloc/autogen/config.h b/src/3rdparty/hwloc/include/hwloc/autogen/config.h index 36669de5..06963b36 100644 --- a/src/3rdparty/hwloc/include/hwloc/autogen/config.h +++ b/src/3rdparty/hwloc/include/hwloc/autogen/config.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2018 Inria. All rights reserved. + * Copyright © 2009-2019 Inria. All rights reserved. * Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -11,9 +11,9 @@ #ifndef HWLOC_CONFIG_H #define HWLOC_CONFIG_H -#define HWLOC_VERSION "2.1.0" +#define HWLOC_VERSION "2.2.0" #define HWLOC_VERSION_MAJOR 2 -#define HWLOC_VERSION_MINOR 1 +#define HWLOC_VERSION_MINOR 2 #define HWLOC_VERSION_RELEASE 0 #define HWLOC_VERSION_GREEK "" diff --git a/src/3rdparty/hwloc/include/hwloc/helper.h b/src/3rdparty/hwloc/include/hwloc/helper.h index bc27be59..3df64843 100644 --- a/src/3rdparty/hwloc/include/hwloc/helper.h +++ b/src/3rdparty/hwloc/include/hwloc/helper.h @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2019 Inria. All rights reserved. + * Copyright © 2009-2020 Inria. All rights reserved. * Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -672,6 +672,24 @@ hwloc_get_shared_cache_covering_obj (hwloc_topology_t topology __hwloc_attribute * package has fewer caches than its peers. */ +/** \brief Remove simultaneous multithreading PUs from a CPU set. + * + * For each core in \p topology, if \p cpuset contains some PUs of that core, + * modify \p cpuset to only keep a single PU for that core. + * + * \p which specifies which PU will be kept. + * PU are considered in physical index order. + * If 0, for each core, the function keeps the first PU that was originally set in \p cpuset. + * + * If \p which is larger than the number of PUs in a core there were originally set in \p cpuset, + * no PU is kept for that core. + * + * \note PUs that are not below a Core object are ignored + * (for instance if the topology does not contain any Core object). + * None of them is removed from \p cpuset. + */ +HWLOC_DECLSPEC int hwloc_bitmap_singlify_per_core(hwloc_topology_t topology, hwloc_bitmap_t cpuset, unsigned which); + /** \brief Returns the object of type ::HWLOC_OBJ_PU with \p os_index. * * This function is useful for converting a CPU set into the PU @@ -998,15 +1016,16 @@ hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_ * @{ */ -/** \brief Convert a CPU set into a NUMA node set and handle non-NUMA cases +/** \brief Convert a CPU set into a NUMA node set + * + * For each PU included in the input \p _cpuset, set the corresponding + * local NUMA node(s) in the output \p nodeset. * * If some NUMA nodes have no CPUs at all, this function never sets their * indexes in the output node set, even if a full CPU set is given in input. * - * If the topology contains no NUMA nodes, the machine is considered - * as a single memory node, and the following behavior is used: - * If \p cpuset is empty, \p nodeset will be emptied as well. - * Otherwise \p nodeset will be entirely filled. + * Hence the entire topology CPU set is converted into the set of all nodes + * that have some local CPUs. */ static __hwloc_inline int hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset) @@ -1021,13 +1040,16 @@ hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, return 0; } -/** \brief Convert a NUMA node set into a CPU set and handle non-NUMA cases +/** \brief Convert a NUMA node set into a CPU set * - * If the topology contains no NUMA nodes, the machine is considered - * as a single memory node, and the following behavior is used: - * If \p nodeset is empty, \p cpuset will be emptied as well. - * Otherwise \p cpuset will be entirely filled. - * This is useful for manipulating memory binding sets. + * For each NUMA node included in the input \p nodeset, set the corresponding + * local PUs in the output \p _cpuset. + * + * If some CPUs have no local NUMA nodes, this function never sets their + * indexes in the output CPU set, even if a full node set is given in input. + * + * Hence the entire topology node set is converted into the set of all CPUs + * that have some local NUMA nodes. */ static __hwloc_inline int hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset) diff --git a/src/3rdparty/hwloc/include/hwloc/opencl.h b/src/3rdparty/hwloc/include/hwloc/opencl.h index ebf09848..99dfb0c8 100644 --- a/src/3rdparty/hwloc/include/hwloc/opencl.h +++ b/src/3rdparty/hwloc/include/hwloc/opencl.h @@ -1,5 +1,5 @@ /* - * Copyright © 2012-2018 Inria. All rights reserved. + * Copyright © 2012-2019 Inria. All rights reserved. * Copyright © 2013, 2018 Université Bordeaux. All right reserved. * See COPYING in top-level directory. */ @@ -52,6 +52,7 @@ typedef union { /* needs "cl_nv_device_attribute_query" device extension, but not strictly required for clGetDeviceInfo() */ #define HWLOC_CL_DEVICE_PCI_BUS_ID_NV 0x4008 #define HWLOC_CL_DEVICE_PCI_SLOT_ID_NV 0x4009 +#define HWLOC_CL_DEVICE_PCI_DOMAIN_ID_NV 0x400A /** \defgroup hwlocality_opencl Interoperability with OpenCL @@ -74,7 +75,7 @@ hwloc_opencl_get_device_pci_busid(cl_device_id device, unsigned *domain, unsigned *bus, unsigned *dev, unsigned *func) { hwloc_cl_device_topology_amd amdtopo; - cl_uint nvbus, nvslot; + cl_uint nvbus, nvslot, nvdomain; cl_int clret; clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL); @@ -91,8 +92,12 @@ hwloc_opencl_get_device_pci_busid(cl_device_id device, if (CL_SUCCESS == clret) { clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_SLOT_ID_NV, sizeof(nvslot), &nvslot, NULL); if (CL_SUCCESS == clret) { - /* FIXME: PCI bus only uses 8bit, assume nvidia hardcodes the domain in higher bits */ - *domain = nvbus >> 8; + clret = clGetDeviceInfo(device, HWLOC_CL_DEVICE_PCI_DOMAIN_ID_NV, sizeof(nvdomain), &nvdomain, NULL); + if (CL_SUCCESS == clret) { /* available since CUDA 10.2 */ + *domain = nvdomain; + } else { + *domain = 0; + } *bus = nvbus & 0xff; /* non-documented but used in many other projects */ *dev = nvslot >> 3; diff --git a/src/3rdparty/hwloc/include/hwloc/plugins.h b/src/3rdparty/hwloc/include/hwloc/plugins.h index 0f53ac4d..88faf538 100644 --- a/src/3rdparty/hwloc/include/hwloc/plugins.h +++ b/src/3rdparty/hwloc/include/hwloc/plugins.h @@ -1,5 +1,5 @@ /* - * Copyright © 2013-2019 Inria. All rights reserved. + * Copyright © 2013-2020 Inria. All rights reserved. * Copyright © 2016 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. */ @@ -17,7 +17,11 @@ struct hwloc_backend; #ifdef HWLOC_INSIDE_PLUGIN /* needed for hwloc_plugin_check_namespace() */ +#ifdef HWLOC_HAVE_LTDL #include +#else +#include +#endif #endif @@ -418,14 +422,22 @@ static __hwloc_inline int hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, const char *symbol __hwloc_attribute_unused) { #ifdef HWLOC_INSIDE_PLUGIN - lt_dlhandle handle; void *sym; - handle = lt_dlopen(NULL); +#ifdef HWLOC_HAVE_LTDL + lt_dlhandle handle = lt_dlopen(NULL); +#else + void *handle = dlopen(NULL, RTLD_NOW|RTLD_LOCAL); +#endif if (!handle) /* cannot check, assume things will work */ return 0; +#ifdef HWLOC_HAVE_LTDL sym = lt_dlsym(handle, symbol); lt_dlclose(handle); +#else + sym = dlsym(handle, symbol); + dlclose(handle); +#endif if (!sym) { static int verboseenv_checked = 0; static int verboseenv_value = 0; diff --git a/src/3rdparty/hwloc/include/hwloc/rename.h b/src/3rdparty/hwloc/include/hwloc/rename.h index a23738d0..224e2577 100644 --- a/src/3rdparty/hwloc/include/hwloc/rename.h +++ b/src/3rdparty/hwloc/include/hwloc/rename.h @@ -28,6 +28,7 @@ extern "C" { #define HWLOC_MUNGE_NAME(a, b) HWLOC_MUNGE_NAME2(a, b) #define HWLOC_MUNGE_NAME2(a, b) a ## b #define HWLOC_NAME(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX, hwloc_ ## name) +/* FIXME: should be "HWLOC_ ## name" below, unchanged because it doesn't matter much and could break some embedders hacks */ #define HWLOC_NAME_CAPS(name) HWLOC_MUNGE_NAME(HWLOC_SYM_PREFIX_CAPS, hwloc_ ## name) /* Now define all the "real" names to be the prefixed names. This @@ -92,9 +93,6 @@ extern "C" { #define hwloc_compare_types HWLOC_NAME(compare_types) -#define hwloc_compare_types_e HWLOC_NAME(compare_types_e) -#define HWLOC_TYPE_UNORDERED HWLOC_NAME_CAPS(TYPE_UNORDERED) - #define hwloc_obj HWLOC_NAME(obj) #define hwloc_obj_t HWLOC_NAME(obj_t) @@ -324,6 +322,7 @@ extern "C" { #define hwloc_get_ancestor_obj_by_type HWLOC_NAME(get_ancestor_obj_by_type) #define hwloc_get_next_obj_by_depth HWLOC_NAME(get_next_obj_by_depth) #define hwloc_get_next_obj_by_type HWLOC_NAME(get_next_obj_by_type) +#define hwloc_bitmap_singlify_per_core HWLOC_NAME(bitmap_singlify_by_core) #define hwloc_get_pu_obj_by_os_index HWLOC_NAME(get_pu_obj_by_os_index) #define hwloc_get_numanode_obj_by_os_index HWLOC_NAME(get_numanode_obj_by_os_index) #define hwloc_get_next_child HWLOC_NAME(get_next_child) @@ -482,11 +481,6 @@ extern "C" { #define hwloc_ibv_get_device_osdev HWLOC_NAME(ibv_get_device_osdev) #define hwloc_ibv_get_device_osdev_by_name HWLOC_NAME(ibv_get_device_osdev_by_name) -/* intel-mic.h */ - -#define hwloc_intel_mic_get_device_cpuset HWLOC_NAME(intel_mic_get_device_cpuset) -#define hwloc_intel_mic_get_device_osdev_by_index HWLOC_NAME(intel_mic_get_device_osdev_by_index) - /* opencl.h */ #define hwloc_cl_device_topology_amd HWLOC_NAME(cl_device_topology_amd) @@ -709,6 +703,7 @@ extern "C" { #define hwloc_get_sysctlbyname HWLOC_NAME(get_sysctlbyname) #define hwloc_get_sysctl HWLOC_NAME(get_sysctl) #define hwloc_fallback_nbprocessors HWLOC_NAME(fallback_nbprocessors) +#define hwloc_fallback_memsize HWLOC_NAME(fallback_memsize) #define hwloc__object_cpusets_compare_first HWLOC_NAME(_object_cpusets_compare_first) #define hwloc__reorder_children HWLOC_NAME(_reorder_children) diff --git a/src/3rdparty/hwloc/include/private/private.h b/src/3rdparty/hwloc/include/private/private.h index 5f878937..84d95bb3 100644 --- a/src/3rdparty/hwloc/include/private/private.h +++ b/src/3rdparty/hwloc/include/private/private.h @@ -1,7 +1,7 @@ /* * Copyright © 2009 CNRS * Copyright © 2009-2019 Inria. All rights reserved. - * Copyright © 2009-2012 Université Bordeaux + * Copyright © 2009-2012, 2020 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * * See COPYING in top-level directory. @@ -224,11 +224,13 @@ struct hwloc_topology { extern void hwloc_alloc_root_sets(hwloc_obj_t root); extern void hwloc_setup_pu_level(struct hwloc_topology *topology, unsigned nb_pus); extern int hwloc_get_sysctlbyname(const char *name, int64_t *n); -extern int hwloc_get_sysctl(int name[], unsigned namelen, int *n); +extern int hwloc_get_sysctl(int name[], unsigned namelen, int64_t *n); /* returns the number of CPU from the OS (only valid if thissystem) */ #define HWLOC_FALLBACK_NBPROCESSORS_INCLUDE_OFFLINE 1 /* by default we try to get only the online CPUs */ extern int hwloc_fallback_nbprocessors(unsigned flags); +/* returns the memory size from the OS (only valid if thissystem) */ +extern int64_t hwloc_fallback_memsize(void); extern int hwloc__object_cpusets_compare_first(hwloc_obj_t obj1, hwloc_obj_t obj2); extern void hwloc__reorder_children(hwloc_obj_t parent); diff --git a/src/3rdparty/hwloc/src/bitmap.c b/src/3rdparty/hwloc/src/bitmap.c index 5fb9cd35..4791a694 100644 --- a/src/3rdparty/hwloc/src/bitmap.c +++ b/src/3rdparty/hwloc/src/bitmap.c @@ -505,14 +505,16 @@ int hwloc_bitmap_list_sscanf(struct hwloc_bitmap_s *set, const char * __hwloc_re if (begin != -1) { /* finishing a range */ - hwloc_bitmap_set_range(set, begin, val); + if (hwloc_bitmap_set_range(set, begin, val) < 0) + goto failed; begin = -1; } else if (*next == '-') { /* starting a new range */ if (*(next+1) == '\0') { /* infinite range */ - hwloc_bitmap_set_range(set, val, -1); + if (hwloc_bitmap_set_range(set, val, -1) < 0) + goto failed; break; } else { /* normal range */ diff --git a/src/3rdparty/hwloc/src/components.c b/src/3rdparty/hwloc/src/components.c index 5c2879b6..496ed232 100644 --- a/src/3rdparty/hwloc/src/components.c +++ b/src/3rdparty/hwloc/src/components.c @@ -1,5 +1,5 @@ /* - * Copyright © 2009-2019 Inria. All rights reserved. + * Copyright © 2009-2020 Inria. All rights reserved. * Copyright © 2012 Université Bordeaux * See COPYING in top-level directory. */ @@ -63,14 +63,128 @@ static pthread_mutex_t hwloc_components_mutex = PTHREAD_MUTEX_INITIALIZER; #ifdef HWLOC_HAVE_PLUGINS +#ifdef HWLOC_HAVE_LTDL +/* ltdl-based plugin load */ #include +typedef lt_dlhandle hwloc_dlhandle; +#define hwloc_dlinit lt_dlinit +#define hwloc_dlexit lt_dlexit +#define hwloc_dlopenext lt_dlopenext +#define hwloc_dlclose lt_dlclose +#define hwloc_dlerror lt_dlerror +#define hwloc_dlsym lt_dlsym +#define hwloc_dlforeachfile lt_dlforeachfile + +#else /* !HWLOC_HAVE_LTDL */ +/* no-ltdl plugin load relies on less portable libdl */ +#include +typedef void * hwloc_dlhandle; +static __hwloc_inline int hwloc_dlinit(void) { return 0; } +static __hwloc_inline int hwloc_dlexit(void) { return 0; } +#define hwloc_dlclose dlclose +#define hwloc_dlerror dlerror +#define hwloc_dlsym dlsym + +#include +#include +#include +#include + +static hwloc_dlhandle hwloc_dlopenext(const char *_filename) +{ + hwloc_dlhandle handle; + char *filename = NULL; + (void) asprintf(&filename, "%s.so", _filename); + if (!filename) + return NULL; + handle = dlopen(filename, RTLD_NOW|RTLD_LOCAL); + free(filename); + return handle; +} + +static int +hwloc_dlforeachfile(const char *_paths, + int (*func)(const char *filename, void *data), + void *data) +{ + char *paths = NULL, *path; + + paths = strdup(_paths); + if (!paths) + return -1; + + path = paths; + while (*path) { + char *colon; + DIR *dir; + struct dirent *dirent; + + colon = strchr(path, ':'); + if (colon) + *colon = '\0'; + + if (hwloc_plugins_verbose) + fprintf(stderr, " Looking under %s\n", path); + + dir = opendir(path); + if (!dir) + goto next; + + while ((dirent = readdir(dir)) != NULL) { + char *abs_name, *suffix; + struct stat stbuf; + int err; + + err = asprintf(&abs_name, "%s/%s", path, dirent->d_name); + if (err < 0) + continue; + + err = stat(abs_name, &stbuf); + if (err < 0) { + free(abs_name); + continue; + } + if (!S_ISREG(stbuf.st_mode)) { + free(abs_name); + continue; + } + + /* Only keep .so files, and remove that suffix to get the component basename */ + suffix = strrchr(abs_name, '.'); + if (!suffix || strcmp(suffix, ".so")) { + free(abs_name); + continue; + } + *suffix = '\0'; + + err = func(abs_name, data); + if (err) { + free(abs_name); + continue; + } + + free(abs_name); + } + + closedir(dir); + + next: + if (!colon) + break; + path = colon+1; + } + + free(paths); + return 0; +} +#endif /* !HWLOC_HAVE_LTDL */ /* array of pointers to dynamically loaded plugins */ static struct hwloc__plugin_desc { char *name; struct hwloc_component *component; char *filename; - lt_dlhandle handle; + hwloc_dlhandle handle; struct hwloc__plugin_desc *next; } *hwloc_plugins = NULL; @@ -78,9 +192,10 @@ static int hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused) { const char *basename; - lt_dlhandle handle; + hwloc_dlhandle handle; struct hwloc_component *component; struct hwloc__plugin_desc *desc, **prevdesc; + char *componentsymbolname; if (hwloc_plugins_verbose) fprintf(stderr, "Plugin dlforeach found `%s'\n", filename); @@ -98,33 +213,40 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused) } /* dlopen and get the component structure */ - handle = lt_dlopenext(filename); + handle = hwloc_dlopenext(filename); if (!handle) { if (hwloc_plugins_verbose) - fprintf(stderr, "Failed to load plugin: %s\n", lt_dlerror()); + fprintf(stderr, "Failed to load plugin: %s\n", hwloc_dlerror()); goto out; } -{ - char componentsymbolname[strlen(basename)+10+1]; + componentsymbolname = malloc(strlen(basename)+10+1); + if (!componentsymbolname) { + if (hwloc_plugins_verbose) + fprintf(stderr, "Failed to allocation component `%s' symbol\n", + basename); + goto out_with_handle; + } sprintf(componentsymbolname, "%s_component", basename); - component = lt_dlsym(handle, componentsymbolname); + component = hwloc_dlsym(handle, componentsymbolname); if (!component) { if (hwloc_plugins_verbose) fprintf(stderr, "Failed to find component symbol `%s'\n", componentsymbolname); + free(componentsymbolname); goto out_with_handle; } if (component->abi != HWLOC_COMPONENT_ABI) { if (hwloc_plugins_verbose) fprintf(stderr, "Plugin symbol ABI %u instead of %d\n", component->abi, HWLOC_COMPONENT_ABI); + free(componentsymbolname); goto out_with_handle; } if (hwloc_plugins_verbose) fprintf(stderr, "Plugin contains expected symbol `%s'\n", componentsymbolname); -} + free(componentsymbolname); if (HWLOC_COMPONENT_TYPE_DISC == component->type) { if (strncmp(basename, "hwloc_", 6)) { @@ -167,7 +289,7 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused) return 0; out_with_handle: - lt_dlclose(handle); + hwloc_dlclose(handle); out: return 0; } @@ -183,7 +305,7 @@ hwloc_plugins_exit(void) desc = hwloc_plugins; while (desc) { next = desc->next; - lt_dlclose(desc->handle); + hwloc_dlclose(desc->handle); free(desc->name); free(desc->filename); free(desc); @@ -191,7 +313,7 @@ hwloc_plugins_exit(void) } hwloc_plugins = NULL; - lt_dlexit(); + hwloc_dlexit(); } static int @@ -207,7 +329,7 @@ hwloc_plugins_init(void) hwloc_plugins_blacklist = getenv("HWLOC_PLUGINS_BLACKLIST"); - err = lt_dlinit(); + err = hwloc_dlinit(); if (err) goto out; @@ -219,7 +341,7 @@ hwloc_plugins_init(void) if (hwloc_plugins_verbose) fprintf(stderr, "Starting plugin dlforeach in %s\n", path); - err = lt_dlforeachfile(path, hwloc__dlforeach_cb, NULL); + err = hwloc_dlforeachfile(path, hwloc__dlforeach_cb, NULL); if (err) goto out_with_init; @@ -680,7 +802,8 @@ hwloc_disc_components_enable_others(struct hwloc_topology *topology) while (*curenv) { s = strcspn(curenv, HWLOC_COMPONENT_SEPS); if (s) { - char c, *name; + char c; + const char *name; if (!strncmp(curenv, HWLOC_COMPONENT_STOP_NAME, s)) { tryall = 0; diff --git a/src/3rdparty/hwloc/src/distances.c b/src/3rdparty/hwloc/src/distances.c index 9e56a969..4f2897a0 100644 --- a/src/3rdparty/hwloc/src/distances.c +++ b/src/3rdparty/hwloc/src/distances.c @@ -323,6 +323,8 @@ hwloc_internal_distances__add(hwloc_topology_t topology, const char *name, return 0; err_with_dist: + if (name) + free(dist->name); free(dist); err: free(different_types); diff --git a/src/3rdparty/hwloc/src/pci-common.c b/src/3rdparty/hwloc/src/pci-common.c index deca5cce..a817c8da 100644 --- a/src/3rdparty/hwloc/src/pci-common.c +++ b/src/3rdparty/hwloc/src/pci-common.c @@ -1,5 +1,5 @@ /* - * Copyright © 2009-2019 Inria. All rights reserved. + * Copyright © 2009-2020 Inria. All rights reserved. * See COPYING in top-level directory. */ @@ -366,7 +366,7 @@ hwloc_pcidisc_add_hostbridges(struct hwloc_topology *topology, struct hwloc_obj **dstnextp; struct hwloc_obj **srcnextp; struct hwloc_obj *child; - unsigned short current_domain; + unsigned current_domain; unsigned char current_bus; unsigned char current_subordinate; diff --git a/src/3rdparty/hwloc/src/topology-noos.c b/src/3rdparty/hwloc/src/topology-noos.c index 174b6fd8..2658750a 100644 --- a/src/3rdparty/hwloc/src/topology-noos.c +++ b/src/3rdparty/hwloc/src/topology-noos.c @@ -1,7 +1,7 @@ /* * Copyright © 2009 CNRS * Copyright © 2009-2019 Inria. All rights reserved. - * Copyright © 2009-2012 Université Bordeaux + * Copyright © 2009-2012, 2020 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. */ @@ -20,22 +20,27 @@ hwloc_look_noos(struct hwloc_backend *backend, struct hwloc_disc_status *dstatus */ struct hwloc_topology *topology = backend->topology; - int nbprocs; + int64_t memsize; assert(dstatus->phase == HWLOC_DISC_PHASE_CPU); - if (topology->levels[0][0]->cpuset) - /* somebody discovered things */ - return -1; + if (!topology->levels[0][0]->cpuset) { + int nbprocs; + /* Nobody (even the x86 backend) created objects yet, setup basic objects */ - nbprocs = hwloc_fallback_nbprocessors(0); - if (nbprocs >= 1) - topology->support.discovery->pu = 1; - else - nbprocs = 1; + nbprocs = hwloc_fallback_nbprocessors(0); + if (nbprocs >= 1) + topology->support.discovery->pu = 1; + else + nbprocs = 1; + hwloc_alloc_root_sets(topology->levels[0][0]); + hwloc_setup_pu_level(topology, nbprocs); + } + + memsize = hwloc_fallback_memsize(); + if (memsize > 0) + topology->machine_memory.local_memory = memsize;; - hwloc_alloc_root_sets(topology->levels[0][0]); - hwloc_setup_pu_level(topology, nbprocs); hwloc_add_uname_info(topology, NULL); return 0; } diff --git a/src/3rdparty/hwloc/src/topology-synthetic.c b/src/3rdparty/hwloc/src/topology-synthetic.c index 686efce1..50092e47 100644 --- a/src/3rdparty/hwloc/src/topology-synthetic.c +++ b/src/3rdparty/hwloc/src/topology-synthetic.c @@ -1503,6 +1503,7 @@ hwloc_topology_export_synthetic(struct hwloc_topology * topology, signed pdepth; node = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, 0); + assert(node); assert(hwloc__obj_type_is_normal(node->parent->type)); /* only depth-1 memory children for now */ pdepth = node->parent->depth; diff --git a/src/3rdparty/hwloc/src/topology-windows.c b/src/3rdparty/hwloc/src/topology-windows.c index 22521aa3..195e5e22 100644 --- a/src/3rdparty/hwloc/src/topology-windows.c +++ b/src/3rdparty/hwloc/src/topology-windows.c @@ -1,7 +1,7 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2019 Inria. All rights reserved. - * Copyright © 2009-2012 Université Bordeaux + * Copyright © 2009-2020 Inria. All rights reserved. + * Copyright © 2009-2012, 2020 Université Bordeaux * Copyright © 2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. */ @@ -232,6 +232,10 @@ static void hwloc_win_get_function_ptrs(void) { HMODULE kernel32; +#if HWLOC_HAVE_GCC_W_CAST_FUNCTION_TYPE +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + kernel32 = LoadLibrary("kernel32.dll"); if (kernel32) { GetActiveProcessorGroupCountProc = @@ -270,6 +274,10 @@ static void hwloc_win_get_function_ptrs(void) if (psapi) QueryWorkingSetExProc = (PFN_QUERYWORKINGSETEX) GetProcAddress(psapi, "QueryWorkingSetEx"); } + +#if HWLOC_HAVE_GCC_W_CAST_FUNCTION_TYPE +#pragma GCC diagnostic warning "-Wcast-function-type" +#endif } /* @@ -1199,3 +1207,9 @@ hwloc_fallback_nbprocessors(unsigned flags __hwloc_attribute_unused) { return n; } + +int64_t +hwloc_fallback_memsize(void) { + /* Unused */ + return -1; +} diff --git a/src/3rdparty/hwloc/src/topology-xml-nolibxml.c b/src/3rdparty/hwloc/src/topology-xml-nolibxml.c index d0e9ec16..5a0006a0 100644 --- a/src/3rdparty/hwloc/src/topology-xml-nolibxml.c +++ b/src/3rdparty/hwloc/src/topology-xml-nolibxml.c @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2019 Inria. All rights reserved. + * Copyright © 2009-2020 Inria. All rights reserved. * Copyright © 2009-2011 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -34,7 +34,7 @@ struct hwloc__nolibxml_backend_data_s { typedef struct hwloc__nolibxml_import_state_data_s { char *tagbuffer; /* buffer containing the next tag */ char *attrbuffer; /* buffer containing the next attribute of the current node */ - char *tagname; /* tag name of the current node */ + const char *tagname; /* tag name of the current node */ int closed; /* set if the current node is auto-closing */ } __hwloc_attribute_may_alias * hwloc__nolibxml_import_state_data_t; @@ -137,7 +137,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state, return 0; /* normal tag */ - tag = nchildstate->tagname = buffer; + nchildstate->tagname = tag = buffer; /* find the end, mark it and return it */ end = strchr(buffer, '>'); @@ -260,7 +260,7 @@ hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata, unsigned major, minor; char *end; char *buffer = nbdata->buffer; - char *tagname; + const char *tagname; HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data)); diff --git a/src/3rdparty/hwloc/src/topology-xml.c b/src/3rdparty/hwloc/src/topology-xml.c index f6bb210c..ba242853 100644 --- a/src/3rdparty/hwloc/src/topology-xml.c +++ b/src/3rdparty/hwloc/src/topology-xml.c @@ -1,6 +1,6 @@ /* * Copyright © 2009 CNRS - * Copyright © 2009-2019 Inria. All rights reserved. + * Copyright © 2009-2020 Inria. All rights reserved. * Copyright © 2009-2011 Université Bordeaux * Copyright © 2009-2018 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. @@ -107,7 +107,8 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology, struct hwloc_xml_backend_data_s *data, struct hwloc_obj *obj, const char *name, const char *value, - hwloc__xml_import_state_t state) + hwloc__xml_import_state_t state, + int *ignore) { if (!strcmp(name, "type")) { /* already handled */ @@ -252,11 +253,20 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology, case HWLOC_OBJ_PCI_DEVICE: case HWLOC_OBJ_BRIDGE: { unsigned domain, bus, dev, func; - if (sscanf(value, "%04x:%02x:%02x.%01x", + if (sscanf(value, "%x:%02x:%02x.%01x", &domain, &bus, &dev, &func) != 4) { if (hwloc__xml_verbose()) fprintf(stderr, "%s: ignoring invalid pci_busid format string %s\n", state->global->msgprefix, value); + *ignore = 1; +#ifndef HWLOC_HAVE_32BITS_PCI_DOMAIN + } else if (domain > 0xffff) { + static int warned = 0; + if (!warned && !hwloc_hide_errors()) + fprintf(stderr, "Ignoring PCI device with non-16bit domain.\nPass --enable-32bits-pci-domain to configure to support such devices\n(warning: it would break the library ABI, don't enable unless really needed).\n"); + warned = 1; + *ignore = 1; +#endif } else { obj->attr->pcidev.domain = domain; obj->attr->pcidev.bus = bus; @@ -278,7 +288,7 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology, case HWLOC_OBJ_PCI_DEVICE: case HWLOC_OBJ_BRIDGE: { unsigned classid, vendor, device, subvendor, subdevice, revision; - if (sscanf(value, "%04x [%04x:%04x] [%04x:%04x] %02x", + if (sscanf(value, "%x [%04x:%04x] [%04x:%04x] %02x", &classid, &vendor, &device, &subvendor, &subdevice, &revision) != 6) { if (hwloc__xml_verbose()) fprintf(stderr, "%s: ignoring invalid pci_type format string %s\n", @@ -342,11 +352,20 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology, switch (obj->type) { case HWLOC_OBJ_BRIDGE: { unsigned domain, secbus, subbus; - if (sscanf(value, "%04x:[%02x-%02x]", + if (sscanf(value, "%x:[%02x-%02x]", &domain, &secbus, &subbus) != 3) { if (hwloc__xml_verbose()) fprintf(stderr, "%s: ignoring invalid bridge_pci format string %s\n", state->global->msgprefix, value); + *ignore = 1; +#ifndef HWLOC_HAVE_32BITS_PCI_DOMAIN + } else if (domain > 0xffff) { + static int warned = 0; + if (!warned && !hwloc_hide_errors()) + fprintf(stderr, "Ignoring bridge to PCI with non-16bit domain.\nPass --enable-32bits-pci-domain to configure to support such devices\n(warning: it would break the library ABI, don't enable unless really needed).\n"); + warned = 1; + *ignore = 1; +#endif } else { obj->attr->bridge.downstream.pci.domain = domain; obj->attr->bridge.downstream.pci.secondary_bus = secbus; @@ -426,6 +445,7 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology, memory->page_types = malloc(sizeof(*memory->page_types)); memory->page_types_len = 1; } + assert(memory->page_types); memory->page_types[0].size = lvalue << 10; } else if (hwloc__xml_verbose()) { fprintf(stderr, "%s: ignoring huge_page_size_kB attribute for non-NUMAnode non-root object\n", @@ -440,6 +460,7 @@ hwloc__xml_import_object_attr(struct hwloc_topology *topology, memory->page_types = malloc(sizeof(*memory->page_types)); memory->page_types_len = 1; } + assert(memory->page_types); memory->page_types[0].count = lvalue; } else if (hwloc__xml_verbose()) { fprintf(stderr, "%s: ignoring huge_page_free attribute for non-NUMAnode non-root object\n", @@ -835,7 +856,7 @@ hwloc__xml_import_object(hwloc_topology_t topology, state->global->msgprefix, attrname); goto error_with_object; } - hwloc__xml_import_object_attr(topology, data, obj, attrname, attrvalue, state); + hwloc__xml_import_object_attr(topology, data, obj, attrname, attrvalue, state, &ignored); } } @@ -1140,15 +1161,23 @@ hwloc__xml_import_object(hwloc_topology_t topology, ret = -1; } - if (ret < 0) - goto error; + if (ret < 0) { + if (parent && !ignored) + goto error; + else + goto error_with_object; + } state->global->close_child(&childstate); tag = NULL; ret = state->global->find_child(state, &childstate, &tag); - if (ret < 0) - goto error; + if (ret < 0) { + if (parent && !ignored) + goto error; + else + goto error_with_object; + } if (!ret) break; } @@ -1548,7 +1577,7 @@ hwloc__xml_import_diff_one(hwloc__xml_import_state_t state, memset(&diff->obj_attr.diff, 0, sizeof(diff->obj_attr.diff)); diff->obj_attr.diff.generic.type = obj_attr_type; - switch (atoi(obj_attr_type_s)) { + switch (obj_attr_type) { case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE: diff->obj_attr.diff.uint64.oldvalue = strtoull(obj_attr_oldvalue_s, NULL, 0); diff->obj_attr.diff.uint64.newvalue = strtoull(obj_attr_newvalue_s, NULL, 0); @@ -1732,7 +1761,7 @@ hwloc_look_xml(struct hwloc_backend *backend, struct hwloc_disc_status *dstatus) goto failed; } else { if (hwloc__xml_verbose()) - fprintf(stderr, "%s: ignoring unknown tag `%s' after root object, expected `distances2'\n", + fprintf(stderr, "%s: ignoring unknown tag `%s' after root object.\n", data->msgprefix, tag); goto done; } @@ -1778,6 +1807,8 @@ done: if (nbobjs == data->nbnumanodes) { hwloc_obj_t *objs = malloc(nbobjs*sizeof(hwloc_obj_t)); uint64_t *values = malloc(nbobjs*nbobjs*sizeof(*values)); + assert(data->nbnumanodes > 0); /* v1dist->nbobjs is >0 after import */ + assert(data->first_numanode); if (objs && values) { hwloc_obj_t node; unsigned i; @@ -2051,13 +2082,17 @@ hwloc__xml_export_object_contents (hwloc__xml_export_state_t state, hwloc_topolo state->new_prop(state, "online_cpuset", setstring); free(setstring); - if (v1export || !obj->parent) { + if (v1export) { hwloc_bitmap_t allowed_cpuset = hwloc_bitmap_dup(obj->cpuset); hwloc_bitmap_and(allowed_cpuset, allowed_cpuset, topology->allowed_cpuset); hwloc_bitmap_asprintf(&setstring, allowed_cpuset); state->new_prop(state, "allowed_cpuset", setstring); free(setstring); hwloc_bitmap_free(allowed_cpuset); + } else if (!obj->parent) { + hwloc_bitmap_asprintf(&setstring, topology->allowed_cpuset); + state->new_prop(state, "allowed_cpuset", setstring); + free(setstring); } } @@ -2072,13 +2107,17 @@ hwloc__xml_export_object_contents (hwloc__xml_export_state_t state, hwloc_topolo state->new_prop(state, "complete_nodeset", setstring); free(setstring); - if (v1export || !obj->parent) { + if (v1export) { hwloc_bitmap_t allowed_nodeset = hwloc_bitmap_dup(obj->nodeset); hwloc_bitmap_and(allowed_nodeset, allowed_nodeset, topology->allowed_nodeset); hwloc_bitmap_asprintf(&setstring, allowed_nodeset); state->new_prop(state, "allowed_nodeset", setstring); free(setstring); hwloc_bitmap_free(allowed_nodeset); + } else if (!obj->parent) { + hwloc_bitmap_asprintf(&setstring, topology->allowed_nodeset); + state->new_prop(state, "allowed_nodeset", setstring); + free(setstring); } } @@ -2921,6 +2960,7 @@ hwloc_export_obj_userdata(void *reserved, int encoded; size_t encoded_length; const char *realname; + assert(name); if (!strncmp(name, "base64", 6)) { encoded = 1; encoded_length = BASE64_ENCODED_LENGTH(length); diff --git a/src/3rdparty/hwloc/src/topology.c b/src/3rdparty/hwloc/src/topology.c index 8d376193..34692517 100644 --- a/src/3rdparty/hwloc/src/topology.c +++ b/src/3rdparty/hwloc/src/topology.c @@ -1,7 +1,7 @@ /* * Copyright © 2009 CNRS * Copyright © 2009-2019 Inria. All rights reserved. - * Copyright © 2009-2012 Université Bordeaux + * Copyright © 2009-2012, 2020 Université Bordeaux * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. */ @@ -33,6 +33,9 @@ #ifdef HAVE_MACH_MACH_INIT_H #include #endif +#ifdef HAVE_MACH_INIT_H +#include +#endif #ifdef HAVE_MACH_MACH_HOST_H #include #endif @@ -123,15 +126,25 @@ int hwloc_get_sysctlbyname(const char *name, int64_t *ret) #endif #if defined(HAVE_SYSCTL) -int hwloc_get_sysctl(int name[], unsigned namelen, int *ret) +int hwloc_get_sysctl(int name[], unsigned namelen, int64_t *ret) { - int n; + union { + int32_t i32; + int64_t i64; + } n; size_t size = sizeof(n); if (sysctl(name, namelen, &n, &size, NULL, 0)) return -1; - if (size != sizeof(n)) - return -1; - *ret = n; + switch (size) { + case sizeof(n.i32): + *ret = n.i32; + break; + case sizeof(n.i64): + *ret = n.i64; + break; + default: + return -1; + } return 0; } #endif @@ -178,8 +191,10 @@ hwloc_fallback_nbprocessors(unsigned flags) { n = nn; #elif defined(HAVE_SYSCTL) && HAVE_DECL_CTL_HW && HAVE_DECL_HW_NCPU static int name[2] = {CTL_HW, HW_NCPU}; - if (hwloc_get_sysctl(name, sizeof(name)/sizeof(*name), &n)) + int64_t nn; + if (hwloc_get_sysctl(name, sizeof(name)/sizeof(*name), &nn)) n = -1; + n = nn; #else #ifdef __GNUC__ #warning No known way to discover number of available processors on this system @@ -188,6 +203,46 @@ hwloc_fallback_nbprocessors(unsigned flags) { #endif return n; } + +int64_t +hwloc_fallback_memsize(void) { + int64_t size; +#if defined(HAVE_HOST_INFO) && HAVE_HOST_INFO + struct host_basic_info info; + mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; + host_info(mach_host_self(), HOST_BASIC_INFO, (integer_t*) &info, &count); + size = info.memory_size; +#elif defined(HAVE_SYSCTL) && HAVE_DECL_CTL_HW && (HAVE_DECL_HW_REALMEM64 || HAVE_DECL_HW_MEMSIZE64 || HAVE_DECL_HW_PHYSMEM64 || HAVE_DECL_HW_USERMEM64 || HAVE_DECL_HW_REALMEM || HAVE_DECL_HW_MEMSIZE || HAVE_DECL_HW_PHYSMEM || HAVE_DECL_HW_USERMEM) +#if HAVE_DECL_HW_MEMSIZE64 + static int name[2] = {CTL_HW, HW_MEMSIZE64}; +#elif HAVE_DECL_HW_REALMEM64 + static int name[2] = {CTL_HW, HW_REALMEM64}; +#elif HAVE_DECL_HW_PHYSMEM64 + static int name[2] = {CTL_HW, HW_PHYSMEM64}; +#elif HAVE_DECL_HW_USERMEM64 + static int name[2] = {CTL_HW, HW_USERMEM64}; +#elif HAVE_DECL_HW_MEMSIZE + static int name[2] = {CTL_HW, HW_MEMSIZE}; +#elif HAVE_DECL_HW_REALMEM + static int name[2] = {CTL_HW, HW_REALMEM}; +#elif HAVE_DECL_HW_PHYSMEM + static int name[2] = {CTL_HW, HW_PHYSMEM}; +#elif HAVE_DECL_HW_USERMEM + static int name[2] = {CTL_HW, HW_USERMEM}; +#endif + if (hwloc_get_sysctl(name, sizeof(name)/sizeof(*name), &size)) + size = -1; +#elif defined(HAVE_SYSCTLBYNAME) + if (hwloc_get_sysctlbyname("hw.memsize", &size) && + hwloc_get_sysctlbyname("hw.realmem", &size) && + hwloc_get_sysctlbyname("hw.physmem", &size) && + hwloc_get_sysctlbyname("hw.usermem", &size)) + size = -1; +#else + size = -1; +#endif + return size; +} #endif /* !HWLOC_WIN_SYS */ /* @@ -2043,15 +2098,17 @@ propagate_total_memory(hwloc_obj_t obj) if (obj->type == HWLOC_OBJ_NUMANODE) { obj->total_memory += obj->attr->numanode.local_memory; - /* By the way, sort the page_type array. - * Cannot do it on insert since some backends (e.g. XML) add page_types after inserting the object. - */ - qsort(obj->attr->numanode.page_types, obj->attr->numanode.page_types_len, sizeof(*obj->attr->numanode.page_types), hwloc_memory_page_type_compare); - /* Ignore 0-size page_types, they are at the end */ - for(i=obj->attr->numanode.page_types_len; i>=1; i--) - if (obj->attr->numanode.page_types[i-1].size) - break; - obj->attr->numanode.page_types_len = i; + if (obj->attr->numanode.page_types_len) { + /* By the way, sort the page_type array. + * Cannot do it on insert since some backends (e.g. XML) add page_types after inserting the object. + */ + qsort(obj->attr->numanode.page_types, obj->attr->numanode.page_types_len, sizeof(*obj->attr->numanode.page_types), hwloc_memory_page_type_compare); + /* Ignore 0-size page_types, they are at the end */ + for(i=obj->attr->numanode.page_types_len; i>=1; i--) + if (obj->attr->numanode.page_types[i-1].size) + break; + obj->attr->numanode.page_types_len = i; + } } } @@ -2966,7 +3023,8 @@ hwloc_connect_levels(hwloc_topology_t topology) if (hwloc_type_cmp(top_obj, objs[i]) == HWLOC_OBJ_EQUAL) { /* Take it, add main children. */ taken_objs[n_taken_objs++] = objs[i]; - memcpy(&new_objs[n_new_objs], objs[i]->children, objs[i]->arity * sizeof(new_objs[0])); + if (objs[i]->arity) + memcpy(&new_objs[n_new_objs], objs[i]->children, objs[i]->arity * sizeof(new_objs[0])); n_new_objs += objs[i]->arity; } else { /* Leave it. */ @@ -4113,6 +4171,7 @@ hwloc_topology_restrict(struct hwloc_topology *topology, hwloc_const_bitmap_t se /* cpuset to clear */ if (flags & HWLOC_RESTRICT_FLAG_REMOVE_MEMLESS) { hwloc_obj_t pu = hwloc_get_obj_by_type(topology, HWLOC_OBJ_PU, 0); + assert(pu); do { /* PU will be removed if cpuset gets or was empty */ if (hwloc_bitmap_iszero(pu->cpuset) @@ -4148,6 +4207,7 @@ hwloc_topology_restrict(struct hwloc_topology *topology, hwloc_const_bitmap_t se /* nodeset to clear */ if (flags & HWLOC_RESTRICT_FLAG_REMOVE_CPULESS) { hwloc_obj_t node = hwloc_get_obj_by_type(topology, HWLOC_OBJ_NUMANODE, 0); + assert(node); do { /* node will be removed if nodeset gets or was empty */ if (hwloc_bitmap_iszero(node->cpuset) @@ -4242,6 +4302,9 @@ hwloc_topology_allow(struct hwloc_topology *topology, goto error; } topology->binding_hooks.get_allowed_resources(topology); + /* make sure the backend returned something sane (Linux cpusets may return offline PUs in some cases) */ + hwloc_bitmap_and(topology->allowed_cpuset, topology->allowed_cpuset, hwloc_get_root_obj(topology)->cpuset); + hwloc_bitmap_and(topology->allowed_nodeset, topology->allowed_nodeset, hwloc_get_root_obj(topology)->nodeset); break; } case HWLOC_ALLOW_FLAG_CUSTOM: {