123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #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_) && !defined(__ANDROID__)
- 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();
- }
- }
- }
- }
|