µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
os-mempool.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2016 Liviu Ionescu.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#ifndef CMSIS_PLUS_RTOS_OS_MEMPOOL_H_
29#define CMSIS_PLUS_RTOS_OS_MEMPOOL_H_
30
31// ----------------------------------------------------------------------------
32
33#if defined(__cplusplus)
34
35// ----------------------------------------------------------------------------
36
39
41
42// ----------------------------------------------------------------------------
43
44#pragma GCC diagnostic push
45
46#if defined(__clang__)
47#pragma clang diagnostic ignored "-Wc++98-compat"
48#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
49#endif
50
51// ----------------------------------------------------------------------------
52
53namespace os
54{
55 namespace rtos
56 {
57
58 // ========================================================================
59
60#pragma GCC diagnostic push
61#pragma GCC diagnostic ignored "-Wpadded"
62
70 {
71 public:
72
73 // ======================================================================
74
82 using size_t = uint16_t;
83
90 static constexpr memory_pool::size_t max_size =
91 static_cast<memory_pool::size_t> (0 - 1);
92
93 // ======================================================================
94
101 {
102 public:
103
114 constexpr
115 attributes ();
116
117 // The rule of five.
118 attributes (const attributes&) = default;
119 attributes (attributes&&) = default;
121 operator= (const attributes&) = default;
123 operator= (attributes&&) = default;
124
128 ~attributes () = default;
129
134 public:
135
141 // Public members; no accessors and mutators required.
142 // Warning: must match the type & order of the C file header.
146 void* mp_pool_address = nullptr;
147
151 std::size_t mp_pool_size_bytes = 0;
152
153 // Add more attributes here.
154
159 }; /* class attributes */
160
166
175 template<typename T, std::size_t blocks, std::size_t block_size_bytes>
176 class arena
177 {
178 public:
179 T pool[(blocks * block_size_bytes + sizeof(T) - 1) / sizeof(T)];
180 };
181
188 template<typename T>
189 constexpr std::size_t
190 compute_allocated_size_bytes (std::size_t blocks,
191 std::size_t block_size_bytes)
192 {
193 // Align each block
194 return (blocks
195 * ((block_size_bytes + (sizeof(T) - 1)) & ~(sizeof(T) - 1)));
196 }
197
198 // ======================================================================
199
204
218 memory_pool (std::size_t blocks, std::size_t block_size_bytes,
219 const attributes& attr = initializer,
220 const allocator_type& allocator = allocator_type ());
230 memory_pool (const char* name, std::size_t blocks,
231 std::size_t block_size_bytes, const attributes& attr =
233 const allocator_type& allocator = allocator_type ());
234
235 protected:
236
241 // Internal constructors, used from templates.
242 memory_pool ();
243 memory_pool (const char* name);
244
249 public:
250
255 // The rule of five.
256 memory_pool (const memory_pool&) = delete;
257 memory_pool (memory_pool&&) = delete;
259 operator= (const memory_pool&) = delete;
261 operator= (memory_pool&&) = delete;
262
267 public:
268
272 virtual
273 ~memory_pool ();
274
289 bool
290 operator== (const memory_pool& rhs) const;
291
296 public:
297
309 void*
310 alloc (void);
311
318 void*
319 try_alloc (void);
320
326 void*
328
336 free (void* block);
337
344 std::size_t
345 capacity (void) const;
346
353 std::size_t
354 count (void) const;
355
362 std::size_t
363 block_size (void) const;
364
372 bool
373 empty (void) const;
374
382 bool
383 full (void) const;
384
393 reset (void);
394
401 void*
402 pool (void);
403
408 protected:
409
427 void
428 internal_construct_ (std::size_t blocks, std::size_t block_size_bytes,
429 const attributes& attr, void* pool_address,
430 std::size_t pool_size_bytes);
431
439 void
440 internal_init_ (void);
441
448 void*
449 internal_try_first_ (void);
450
459 protected:
460
470#if !defined(OS_USE_RTOS_PORT_MEMORY_POOL)
478 clock* clock_ = nullptr;
479#endif
484 void* pool_addr_ = nullptr;
489 void* allocated_pool_addr_ = nullptr;
490
494 const void* allocator_ = nullptr;
495
496#if defined(OS_USE_RTOS_PORT_MEMORY_POOL)
497 friend class port::memory_pool;
498 os_mempool_port_data_t port_;
499#endif
500
505 std::size_t pool_size_bytes_ = 0;
509 std::size_t allocated_pool_size_elements_ = 0;
510
514 memory_pool::size_t blocks_ = 0;
515
519 memory_pool::size_t block_size_bytes_ = 0;
520
524 volatile memory_pool::size_t count_ = 0;
525
529 void* volatile first_ = nullptr;
530
539 };
540
541 // ========================================================================
542
548 template<typename Allocator = memory::allocator<void*>>
550 {
551 public:
552
556 using allocator_type = Allocator;
557
571 memory_pool_allocated (std::size_t blocks, std::size_t block_size_bytes,
572 const attributes& attr = initializer,
573 const allocator_type& allocator =
574 allocator_type ());
575
585 memory_pool_allocated (const char* name, std::size_t blocks,
586 std::size_t block_size_bytes,
587 const attributes& attr = initializer,
588 const allocator_type& allocator =
589 allocator_type ());
590
595 // The rule of five.
599 operator= (const memory_pool_allocated&) = delete;
601 operator= (memory_pool_allocated&&) = delete;
602
610 virtual
612
617 };
618
619 // ========================================================================
620
627 template<typename T, typename Allocator = memory::allocator<void*>>
628 class memory_pool_typed : public memory_pool_allocated<Allocator>
629 {
630 public:
631
635 using value_type = T;
639 using allocator_type = Allocator;
640
653 memory_pool_typed (std::size_t blocks,
654 const memory_pool::attributes& attr =
656 const allocator_type& allocator = allocator_type ());
657
666 memory_pool_typed (const char* name, std::size_t blocks,
667 const memory_pool::attributes& attr =
669 const allocator_type& allocator = allocator_type ());
670
675 // The rule of five.
676 memory_pool_typed (const memory_pool_typed&) = delete;
679 operator= (const memory_pool_typed&) = delete;
681 operator= (memory_pool_typed&&) = delete;
682
690 virtual
691 ~memory_pool_typed () override;
692
697 public:
698
711 alloc (void);
712
720 try_alloc (void);
721
729
738 free (value_type* block);
739
744 };
745
746 // ========================================================================
747
754 template<typename T, std::size_t N>
756 {
757 public:
758
762 using value_type = T;
763
767 static const std::size_t blocks = N;
768
779
785 memory_pool_inclusive (const char* name, const attributes& attr =
787
792 // The rule of five.
796 operator= (const memory_pool_inclusive&) = delete;
798 operator= (memory_pool_inclusive&&) = delete;
799
807 virtual
808 ~memory_pool_inclusive () override;
809
814 protected:
815
829 arena<void*, blocks, sizeof(T)> arena_;
830
835 public:
836
849 alloc (void);
850
858 try_alloc (void);
859
867
876 free (value_type* block);
877
882 };
883
884#pragma GCC diagnostic pop
885
886 } /* namespace rtos */
887} /* namespace os */
888
889// ===== Inline & template implementations ====================================
890
891namespace os
892{
893 namespace rtos
894 {
895 constexpr
897 {
898 ;
899 }
900
901 // ========================================================================
902
907 inline bool
909 {
910 return this == &rhs;
911 }
912
916 inline std::size_t
918 {
919 return blocks_;
920 }
921
925 inline std::size_t
927 {
928 return block_size_bytes_;
929 }
930
934 inline std::size_t
936 {
937 return count_;
938 }
939
943 inline bool
945 {
946 return (count () == 0);
947 }
948
952 inline bool
953 memory_pool::full (void) const
954 {
955 return (count () == capacity ());
956 }
957
961 inline void*
963 {
964 return pool_addr_;
965 }
966
967 // ========================================================================
968
994 template<typename Allocator>
995 inline
997 std::size_t blocks, std::size_t block_size_bytes,
998 const attributes& attr, const allocator_type& allocator) :
1000 { nullptr, blocks, block_size_bytes, attr, allocator }
1001 {
1002 ;
1003 }
1004
1030 template<typename Allocator>
1032 const char* name, std::size_t blocks, std::size_t block_size_bytes,
1033 const attributes& attr, const allocator_type& allocator) :
1035 { name }
1036 {
1037#if defined(OS_TRACE_RTOS_MEMPOOL)
1038 trace::printf ("%s() @%p %s %d %d\n", __func__, this, this->name (),
1039 blocks, block_size_bytes);
1040#endif
1041 if (attr.mp_pool_address != nullptr)
1042 {
1043 // Do not use any allocator at all.
1044 internal_construct_ (blocks, block_size_bytes, attr, nullptr, 0);
1045 }
1046 else
1047 {
1048 allocator_ = &allocator;
1049
1050 // If no user storage was provided via attributes,
1051 // allocate it dynamically via the allocator.
1052 allocated_pool_size_elements_ = (compute_allocated_size_bytes<
1053 typename allocator_type::value_type> (blocks, block_size_bytes)
1054 + sizeof(typename allocator_type::value_type) - 1)
1055 / sizeof(typename allocator_type::value_type);
1056
1057 allocated_pool_addr_ =
1058 const_cast<allocator_type&> (allocator).allocate (
1059 allocated_pool_size_elements_);
1060
1061 internal_construct_ (
1062 blocks,
1063 block_size_bytes,
1064 attr,
1065 allocated_pool_addr_,
1066 allocated_pool_size_elements_
1067 * sizeof(typename allocator_type::value_type));
1068 }
1069 }
1070
1087 template<typename Allocator>
1089 {
1090#if defined(OS_TRACE_RTOS_MEMPOOL)
1091 trace::printf ("%s() @%p %s\n", __func__, this, name ());
1092#endif
1093 typedef typename std::allocator_traits<allocator_type>::pointer pointer;
1094
1095 if (allocated_pool_addr_ != nullptr)
1096 {
1097 static_cast<allocator_type*> (const_cast<void*> (allocator_))->deallocate (
1098 static_cast<pointer> (allocated_pool_addr_),
1099 allocated_pool_size_elements_);
1100
1101 allocated_pool_addr_ = nullptr;
1102 }
1103 }
1104
1105 // ========================================================================
1106
1135 template<typename T, typename Allocator>
1136 inline
1138 std::size_t blocks, const memory_pool::attributes& attr,
1139 const allocator_type& allocator) :
1140 memory_pool_allocated<allocator_type> (blocks, sizeof(T), attr,
1141 allocator)
1142 {
1143 ;
1144 }
1145
1174 template<typename T, typename Allocator>
1175 inline
1177 const char* name, std::size_t blocks,
1178 const memory_pool::attributes& attr, const allocator_type& allocator) :
1179 memory_pool_allocated<allocator_type> (name, blocks, sizeof(T), attr,
1180 allocator)
1181 {
1182 ;
1183 }
1184
1203 template<typename T, typename Allocator>
1205 {
1206 ;
1207 }
1208
1216 template<typename T, typename Allocator>
1219 {
1221 }
1222
1230 template<typename T, typename Allocator>
1233 {
1235 }
1236
1244 template<typename T, typename Allocator>
1247 {
1249 timeout));
1250 }
1251
1259 template<typename T, typename Allocator>
1260 inline result_t
1262 {
1264 }
1265
1266 // ========================================================================
1267
1294 template<typename T, std::size_t N>
1296 const attributes& attr)
1297 {
1298 internal_construct_ (blocks, sizeof(T), attr, &arena_, sizeof(arena_));
1299 }
1300
1327 template<typename T, std::size_t N>
1329 const char* name, const attributes& attr) :
1331 { name }
1332 {
1333 internal_construct_ (blocks, sizeof(T), attr, &arena_, sizeof(arena_));
1334 }
1335
1349 template<typename T, std::size_t N>
1351 {
1352 ;
1353 }
1354
1362 template<typename T, std::size_t N>
1365 {
1366 return static_cast<value_type*> (memory_pool::alloc ());
1367 }
1368
1376 template<typename T, std::size_t N>
1379 {
1380 return static_cast<value_type*> (memory_pool::try_alloc ());
1381 }
1382
1390 template<typename T, std::size_t N>
1393 {
1394 return static_cast<value_type*> (memory_pool::timed_alloc (timeout));
1395 }
1396
1404 template<typename T, std::size_t N>
1405 inline result_t
1407 {
1408 return memory_pool::free (block);
1409 }
1410
1411 } /* namespace rtos */
1412} /* namespace os */
1413
1414#pragma GCC diagnostic pop
1415
1416// ----------------------------------------------------------------------------
1417
1418#endif /* __cplusplus */
1419
1420// ----------------------------------------------------------------------------
1421
1422#endif /* CMSIS_PLUS_RTOS_OS_MEMPOOL_H_ */
Generic clock.
Definition os-clocks.h:66
Base class for attributes.
Definition os-decls.h:577
Base class for named system objects.
Definition os-decls.h:459
const char * name(void) const
Get object name.
Definition os-decls.h:774
Priority ordered list of threads.
Definition os-lists.h:550
Standard allocator based on the RTOS system default memory manager.
Definition os-memory.h:544
Storage for a memory pool.
Definition os-mempool.h:177
T pool[(blocks *block_size_bytes+sizeof(T) - 1)/sizeof(T)]
Definition os-mempool.h:179
Memory pool attributes.
Definition os-mempool.h:101
void * mp_pool_address
Address of the user defined storage for the memory pool.
Definition os-mempool.h:146
~attributes()=default
Destruct the memory pool attributes object instance.
std::size_t mp_pool_size_bytes
Size of the user defined storage for the memory pool.
Definition os-mempool.h:151
attributes(const attributes &)=default
attributes(attributes &&)=default
constexpr attributes()
Construct a memory pool attributes object instance.
Definition os-mempool.h:896
attributes & operator=(const attributes &)=default
Template of a synchronised memory pool with allocator.
Definition os-mempool.h:550
virtual ~memory_pool_allocated() override
Destruct the memory pool object instance.
memory_pool_allocated(const char *name, std::size_t blocks, std::size_t block_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
Construct a named memory pool object instance.
Allocator allocator_type
Standard allocator type definition.
Definition os-mempool.h:556
memory_pool_allocated(std::size_t blocks, std::size_t block_size_bytes, const attributes &attr=initializer, const allocator_type &allocator=allocator_type())
Construct a memory pool object instance.
Definition os-mempool.h:996
Template of a synchronised memory pool with block type and local storage.
Definition os-mempool.h:756
arena< void *, blocks, sizeof(T)> arena_
Local storage for the pool.
Definition os-mempool.h:829
result_t free(value_type *block)
Free the memory block.
memory_pool_inclusive(const attributes &attr=initializer)
Construct a memory pool object instance.
T value_type
Local type of message.
Definition os-mempool.h:762
value_type * timed_alloc(clock::duration_t timeout)
Allocate a memory block with timeout.
virtual ~memory_pool_inclusive() override
Destruct the memory pool object instance.
static const std::size_t blocks
Local constant based on template definition.
Definition os-mempool.h:767
value_type * try_alloc(void)
Allocate a memory block.
value_type * alloc(void)
Allocate a memory block.
Template of a synchronised memory pool with block type and allocator.
Definition os-mempool.h:629
result_t free(value_type *block)
Free the memory block.
T value_type
Standard allocator type definition.
Definition os-mempool.h:635
value_type * try_alloc(void)
Allocate a memory block.
value_type * alloc(void)
Allocate a memory block.
Allocator allocator_type
Standard allocator type definition.
Definition os-mempool.h:639
virtual ~memory_pool_typed() override
Destruct the memory pool object instance.
memory_pool_typed(std::size_t blocks, const memory_pool::attributes &attr=memory_pool::initializer, const allocator_type &allocator=allocator_type())
Construct a memory pool object instance.
value_type * timed_alloc(clock::duration_t timeout)
Allocate a memory block with timeout.
Synchronised memory pool, using the default RTOS allocator.
Definition os-mempool.h:70
void * timed_alloc(clock::duration_t timeout)
Allocate a memory block with timeout.
void * try_alloc(void)
Try to allocate a memory block.
std::size_t block_size(void) const
Get block size.
Definition os-mempool.h:926
void * alloc(void)
Allocate a memory block.
bool empty(void) const
Check if the memory pool is empty.
Definition os-mempool.h:944
std::size_t capacity(void) const
Get memory pool capacity.
Definition os-mempool.h:917
std::size_t count(void) const
Get blocks count.
Definition os-mempool.h:935
result_t free(void *block)
Free the memory block.
void * pool(void)
Get the pool storage address.
Definition os-mempool.h:962
result_t reset(void)
Reset the memory pool.
constexpr std::size_t compute_allocated_size_bytes(std::size_t blocks, std::size_t block_size_bytes)
Calculator for pool storage requirements.
Definition os-mempool.h:190
virtual ~memory_pool()
Destruct the memory pool object instance.
bool operator==(const memory_pool &rhs) const
Compare memory pools.
Definition os-mempool.h:908
bool full(void) const
Check if the memory pool is full.
Definition os-mempool.h:953
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:83
static constexpr memory_pool::size_t max_size
Maximum pool size.
Definition os-mempool.h:90
uint16_t size_t
Type of memory pool size storage.
Definition os-mempool.h:82
static const attributes initializer
Default memory pool initialiser.
Definition os-mempool.h:165
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:110
System namespace.