diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/system/info.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/system/info.cpp')
-rw-r--r-- | util/system/info.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/util/system/info.cpp b/util/system/info.cpp new file mode 100644 index 0000000000..cf6681e89a --- /dev/null +++ b/util/system/info.cpp @@ -0,0 +1,239 @@ +#include "info.h" + +#include "error.h" + +#include <cstdlib> + +#if defined(_linux_) || defined(_cygwin_) + #include <fcntl.h> + #include <sys/sysinfo.h> +#endif + +#if defined(_win_) + #include "winint.h" + #include <stdio.h> +#else + #include <unistd.h> +#endif + +#if defined(_bionic_) +//TODO +#elif defined(_cygwin_) +static int getloadavg(double* loadavg, int nelem) { + for (int i = 0; i < nelem; ++i) { + loadavg[i] = 0.0; + } + + return nelem; +} +#elif defined(_unix_) || defined(_darwin_) + #include <sys/types.h> +#endif + +#if defined(_freebsd_) || defined(_darwin_) + #include <sys/sysctl.h> +#endif + +#include <util/string/ascii.h> +#include <util/string/cast.h> +#include <util/string/strip.h> +#include <util/stream/file.h> +#include <util/generic/yexception.h> + +#if defined(_linux_) +static inline size_t CgroupCpus() { + try { + auto q = FromString<ssize_t>(StripString(TFileInput("/sys/fs/cgroup/cpu/cpu.cfs_quota_us").ReadAll())); + + if (q <= 0) { + return 0; + } + + auto p = FromString<ssize_t>(StripString(TFileInput("/sys/fs/cgroup/cpu/cpu.cfs_period_us").ReadAll())); + + if (p <= 0) { + return 0; + } + + return Max<ssize_t>(1, (q + p / 2) / p); + } catch (...) { + return 0; + } +} +#endif + +size_t NSystemInfo::NumberOfCpus() { +#if defined(_linux_) + if (auto res = CgroupCpus(); res) { + return res; + } +#endif + +#if defined(_win_) + SYSTEM_INFO info; + + GetSystemInfo(&info); + + return info.dwNumberOfProcessors; +#elif defined(_SC_NPROCESSORS_ONLN) + return sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(_linux_) + unsigned ret; + int fd, nread, column; + char buf[512]; + static const char matchstr[] = "processor\t:"; + + fd = open("/proc/cpuinfo", O_RDONLY); + + if (fd == -1) { + abort(); + } + + column = 0; + ret = 0; + + while (true) { + nread = read(fd, buf, sizeof(buf)); + + if (nread <= 0) { + break; + } + + for (int i = 0; i < nread; ++i) { + const char ch = buf[i]; + + if (ch == '\n') { + column = 0; + } else if (column != -1) { + if (AsciiToLower(ch) == matchstr[column]) { + ++column; + + if (column == sizeof(matchstr) - 1) { + column = -1; + ++ret; + } + } else { + column = -1; + } + } + } + } + + if (ret == 0) { + abort(); + } + + close(fd); + + return ret; +#elif defined(_freebsd_) || defined(_darwin_) + int mib[2]; + size_t len; + unsigned ncpus = 1; + + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + len = sizeof(ncpus); + if (sysctl(mib, 2, &ncpus, &len, nullptr, 0) == -1) { + abort(); + } + + return ncpus; +#else + #error todo +#endif +} + +size_t NSystemInfo::LoadAverage(double* la, size_t len) { +#if defined(_win_) || defined(_musl_) || defined(_bionic_) + int ret = -1; +#else + for (size_t i = 0; i < len; ++i) { + la[i] = 0; + } + + int ret = getloadavg(la, len); +#endif + + if (ret < 0) { + for (size_t i = 0; i < len; ++i) { + la[i] = 0; + } + + ret = len; + } + + return (size_t)ret; +} + +static size_t NCpus; + +size_t NSystemInfo::CachedNumberOfCpus() { + if (!NCpus) { + NCpus = NumberOfCpus(); + } + + return NCpus; +} + +size_t NSystemInfo::GetPageSize() noexcept { +#if defined(_win_) + SYSTEM_INFO sysInfo; + GetSystemInfo(&sysInfo); + + return sysInfo.dwPageSize; +#else + return sysconf(_SC_PAGESIZE); +#endif +} + +size_t NSystemInfo::TotalMemorySize() { +#if defined(_linux_) && defined(_64_) + try { + auto q = FromString<size_t>(StripString(TFileInput("/sys/fs/cgroup/memory/memory.limit_in_bytes").ReadAll())); + + if (q < (((size_t)1) << 60)) { + return q; + } + } catch (...) { + } +#endif + +#if defined(_linux_) || defined(_cygwin_) + struct sysinfo info; + sysinfo(&info); + return info.totalram; +#elif defined(_darwin_) + int mib[2]; + int64_t memSize; + size_t length; + + // Get the Physical memory size + mib[0] = CTL_HW; + mib[1] = HW_MEMSIZE; + length = sizeof(int64_t); + if (sysctl(mib, 2, &memSize, &length, NULL, 0) != 0) { + ythrow yexception() << "sysctl failed: " << LastSystemErrorText(); + } + return (size_t)memSize; +#elif defined(_win_) + MEMORYSTATUSEX memoryStatusEx; + memoryStatusEx.dwLength = sizeof(memoryStatusEx); + if (!GlobalMemoryStatusEx(&memoryStatusEx)) { + ythrow yexception() << "GlobalMemoryStatusEx failed: " << LastSystemErrorText(); + } + return (size_t)memoryStatusEx.ullTotalPhys; +#else + return 0; +#endif +} + +size_t NSystemInfo::MaxOpenFiles() { +#if defined(ANDROID) || defined(__ANDROID__) + return sysconf(_SC_OPEN_MAX); +#elif defined(_win_) + return _getmaxstdio(); +#else + return getdtablesize(); +#endif +} |