Embedded Template Library 1.0
Loading...
Searching...
No Matches
reference_counted_message_pool.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2020 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_REFERENCE_COUNTED_MESSAGE_POOL_INCLUDED
32#define ETL_REFERENCE_COUNTED_MESSAGE_POOL_INCLUDED
33
34#include "platform.h"
35#include "message.h"
38#include "reference_counted_message.h"
39#include "static_assert.h"
40#include "error_handler.h"
41#include "utility.h"
42#include "atomic.h"
43#include "memory.h"
44#include "largest.h"
45
46namespace etl
47{
48 //***************************************************************************
50 //***************************************************************************
60
61 //***************************************************************************
63 //***************************************************************************
65 {
66 public:
67
69 : reference_counted_message_pool_exception(ETL_ERROR_TEXT("reference_counted_message_pool:allocation failure", ETL_REFERENCE_COUNTER_MESSAGE_POOL_FILE_ID"A"), file_name_, line_number_)
70 {
71 }
72 };
73
74 //***************************************************************************
76 //***************************************************************************
78 {
79 public:
80
82 : reference_counted_message_pool_exception(ETL_ERROR_TEXT("reference_counted_message_pool:release failure", ETL_REFERENCE_COUNTER_MESSAGE_POOL_FILE_ID"B"), file_name_, line_number_)
83 {
84 }
85 };
86
87 //***************************************************************************
89 //***************************************************************************
90 template <typename TCounter>
92 {
93 public:
94
95 //*************************************************************************
97 //*************************************************************************
102
103#if ETL_USING_CPP11
104 //*************************************************************************
106 //*************************************************************************
107 template <typename TMessage, typename... TArgs>
109 {
110 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
111
113 typedef rcm_t* prcm_t;
114
115 prcm_t p = ETL_NULLPTR;
116
117 lock();
118 p = static_cast<prcm_t>(memory_block_allocator.allocate(sizeof(rcm_t), etl::alignment_of<rcm_t>::value));
119 unlock();
120
121 if (p != ETL_NULLPTR)
122 {
123 ::new(p) rcm_t(*this, etl::forward<TArgs>(args)...);
124 }
125
127
128 return p;
129 }
130#endif
131
132 //*************************************************************************
134 //*************************************************************************
135 template <typename TMessage>
137 {
138 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
139
141 typedef rcm_t* prcm_t;
142
143 prcm_t p = ETL_NULLPTR;
144
145 lock();
146 p = static_cast<prcm_t>(memory_block_allocator.allocate(sizeof(rcm_t), etl::alignment_of<rcm_t>::value));
147 unlock();
148
149 if (p != ETL_NULLPTR)
150 {
151 ::new(p) rcm_t(message, *this);
152 }
153
155
156 return p;
157 }
158
159 //*************************************************************************
161 //*************************************************************************
162 template <typename TMessage>
164 {
165 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage>::value), "Not a message type");
166
168 typedef rcm_t* prcm_t;
169
170 prcm_t p = ETL_NULLPTR;
171
172 lock();
173 p = static_cast<prcm_t>(memory_block_allocator.allocate(sizeof(rcm_t), etl::alignment_of<rcm_t>::value));
174 unlock();
175
176 if (p != ETL_NULLPTR)
177 {
178 ::new(p) rcm_t(*this);
179 }
180
182
183 return p;
184 }
185
186 //*************************************************************************
188 //*************************************************************************
190 {
191 bool released = false;
192
193 lock();
194 if (memory_block_allocator.is_owner_of(&rcmessage))
195 {
196 rcmessage.~ireference_counted_message();
197 released = memory_block_allocator.release(&rcmessage);
198 }
199 unlock();
200
202 }
203
204#if ETL_USING_CPP11
205 //*****************************************************
206 template <typename TMessage1, typename... TMessages>
207 struct pool_message_parameters
208 {
209 private:
210
211 // Size of the first pool message type.
212 static constexpr size_t size1 = sizeof(etl::reference_counted_message<TMessage1, TCounter>);
213
214 // Maximum size of the rest of the pool message types.
215 static constexpr size_t size2 = pool_message_parameters<TMessages...>::max_size;
216
217 // Size of the first pool message type.
219
220 // Maximum size of the rest of the pool message types.
221 static constexpr size_t alignment2 = pool_message_parameters<TMessages...>::max_alignment;
222
223 public:
224
225 // The maximum size.
226 static constexpr size_t max_size = (size1 < size2) ? size2 : size1;
227
228 // The maximum alignment.
229 static constexpr size_t max_alignment = (alignment1 < alignment2) ? alignment2 : alignment1;
230 };
231
232 //*****************************************************
233 template <typename TMessage1>
234 struct pool_message_parameters<TMessage1>
235 {
236 public:
237
238 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage not derived from etl::imessage");
239
240 // The size of this pool message type.
241 static constexpr size_t max_size = sizeof(etl::reference_counted_message<TMessage1, TCounter>);
242
243 // The maximum alignment.
244 static constexpr size_t max_alignment = etl::alignment_of<etl::reference_counted_message<TMessage1, TCounter>>::value;
245 };
246
247#else
248 template <typename TMessage1, typename TMessage2 = TMessage1, typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
249 typename TMessage5 = TMessage1, typename TMessage6 = TMessage1, typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
251 {
252 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage1 not derived from etl::imessage");
253 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage2 not derived from etl::imessage");
254 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage3 not derived from etl::imessage");
255 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage4 not derived from etl::imessage");
256 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage5 not derived from etl::imessage");
257 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage6 not derived from etl::imessage");
258 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage7 not derived from etl::imessage");
259 ETL_STATIC_ASSERT((etl::is_base_of<etl::imessage, TMessage1>::value), "TMessage8 not derived from etl::imessage");
260
261 static ETL_CONSTANT size_t max_size = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
269
270
271 static ETL_CONSTANT size_t max_alignment = etl::largest<etl::reference_counted_message<TMessage1, TCounter>,
279 };
280
281#endif
282
283 private:
284
286 imemory_block_allocator& memory_block_allocator;
287
288 // Should not be copied.
291 };
292
293#if ETL_USING_CPP11
294
295 template <typename TCounter>
296 template <typename TMessage1, typename... TMessages>
298
299 template <typename TCounter>
300 template <typename TMessage1, typename... TMessages>
302
303#else
304
305 template <typename TCounter>
306 template <typename TMessage1, typename TMessage2, typename TMessage3, typename TMessage4,
307 typename TMessage5, typename TMessage6, typename TMessage7, typename TMessage8>
309
310 template <typename TCounter>
311 template <typename TMessage1, typename TMessage2, typename TMessage3, typename TMessage4,
312 typename TMessage5, typename TMessage6, typename TMessage7, typename TMessage8>
314
315#endif
316
317#if ETL_USING_CPP11 && ETL_HAS_ATOMIC
319#endif
320}
321
322#endif
The interface for a memory block pool.
Definition imemory_block_allocator.h:44
bool release(const void *const p)
Definition imemory_block_allocator.h:81
bool is_owner_of(const void *const p) const
Definition imemory_block_allocator.h:103
void * allocate(size_t required_size, size_t required_alignment)
Definition imemory_block_allocator.h:58
Interface for a reference counted message pool.
Definition ireference_counted_message_pool.h:44
virtual void unlock()
Definition ireference_counted_message_pool.h:65
virtual void lock()
Definition ireference_counted_message_pool.h:56
Definition reference_counted_message.h:48
Definition message.h:91
Exception if the allocation failed.
Definition reference_counted_message_pool.h:65
Exception type for etl::reference_counted_message_pool.
Definition reference_counted_message_pool.h:52
Exception if the release failed.
Definition reference_counted_message_pool.h:78
A pool for allocating reference counted messages.
Definition reference_counted_message_pool.h:92
void release(const etl::ireference_counted_message &rcmessage)
Destruct a message and send it back to the allocator.
Definition reference_counted_message_pool.h:189
reference_counted_message_pool(etl::imemory_block_allocator &memory_block_allocator_)
Constructor.
Definition reference_counted_message_pool.h:98
etl::reference_counted_message< TMessage, TCounter > * allocate(const TMessage &message)
Allocate a reference counted message from the pool.
Definition reference_counted_message_pool.h:136
etl::reference_counted_message< TMessage, TCounter > * allocate()
Allocate a reference counted message from the pool.
Definition reference_counted_message_pool.h:163
#define ETL_ASSERT(b, e)
Definition error_handler.h:316
Definition exception.h:47
add_rvalue_reference
Definition type_traits_generator.h:1327
is_base_of
Definition type_traits_generator.h:1252
bitset_ext
Definition absolute.h:38
size_t max_size() const
Returns the maximum number of items in the variant_pool.
Definition variant_pool_generator.h:395
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1187
pair holds two objects of arbitrary type
Definition utility.h:164
Definition reference_counted_message_pool.h:251