mirror of https://github.com/bitcoin/bitcoin.git
system: add helper for fetching total system memory
Added a minimal system helper to query total physical RAM on [Linux/macOS/Windows](https://stackoverflow.com/a/2513561) (on other platforms we just return an empty optional).
The added test checks if the value is roughly correct by checking if the CI platforms are returning any value and if the value is at least 1 GiB and not more than 10 TiB.
The max value is only validated on 64 bits, since it's not unreasonable for 32 bits to have max memory, but on 64 bits it's likely an error.
https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-memorystatusex
> ullTotalPhys The amount of actual physical memory, in bytes.
https://man7.org/linux/man-pages/man3/sysconf.3.html:
> _SC_PHYS_PAGES The number of pages of physical memory. Note that it is possible for the product of this value and the value of _SC_PAGESIZE to overflow.
> _SC_PAGESIZE Size of a page in bytes. Must not be less than 1.
See https://godbolt.org/z/ec81Tjvrj for further details
Github-Pull: #33333
Rebased-From: 6c720459be
This commit is contained in:
parent
0a80b1ae62
commit
49d4ebcbfe
|
@ -11,19 +11,25 @@
|
|||
#include <util/string.h>
|
||||
#include <util/time.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#include <compat/compat.h>
|
||||
#ifdef WIN32
|
||||
#include <codecvt>
|
||||
#include <compat/compat.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MALLOPT_ARENA_MAX
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <locale>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
@ -105,6 +111,17 @@ int GetNumCores()
|
|||
return std::thread::hardware_concurrency();
|
||||
}
|
||||
|
||||
std::optional<size_t> GetTotalRAM()
|
||||
{
|
||||
auto clamp{[](uint64_t v) { return size_t(std::min(v, uint64_t{std::numeric_limits<size_t>::max()})); }};
|
||||
#ifdef WIN32
|
||||
if (MEMORYSTATUSEX m{}; (m.dwLength = sizeof(m), GlobalMemoryStatusEx(&m))) return clamp(m.ullTotalPhys);
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
if (long p{sysconf(_SC_PHYS_PAGES)}, s{sysconf(_SC_PAGESIZE)}; p > 0 && s > 0) return clamp(1ULL * p * s);
|
||||
#endif
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Obtain the application startup time (used for uptime calculation)
|
||||
int64_t GetStartupTime()
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <bitcoin-build-config.h> // IWYU pragma: keep
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
// Application startup time (used for uptime calculation)
|
||||
|
@ -29,4 +30,9 @@ void runCommand(const std::string& strCommand);
|
|||
*/
|
||||
int GetNumCores();
|
||||
|
||||
/**
|
||||
* Return the total RAM available on the current system, if detectable.
|
||||
*/
|
||||
std::optional<size_t> GetTotalRAM();
|
||||
|
||||
#endif // BITCOIN_COMMON_SYSTEM_H
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <common/run_command.h>
|
||||
#include <univalue.h>
|
||||
|
||||
#include <common/system.h>
|
||||
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
#include <util/subprocess.h>
|
||||
#endif // ENABLE_EXTERNAL_SIGNER
|
||||
|
@ -16,6 +18,17 @@
|
|||
|
||||
BOOST_FIXTURE_TEST_SUITE(system_tests, BasicTestingSetup)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(total_ram)
|
||||
{
|
||||
BOOST_CHECK_GE(GetTotalRAM(), 1000_MiB);
|
||||
|
||||
if constexpr (SIZE_MAX == UINT64_MAX) {
|
||||
// Upper bound check only on 64-bit: 32-bit systems can reasonably have max memory,
|
||||
// but extremely large values on 64-bit likely indicate detection errors
|
||||
BOOST_CHECK_LT(GetTotalRAM(), 10'000'000_MiB); // >10 TiB memory is unlikely
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EXTERNAL_SIGNER
|
||||
|
||||
BOOST_AUTO_TEST_CASE(run_command)
|
||||
|
|
Loading…
Reference in New Issue