Beispiel #1
0
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)
{
  processorid_t binding;
  int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
  int n;
  int i;

  if (depth < 0) {
    errno = ENOSYS;
    return -1;
  }

  /* first check if processor_bind() was used to bind to a single processor rather than to an lgroup */
  if ( processor_bind(idtype, id, PBIND_QUERY, &binding) == 0 && binding != PBIND_NONE ) {
    hwloc_bitmap_only(hwloc_set, binding);
    return 0;
  }

  /* if not, check lgroups */
  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;
}
Beispiel #2
0
static HYD_status handle_rr_binding(void)
{
    int i;
    HYD_status status = HYD_SUCCESS;

    HYDU_FUNC_ENTER();

    HYDU_ASSERT(hwloc_initialized, status);

    /* initialize bitmaps */
    HYDT_topo_hwloc_info.num_bitmaps = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_PU);

    HYDU_MALLOC_OR_JUMP(HYDT_topo_hwloc_info.bitmap, hwloc_bitmap_t *,
                        HYDT_topo_hwloc_info.num_bitmaps * sizeof(hwloc_bitmap_t), status);

    for (i = 0; i < HYDT_topo_hwloc_info.num_bitmaps; i++) {
        HYDT_topo_hwloc_info.bitmap[i] = hwloc_bitmap_alloc();
        hwloc_bitmap_only(HYDT_topo_hwloc_info.bitmap[i], i);
    }

  fn_exit:
    HYDU_FUNC_EXIT();
    return status;

  fn_fail:
    goto fn_exit;
}
Beispiel #3
0
static int
hwloc_win_get_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags)
{
  SYSTEM_INFO SystemInfo;
  DWORD page_size;
  uintptr_t start;
  unsigned nb;

  GetSystemInfo(&SystemInfo);
  page_size = SystemInfo.dwPageSize;

  start = (((uintptr_t) addr) / page_size) * page_size;
  nb = (unsigned)((((uintptr_t) addr + len - start) + page_size - 1) / page_size);

  if (!nb)
    nb = 1;

  {
    PSAPI_WORKING_SET_EX_INFORMATION *pv;
    unsigned i;

    pv = calloc(nb, sizeof(*pv));

    for (i = 0; i < nb; i++)
      pv[i].VirtualAddress = (void*) (start + i * page_size);
    if (!QueryWorkingSetExProc(GetCurrentProcess(), pv, nb * sizeof(*pv))) {
      free(pv);
      return -1;
    }
    *policy = HWLOC_MEMBIND_BIND;
    if (flags & HWLOC_MEMBIND_STRICT) {
      unsigned node = pv[0].VirtualAttributes.Node;
      for (i = 1; i < nb; i++) {
        if (pv[i].VirtualAttributes.Node != node) {
          errno = EXDEV;
          free(pv);
          return -1;
        }
      }
      hwloc_bitmap_only(nodeset, node);
      free(pv);
      return 0;
    }
    hwloc_bitmap_zero(nodeset);
    for (i = 0; i < nb; i++)
      hwloc_bitmap_set(nodeset, pv[i].VirtualAttributes.Node);
    free(pv);
    return 0;
  }
}
Beispiel #4
0
static int
hwloc_aix_get_thisthread_last_cpu_location(hwloc_topology_t topology, hwloc_bitmap_t hwloc_set, int flags __hwloc_attribute_unused)
{
  cpu_t cpu;

  if (topology->pid) {
    errno = ENOSYS;
    return -1;
  }

  cpu = mycpu();
  if (cpu < 0)
    return -1;

  hwloc_bitmap_only(hwloc_set, cpu);
  return 0;
}
Beispiel #5
0
std::size_t thread_affinity_worker(std::size_t desired)
{
    // Returns the OS-thread number of the worker that is running this
    // PX-thread.
    std::size_t current = hpx::get_worker_thread_num();
    bool numa_sensitive = hpx::is_scheduler_numa_sensitive();

    if (current == desired)
    {
        // extract the desired affinity mask
        hpx::threads::topology const& t = hpx::get_runtime().get_topology();
        hpx::threads::mask_type desired_mask = t.get_thread_affinity_mask(current, numa_sensitive);

#if defined(HPX_HAVE_HWLOC)
        std::size_t idx = hpx::threads::find_first(desired_mask);

        hwloc_topology_t topo;
        hwloc_topology_init(&topo);
        hwloc_topology_load(topo);

        // retrieve the current affinity mask
        hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
        hwloc_bitmap_zero(cpuset);
        if (0 == hwloc_get_cpubind(topo, cpuset, HWLOC_CPUBIND_THREAD)) {
            // sadly get_cpubind is not implemented for Windows based systems
            hwloc_cpuset_t cpuset_cmp = hwloc_bitmap_alloc();
            hwloc_bitmap_zero(cpuset_cmp);
            hwloc_bitmap_only(cpuset_cmp, unsigned(idx));
            HPX_TEST(hwloc_bitmap_compare(cpuset, cpuset_cmp) == 0);
            hwloc_bitmap_free(cpuset_cmp);
        }
        else
        {
            HPX_TEST(false && "hwloc_get_cpubind(topo, cpuset, HWLOC_CPUBIND_THREAD) failed!");
        }

        hwloc_bitmap_free(cpuset);
        hwloc_topology_destroy(topo);
#endif
        return desired;
    }

    // This PX-thread has been run by the wrong OS-thread, make the foreman
    // try again by rescheduling it.
    return std::size_t(-1);
}
 void UseOnly(ui32 id) {
     hwloc_bitmap_only(Set, id);
 }
Beispiel #7
0
static int
hwloc_look_windows(struct hwloc_backend *backend)
{
  struct hwloc_topology *topology = backend->topology;
  hwloc_bitmap_t groups_pu_set = NULL;
  SYSTEM_INFO SystemInfo;
  DWORD length;

  if (topology->levels[0][0]->cpuset)
    /* somebody discovered things */
    return -1;

  hwloc_alloc_obj_cpusets(topology->levels[0][0]);

  GetSystemInfo(&SystemInfo);

  if (!GetLogicalProcessorInformationExProc && GetLogicalProcessorInformationProc) {
      PSYSTEM_LOGICAL_PROCESSOR_INFORMATION procInfo, tmpprocInfo;
      unsigned id;
      unsigned i;
      struct hwloc_obj *obj;
      hwloc_obj_type_t type;

      length = 0;
      procInfo = NULL;

      while (1) {
        if (GetLogicalProcessorInformationProc(procInfo, &length))
          break;
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
          return -1;
        tmpprocInfo = realloc(procInfo, length);
        if (!tmpprocInfo) {
          free(procInfo);
          goto out;
        }
        procInfo = tmpprocInfo;
      }

      assert(!length || procInfo);

      for (i = 0; i < length / sizeof(*procInfo); i++) {

        /* Ignore unknown caches */
        if (procInfo->Relationship == RelationCache
                && procInfo->Cache.Type != CacheUnified
                && procInfo->Cache.Type != CacheData
                && procInfo->Cache.Type != CacheInstruction)
          continue;

        id = -1;
        switch (procInfo[i].Relationship) {
          case RelationNumaNode:
            type = HWLOC_OBJ_NUMANODE;
            id = procInfo[i].NumaNode.NodeNumber;
            break;
          case RelationProcessorPackage:
            type = HWLOC_OBJ_PACKAGE;
            break;
          case RelationCache:
            type = (procInfo[i].Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo[i].Cache.Level - 1;
            break;
          case RelationProcessorCore:
            type = HWLOC_OBJ_CORE;
            break;
          case RelationGroup:
          default:
            type = HWLOC_OBJ_GROUP;
            break;
        }

        if (!hwloc_filter_check_keep_object_type(topology, type))
          continue;

        obj = hwloc_alloc_setup_object(topology, type, id);
        obj->cpuset = hwloc_bitmap_alloc();
        hwloc_debug("%s#%u mask %lx\n", hwloc_type_name(type), id, procInfo[i].ProcessorMask);
        /* ProcessorMask is a ULONG_PTR */
        hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, 0, procInfo[i].ProcessorMask);
        hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_type_name(type), id, obj->cpuset);

        switch (type) {
          case HWLOC_OBJ_NUMANODE:
            {
              ULONGLONG avail;
              obj->nodeset = hwloc_bitmap_alloc();
              hwloc_bitmap_set(obj->nodeset, id);
              if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
               || (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail)))
                obj->memory.local_memory = avail;
              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_len = 1;
              obj->memory.page_types[0].size = SystemInfo.dwPageSize;
#if HAVE_DECL__SC_LARGE_PAGESIZE
              obj->memory.page_types_len++;
              obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
              break;
            }
          case HWLOC_OBJ_L1CACHE:
          case HWLOC_OBJ_L2CACHE:
          case HWLOC_OBJ_L3CACHE:
          case HWLOC_OBJ_L4CACHE:
          case HWLOC_OBJ_L5CACHE:
          case HWLOC_OBJ_L1ICACHE:
          case HWLOC_OBJ_L2ICACHE:
          case HWLOC_OBJ_L3ICACHE:
            obj->attr->cache.size = procInfo[i].Cache.Size;
            obj->attr->cache.associativity = procInfo[i].Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo[i].Cache.Associativity ;
            obj->attr->cache.linesize = procInfo[i].Cache.LineSize;
            obj->attr->cache.depth = procInfo[i].Cache.Level;
            switch (procInfo->Cache.Type) {
              case CacheUnified:
                obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
                break;
              case CacheData:
                obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
                break;
              case CacheInstruction:
                obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
                break;
              default:
                hwloc_free_unlinked_object(obj);
                continue;
            }
            break;
          case HWLOC_OBJ_GROUP:
            obj->attr->group.kind = procInfo[i].Relationship == RelationGroup ? HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP : HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN;
            break;
          default:
            break;
        }
        hwloc_insert_object_by_cpuset(topology, obj);
      }

      free(procInfo);
  }

  if (GetLogicalProcessorInformationExProc) {
      PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX procInfoTotal, tmpprocInfoTotal, procInfo;
      unsigned id;
      struct hwloc_obj *obj;
      hwloc_obj_type_t type;

      length = 0;
      procInfoTotal = NULL;

      while (1) {
        if (GetLogicalProcessorInformationExProc(RelationAll, procInfoTotal, &length))
          break;
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
          return -1;
        tmpprocInfoTotal = realloc(procInfoTotal, length);
        if (!tmpprocInfoTotal) {
          free(procInfoTotal);
          goto out;
        }
        procInfoTotal = tmpprocInfoTotal;
      }

      for (procInfo = procInfoTotal;
           (void*) procInfo < (void*) ((uintptr_t) procInfoTotal + length);
           procInfo = (void*) ((uintptr_t) procInfo + procInfo->Size)) {
        unsigned num, i;
        GROUP_AFFINITY *GroupMask;

        /* Ignore unknown caches */
        if (procInfo->Relationship == RelationCache
                && procInfo->Cache.Type != CacheUnified
                && procInfo->Cache.Type != CacheData
                && procInfo->Cache.Type != CacheInstruction)
          continue;

        id = -1;
        switch (procInfo->Relationship) {
          case RelationNumaNode:
            type = HWLOC_OBJ_NUMANODE;
            num = 1;
            GroupMask = &procInfo->NumaNode.GroupMask;
            id = procInfo->NumaNode.NodeNumber;
            break;
          case RelationProcessorPackage:
            type = HWLOC_OBJ_PACKAGE;
            num = procInfo->Processor.GroupCount;
            GroupMask = procInfo->Processor.GroupMask;
            break;
          case RelationCache:
            type = (procInfo->Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo->Cache.Level - 1;
            num = 1;
            GroupMask = &procInfo->Cache.GroupMask;
            break;
          case RelationProcessorCore:
            type = HWLOC_OBJ_CORE;
            num = procInfo->Processor.GroupCount;
            GroupMask = procInfo->Processor.GroupMask;
            break;
          case RelationGroup:
            /* So strange an interface... */
            for (id = 0; id < procInfo->Group.ActiveGroupCount; id++) {
              KAFFINITY mask;
              hwloc_bitmap_t set;

              set = hwloc_bitmap_alloc();
              mask = procInfo->Group.GroupInfo[id].ActiveProcessorMask;
              hwloc_debug("group %u %d cpus mask %lx\n", id,
                          procInfo->Group.GroupInfo[id].ActiveProcessorCount, mask);
              /* KAFFINITY is ULONG_PTR */
              hwloc_bitmap_set_ith_ULONG_PTR(set, id, mask);
              /* FIXME: what if running 32bits on a 64bits windows with 64-processor groups?
               * ULONG_PTR is 32bits, so half the group is invisible?
               * maybe scale id to id*8/sizeof(ULONG_PTR) so that groups are 64-PU aligned?
               */
              hwloc_debug_2args_bitmap("group %u %d bitmap %s\n", id, procInfo->Group.GroupInfo[id].ActiveProcessorCount, set);

              /* save the set of PUs so that we can create them at the end */
              if (!groups_pu_set)
                groups_pu_set = hwloc_bitmap_alloc();
              hwloc_bitmap_or(groups_pu_set, groups_pu_set, set);

              if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) {
                obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, id);
                obj->cpuset = set;
                obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP;
                hwloc_insert_object_by_cpuset(topology, obj);
              } else
                hwloc_bitmap_free(set);
            }
            continue;
          default:
            /* Don't know how to get the mask.  */
            hwloc_debug("unknown relation %d\n", procInfo->Relationship);
            continue;
        }

        if (!hwloc_filter_check_keep_object_type(topology, type))
          continue;

        obj = hwloc_alloc_setup_object(topology, type, id);
        obj->cpuset = hwloc_bitmap_alloc();
        for (i = 0; i < num; i++) {
          hwloc_debug("%s#%u %d: mask %d:%lx\n", hwloc_type_name(type), id, i, GroupMask[i].Group, GroupMask[i].Mask);
          /* GROUP_AFFINITY.Mask is KAFFINITY, which is ULONG_PTR */
          hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, GroupMask[i].Group, GroupMask[i].Mask);
          /* FIXME: scale id to id*8/sizeof(ULONG_PTR) as above? */
        }
        hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_type_name(type), id, obj->cpuset);
        switch (type) {
          case HWLOC_OBJ_NUMANODE:
            {
              ULONGLONG avail;
              obj->nodeset = hwloc_bitmap_alloc();
              hwloc_bitmap_set(obj->nodeset, id);
              if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
               || (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail)))
                obj->memory.local_memory = avail;
              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_len = 1;
              obj->memory.page_types[0].size = SystemInfo.dwPageSize;
#if HAVE_DECL__SC_LARGE_PAGESIZE
              obj->memory.page_types_len++;
              obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
              break;
            }
          case HWLOC_OBJ_L1CACHE:
          case HWLOC_OBJ_L2CACHE:
          case HWLOC_OBJ_L3CACHE:
          case HWLOC_OBJ_L4CACHE:
          case HWLOC_OBJ_L5CACHE:
          case HWLOC_OBJ_L1ICACHE:
          case HWLOC_OBJ_L2ICACHE:
          case HWLOC_OBJ_L3ICACHE:
            obj->attr->cache.size = procInfo->Cache.CacheSize;
            obj->attr->cache.associativity = procInfo->Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo->Cache.Associativity ;
            obj->attr->cache.linesize = procInfo->Cache.LineSize;
            obj->attr->cache.depth = procInfo->Cache.Level;
            switch (procInfo->Cache.Type) {
              case CacheUnified:
                obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
                break;
              case CacheData:
                obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
                break;
              case CacheInstruction:
                obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
                break;
              default:
                hwloc_free_unlinked_object(obj);
                continue;
            }
            break;
          default:
            break;
        }
        hwloc_insert_object_by_cpuset(topology, obj);
      }
      free(procInfoTotal);
  }

  if (groups_pu_set) {
    /* the system supports multiple Groups.
     * PU indexes may be discontiguous, especially if Groups contain less than 64 procs.
     */
    hwloc_obj_t obj;
    unsigned idx;
    hwloc_bitmap_foreach_begin(idx, groups_pu_set) {
      obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, idx);
      obj->cpuset = hwloc_bitmap_alloc();
      hwloc_bitmap_only(obj->cpuset, idx);
      hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n",
                              idx, obj->cpuset);
      hwloc_insert_object_by_cpuset(topology, obj);
    } hwloc_bitmap_foreach_end();
    hwloc_bitmap_free(groups_pu_set);
  } else {