From 52b8f93e0f69b0ae631a96b3061da7a871e8766e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=B6hler?= Date: Tue, 13 Aug 2024 16:21:04 +0200 Subject: [PATCH 1/2] Added macOS implementation of portableGetFreeMemory() wxGetFreeMemory() does not work on UNIX platforms --- Solver/Autorefine.cpp | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Solver/Autorefine.cpp b/Solver/Autorefine.cpp index 56e2038..982476c 100644 --- a/Solver/Autorefine.cpp +++ b/Solver/Autorefine.cpp @@ -37,12 +37,19 @@ #include // for _chdir() //#include + // for openmp #include "omp.h" // for wxGetFreeMemory() #include +#ifdef __DARWIN__ +#include +#include +#endif + + #include "SolverGlobal.h" #include "Autorefine.h" @@ -106,6 +113,26 @@ // init static vars unsigned long CAutoRefine::m_ulTempFileID = 1; +// wxGetFreeMemory() replacement, +// as it does not work on UNIX platforms (Linux, macOS, ...) +wxMemorySize portableGetFreeMemory() { + wxMemorySize freeMemory; + +#ifdef __LINUX__ + // TODO +#elif __DARWIN__ + const char *key = "hw.memsize_usable"; + size_t size = sizeof(freeMemory); + if (sysctlbyname(key, &freeMemory, &size, NULL, 0) != 0) { + printf("Failed to retrieve free memory using sysctlbyname(): %s\n", strerror(errno)); + } +#else + freeMemory = wxGetFreeMemory(); +#endif + + return freeMemory; +} + CAutoRefine::CAutoRefine() { unsigned char i; @@ -522,7 +549,7 @@ int CAutoRefine::AutoRefineLinks(CAutoRefGlobalVars globalVars) mem_LinksTotal = mem_Potest + mem_pCharge; // get available memory - mem_AvailVirtual = (wxLongLong) wxGetFreeMemory(); + mem_AvailVirtual = (wxLongLong) portableGetFreeMemory(); // debug //mem_AvailVirtual = 50000000; @@ -1068,7 +1095,7 @@ void CAutoRefine::DumpMemoryInfo() wxLongLong freeMem; // get available memory - freeMem = (wxLongLong) wxGetFreeMemory(); + freeMem = (wxLongLong) portableGetFreeMemory(); LogMsg("Available virtual memory: %lu kilobytes\n", (freeMem/G_KILOBYTE).ToLong()); From 2bfc0dd33caccf9d08bfde821ddf7cfb0eefddb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=B6hler?= Date: Tue, 13 Aug 2024 14:52:12 +0000 Subject: [PATCH 2/2] Added Linux implementation for portableGetFreeMemory() --- Solver/Autorefine.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Solver/Autorefine.cpp b/Solver/Autorefine.cpp index 982476c..5489bc8 100644 --- a/Solver/Autorefine.cpp +++ b/Solver/Autorefine.cpp @@ -49,6 +49,11 @@ #include #endif +#ifdef __LINUX__ +#include +#include +#endif + #include "SolverGlobal.h" @@ -119,8 +124,28 @@ wxMemorySize portableGetFreeMemory() { wxMemorySize freeMemory; #ifdef __LINUX__ - // TODO -#elif __DARWIN__ + // NOTE: unfortunatly, does not include the MemAvailable (only MemFree), + // so we have to parse /proc/meminfo + std::ifstream inputStream("/proc/meminfo"); + std::string keyword("MemAvailable:"); + std::string suffix(" kB"); + std::string line; + while (std::getline(inputStream, line)) { + if (line.substr(0, keyword.size()) == keyword) { + if (line.substr(line.size() - suffix.size(), suffix.size()) != suffix) { + std::cerr << "ERROR: expected /proc/meminfo line to end with suffix '" << suffix + << "', but obtained line: " << line << std::endl; + break; + } + size_t idx = line.find_first_not_of(" ", keyword.size()); + const std::string memAvail = line.substr(idx, line.size() - idx - suffix.size()); + freeMemory = strtoul(memAvail.c_str(), NULL, 10); + freeMemory *= 1024; + break; + } + } +#else +#ifdef __DARWIN__ const char *key = "hw.memsize_usable"; size_t size = sizeof(freeMemory); if (sysctlbyname(key, &freeMemory, &size, NULL, 0) != 0) { @@ -128,6 +153,7 @@ wxMemorySize portableGetFreeMemory() { } #else freeMemory = wxGetFreeMemory(); +#endif #endif return freeMemory;