blob: 29741aa1d643141681b0c3501e7174a5158cc6ea (
plain) (
tree)
|
|
#pragma once
#include "defs.h"
#include <library/cpp/containers/stack_vector/stack_vec.h>
#include <util/string/split.h>
#include <util/generic/yexception.h>
using TCpuId = ui32;
// Simple data structure to operate with set of cpus
struct TCpuMask {
TStackVec<bool, 1024> Cpus;
// Creates empty mask
TCpuMask() {}
// Creates mask with single cpu set
explicit TCpuMask(TCpuId cpuId) {
Set(cpuId);
}
// Initialize mask from raw boolean array
template <class T>
TCpuMask(const T* cpus, TCpuId size) {
Cpus.reserve(size);
for (TCpuId i = 0; i != size; ++i) {
Cpus.emplace_back(bool(cpus[i]));
}
}
// Parse a numerical list of processors. The numbers are separated by commas and may include ranges. For example: 0,5,7,9-11
explicit TCpuMask(const TString& cpuList) {
try {
for (TStringBuf s : StringSplitter(cpuList).Split(',')) {
TCpuId l, r;
if (s.find('-') != TString::npos) {
StringSplitter(s).Split('-').CollectInto(&l, &r);
} else {
l = r = FromString<TCpuId>(s);
}
if (r >= Cpus.size()) {
Cpus.resize(r + 1, false);
}
for (TCpuId cpu = l; cpu <= r; cpu++) {
Cpus[cpu] = true;
}
}
} catch (...) {
ythrow TWithBackTrace<yexception>() << "Exception occured while parsing cpu list '" << cpuList << "': " << CurrentExceptionMessage();
}
}
// Returns size of underlying vector
TCpuId Size() const {
return Cpus.size();
}
// Returns number of set bits in mask
TCpuId CpuCount() const {
TCpuId result = 0;
for (bool value : Cpus) {
result += value;
}
return result;
}
bool IsEmpty() const {
for (bool value : Cpus) {
if (value) {
return false;
}
}
return true;
}
bool IsSet(TCpuId cpu) const {
return cpu < Cpus.size() && Cpus[cpu];
}
void Set(TCpuId cpu) {
if (cpu >= Cpus.size()) {
Cpus.resize(cpu + 1, false);
}
Cpus[cpu] = true;
}
void Reset(TCpuId cpu) {
if (cpu < Cpus.size()) {
Cpus[cpu] = false;
}
}
void RemoveTrailingZeros() {
while (!Cpus.empty() && !Cpus.back()) {
Cpus.pop_back();
}
}
explicit operator bool() const {
return !IsEmpty();
}
TCpuMask operator &(const TCpuMask& rhs) const {
TCpuMask result;
TCpuId size = Max(Size(), rhs.Size());
result.Cpus.reserve(size);
for (TCpuId cpu = 0; cpu < size; cpu++) {
result.Cpus.emplace_back(IsSet(cpu) && rhs.IsSet(cpu));
}
return result;
}
TCpuMask operator |(const TCpuMask& rhs) const {
TCpuMask result;
TCpuId size = Max(Size(), rhs.Size());
result.Cpus.reserve(size);
for (TCpuId cpu = 0; cpu < size; cpu++) {
result.Cpus.emplace_back(IsSet(cpu) || rhs.IsSet(cpu));
}
return result;
}
TCpuMask operator -(const TCpuMask& rhs) const {
TCpuMask result;
result.Cpus.reserve(Size());
for (TCpuId cpu = 0; cpu < Size(); cpu++) {
result.Cpus.emplace_back(IsSet(cpu) && !rhs.IsSet(cpu));
}
return result;
}
};
|