@@ -69,7 +69,14 @@ class BoundedMemoryResource final : public std::pmr::memory_resource
6969 } while (!mUsedMemory.compare_exchange_weak(current_used, new_used,
7070 std::memory_order_acq_rel,
7171 std::memory_order_relaxed));
72- return mUpstream->allocate(bytes, alignment);
72+ void* p{nullptr};
73+ try {
74+ p = mUpstream->allocate(bytes, alignment);
75+ } catch (...) {
76+ mUsedMemory.fetch_sub(bytes, std::memory_order_relaxed);
77+ throw;
78+ }
79+ return p;
7380 }
7481
7582 void do_deallocate(void* p, size_t bytes, size_t alignment) final
@@ -87,11 +94,12 @@ class BoundedMemoryResource final : public std::pmr::memory_resource
8794 size_t getMaxMemory() const noexcept { return mMaxMemory; }
8895 void setMaxMemory(size_t max)
8996 {
90- if (mUsedMemory > max) {
97+ size_t used = mUsedMemory.load(std::memory_order_acquire);
98+ if (used > max) {
9199 ++mCountThrow;
92- throw MemoryLimitExceeded(0, mUsedMemory , max);
100+ throw MemoryLimitExceeded(0, used , max);
93101 }
94- mMaxMemory = max;
102+ mMaxMemory.store( max, std::memory_order_release) ;
95103 }
96104
97105 void print() const
@@ -106,7 +114,7 @@ class BoundedMemoryResource final : public std::pmr::memory_resource
106114 }
107115
108116 private:
109- size_t mMaxMemory{std::numeric_limits<size_t>::max()};
117+ std::atomic< size_t> mMaxMemory{std::numeric_limits<size_t>::max()};
110118 std::atomic<size_t> mCountThrow{0};
111119 std::atomic<size_t> mUsedMemory{0};
112120 std::pmr::memory_resource* mUpstream;
@@ -116,66 +124,71 @@ template <typename T>
116124using bounded_vector = std::pmr::vector<T>;
117125
118126template <typename T>
119- void deepVectorClear(std::vector<T>& vec)
127+ inline void deepVectorClear(std::vector<T>& vec)
120128{
121129 std::vector<T>().swap(vec);
122130}
123131
124132template <typename T>
125- inline void deepVectorClear(bounded_vector<T>& vec, BoundedMemoryResource* bmr = nullptr)
133+ inline void deepVectorClear(bounded_vector<T>& vec, std::pmr::memory_resource* mr = nullptr)
126134{
127- vec.~bounded_vector<T> ();
128- if (bmr == nullptr ) {
129- auto alloc = vec.get_allocator().resource() ;
130- new (& vec) bounded_vector<T>(alloc );
135+ auto* res = mr ? mr : vec.get_allocator().resource ();
136+ if (res == vec.get_allocator().resource() ) {
137+ bounded_vector<T> empty{std::pmr::polymorphic_allocator<T>{res}} ;
138+ vec.swap(empty );
131139 } else {
132- new (& vec) bounded_vector<T>(bmr );
140+ vec = bounded_vector<T>(std::pmr::polymorphic_allocator<T>{res} );
133141 }
134142}
135143
136144template <typename T>
137- void deepVectorClear(std::vector<bounded_vector<T>>& vec, BoundedMemoryResource* bmr = nullptr)
145+ inline void deepVectorClear(std::vector<bounded_vector<T>>& vec, std::pmr::memory_resource* mr = nullptr)
138146{
139147 for (auto& v : vec) {
140- deepVectorClear(v, bmr );
148+ deepVectorClear(v, mr );
141149 }
142150}
143151
144152template <typename T, size_t S>
145- void deepVectorClear(std::array<bounded_vector<T>, S>& arr, BoundedMemoryResource* bmr = nullptr)
153+ inline void deepVectorClear(std::array<bounded_vector<T>, S>& arr, std::pmr::memory_resource* mr = nullptr)
146154{
147155 for (size_t i{0}; i < S; ++i) {
148- deepVectorClear(arr[i], bmr );
156+ deepVectorClear(arr[i], mr );
149157 }
150158}
151159
152160template <typename T>
153- void clearResizeBoundedVector(bounded_vector<T>& vec, size_t size, BoundedMemoryResource* bmr , T def = T())
161+ inline void clearResizeBoundedVector(bounded_vector<T>& vec, size_t sz, std::pmr::memory_resource* mr = nullptr , T def = T())
154162{
155- vec.~bounded_vector<T>();
156- new (&vec) bounded_vector<T>(size, def, bmr);
163+ auto* res = mr ? mr : vec.get_allocator().resource();
164+ if (res == vec.get_allocator().resource()) {
165+ bounded_vector<T> tmp(sz, def, std::pmr::polymorphic_allocator<T>{res});
166+ vec.swap(tmp);
167+ } else {
168+ vec = bounded_vector<T>(sz, def, std::pmr::polymorphic_allocator<T>{res});
169+ }
157170}
158171
159172template <typename T>
160- void clearResizeBoundedVector(std::vector<bounded_vector<T>>& vec, size_t size, BoundedMemoryResource* bmr )
173+ void clearResizeBoundedVector(std::vector<bounded_vector<T>>& vec, size_t size, std::pmr::memory_resource* mr )
161174{
162175 vec.clear();
163176 vec.reserve(size);
164- for (size_t i{0} ; i < size; ++i) {
165- vec.emplace_back(bmr );
177+ for (size_t i = 0 ; i < size; ++i) {
178+ vec.emplace_back(std::pmr::polymorphic_allocator<bounded_vector<T>>{mr} );
166179 }
167180}
168181
169182template <typename T, size_t S>
170- void clearResizeBoundedArray(std::array<bounded_vector<T>, S>& arr, size_t size, BoundedMemoryResource* bmr , T def = T())
183+ inline void clearResizeBoundedArray(std::array<bounded_vector<T>, S>& arr, size_t size, std::pmr::memory_resource* mr = nullptr , T def = T())
171184{
172185 for (size_t i{0}; i < S; ++i) {
173- clearResizeBoundedVector(arr[i], size, bmr , def);
186+ clearResizeBoundedVector(arr[i], size, mr , def);
174187 }
175188}
176189
177190template <typename T>
178- std::vector<T> toSTDVector(const bounded_vector<T>& b)
191+ inline std::vector<T> toSTDVector(const bounded_vector<T>& b)
179192{
180193 std::vector<T> t(b.size());
181194 std::copy(b.cbegin(), b.cend(), t.begin());
0 commit comments