diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /library/cpp/netliba/v6/cpu_affinity.cpp | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'library/cpp/netliba/v6/cpu_affinity.cpp')
-rw-r--r-- | library/cpp/netliba/v6/cpu_affinity.cpp | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/library/cpp/netliba/v6/cpu_affinity.cpp b/library/cpp/netliba/v6/cpu_affinity.cpp new file mode 100644 index 0000000000..7808092a72 --- /dev/null +++ b/library/cpp/netliba/v6/cpu_affinity.cpp @@ -0,0 +1,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: + enum { 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(); + } + } + } + +} |