diff options
Diffstat (limited to 'hwloc-1.2.1/src/topology-solaris.c')
-rw-r--r-- | hwloc-1.2.1/src/topology-solaris.c | 667 |
1 files changed, 667 insertions, 0 deletions
diff --git a/hwloc-1.2.1/src/topology-solaris.c b/hwloc-1.2.1/src/topology-solaris.c new file mode 100644 index 00000000..55aff8c8 --- /dev/null +++ b/hwloc-1.2.1/src/topology-solaris.c @@ -0,0 +1,667 @@ +/* + * Copyright © 2009 CNRS + * Copyright © 2009-2011 INRIA. All rights reserved. + * Copyright © 2009-2011 Université Bordeaux 1 + * Copyright © 2011 Cisco Systems, Inc. All rights reserved. + * See COPYING in top-level directory. + */ + +#include <private/autogen/config.h> +#include <hwloc.h> +#include <private/private.h> +#include <private/debug.h> + +#include <stdio.h> +#include <errno.h> +#include <dirent.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/processor.h> +#include <sys/procset.h> +#include <sys/types.h> +#include <sys/mman.h> + +#ifdef HAVE_LIBLGRP +# include <sys/lgrp_user.h> +#endif + +/* TODO: use psets? (only for root) + * TODO: get cache info from prtdiag? (it is setgid sys to be able to read from + * crw-r----- 1 root sys 88, 0 nov 3 14:35 /devices/pseudo/devinfo@0:devinfo + * and run (apparently undocumented) ioctls on it. + */ + +static int +hwloc_solaris_set_sth_cpubind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_const_bitmap_t hwloc_set, int flags) +{ + unsigned target_cpu; + + /* The resulting binding is always strict */ + + if (hwloc_bitmap_isequal(hwloc_set, hwloc_topology_get_complete_cpuset(topology))) { + if (processor_bind(idtype, id, PBIND_NONE, NULL) != 0) + return -1; +#ifdef HAVE_LIBLGRP + if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) { + int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); + if (depth >= 0) { + int n = hwloc_get_nbobjs_by_depth(topology, depth); + int i; + + for (i = 0; i < n; i++) { + hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); + lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_NONE); + } + } + } +#endif /* HAVE_LIBLGRP */ + return 0; + } + +#ifdef HAVE_LIBLGRP + if (!(flags & HWLOC_CPUBIND_NOMEMBIND)) { + int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); + if (depth >= 0) { + int n = hwloc_get_nbobjs_by_depth(topology, depth); + int i; + int ok; + hwloc_bitmap_t target = hwloc_bitmap_alloc(); + + for (i = 0; i < n; i++) { + hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); + if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set)) + hwloc_bitmap_or(target, target, obj->cpuset); + } + + ok = hwloc_bitmap_isequal(target, hwloc_set); + hwloc_bitmap_free(target); + + if (ok) { + /* Ok, managed to achieve hwloc_set by just combining NUMA nodes */ + + for (i = 0; i < n; i++) { + hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); + + if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set)) { + lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_STRONG); + } else { + if (flags & HWLOC_CPUBIND_STRICT) + lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_NONE); + else + lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_WEAK); + } + } + + return 0; + } + } + } +#endif /* HAVE_LIBLGRP */ + + if (hwloc_bitmap_weight(hwloc_set) != 1) { + errno = EXDEV; + return -1; + } + + target_cpu = hwloc_bitmap_first(hwloc_set); + + if (processor_bind(idtype, id, + (processorid_t) (target_cpu), NULL) != 0) + return -1; + + return 0; +} + +static int +hwloc_solaris_set_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_bitmap_t hwloc_set, int flags) +{ + return hwloc_solaris_set_sth_cpubind(topology, P_PID, pid, hwloc_set, flags); +} + +static int +hwloc_solaris_set_thisproc_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags) +{ + return hwloc_solaris_set_sth_cpubind(topology, P_PID, P_MYID, hwloc_set, flags); +} + +static int +hwloc_solaris_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set, int flags) +{ + return hwloc_solaris_set_sth_cpubind(topology, P_LWPID, P_MYID, hwloc_set, flags); +} + +#ifdef HAVE_LIBLGRP +static int +hwloc_solaris_get_sth_cpubind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused) +{ + int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); + int n; + int i; + + if (depth < 0) { + errno = ENOSYS; + return -1; + } + + hwloc_bitmap_zero(hwloc_set); + n = hwloc_get_nbobjs_by_depth(topology, depth); + + for (i = 0; i < n; i++) { + hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); + lgrp_affinity_t aff = lgrp_affinity_get(idtype, id, obj->os_index); + + if (aff == LGRP_AFF_STRONG) + hwloc_bitmap_or(hwloc_set, hwloc_set, obj->cpuset); + } + + if (hwloc_bitmap_iszero(hwloc_set)) + hwloc_bitmap_copy(hwloc_set, hwloc_topology_get_complete_cpuset(topology)); + + return 0; +} + +static int +hwloc_solaris_get_proc_cpubind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_t hwloc_set, int flags) +{ + return hwloc_solaris_get_sth_cpubind(topology, P_PID, pid, hwloc_set, flags); +} + +static int +hwloc_solaris_get_thisproc_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags) +{ + return hwloc_solaris_get_sth_cpubind(topology, P_PID, P_MYID, hwloc_set, flags); +} + +static int +hwloc_solaris_get_thisthread_cpubind(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags) +{ + return hwloc_solaris_get_sth_cpubind(topology, P_LWPID, P_MYID, hwloc_set, flags); +} +#endif /* HAVE_LIBLGRP */ + +/* TODO: given thread, probably not easy because of the historical n:m implementation */ +#ifdef HAVE_LIBLGRP +static int +hwloc_solaris_set_sth_membind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) +{ + int depth; + int n, i; + + switch (policy) { + case HWLOC_MEMBIND_DEFAULT: + case HWLOC_MEMBIND_BIND: + break; + default: + errno = ENOSYS; + return -1; + } + + if (flags & HWLOC_MEMBIND_NOCPUBIND) { + errno = ENOSYS; + return -1; + } + + depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); + if (depth < 0) { + errno = EXDEV; + return -1; + } + n = hwloc_get_nbobjs_by_depth(topology, depth); + + for (i = 0; i < n; i++) { + hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); + if (hwloc_bitmap_isset(nodeset, obj->os_index)) { + lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_STRONG); + } else { + if (flags & HWLOC_CPUBIND_STRICT) + lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_NONE); + else + lgrp_affinity_set(idtype, id, obj->os_index, LGRP_AFF_WEAK); + } + } + + return 0; +} + +static int +hwloc_solaris_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) +{ + return hwloc_solaris_set_sth_membind(topology, P_PID, pid, nodeset, policy, flags); +} + +static int +hwloc_solaris_set_thisproc_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) +{ + return hwloc_solaris_set_sth_membind(topology, P_PID, P_MYID, nodeset, policy, flags); +} + +static int +hwloc_solaris_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) +{ + return hwloc_solaris_set_sth_membind(topology, P_LWPID, P_MYID, nodeset, policy, flags); +} + +static int +hwloc_solaris_get_sth_membind(hwloc_topology_t topology, idtype_t idtype, id_t id, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags __hwloc_attribute_unused) +{ + int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NODE); + int n; + int i; + + if (depth < 0) { + errno = ENOSYS; + return -1; + } + + hwloc_bitmap_zero(nodeset); + n = hwloc_get_nbobjs_by_depth(topology, depth); + + for (i = 0; i < n; i++) { + hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); + lgrp_affinity_t aff = lgrp_affinity_get(idtype, id, obj->os_index); + + if (aff == LGRP_AFF_STRONG) + hwloc_bitmap_set(nodeset, obj->os_index); + } + + if (hwloc_bitmap_iszero(nodeset)) + hwloc_bitmap_copy(nodeset, hwloc_topology_get_complete_nodeset(topology)); + + *policy = HWLOC_MEMBIND_DEFAULT; + return 0; +} + +static int +hwloc_solaris_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags) +{ + return hwloc_solaris_get_sth_membind(topology, P_PID, pid, nodeset, policy, flags); +} + +static int +hwloc_solaris_get_thisproc_membind(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags) +{ + return hwloc_solaris_get_sth_membind(topology, P_PID, P_MYID, nodeset, policy, flags); +} + +static int +hwloc_solaris_get_thisthread_membind(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_membind_policy_t *policy, int flags) +{ + return hwloc_solaris_get_sth_membind(topology, P_LWPID, P_MYID, nodeset, policy, flags); +} +#endif /* HAVE_LIBLGRP */ + + +#ifdef MADV_ACCESS_LWP +static int +hwloc_solaris_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags __hwloc_attribute_unused) +{ + int advice; + size_t remainder; + + /* Can not give a set of nodes just for an area. */ + if (!hwloc_bitmap_isequal(nodeset, hwloc_topology_get_complete_nodeset(topology))) { + errno = EXDEV; + return -1; + } + + switch (policy) { + case HWLOC_MEMBIND_DEFAULT: + case HWLOC_MEMBIND_BIND: + advice = MADV_ACCESS_DEFAULT; + break; + case HWLOC_MEMBIND_FIRSTTOUCH: + case HWLOC_MEMBIND_NEXTTOUCH: + advice = MADV_ACCESS_LWP; + break; + case HWLOC_MEMBIND_INTERLEAVE: + advice = MADV_ACCESS_MANY; + break; + default: + errno = ENOSYS; + return -1; + } + + remainder = (uintptr_t) addr & (sysconf(_SC_PAGESIZE)-1); + addr = (char*) addr - remainder; + len += remainder; + return madvise((void*) addr, len, advice); +} +#endif + +#ifdef HAVE_LIBLGRP +static void +browse(struct hwloc_topology *topology, lgrp_cookie_t cookie, lgrp_id_t lgrp, hwloc_obj_t *glob_lgrps, unsigned *curlgrp) +{ + int n; + hwloc_obj_t obj; + lgrp_mem_size_t mem_size; + + n = lgrp_cpus(cookie, lgrp, NULL, 0, LGRP_CONTENT_HIERARCHY); + if (n == -1) + return; + + /* Is this lgrp a NUMA node? */ + if ((mem_size = lgrp_mem_size(cookie, lgrp, LGRP_MEM_SZ_INSTALLED, LGRP_CONTENT_DIRECT)) > 0) + { + int i; + processorid_t *cpuids; + cpuids = malloc(sizeof(processorid_t) * n); + assert(cpuids != NULL); + + obj = hwloc_alloc_setup_object(HWLOC_OBJ_NODE, lgrp); + obj->nodeset = hwloc_bitmap_alloc(); + hwloc_bitmap_set(obj->nodeset, lgrp); + obj->cpuset = hwloc_bitmap_alloc(); + glob_lgrps[(*curlgrp)++] = obj; + + lgrp_cpus(cookie, lgrp, cpuids, n, LGRP_CONTENT_HIERARCHY); + for (i = 0; i < n ; i++) { + hwloc_debug("node %ld's cpu %d is %d\n", lgrp, i, cpuids[i]); + hwloc_bitmap_set(obj->cpuset, cpuids[i]); + } + hwloc_debug_1arg_bitmap("node %ld has cpuset %s\n", + lgrp, obj->cpuset); + + /* or LGRP_MEM_SZ_FREE */ + hwloc_debug("node %ld has %lldkB\n", lgrp, mem_size/1024); + obj->memory.local_memory = mem_size; + 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); + free(cpuids); + } + + n = lgrp_children(cookie, lgrp, NULL, 0); + { + lgrp_id_t *lgrps; + int i; + + lgrps = malloc(sizeof(lgrp_id_t) * n); + assert(lgrps != NULL); + lgrp_children(cookie, lgrp, lgrps, n); + hwloc_debug("lgrp %ld has %d children\n", lgrp, n); + for (i = 0; i < n ; i++) + { + browse(topology, cookie, lgrps[i], glob_lgrps, curlgrp); + } + hwloc_debug("lgrp %ld's children done\n", lgrp); + free(lgrps); + } +} + +static void +hwloc_look_lgrp(struct hwloc_topology *topology) +{ + lgrp_cookie_t cookie; + unsigned curlgrp = 0; + int nlgrps; + lgrp_id_t root; + + if ((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM)) + cookie = lgrp_init(LGRP_VIEW_OS); + else + cookie = lgrp_init(LGRP_VIEW_CALLER); + if (cookie == LGRP_COOKIE_NONE) + { + hwloc_debug("lgrp_init failed: %s\n", strerror(errno)); + return; + } + nlgrps = lgrp_nlgrps(cookie); + root = lgrp_root(cookie); + { + hwloc_obj_t *glob_lgrps = calloc(nlgrps, sizeof(hwloc_obj_t)); + browse(topology, cookie, root, glob_lgrps, &curlgrp); +#ifdef HAVE_LGRP_LATENCY_COOKIE + { + float *distances = calloc(curlgrp*curlgrp, sizeof(float)); + unsigned *indexes = calloc(curlgrp,sizeof(unsigned)); + unsigned i, j; + for (i = 0; i < curlgrp; i++) { + indexes[i] = glob_lgrps[i]->os_index; + for (j = 0; j < curlgrp; j++) + distances[i*curlgrp+j] = (float) lgrp_latency_cookie(cookie, glob_lgrps[i]->os_index, glob_lgrps[j]->os_index, LGRP_LAT_CPU_TO_MEM); + } + hwloc_topology__set_distance_matrix(topology, HWLOC_OBJ_NODE, curlgrp, indexes, glob_lgrps, distances); + } +#endif /* HAVE_LGRP_LATENCY_COOKIE */ + } + lgrp_fini(cookie); +} +#endif /* LIBLGRP */ + +#ifdef HAVE_LIBKSTAT +#include <kstat.h> +#define HWLOC_NBMAXCPUS 1024 /* FIXME: drop */ +static int +hwloc_look_kstat(struct hwloc_topology *topology) +{ + kstat_ctl_t *kc = kstat_open(); + kstat_t *ksp; + kstat_named_t *stat; + unsigned look_cores = 1, look_chips = 1; + + unsigned numsockets = 0; + unsigned proc_physids[HWLOC_NBMAXCPUS]; + unsigned proc_osphysids[HWLOC_NBMAXCPUS]; + unsigned osphysids[HWLOC_NBMAXCPUS]; + + unsigned numcores = 0; + unsigned proc_coreids[HWLOC_NBMAXCPUS]; + unsigned oscoreids[HWLOC_NBMAXCPUS]; + + unsigned core_osphysids[HWLOC_NBMAXCPUS]; + + unsigned numprocs = 0; + unsigned proc_procids[HWLOC_NBMAXCPUS]; + unsigned osprocids[HWLOC_NBMAXCPUS]; + + unsigned physid, coreid, cpuid; + unsigned procid_max = 0; + unsigned i; + + for (cpuid = 0; cpuid < HWLOC_NBMAXCPUS; cpuid++) + { + proc_procids[cpuid] = -1; + proc_physids[cpuid] = -1; + proc_osphysids[cpuid] = -1; + proc_coreids[cpuid] = -1; + } + + if (!kc) + { + hwloc_debug("kstat_open failed: %s\n", strerror(errno)); + return 0; + } + + for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) + { + if (strncmp("cpu_info", ksp->ks_module, 8)) + continue; + + cpuid = ksp->ks_instance; + if (cpuid > HWLOC_NBMAXCPUS) + { + fprintf(stderr,"CPU id too big: %u\n", cpuid); + continue; + } + + if (kstat_read(kc, ksp, NULL) == -1) + { + fprintf(stderr, "kstat_read failed for CPU%u: %s\n", cpuid, strerror(errno)); + continue; + } + + hwloc_debug("cpu%u\n", cpuid); + proc_procids[cpuid] = numprocs; + osprocids[numprocs] = cpuid; + numprocs++; + + if (cpuid >= procid_max) + procid_max = cpuid + 1; + + stat = (kstat_named_t *) kstat_data_lookup(ksp, "state"); + if (!stat) + hwloc_debug("could not read state for CPU%u: %s\n", cpuid, strerror(errno)); + else if (stat->data_type != KSTAT_DATA_CHAR) + hwloc_debug("unknown kstat type %d for cpu state\n", stat->data_type); + else + { + hwloc_debug("cpu%u's state is %s\n", cpuid, stat->value.c); + if (strcmp(stat->value.c, "on-line")) + /* not online */ + hwloc_bitmap_clr(topology->levels[0][0]->online_cpuset, cpuid); + } + + if (look_chips) do { + /* Get Chip ID */ + stat = (kstat_named_t *) kstat_data_lookup(ksp, "chip_id"); + if (!stat) + { + if (numsockets) + fprintf(stderr, "could not read socket id for CPU%u: %s\n", cpuid, strerror(errno)); + else + hwloc_debug("could not read socket id for CPU%u: %s\n", cpuid, strerror(errno)); + look_chips = 0; + continue; + } + switch (stat->data_type) { + case KSTAT_DATA_INT32: + physid = stat->value.i32; + break; + case KSTAT_DATA_UINT32: + physid = stat->value.ui32; + break; +#ifdef _INT64_TYPE + case KSTAT_DATA_UINT64: + physid = stat->value.ui64; + break; + case KSTAT_DATA_INT64: + physid = stat->value.i64; + break; +#endif + default: + fprintf(stderr, "chip_id type %d unknown\n", stat->data_type); + look_chips = 0; + continue; + } + proc_osphysids[cpuid] = physid; + for (i = 0; i < numsockets; i++) + if (physid == osphysids[i]) + break; + proc_physids[cpuid] = i; + hwloc_debug("%u on socket %u (%u)\n", cpuid, i, physid); + if (i == numsockets) + osphysids[numsockets++] = physid; + } while(0); + + if (look_cores) do { + /* Get Core ID */ + stat = (kstat_named_t *) kstat_data_lookup(ksp, "core_id"); + if (!stat) + { + if (numcores) + fprintf(stderr, "could not read core id for CPU%u: %s\n", cpuid, strerror(errno)); + else + hwloc_debug("could not read core id for CPU%u: %s\n", cpuid, strerror(errno)); + look_cores = 0; + continue; + } + switch (stat->data_type) { + case KSTAT_DATA_INT32: + coreid = stat->value.i32; + break; + case KSTAT_DATA_UINT32: + coreid = stat->value.ui32; + break; +#ifdef _INT64_TYPE + case KSTAT_DATA_UINT64: + coreid = stat->value.ui64; + break; + case KSTAT_DATA_INT64: + coreid = stat->value.i64; + break; +#endif + default: + fprintf(stderr, "core_id type %d unknown\n", stat->data_type); + look_cores = 0; + continue; + } + for (i = 0; i < numcores; i++) + if (coreid == oscoreids[i] && proc_osphysids[cpuid] == core_osphysids[i]) + break; + proc_coreids[cpuid] = i; + hwloc_debug("%u on core %u (%u)\n", cpuid, i, coreid); + if (i == numcores) + { + core_osphysids[numcores] = proc_osphysids[cpuid]; + oscoreids[numcores++] = coreid; + } + } while(0); + + /* Note: there is also clog_id for the Thread ID (not unique) and + * pkg_core_id for the core ID (not unique). They are not useful to us + * however. */ + } + + if (look_chips) + hwloc_setup_level(procid_max, numsockets, osphysids, proc_physids, topology, HWLOC_OBJ_SOCKET); + + if (look_cores) + hwloc_setup_level(procid_max, numcores, oscoreids, proc_coreids, topology, HWLOC_OBJ_CORE); + + if (numprocs) + hwloc_setup_level(procid_max, numprocs, osprocids, proc_procids, topology, HWLOC_OBJ_PU); + + kstat_close(kc); + + return numprocs > 0; +} +#endif /* LIBKSTAT */ + +void +hwloc_look_solaris(struct hwloc_topology *topology) +{ + unsigned nbprocs = hwloc_fallback_nbprocessors (topology); +#ifdef HAVE_LIBLGRP + hwloc_look_lgrp(topology); +#endif /* HAVE_LIBLGRP */ +#ifdef HAVE_LIBKSTAT + nbprocs = 0; + if (hwloc_look_kstat(topology)) + return; +#endif /* HAVE_LIBKSTAT */ + hwloc_setup_pu_level(topology, nbprocs); + + hwloc_add_object_info(topology->levels[0][0], "Backend", "Solaris"); +} + +void +hwloc_set_solaris_hooks(struct hwloc_topology *topology) +{ + topology->set_proc_cpubind = hwloc_solaris_set_proc_cpubind; + topology->set_thisproc_cpubind = hwloc_solaris_set_thisproc_cpubind; + topology->set_thisthread_cpubind = hwloc_solaris_set_thisthread_cpubind; +#ifdef HAVE_LIBLGRP + topology->get_proc_cpubind = hwloc_solaris_get_proc_cpubind; + topology->get_thisproc_cpubind = hwloc_solaris_get_thisproc_cpubind; + topology->get_thisthread_cpubind = hwloc_solaris_get_thisthread_cpubind; + topology->set_proc_membind = hwloc_solaris_set_proc_membind; + topology->set_thisproc_membind = hwloc_solaris_set_thisproc_membind; + topology->set_thisthread_membind = hwloc_solaris_set_thisthread_membind; + topology->get_proc_membind = hwloc_solaris_get_proc_membind; + topology->get_thisproc_membind = hwloc_solaris_get_thisproc_membind; + topology->get_thisthread_membind = hwloc_solaris_get_thisthread_membind; +#endif /* HAVE_LIBLGRP */ +#ifdef MADV_ACCESS_LWP + topology->set_area_membind = hwloc_solaris_set_area_membind; + topology->support.membind->firsttouch_membind = 1; + topology->support.membind->bind_membind = 1; + topology->support.membind->interleave_membind = 1; + topology->support.membind->nexttouch_membind = 1; +#endif +} |