src/zserio/pmr/MemoryResource.h
Line | Count | Source |
1 | | #ifndef ZSERIO_PMR_I_MEMORY_RESOURCE_H_INC |
2 | | #define ZSERIO_PMR_I_MEMORY_RESOURCE_H_INC |
3 | | |
4 | | #include <cstddef> |
5 | | #ifdef ZSERIO_MEMORY_RESOURCE_TRACING |
6 | | #include <iostream> |
7 | | #endif |
8 | | |
9 | | namespace zserio |
10 | | { |
11 | | namespace pmr |
12 | | { |
13 | | |
14 | | /** |
15 | | * Abstract base class for memory resources which are to be used by polymorphic allocators defined by zserio. |
16 | | */ |
17 | | class MemoryResource |
18 | | { |
19 | | public: |
20 | | // this empty constructor is necessary for gcc 9.3.0 bug which causes test coverage failure |
21 | | /** |
22 | | * Constructor. |
23 | | */ |
24 | 25 | MemoryResource() = default; |
25 | | |
26 | | /** |
27 | | * Destructor. |
28 | | */ |
29 | 26 | virtual ~MemoryResource() = default; |
30 | | |
31 | | /** |
32 | | * Copying and moving is disallowed! |
33 | | * \{ |
34 | | */ |
35 | | MemoryResource(const MemoryResource& other) = delete; |
36 | | MemoryResource(MemoryResource&& other) = delete; |
37 | | |
38 | | MemoryResource& operator=(const MemoryResource& other) = delete; |
39 | | MemoryResource& operator=(MemoryResource&& other) = delete; |
40 | | /** \} */ |
41 | | |
42 | | /** |
43 | | * Allocates storage with a size of at least bytes bytes, aligned to the specified alignment. |
44 | | * |
45 | | * \param bytes Minimum number of bytes to allocate. |
46 | | * \param alignment Requested alignment. |
47 | | * |
48 | | * \return Pointer to the allocated storage. |
49 | | */ |
50 | | void* allocate(size_t bytes, size_t alignment = alignof(max_align_t)) |
51 | 197 | { |
52 | | #ifdef ZSERIO_MEMORY_RESOURCE_TRACING |
53 | | void* const ptr = doAllocate(bytes, alignment); |
54 | | std::cout << "MemoryResource::allocate bytes=" << bytes << " alignment=" << alignment << " -> " |
55 | | << std::hex << ptr << std::dec << std::endl; |
56 | | return ptr; |
57 | | #else |
58 | 197 | return doAllocate(bytes, alignment); |
59 | 197 | #endif |
60 | 197 | } |
61 | | |
62 | | /** |
63 | | * Deallocates the storage pointed to by p. |
64 | | * |
65 | | * Arguments shall match to prior call to allocate! |
66 | | * |
67 | | * \param storage Pointer to the storage to deallocate. |
68 | | * \param bytes Number of bytes to deallocate. |
69 | | * \param alignment Requested alignment. |
70 | | */ |
71 | | void deallocate(void* storage, size_t bytes, size_t alignment = alignof(max_align_t)) |
72 | 197 | { |
73 | | #ifdef ZSERIO_MEMORY_RESOURCE_TRACING |
74 | | std::cout << "MemoryResource::deallocate p=" << std::hex << storage << std::dec << " bytes=" << bytes |
75 | | << " alignment=" << alignment << std::endl; |
76 | | #endif |
77 | 197 | doDeallocate(storage, bytes, alignment); |
78 | 197 | } |
79 | | |
80 | | /** |
81 | | * Compares *this for equality with other. |
82 | | * |
83 | | * Two memory resources compare equal if and only if memory allocated from one memory resource |
84 | | * can be deallocated from the other and vice versa. |
85 | | * |
86 | | * \param other Other memory resource to compare. |
87 | | * |
88 | | * \return True when the two resources are equal, false otherwise. |
89 | | */ |
90 | | bool isEqual(const MemoryResource& other) const noexcept |
91 | 13 | { |
92 | | #ifdef ZSERIO_MEMORY_RESOURCE_TRACING |
93 | | std::cout << "MemoryResource::isEqual other=" << std::hex << &other << std::dec << std::endl; |
94 | | #endif |
95 | 13 | return doIsEqual(other); |
96 | 13 | } |
97 | | |
98 | | private: |
99 | | /** |
100 | | * Allocates storage with a size of at least bytes bytes, aligned to the specified alignment. |
101 | | * |
102 | | * \param bytes Minimum number of bytes to allocate. |
103 | | * \param alignment Requested alignment. |
104 | | * |
105 | | * \return Pointer to the allocated storage. |
106 | | */ |
107 | | virtual void* doAllocate(size_t bytes, size_t alignment) = 0; |
108 | | |
109 | | /** |
110 | | * Deallocates the storage pointed to by storage. |
111 | | * |
112 | | * Arguments shall match to prior call to doAllocate! |
113 | | * |
114 | | * \param storage Pointer to the storage to deallocate. |
115 | | * \param bytes Number of bytes to deallocate. |
116 | | * \param alignment Requested alignment. |
117 | | */ |
118 | | virtual void doDeallocate(void* storage, size_t bytes, size_t alignment) = 0; |
119 | | |
120 | | /** |
121 | | * Compares *this for equality with other. |
122 | | * |
123 | | * Two memory resources compare equal if and only if memory allocated from one memory resource |
124 | | * can be deallocated from the other and vice versa. |
125 | | * |
126 | | * \param other Other memory resource to compare. |
127 | | * |
128 | | * \return True when the two resources are equal, false otherwise. |
129 | | */ |
130 | | virtual bool doIsEqual(const MemoryResource& other) const noexcept = 0; |
131 | | }; |
132 | | |
133 | | /** |
134 | | * Compares the memory resources lhs and rhs for equality. |
135 | | * |
136 | | * \param lhs First memory resource to compare. |
137 | | * \param rhs Second memory resource to compare. |
138 | | * |
139 | | * \return True when the two resources are equal, false otherwise. |
140 | | */ |
141 | | inline bool operator==(const MemoryResource& lhs, const MemoryResource& rhs) |
142 | 74 | { |
143 | 74 | return &lhs == &rhs || lhs.isEqual(rhs)8 ; |
144 | 74 | } |
145 | | |
146 | | /** |
147 | | * Compares the memory resources lhs and rhs for non-equality. |
148 | | * |
149 | | * \param lhs First memory resource to compare. |
150 | | * \param rhs Second memory resource to compare. |
151 | | * |
152 | | * \return True when the two resources are NOT equal, false otherwise. |
153 | | */ |
154 | | inline bool operator!=(const MemoryResource& lhs, const MemoryResource& rhs) |
155 | 3 | { |
156 | 3 | return !(lhs == rhs); |
157 | 3 | } |
158 | | |
159 | | /** |
160 | | * Returns default memory resource, which is the resource set by previous call to |
161 | | * setDefaultResource, or zserio::pmr::NewDeleteResource if no call to setDefaultResource |
162 | | * was done. |
163 | | * |
164 | | * \warning This function does not synchronize with setDefaultResource. |
165 | | * |
166 | | * \return Default memory resource. |
167 | | */ |
168 | | MemoryResource* getDefaultResource() noexcept; |
169 | | |
170 | | /** |
171 | | * If resource is not null, sets the default memory resource pointer to resource, |
172 | | * otherwise, sets the default memory resource pointer to zserio::pmr::NewDeleteResource. |
173 | | * All subsequent calls to getDefaultResource() returns resource set by this function. |
174 | | * |
175 | | * \warning This function does not synchronize with getDefaultResource or other calls to setDefaultResource. |
176 | | * It is undefined behavior to call setDefaultResource together with getDefaultResource concurrently. |
177 | | * |
178 | | * \param resource Resource to be set as default, or nullptr to use zserio::pmr::NewDeleteResource. |
179 | | * |
180 | | * \return Previous default resource. |
181 | | */ |
182 | | MemoryResource* setDefaultResource(MemoryResource* resource) noexcept; |
183 | | |
184 | | } // namespace pmr |
185 | | } // namespace zserio |
186 | | |
187 | | #endif // ZSERIO_PMR_I_MEMORY_RESOURCE_H_INC |