diff options
Diffstat (limited to 'hwloc-1.2.1/src/topology-darwin.c')
-rw-r--r-- | hwloc-1.2.1/src/topology-darwin.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/hwloc-1.2.1/src/topology-darwin.c b/hwloc-1.2.1/src/topology-darwin.c new file mode 100644 index 00000000..d5d0ef4a --- /dev/null +++ b/hwloc-1.2.1/src/topology-darwin.c @@ -0,0 +1,216 @@ +/* + * Copyright © 2009 CNRS + * Copyright © 2009-2010 INRIA. All rights reserved. + * Copyright © 2009-2010 Université Bordeaux 1 + * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. + * See COPYING in top-level directory. + */ + +/* Detect topology change: registering for power management changes and check + * if for example hw.activecpu changed */ + +/* Apparently, Darwin people do not _want_ to provide binding functions. */ + +#include <private/autogen/config.h> + +#include <sys/types.h> +#include <sys/sysctl.h> +#include <stdlib.h> +#include <inttypes.h> + +#include <hwloc.h> +#include <private/private.h> +#include <private/debug.h> + +void +hwloc_look_darwin(struct hwloc_topology *topology) +{ + int64_t _nprocs; + unsigned nprocs; + int64_t _npackages; + unsigned i, j, cpu; + struct hwloc_obj *obj; + size_t size; + int64_t l1cachesize; + int64_t l2cachesize; + int64_t cachelinesize; + int64_t memsize; + + if (hwloc_get_sysctlbyname("hw.ncpu", &_nprocs) || _nprocs <= 0) + return; + nprocs = _nprocs; + topology->support.discovery->pu = 1; + + hwloc_debug("%u procs\n", nprocs); + + if (!hwloc_get_sysctlbyname("hw.packages", &_npackages) && _npackages > 0) { + unsigned npackages = _npackages; + int64_t _cores_per_package; + int64_t _logical_per_package; + unsigned logical_per_package; + + hwloc_debug("%u packages\n", npackages); + + if (!hwloc_get_sysctlbyname("machdep.cpu.logical_per_package", &_logical_per_package) && _logical_per_package > 0) + logical_per_package = _logical_per_package; + else + /* Assume the trivia. */ + logical_per_package = nprocs / npackages; + + hwloc_debug("%u threads per package\n", logical_per_package); + + + if (nprocs == npackages * logical_per_package) + for (i = 0; i < npackages; i++) { + obj = hwloc_alloc_setup_object(HWLOC_OBJ_SOCKET, i); + obj->cpuset = hwloc_bitmap_alloc(); + for (cpu = i*logical_per_package; cpu < (i+1)*logical_per_package; cpu++) + hwloc_bitmap_set(obj->cpuset, cpu); + + hwloc_debug_1arg_bitmap("package %u has cpuset %s\n", + i, obj->cpuset); + hwloc_insert_object_by_cpuset(topology, obj); + } + + if (!hwloc_get_sysctlbyname("machdep.cpu.cores_per_package", &_cores_per_package) && _cores_per_package > 0) { + unsigned cores_per_package = _cores_per_package; + hwloc_debug("%u cores per package\n", cores_per_package); + + if (!(logical_per_package % cores_per_package)) + for (i = 0; i < npackages * cores_per_package; i++) { + obj = hwloc_alloc_setup_object(HWLOC_OBJ_CORE, i); + obj->cpuset = hwloc_bitmap_alloc(); + for (cpu = i*(logical_per_package/cores_per_package); + cpu < (i+1)*(logical_per_package/cores_per_package); + cpu++) + hwloc_bitmap_set(obj->cpuset, cpu); + + hwloc_debug_1arg_bitmap("core %u has cpuset %s\n", + i, obj->cpuset); + hwloc_insert_object_by_cpuset(topology, obj); + } + } + } + + if (hwloc_get_sysctlbyname("hw.l1dcachesize", &l1cachesize)) + l1cachesize = 0; + + if (hwloc_get_sysctlbyname("hw.l2cachesize", &l2cachesize)) + l2cachesize = 0; + + if (hwloc_get_sysctlbyname("hw.cachelinesize", &cachelinesize)) + cachelinesize = 0; + + if (hwloc_get_sysctlbyname("hw.memsize", &memsize)) + memsize = 0; + + if (!sysctlbyname("hw.cacheconfig", NULL, &size, NULL, 0)) { + unsigned n = size / sizeof(uint32_t); + uint64_t *cacheconfig = NULL; + uint64_t *cachesize = NULL; + uint32_t *cacheconfig32 = NULL; + + cacheconfig = malloc(sizeof(uint64_t) * n); + if (NULL == cacheconfig) { + goto out; + } + cachesize = malloc(sizeof(uint64_t) * n); + if (NULL == cachesize) { + goto out; + } + cacheconfig32 = malloc(sizeof(uint32_t) * n); + if (NULL == cacheconfig32) { + goto out; + } + + if ((!sysctlbyname("hw.cacheconfig", cacheconfig, &size, NULL, 0))) { + /* Yeech. Darwin seemingly has changed from 32bit to 64bit integers for + * cacheconfig, with apparently no way for detection. Assume the machine + * won't have more than 4 billion cpus */ + if (cacheconfig[0] > 0xFFFFFFFFUL) { + memcpy(cacheconfig32, cacheconfig, size); + for (i = 0 ; i < size / sizeof(uint32_t); i++) + cacheconfig[i] = cacheconfig32[i]; + } + + memset(cachesize, 0, sizeof(uint64_t) * n); + size = sizeof(uint64_t) * n; + if (sysctlbyname("hw.cachesize", cachesize, &size, NULL, 0)) { + if (n > 0) + cachesize[0] = memsize; + if (n > 1) + cachesize[1] = l1cachesize; + if (n > 2) + cachesize[2] = l2cachesize; + } + + hwloc_debug("%s", "caches"); + for (i = 0; i < n && cacheconfig[i]; i++) + hwloc_debug(" %"PRIu64"(%"PRIu64"kB)", cacheconfig[i], cachesize[i] / 1024); + + cacheconfig[i] = cacheconfig32[i]; + /* Now we know how many caches there are */ + n = i; + hwloc_debug("\n%u cache levels\n", n - 1); + + /* For each cache level (0 is memory) */ + for (i = 0; i < n; i++) { + /* cacheconfig tells us how many cpus share it, let's iterate on each cache */ + for (j = 0; j < (nprocs / cacheconfig[i]); j++) { + obj = hwloc_alloc_setup_object(i?HWLOC_OBJ_CACHE:HWLOC_OBJ_NODE, j); + if (!i) { + obj->nodeset = hwloc_bitmap_alloc(); + hwloc_bitmap_set(obj->nodeset, j); + } + obj->cpuset = hwloc_bitmap_alloc(); + for (cpu = j*cacheconfig[i]; + cpu < ((j+1)*cacheconfig[i]); + cpu++) + hwloc_bitmap_set(obj->cpuset, cpu); + + if (i) { + hwloc_debug_2args_bitmap("L%ucache %u has cpuset %s\n", + i, j, obj->cpuset); + obj->attr->cache.depth = i; + obj->attr->cache.size = cachesize[i]; + obj->attr->cache.linesize = cachelinesize; + } else { + hwloc_debug_1arg_bitmap("node %u has cpuset %s\n", + j, obj->cpuset); + obj->memory.local_memory = cachesize[i]; + obj->memory.page_types_len = 2; + obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types)); + memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types)); + obj->memory.page_types[0].size = getpagesize(); +#ifdef HAVE__SC_LARGE_PAGESIZE + obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE); +#endif + } + + hwloc_insert_object_by_cpuset(topology, obj); + } + } + } + out: + if (NULL != cacheconfig) { + free(cacheconfig); + } + if (NULL != cachesize) { + free(cachesize); + } + if (NULL != cacheconfig32) { + free(cacheconfig32); + } + } + + + /* add PU objects */ + hwloc_setup_pu_level(topology, nprocs); + + hwloc_add_object_info(topology->levels[0][0], "Backend", "Darwin"); +} + +void +hwloc_set_darwin_hooks(struct hwloc_topology *topology __hwloc_attribute_unused) +{ +} |