78 size_t current_used{mUsedMemory.load(std::memory_order_relaxed)};
80 new_used = current_used + bytes;
81 if (new_used > mMaxMemory.load(std::memory_order_relaxed)) {
82 mCountThrow.fetch_add(1, std::memory_order_relaxed);
84 mMaxMemory.load(std::memory_order_relaxed));
86 }
while (!mUsedMemory.compare_exchange_weak(current_used, new_used,
87 std::memory_order_acq_rel,
88 std::memory_order_relaxed));
92 p = mUpstream->allocate(bytes, alignment);
94 mUsedMemory.fetch_sub(bytes, std::memory_order_relaxed);
95#ifdef BOUNDED_MR_STATS
96 mStats.upstreamFailures.fetch_add(1, std::memory_order_relaxed);
101 size_t peak = mPeakUsedMemory.load(std::memory_order_relaxed);
102 while (new_used > peak &&
103 !mPeakUsedMemory.compare_exchange_weak(peak, new_used,
104 std::memory_order_relaxed)) {
107#ifdef BOUNDED_MR_STATS
108 size_t statsPeak = mStats.peak.load(std::memory_order_relaxed);
109 while (new_used > statsPeak &&
110 !mStats.peak.compare_exchange_weak(statsPeak, new_used,
111 std::memory_order_relaxed)) {
113 mStats.live.fetch_add(1, std::memory_order_relaxed);
114 mStats.nAlloc.fetch_add(1, std::memory_order_relaxed);
115 mStats.totalAlloc.fetch_add(bytes, std::memory_order_relaxed);
117 size_t ma = mStats.maxAlign.load(std::memory_order_relaxed);
118 while (alignment > ma && !mStats.maxAlign.compare_exchange_weak(ma, alignment, std::memory_order_relaxed)) {
126 mUpstream->deallocate(p, bytes, alignment);
127 mUsedMemory.fetch_sub(bytes, std::memory_order_relaxed);
128#ifdef BOUNDED_MR_STATS
129 mStats.live.fetch_sub(1, std::memory_order_relaxed);
130 mStats.nFree.fetch_add(1, std::memory_order_relaxed);
131 mStats.totalFreed.fetch_add(bytes, std::memory_order_relaxed);
172 size_t current = mMaxMemory.load(std::memory_order_relaxed);
173 if (
max == current) {
177 size_t used = mUsedMemory.load(std::memory_order_acquire);
179 mCountThrow.fetch_add(1, std::memory_order_relaxed);
182 if (mMaxMemory.compare_exchange_weak(current,
max,
183 std::memory_order_release,
184 std::memory_order_relaxed)) {
187 if (current ==
max) {
196 const auto throw_ = mCountThrow.load(std::memory_order_relaxed);
197 const auto used =
static_cast<double>(mUsedMemory.load(std::memory_order_relaxed));
198 const auto peak =
static_cast<double>(mPeakUsedMemory.load(std::memory_order_relaxed));
200 const auto maxm = mMaxMemory.load(std::memory_order_relaxed);
202 if (maxm == std::numeric_limits<size_t>::max()) {
207#ifdef BOUNDED_MR_STATS
208 ret += std::format(
" peak={:.2f} GB live={} nAlloc={} nFree={} totalAlloc={:.2f} GB totalFreed={:.2f} GB maxAlign={} upstreamFail={}",
209 (
float)mStats.peak.load(std::memory_order_relaxed) /
constants::GB,
210 mStats.live.load(std::memory_order_relaxed),
211 mStats.nAlloc.load(std::memory_order_relaxed),
212 mStats.nFree.load(std::memory_order_relaxed),
213 (
float)mStats.totalAlloc.load(std::memory_order_relaxed) /
constants::GB,
214 (
float)mStats.totalFreed.load(std::memory_order_relaxed) /
constants::GB,
215 mStats.maxAlign.load(std::memory_order_relaxed),
216 mStats.upstreamFailures.load(std::memory_order_relaxed));