16#ifndef TRACKINGITSU_INCLUDE_BOUNDEDALLOCATOR_H_
17#define TRACKINGITSU_INCLUDE_BOUNDEDALLOCATOR_H_
20#include <memory_resource>
37 : mAttempted(attempted), mUsed(used), mMax(
max) {}
38 const char*
what() const noexcept final
40 static thread_local char msg[256];
41 if (mAttempted != 0) {
43 "Reached set memory limit (attempted: %zu, used: %zu, max: %zu)",
44 mAttempted, mUsed, mMax);
47 "New set maximum below current used (newMax: %zu, used: %zu)",
54 size_t mAttempted{0}, mUsed{0}, mMax{0};
58 : mMaxMemory(maxBytes), mUpstream(upstream) {}
62 size_t new_used{0}, current_used{mUsedMemory.load(std::memory_order_relaxed)};
64 new_used = current_used + bytes;
65 if (new_used > mMaxMemory) {
69 }
while (!mUsedMemory.compare_exchange_weak(current_used, new_used,
70 std::memory_order_acq_rel,
71 std::memory_order_relaxed));
72 return mUpstream->allocate(bytes, alignment);
77 mUpstream->deallocate(p, bytes, alignment);
78 mUsedMemory.fetch_sub(bytes, std::memory_order_relaxed);
83 return this == &
other;
90 if (mUsedMemory >
max) {
99#if !defined(GPUCA_GPUCODE_DEVICE)
100 constexpr double GB{1024 * 1024 * 1024};
101 auto throw_ = mCountThrow.load(std::memory_order_relaxed);
102 auto used =
static_cast<double>(mUsedMemory.load(std::memory_order_relaxed));
103 LOGP(info,
"maxthrow={} maxmem={:.2f} GB used={:.2f} ({:.2f}%)",
104 throw_, (
double)mMaxMemory /
GB, used /
GB, 100. * used / (
double)mMaxMemory);
109 size_t mMaxMemory{std::numeric_limits<size_t>::max()};
110 std::atomic<size_t> mCountThrow{0};
111 std::atomic<size_t> mUsedMemory{0};
121 std::vector<T>().swap(
vec);
127 vec.~bounded_vector<T>();
128 if (bmr ==
nullptr) {
129 auto alloc =
vec.get_allocator().resource();
139 for (
auto&
v :
vec) {
144template <
typename T,
size_t S>
147 for (
size_t i{0};
i <
S; ++
i) {
155 vec.~bounded_vector<T>();
164 for (
size_t i{0};
i <
size; ++
i) {
165 vec.emplace_back(bmr);
169template <
typename T,
size_t S>
172 for (
size_t i{0};
i <
S; ++
i) {
const char * what() const noexcept final
MemoryLimitExceeded(size_t attempted, size_t used, size_t max)
void * do_allocate(size_t bytes, size_t alignment) final
void do_deallocate(void *p, size_t bytes, size_t alignment) final
size_t getMaxMemory() const noexcept
bool do_is_equal(const std::pmr::memory_resource &other) const noexcept final
void setMaxMemory(size_t max)
BoundedMemoryResource(size_t maxBytes=std::numeric_limits< size_t >::max(), std::pmr::memory_resource *upstream=std::pmr::get_default_resource())
size_t getUsedMemory() const noexcept
void deepVectorClear(std::vector< T > &vec)
std::pmr::vector< T > bounded_vector
void clearResizeBoundedArray(std::array< bounded_vector< T >, S > &arr, size_t size, BoundedMemoryResource *bmr, T def=T())
void clearResizeBoundedVector(bounded_vector< T > &vec, size_t size, BoundedMemoryResource *bmr, T def=T())
VectorOfTObjectPtrs other
std::vector< o2::ctf::BufferType > vec
uint64_t const void const *restrict const msg