diff --git a/Solver/Autorefine.cpp b/Solver/Autorefine.cpp index 56e2038..5489bc8 100644 --- a/Solver/Autorefine.cpp +++ b/Solver/Autorefine.cpp @@ -37,12 +37,24 @@ #include // for _chdir() //#include + // for openmp #include "omp.h" // for wxGetFreeMemory() #include +#ifdef __DARWIN__ +#include +#include +#endif + +#ifdef __LINUX__ +#include +#include +#endif + + #include "SolverGlobal.h" #include "Autorefine.h" @@ -106,6 +118,47 @@ // 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__ + // 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) { + printf("Failed to retrieve free memory using sysctlbyname(): %s\n", strerror(errno)); + } +#else + freeMemory = wxGetFreeMemory(); +#endif +#endif + + return freeMemory; +} + CAutoRefine::CAutoRefine() { unsigned char i; @@ -522,7 +575,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 +1121,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());