File size: 1,519 Bytes
bbb6388 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include "strata/core/conversation_memory.hpp"
#include <charconv>
#include <fstream>
#include <limits>
#include <sstream>
#include <string>
#if defined(_WIN32)
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#endif
namespace strata::core {
std::optional<uint64_t> conversation_mem_available(std::istream& meminfo) {
std::optional<uint64_t> result;
std::string line;
while (std::getline(meminfo, line)) {
std::istringstream fields(line);
std::string key, value, unit, extra;
if (!(fields >> key) || key != "MemAvailable:") continue;
if (result || !(fields >> value >> unit) || unit != "kB" || (fields >> extra)) return {};
uint64_t kb = 0;
const auto parsed = std::from_chars(value.data(), value.data() + value.size(), kb);
if (parsed.ec != std::errc{} || parsed.ptr != value.data() + value.size() ||
kb > std::numeric_limits<uint64_t>::max() / 1024) return {};
result = kb * 1024;
}
if (meminfo.bad() || (meminfo.fail() && !meminfo.eof())) return {};
return result;
}
std::optional<uint64_t> conversation_available_memory() {
#if defined(_WIN32)
MEMORYSTATUSEX status{};
status.dwLength = sizeof status;
if (GlobalMemoryStatusEx(&status)) return status.ullAvailPhys;
return {};
#elif defined(__linux__)
std::ifstream meminfo("/proc/meminfo");
if (!meminfo) return {};
return conversation_mem_available(meminfo);
#else
return {};
#endif
}
} // namespace strata::core
|