Mantid
Loading...
Searching...
No Matches
MockMemory.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2026 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX-License-Identifier: GPL-3.0+
7
9
10// only define the methods for the patch if using Linux
11#if defined(__linux__) || defined(__gnu_linux__)
12
13#include "MantidKernel/Memory.h"
14
15#include <atomic>
16#include <dlfcn.h>
17#include <stdexcept>
18
19namespace {
20using AvailMemFunc = std::size_t (*)(Mantid::Kernel::MemoryStats const *);
21static std::atomic<bool> g_override_availMem{false}; // flag, whether to use the real or mock availMem
22static std::atomic<AvailMemFunc> g_real_availMem(nullptr); // the real function, looked up from symbol list
23static std::atomic<std::size_t> g_value{Mantid::TestMemory::g_default_value}; // the return value of mocked availMem
24static std::once_flag g_init_flag;
25
26static void init_real_availMem() {
27 // NOTE: begin Deep Magic
28 // if not set, set the real function for availMem by looking up its mangled name in the symbol list
29 std::call_once(g_init_flag, []() {
30 // the mangled name may be found with: nm -D bin/libMantidKernel.so | grep availMem
31 char const *const mangled = "_ZNK6Mantid6Kernel11MemoryStats8availMemEv";
32 void *sym = dlsym(RTLD_NEXT, mangled);
33 // fallback to RTLD_DEFAULT if still not found
34 if (!sym) {
35 sym = dlsym(RTLD_DEFAULT, mangled);
36 }
37 if (sym) {
38 g_real_availMem.store(reinterpret_cast<AvailMemFunc>(sym));
39 }
40 });
41 // end Deep Magic
42}
43} // namespace
44
45namespace Mantid::TestMemory {
46extern "C" void enable_mem_override(std::size_t value) {
47 g_value.store(value);
48 g_override_availMem.store(true);
49}
50extern "C" void disable_mem_override() { g_override_availMem.store(false); }
51} // namespace Mantid::TestMemory
52
53// this is a patched availMem which will be used in testing.
54// when g_override_availMem has been set, it will return a fixed value
55// otherwise, it will prepare the real function from symbol lookup,
56// and return the actual memory count
57std::size_t Mantid::Kernel::MemoryStats::availMem() const {
58 if (g_override_availMem.load()) {
59 return g_value.load();
60 } else {
61 init_real_availMem();
62 if (g_real_availMem.load()) {
63 return g_real_availMem.load()(this);
64 } else {
65 // if it cannot be thrown, this can cause opaque testing errors; throw an error here instead
66 throw std::runtime_error("Failed to reset the MemoryStats patch by name lookup");
67 }
68 }
69}
70
71std::string Mantid::Kernel::MemoryStats::checkAvailableMemory(std::size_t const requestedMemory) const {
72 if (g_override_availMem.load()) {
73 std::size_t avail = g_value.load();
74 if (requestedMemory > avail) {
75 return "Mock Memory Failure";
76 } else {
77 return "";
78 }
79 } else {
80 init_real_availMem();
81 if (g_real_availMem.load()) {
82 // requestedMemory is in bytes, availMem is in KiB, so multiply
83 std::size_t avail = g_real_availMem.load()(this) * 1024;
84 if (requestedMemory > avail) {
85 return "Requested Memory Failure " + std::to_string(requestedMemory) + " > " + std::to_string(avail);
86 } else {
87 return "";
88 }
89 } else {
90 // if it cannot be thrown, this can cause opaque testing errors; throw an error here instead
91 throw std::runtime_error("Failed to reset the MemoryStats patch by name lookup");
92 }
93 }
94}
95
96#else
97namespace Mantid::TestMemory {
98extern "C" void enable_mem_override(std::size_t value) { (void)value; }
99extern "C" void disable_mem_override() {}
100} // namespace Mantid::TestMemory
101#endif
double value
The value of the point.
Definition FitMW.cpp:51
This class is responsible for memory statistics.
Definition Memory.h:28
std::string checkAvailableMemory(std::size_t const requestedMemoryBytes) const
Check if there is enough space in memory to hold the requested amount of memory.
Definition Memory.cpp:571
std::size_t availMem() const
Returns the available memory of the system in kiB.
Definition Memory.cpp:402
void disable_mem_override()
void enable_mem_override(std::size_t value=g_default_value)
constexpr std::size_t g_default_value
Definition MockMemory.h:13
std::string to_string(const wide_integer< Bits, Signed > &n)