text: /**
   * Copyright (C) Mellanox Technologies Ltd. 2001-2018.  ALL RIGHTS RESERVED.
   *
   * See file LICENSE for terms.
   */
  
  #include "numa.h"
  
  #include <ucs/debug/assert.h>
  #include <ucs/debug/log.h>
  #include <stdint.h>
  #include <sched.h>
  
  
  const char *ucs_numa_policy_names[] = {
      [UCS_NUMA_POLICY_DEFAULT]   = "default",
      [UCS_NUMA_POLICY_PREFERRED] = "preferred",
      [UCS_NUMA_POLICY_BIND]      = "bind",
      [UCS_NUMA_POLICY_LAST]      = NULL,
  };
  
  #if HAVE_NUMA
  
  
  static void ucs_numa_populate_cpumap(int16_t cpu_numa_nodes[])
  {
      struct bitmask *cpumask;
      int numa_node, cpu;
      int ret;
  
      cpumask = numa_allocate_cpumask();
  
      for (numa_node = 0; numa_node <= numa_max_node(); ++numa_node) {
          if (!numa_bitmask_isbitset(numa_all_nodes_ptr, numa_node)) {
              continue;
          }
  
          ret = numa_node_to_cpus(numa_node, cpumask);
          if (ret == -1) {
              ucs_warn("failed to get CPUs for NUMA node %d: %m", numa_node);
              continue;
          }
  
          for (cpu = 0; cpu < numa_num_configured_cpus(); ++cpu) {
              if (numa_bitmask_isbitset(cpumask, cpu)) {
                  cpu_numa_nodes[cpu] = numa_node + 1;
              }
          }
      }
  
      numa_free_cpumask(cpumask);
  }
  
  
  int ucs_numa_node_of_cpu(int cpu)
  {
      /* we can initialize statically only to the value 0, so the NUMA node
       * numbers will be stored as 1..N instead of 0..N-1 */
      static int16_t cpu_numa_nodes[__CPU_SETSIZE] = {0};
  
      UCS_STATIC_ASSERT(NUMA_NUM_NODES <= INT16_MAX);
      ucs_assert(cpu < __CPU_SETSIZE);
  
      if (cpu_numa_nodes[cpu] == 0) {
          ucs_numa_populate_cpumap(cpu_numa_nodes);
      }
      return cpu_numa_nodes[cpu] - 1;
  }
  
  #endif
  