Itoyori  v0.0.1
numa.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "ityr/common/util.hpp"
5 
6 #if __has_include(<numa.h>)
7 #include <numa.h>
8 
9 namespace ityr::common::numa {
10 
11 inline bool enabled() {
12  return numa_available() >= 0;
13 }
14 
15 using node_t = int;
16 
17 class node_bitmask {
18 public:
19  node_bitmask()
20  : bitmask_(alloc_node_bitmask()) {}
21 
22  struct bitmask* get() const { return bitmask_->get(); }
23 
24  void setbit(node_t node) {
25  if (!enabled()) return;
26  ITYR_CHECK(bitmask_.has_value());
27  ITYR_CHECK(0 <= node);
28  ITYR_CHECK(node <= numa_max_node());
29  numa_bitmask_setbit(get(), node);
30  }
31 
32  void clear() {
33  if (!enabled()) return;
34  ITYR_CHECK(bitmask_.has_value());
35  numa_bitmask_clearall(get());
36  }
37 
38 private:
39  using bitmask_holder_t = std::unique_ptr<struct bitmask, void(*)(struct bitmask*)>;
40 
41  std::optional<bitmask_holder_t> alloc_node_bitmask() const {
42  if (!enabled()) return std::nullopt;
43  return bitmask_holder_t{numa_allocate_nodemask(), numa_free_nodemask};
44  }
45 
46  std::optional<bitmask_holder_t> bitmask_;
47 };
48 
49 inline node_t get_current_node() {
50  if (!enabled()) return 0;
51  return numa_node_of_cpu(sched_getcpu());
52 }
53 
54 inline void bind_to(void* addr, std::size_t size, node_t node) {
55  if (!enabled()) return;
56  ITYR_CHECK(0 <= node);
57  ITYR_CHECK(node <= numa_max_node());
58  ITYR_CHECK(reinterpret_cast<uintptr_t>(addr) % numa_pagesize() == 0);
59  ITYR_CHECK(size % get_page_size() == 0);
60  numa_tonode_memory(addr, size, node);
61 }
62 
63 inline void interleave(void* addr, std::size_t size, const node_bitmask& nodemask) {
64  if (!enabled()) return;
65  ITYR_CHECK(reinterpret_cast<uintptr_t>(addr) % numa_pagesize() == 0);
66  ITYR_CHECK(size % numa_pagesize() == 0);
67  numa_interleave_memory(addr, size, nodemask.get());
68 }
69 
70 }
71 
72 #else
73 
74 namespace ityr::common::numa {
75 
76 using node_t = int;
77 
78 class node_bitmask {
79 public:
81  void* get() const { return nullptr; }
82  void setbit(node_t node) {}
83  void clear() {}
84 };
85 
86 inline bool enabled() { return false; }
87 inline node_t get_current_node() { return 0; }
88 inline void bind_to(void*, std::size_t, node_t) {}
89 inline void interleave(void*, std::size_t, const node_bitmask&) {}
90 
91 }
92 
93 #endif
Definition: numa.hpp:78
void clear()
Definition: numa.hpp:83
void * get() const
Definition: numa.hpp:81
void setbit(node_t node)
Definition: numa.hpp:82
node_bitmask()
Definition: numa.hpp:80
#define ITYR_CHECK(cond)
Definition: util.hpp:48
Definition: numa.hpp:74
void bind_to(void *, std::size_t, node_t)
Definition: numa.hpp:88
void interleave(void *, std::size_t, const node_bitmask &)
Definition: numa.hpp:89
int node_t
Definition: numa.hpp:76
bool enabled()
Definition: numa.hpp:86
node_t get_current_node()
Definition: numa.hpp:87
std::size_t get_page_size()
Definition: util.hpp:170
constexpr auto size(const span< T > &s) noexcept
Definition: span.hpp:61