summaryrefslogtreecommitdiffstats
path: root/hwloc-1.2.1/src/topology-solaris.c
diff options
context:
space:
mode:
Diffstat (limited to 'hwloc-1.2.1/src/topology-solaris.c')
-rw-r--r--hwloc-1.2.1/src/topology-solaris.c667
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
+}