]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/numa.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
10 #include "include/stringify.h"
11 #include "common/safe_io.h"
13 using namespace std::literals
;
19 #if defined(__linux__)
20 int parse_cpu_set_list(const char *s
,
27 int a
= strtol(s
, &end
, 10);
33 int b
= strtol(s
, &end
, 10);
43 *cpu_set_size
= a
+ 1;
56 std::string
cpu_set_to_str_list(size_t cpu_set_size
,
57 const cpu_set_t
*cpu_set
)
62 while (a
< cpu_set_size
&& !CPU_ISSET(a
, cpu_set
)) {
65 if (a
>= cpu_set_size
) {
69 while (b
< cpu_set_size
&& CPU_ISSET(b
, cpu_set
)) {
76 r
+= stringify(a
) + "-" + stringify(b
- 1);
85 std::set
<int> cpu_set_to_set(size_t cpu_set_size
,
86 const cpu_set_t
*cpu_set
)
91 while (a
< cpu_set_size
&& !CPU_ISSET(a
, cpu_set
)) {
94 if (a
>= cpu_set_size
) {
98 while (b
< cpu_set_size
&& CPU_ISSET(b
, cpu_set
)) {
110 int get_numa_node_cpu_set(
112 size_t *cpu_set_size
,
115 std::string fn
= "/sys/devices/system/node/node";
116 fn
+= stringify(node
);
118 int fd
= ::open(fn
.c_str(), O_RDONLY
);
123 int r
= safe_read(fd
, &buf
, sizeof(buf
));
128 while (r
> 0 && ::isspace(buf
[--r
])) {
131 r
= parse_cpu_set_list(buf
, cpu_set_size
, cpu_set
);
141 static int easy_readdir(const std::string
& dir
, std::set
<std::string
> *out
)
143 DIR *h
= ::opendir(dir
.c_str());
147 struct dirent
*de
= nullptr;
148 while ((de
= ::readdir(h
))) {
149 if (strcmp(de
->d_name
, ".") == 0 ||
150 strcmp(de
->d_name
, "..") == 0) {
153 out
->insert(de
->d_name
);
159 int set_cpu_affinity_all_threads(size_t cpu_set_size
, cpu_set_t
*cpu_set
)
161 // first set my affinity
162 int r
= sched_setaffinity(getpid(), cpu_set_size
, cpu_set
);
167 // make 2 passes here so that we (hopefully) catch racing threads creating
169 for (unsigned pass
= 0; pass
< 2; ++pass
) {
170 // enumerate all child threads from /proc
171 std::set
<std::string
> ls
;
172 std::string path
= "/proc/"s
+ stringify(getpid()) + "/task";
173 r
= easy_readdir(path
, &ls
);
178 pid_t tid
= atoll(i
.c_str());
182 r
= sched_setaffinity(tid
, cpu_set_size
, cpu_set
);
192 int parse_cpu_set_list(const char *s
,
193 size_t *cpu_set_size
,
199 std::string
cpu_set_to_str_list(size_t cpu_set_size
,
200 const cpu_set_t
*cpu_set
)
205 std::set
<int> cpu_set_to_set(size_t cpu_set_size
,
206 const cpu_set_t
*cpu_set
)
211 int get_numa_node_cpu_set(int node
,
212 size_t *cpu_set_size
,
218 int set_cpu_affinity_all_threads(size_t cpu_set_size
,