1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#include "stdafx.h"
#include "cpu_affinity.h"
#if defined(__FreeBSD__) && (__FreeBSD__ >= 7)
#include <sys/param.h>
#include <sys/cpuset.h>
#elif defined(_linux_)
#include <pthread.h>
#include <util/stream/file.h>
#include <util/string/printf.h>
#endif
namespace NNetliba {
class TCPUSet {
public:
static constexpr int MAX_SIZE = 128;
private:
#if defined(__FreeBSD__) && (__FreeBSD__ >= 7)
#define NUMCPU ((CPU_MAXSIZE > MAX_SIZE) ? 1 : (MAX_SIZE / CPU_MAXSIZE))
cpuset_t CpuInfo[NUMCPU];
public:
bool GetAffinity() {
int error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(CpuInfo), CpuInfo);
return error == 0;
}
bool SetAffinity() {
int error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(CpuInfo), CpuInfo);
return error == 0;
}
bool IsSet(size_t i) {
return CPU_ISSET(i, CpuInfo);
}
void Set(size_t i) {
CPU_SET(i, CpuInfo);
}
#elif defined(_linux_)
public:
#define NUMCPU ((CPU_SETSIZE > MAX_SIZE) ? 1 : (MAX_SIZE / CPU_SETSIZE))
cpu_set_t CpuInfo[NUMCPU];
public:
bool GetAffinity() {
int error = pthread_getaffinity_np(pthread_self(), sizeof(CpuInfo), CpuInfo);
return error == 0;
}
bool SetAffinity() {
int error = pthread_setaffinity_np(pthread_self(), sizeof(CpuInfo), CpuInfo);
return error == 0;
}
bool IsSet(size_t i) {
return CPU_ISSET(i, CpuInfo);
}
void Set(size_t i) {
CPU_SET(i, CpuInfo);
}
#else
public:
bool GetAffinity() {
return true;
}
bool SetAffinity() {
return true;
}
bool IsSet(size_t i) {
Y_UNUSED(i);
return true;
}
void Set(size_t i) {
Y_UNUSED(i);
}
#endif
TCPUSet() {
Clear();
}
void Clear() {
memset(this, 0, sizeof(*this));
}
};
static TMutex CPUSetsLock;
struct TCPUSetInfo {
TCPUSet CPUSet;
bool IsOk;
TCPUSetInfo()
: IsOk(false)
{
}
};
static THashMap<int, TCPUSetInfo> CPUSets;
void BindToSocket(int n) {
TGuard<TMutex> gg(CPUSetsLock);
if (CPUSets.find(n) == CPUSets.end()) {
TCPUSetInfo& res = CPUSets[n];
bool foundCPU = false;
#ifdef _linux_
for (int cpuId = 0; cpuId < TCPUSet::MAX_SIZE; ++cpuId) {
try { // I just wanna check if file exists, I don't want your stinking exceptions :/
TIFStream f(Sprintf("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpuId).c_str());
TString s;
if (f.ReadLine(s) && !s.empty()) {
//printf("cpu%d - %s\n", cpuId, s.c_str());
int physCPU = atoi(s.c_str());
if (physCPU == 0) {
res.IsOk = true;
res.CPUSet.Set(cpuId);
foundCPU = true;
}
} else {
break;
}
} catch (const TFileError&) {
break;
}
}
#endif
if (!foundCPU && n == 0) {
for (int i = 0; i < 6; ++i) {
res.CPUSet.Set(i);
}
res.IsOk = true;
foundCPU = true;
}
}
{
TCPUSetInfo& cc = CPUSets[n];
if (cc.IsOk) {
cc.CPUSet.SetAffinity();
}
}
}
}
|