// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "HostMemory.h" #if defined(_WIN32) #ifndef NOMINMAX #define NOMINMAX #endif #include #elif defined(__APPLE__) #include #include #include #else #include #endif size_t get_host_total_memory() { #if defined(_WIN32) MEMORYSTATUSEX status{}; status.dwLength = sizeof(status); if (!GlobalMemoryStatusEx(&status)) return 0; return static_cast(status.ullTotalPhys); #elif defined(__APPLE__) uint64_t bytes = 0; size_t len = sizeof(bytes); if (sysctlbyname("hw.memsize", &bytes, &len, nullptr, 0) != 0) return 0; return static_cast(bytes); #else const long pages = sysconf(_SC_PHYS_PAGES), page = sysconf(_SC_PAGE_SIZE); if (pages <= 0 || page <= 0) return 0; return static_cast(pages) * static_cast(page); #endif } size_t DefaultHostMemoryBudget() { return static_cast(HOST_MEMORY_BUDGET_FRACTION * static_cast(get_host_total_memory())); } HostWorkerPool &HostWorkerPool::Instance() { static HostWorkerPool pool; return pool; } HostWorkerPool::HostWorkerPool() { SetSize(0); } void HostWorkerPool::SetSize(size_t bytes) { std::lock_guard lock(m); size = bytes > 0 ? bytes : static_cast(HOST_WORKER_POOL_FRACTION * static_cast(DefaultHostMemoryBudget())); cv.notify_all(); } size_t HostWorkerPool::Size() { std::lock_guard lock(m); return size; } HostWorkerPool::Reservation::Reservation(HostWorkerPool &pool, size_t bytes) : pool(pool), bytes(bytes) { std::unique_lock lock(pool.m); pool.cv.wait(lock, [&] { return pool.reserved == 0 || pool.reserved + bytes <= pool.size; }); pool.reserved += bytes; } HostWorkerPool::Reservation::~Reservation() { { std::lock_guard lock(pool.m); pool.reserved -= bytes; } pool.cv.notify_all(); }