Status WindowsEnvironment::SetThreadAffinity()

in src/environment/environment_windows.cc [247:302]


Status WindowsEnvironment::SetThreadAffinity(HANDLE thread, uint64_t core,
    AffinityPattern affinity_pattern) {
  if(affinity_pattern == AffinityPattern::PhysicalCoresFirst) {
    // Recalculate "core" so that all physical cores are scheduled, 1 thread per
    // each, before we schedule any hyperthread cores.
    if(core >= sys_info_.dwNumberOfProcessors) {
      return Status::Aborted("Too few logical cores.",
                             std::to_string(sys_info_.dwNumberOfProcessors));
    }

    // Assume 2 logical cores per physical core.
    if(sys_info_.dwNumberOfProcessors % 2 != 0) {
      return Status::Aborted("Not an even number of logical cores.",
                             std::to_string(sys_info_.dwNumberOfProcessors));
    }
    uint32_t physical_core_count = sys_info_.dwNumberOfProcessors / 2;

    if(core < physical_core_count) {
      core = core * 2;
    } else {
      core = (core - physical_core_count) * 2 + 1;
    }
  } else if(affinity_pattern == AffinityPattern::BalanceNumaNodes) {
    // For now, assume that we're running on a 4-node NUMA system, where the
    // cores are numbered with the first n cores on node 0, the next n cores on
    // node 1, ... and the last n cores on node 3.
    const uint32_t numa_node_count = 4;
    CHECK_EQ(sys_info_.dwNumberOfProcessors % numa_node_count, 0) <<
        "Unexpected system configuration!";
    uint32_t logical_core_count =
      sys_info_.dwNumberOfProcessors / numa_node_count;
    // Assume 2 logical cores per physical core.
    CHECK_EQ(logical_core_count % 2, 0) << "Unexpected system configuration!";
    uint32_t physical_core_count = logical_core_count / 2;

    uint32_t numa_node = core % numa_node_count;
    uint32_t numa_core = core / numa_node_count;

    if(numa_core < physical_core_count) {
      numa_core = numa_core * 2;
    } else {
      numa_core = (numa_core - physical_core_count) * 2 + 1;
    }
    core = (numa_node * logical_core_count) + numa_core;
  }

  DWORD_PTR result = ::SetThreadAffinityMask(thread, (uint64_t)0x1 << core);

  if(result == 0) {
    DWORD error = ::GetLastError();
    return Status::Aborted("Failed to set thread affinity.",
        FormatWin32AndHRESULT(result));
  } else {
    return Status::OK();
  }
}