Project
Loading...
Searching...
No Matches
BoundedAllocator.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
15
16#ifndef ALICEO2_ITSMFT_TRACKING_BOUNDEDALLOCATOR_H_
17#define ALICEO2_ITSMFT_TRACKING_BOUNDEDALLOCATOR_H_
18
19#include <algorithm>
20#include <array>
21#include <atomic>
22#include <limits>
23#include <memory>
24#include <memory_resource>
25#include <new>
26#include <string>
27#include <utility>
28#include <vector>
29
31{
32
33// #define BOUNDED_MR_STATS
35{
36 public:
37 class MemoryLimitExceeded final : public std::bad_alloc
38 {
39 public:
40 MemoryLimitExceeded(size_t attempted, size_t used, size_t max);
41 const char* what() const noexcept final;
42
43 private:
44 std::string mMsg;
45 };
46
48
49 BoundedMemoryResource(size_t maxBytes = std::numeric_limits<size_t>::max(),
50 std::pmr::memory_resource* upstream = nullptr);
51
52 BoundedMemoryResource(std::unique_ptr<std::pmr::memory_resource> upstream,
53 size_t maxBytes = std::numeric_limits<size_t>::max());
54
55 [[nodiscard]] size_t getUsedMemory() const noexcept;
56 [[nodiscard]] size_t getMaxMemory() const noexcept;
57 [[nodiscard]] size_t getThrowCount() const noexcept;
58 [[nodiscard]] size_t getPeakMemory() const noexcept;
59 [[nodiscard]] size_t getPeakMemoryDelta() const noexcept;
60
61 void resetPeakMemory() noexcept;
62 void setMaxMemory(size_t max);
63
64#if !defined(__HIPCC__) && !defined(__CUDACC__)
65 std::string asString() const;
66 void print() const;
67#endif
68
69 private:
70 void* do_allocate(size_t bytes, size_t alignment) final;
71 void do_deallocate(void* p, size_t bytes, size_t alignment) final;
72 bool do_is_equal(const std::pmr::memory_resource& other) const noexcept final;
73
74 std::atomic<size_t> mMaxMemory{std::numeric_limits<size_t>::max()};
75 std::atomic<size_t> mCountThrow{0};
76 std::atomic<size_t> mUsedMemory{0};
77 std::atomic<size_t> mPeakUsedMemory{0};
78 std::atomic<size_t> mPeakBaselineMemory{0};
79 std::unique_ptr<std::pmr::memory_resource> mOwnedUpstream;
80 std::pmr::memory_resource* mUpstream{nullptr};
81
82#ifdef BOUNDED_MR_STATS
83 struct Stats {
84 std::atomic<size_t> peak{0};
85 std::atomic<size_t> live{0};
86 std::atomic<size_t> nAlloc{0};
87 std::atomic<size_t> nFree{0};
88 std::atomic<size_t> totalAlloc{0};
89 std::atomic<size_t> totalFreed{0};
90 std::atomic<size_t> maxAlign{0};
91 std::atomic<size_t> upstreamFailures{0};
92 };
93 Stats mStats{};
94#endif
95};
96
97template <typename T>
98using bounded_vector = std::pmr::vector<T>;
99
100template <typename T>
101inline void deepVectorClear(std::vector<T>& vec)
102{
103 std::vector<T>().swap(vec);
104}
105
106template <typename T>
108{
109 std::pmr::memory_resource* tmr = (mr != nullptr) ? mr : vec.get_allocator().resource();
110 vec.~bounded_vector<T>();
111 new (&vec) bounded_vector<T>(std::pmr::polymorphic_allocator<T>{tmr});
112}
113
114template <typename T>
115inline void deepVectorClear(std::vector<bounded_vector<T>>& vec, std::pmr::memory_resource* mr = nullptr)
116{
117 for (auto& v : vec) {
118 deepVectorClear(v, mr);
119 }
120}
121
122template <typename T, size_t S>
123inline void deepVectorClear(std::array<bounded_vector<T>, S>& arr, std::pmr::memory_resource* mr = nullptr)
124{
125 for (size_t i{0}; i < S; ++i) {
126 deepVectorClear(arr[i], mr);
127 }
128}
129
130template <typename T>
131inline void clearResizeBoundedVector(bounded_vector<T>& vec, size_t sz, std::pmr::memory_resource* mr = nullptr, T def = T())
132{
133 std::pmr::memory_resource* tmr = (mr != nullptr) ? mr : vec.get_allocator().resource();
134 vec.~bounded_vector<T>();
135 new (&vec) bounded_vector<T>(sz, def, std::pmr::polymorphic_allocator<T>{tmr});
136}
137
138template <typename T>
140{
141 vec.clear();
142 vec.reserve(size);
143 for (size_t i = 0; i < size; ++i) {
144 vec.emplace_back(std::pmr::polymorphic_allocator<bounded_vector<T>>{mr});
145 }
146}
147
148template <typename T, size_t S>
149inline void clearResizeBoundedArray(std::array<bounded_vector<T>, S>& arr, size_t size, std::pmr::memory_resource* mr = nullptr, T def = T())
150{
151 for (size_t i{0}; i < S; ++i) {
152 clearResizeBoundedVector(arr[i], size, mr, def);
153 }
154}
155
156template <typename T>
157inline std::vector<T> toSTDVector(const bounded_vector<T>& b)
158{
159 std::vector<T> t(b.size());
160 std::copy(b.cbegin(), b.cend(), t.begin());
161 return t;
162}
163
164} // namespace o2::itsmft::tracking
165
166#endif /* ALICEO2_ITSMFT_TRACKING_BOUNDEDALLOCATOR_H_ */
int32_t i
static std::pmr::memory_resource * cachingUpstream()
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
void clearResizeBoundedArray(std::array< bounded_vector< T >, S > &arr, size_t size, std::pmr::memory_resource *mr=nullptr, T def=T())
void deepVectorClear(std::vector< T > &vec)
void clearResizeBoundedVector(bounded_vector< T > &vec, size_t sz, std::pmr::memory_resource *mr=nullptr, T def=T())
std::pmr::vector< T > bounded_vector
std::vector< T > toSTDVector(const bounded_vector< T > &b)
constexpr size_t max
VectorOfTObjectPtrs other
std::vector< o2::ctf::BufferType > vec