72 size_t current_used{mUsedMemory.load(std::memory_order_relaxed)};
74 new_used = current_used + bytes;
75 if (new_used > mMaxMemory.load(std::memory_order_relaxed)) {
76 mCountThrow.fetch_add(1, std::memory_order_relaxed);
78 mMaxMemory.load(std::memory_order_relaxed));
80 }
while (!mUsedMemory.compare_exchange_weak(current_used, new_used,
81 std::memory_order_acq_rel,
82 std::memory_order_relaxed));
86 p = mUpstream->allocate(bytes, alignment);
88 mUsedMemory.fetch_sub(bytes, std::memory_order_relaxed);
89#ifdef BOUNDED_MR_STATS
90 mStats.upstreamFailures.fetch_add(1, std::memory_order_relaxed);
95 size_t peak = mPeakUsedMemory.load(std::memory_order_relaxed);
96 while (new_used > peak &&
97 !mPeakUsedMemory.compare_exchange_weak(peak, new_used,
98 std::memory_order_relaxed)) {
101#ifdef BOUNDED_MR_STATS
102 size_t statsPeak = mStats.peak.load(std::memory_order_relaxed);
103 while (new_used > statsPeak &&
104 !mStats.peak.compare_exchange_weak(statsPeak, new_used,
105 std::memory_order_relaxed)) {
107 mStats.live.fetch_add(1, std::memory_order_relaxed);
108 mStats.nAlloc.fetch_add(1, std::memory_order_relaxed);
109 mStats.totalAlloc.fetch_add(bytes, std::memory_order_relaxed);
111 size_t ma = mStats.maxAlign.load(std::memory_order_relaxed);
112 while (alignment > ma && !mStats.maxAlign.compare_exchange_weak(ma, alignment, std::memory_order_relaxed)) {
120 mUpstream->deallocate(p, bytes, alignment);
121 mUsedMemory.fetch_sub(bytes, std::memory_order_relaxed);
122#ifdef BOUNDED_MR_STATS
123 mStats.live.fetch_sub(1, std::memory_order_relaxed);
124 mStats.nFree.fetch_add(1, std::memory_order_relaxed);
125 mStats.totalFreed.fetch_add(bytes, std::memory_order_relaxed);
166 size_t current = mMaxMemory.load(std::memory_order_relaxed);
167 if (
max == current) {
171 size_t used = mUsedMemory.load(std::memory_order_acquire);
173 mCountThrow.fetch_add(1, std::memory_order_relaxed);
176 if (mMaxMemory.compare_exchange_weak(current,
max,
177 std::memory_order_release,
178 std::memory_order_relaxed)) {
181 if (current ==
max) {
190 const auto throw_ = mCountThrow.load(std::memory_order_relaxed);
191 const auto used =
static_cast<double>(mUsedMemory.load(std::memory_order_relaxed));
192 const auto peak =
static_cast<double>(mPeakUsedMemory.load(std::memory_order_relaxed));
194 const auto maxm = mMaxMemory.load(std::memory_order_relaxed);
196 if (maxm == std::numeric_limits<size_t>::max()) {
201#ifdef BOUNDED_MR_STATS
202 ret += std::format(
" peak={:.2f} GB live={} nAlloc={} nFree={} totalAlloc={:.2f} GB totalFreed={:.2f} GB maxAlign={} upstreamFail={}",
203 (
float)mStats.peak.load(std::memory_order_relaxed) /
constants::GB,
204 mStats.live.load(std::memory_order_relaxed),
205 mStats.nAlloc.load(std::memory_order_relaxed),
206 mStats.nFree.load(std::memory_order_relaxed),
207 (
float)mStats.totalAlloc.load(std::memory_order_relaxed) /
constants::GB,
208 (
float)mStats.totalFreed.load(std::memory_order_relaxed) /
constants::GB,
209 mStats.maxAlign.load(std::memory_order_relaxed),
210 mStats.upstreamFailures.load(std::memory_order_relaxed));