@@ -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