#include "affinity.h" #ifdef _linux_ #include <sched.h> #endif class TAffinity::TImpl { #ifdef _linux_ cpu_set_t Mask; #endif public: TImpl() { #ifdef _linux_ int ar = sched_getaffinity(0, sizeof(cpu_set_t), &Mask); Y_VERIFY_DEBUG(ar == 0); #endif } explicit TImpl(const ui8* cpus, ui32 size) { #ifdef _linux_ CPU_ZERO(&Mask); for (ui32 i = 0; i != size; ++i) { if (cpus[i]) { CPU_SET(i, &Mask); } } #else Y_UNUSED(cpus); Y_UNUSED(size); #endif } void Set() const { #ifdef _linux_ int ar = sched_setaffinity(0, sizeof(cpu_set_t), &Mask); Y_VERIFY_DEBUG(ar == 0); #endif } operator TCpuMask() const { TCpuMask result; #ifdef _linux_ for (ui32 i = 0; i != CPU_SETSIZE; ++i) { result.Cpus.emplace_back(CPU_ISSET(i, &Mask)); } result.RemoveTrailingZeros(); #endif return result; } }; TAffinity::TAffinity() { } TAffinity::~TAffinity() { } TAffinity::TAffinity(const ui8* x, ui32 sz) { if (x && sz) { Impl.Reset(new TImpl(x, sz)); } } TAffinity::TAffinity(const TCpuMask& mask) { if (!mask.IsEmpty()) { static_assert(sizeof(ui8) == sizeof(mask.Cpus[0])); const ui8* x = reinterpret_cast<const ui8*>(&mask.Cpus[0]); const ui32 sz = mask.Size(); Impl.Reset(new TImpl(x, sz)); } } void TAffinity::Current() { Impl.Reset(new TImpl()); } void TAffinity::Set() const { if (!!Impl) { Impl->Set(); } } bool TAffinity::Empty() const { return !Impl; } TAffinity::operator TCpuMask() const { if (!!Impl) { return *Impl; } return TCpuMask(); }