µ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++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2016-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12#ifndef CMSIS_PLUS_RTOS_OS_MEMPOOL_H_
13#define CMSIS_PLUS_RTOS_OS_MEMPOOL_H_
14
15// ----------------------------------------------------------------------------
16
17#if defined(__cplusplus)
18
19// ----------------------------------------------------------------------------
20
21#if defined(OS_USE_OS_APP_CONFIG_H)
22#include <cmsis-plus/os-app-config.h>
23#endif
24
27
29
30// ----------------------------------------------------------------------------
31
32#pragma GCC diagnostic push
33#if defined(__clang__)
34#pragma clang diagnostic ignored "-Wc++98-compat"
35#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
36#endif
37
38// ----------------------------------------------------------------------------
39
40namespace os
41{
42 namespace rtos
43 {
44
45 // ========================================================================
46
47#pragma GCC diagnostic push
48#if defined(__clang__)
49#pragma clang diagnostic ignored "-Wpadded"
50#elif defined(__GNUC__)
51#pragma GCC diagnostic ignored "-Wpadded"
52#endif
53
60#pragma GCC diagnostic push
61#if defined(__clang__)
62#elif defined(__GNUC__)
63#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
64#pragma GCC diagnostic ignored "-Wsuggest-final-types"
65#endif
67 {
68 public:
69 // ======================================================================
70
79 using size_t = uint16_t;
80
89 = static_cast<memory_pool::size_t> (0 - 1);
90
91 // ======================================================================
92
99 {
100 public:
111 constexpr attributes ();
112
113 // The rule of five.
114 attributes (const attributes&) = default;
115 attributes (attributes&&) = default;
118 = default;
121 = default;
122
126 ~attributes () = default;
127
132 public:
138 // Public members; no accessors and mutators required.
139 // Warning: must match the type & order of the C file header.
143 void* mp_pool_address = nullptr;
144
148 std::size_t mp_pool_size_bytes = 0;
149
150 // Add more attributes here.
151
156 }; /* class attributes */
157
163
173 template <typename T, std::size_t blocks, std::size_t block_size_bytes>
174 class arena
175 {
176 public:
177 T pool[(blocks * block_size_bytes + sizeof (T) - 1) / sizeof (T)];
178 };
179
186 template <typename T>
187 constexpr std::size_t
188 compute_allocated_size_bytes (std::size_t blocks,
189 std::size_t block_size_bytes)
190 {
191 // Align each block
192 return (blocks
193 * ((block_size_bytes + (sizeof (T) - 1)) & ~(sizeof (T) - 1)));
194 }
195
196 // ======================================================================
197
203
217 memory_pool (std::size_t blocks, std::size_t block_size_bytes,
218 const attributes& attr = initializer,
219 const allocator_type& allocator = allocator_type ());
229 memory_pool (const char* name, std::size_t blocks,
230 std::size_t block_size_bytes,
231 const attributes& attr = initializer,
232 const allocator_type& allocator = allocator_type ());
233
234 protected:
239 // Internal constructors, used from templates.
240 memory_pool ();
241 memory_pool (const char* name);
242
247 public:
252 // The rule of five.
253 memory_pool (const memory_pool&) = delete;
254 memory_pool (memory_pool&&) = delete;
256 operator= (const memory_pool&)
257 = delete;
259 operator= (memory_pool&&)
260 = delete;
261
266 public:
270 virtual ~memory_pool ();
271
286 bool
287 operator== (const memory_pool& rhs) const;
288
293 public:
305 void*
306 alloc (void);
307
314 void*
315 try_alloc (void);
316
323 void*
325
333 free (void* block);
334
341 std::size_t
342 capacity (void) const;
343
350 std::size_t
351 count (void) const;
352
359 std::size_t
360 block_size (void) const;
361
369 bool
370 empty (void) const;
371
379 bool
380 full (void) const;
381
390 reset (void);
391
398 void*
399 pool (void);
400
405 protected:
423 void
424 internal_construct_ (std::size_t blocks, std::size_t block_size_bytes,
425 const attributes& attr, void* pool_address,
426 std::size_t pool_size_bytes);
427
435 void
436 internal_init_ (void);
437
444 void*
445 internal_try_first_ (void);
446
455 protected:
465#if !defined(OS_USE_RTOS_PORT_MEMORY_POOL)
473 clock* clock_ = nullptr;
474#endif
479 void* pool_addr_ = nullptr;
484 void* allocated_pool_addr_ = nullptr;
485
489 const void* allocator_ = nullptr;
490
491#if defined(OS_USE_RTOS_PORT_MEMORY_POOL)
492 friend class port::memory_pool;
493 os_mempool_port_data_t port_;
494#endif
495
500 std::size_t pool_size_bytes_ = 0;
504 std::size_t allocated_pool_size_elements_ = 0;
505
509 memory_pool::size_t blocks_ = 0;
510
514 memory_pool::size_t block_size_bytes_ = 0;
515
519 volatile memory_pool::size_t count_ = 0;
520
524 void* volatile first_ = nullptr;
525
533 };
534#pragma GCC diagnostic pop
535
536 // ========================================================================
537
543 template <typename Allocator = memory::allocator<void*>>
545 {
546 public:
550 using allocator_type = Allocator;
551
565 memory_pool_allocated (std::size_t blocks, std::size_t block_size_bytes,
566 const attributes& attr = initializer,
567 const allocator_type& allocator
568 = allocator_type ());
569
579 memory_pool_allocated (const char* name, std::size_t blocks,
580 std::size_t block_size_bytes,
581 const attributes& attr = initializer,
582 const allocator_type& allocator
583 = allocator_type ());
584
589 // The rule of five.
593 operator= (const memory_pool_allocated&)
594 = delete;
596 operator= (memory_pool_allocated&&)
597 = delete;
598
606 virtual ~memory_pool_allocated () override;
607
611 };
612
613 // ========================================================================
614
621#pragma GCC diagnostic push
622#if defined(__clang__)
623#elif defined(__GNUC__)
624#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
625#pragma GCC diagnostic ignored "-Wsuggest-final-types"
626#endif
627 template <typename T, typename Allocator = memory::allocator<void*>>
628 class memory_pool_typed : public memory_pool_allocated<Allocator>
629 {
630 public:
634 using value_type = T;
638 using allocator_type = Allocator;
639
652 memory_pool_typed (std::size_t blocks,
653 const memory_pool::attributes& attr
655 const allocator_type& allocator = allocator_type ());
656
665 memory_pool_typed (const char* name, std::size_t blocks,
666 const memory_pool::attributes& attr
668 const allocator_type& allocator = allocator_type ());
669
674 // The rule of five.
675 memory_pool_typed (const memory_pool_typed&) = delete;
678 operator= (const memory_pool_typed&)
679 = delete;
681 operator= (memory_pool_typed&&)
682 = delete;
683
691 virtual ~memory_pool_typed () override;
692
697 public:
710 alloc (void);
711
719 try_alloc (void);
720
729
738 free (value_type* block);
739
743 };
744#pragma GCC diagnostic pop
745
746 // ========================================================================
747
754 template <typename T, std::size_t N>
756 {
757 public:
761 using value_type = T;
762
766 static const std::size_t blocks = N;
767
778
784 memory_pool_inclusive (const char* name,
785 const attributes& attr = initializer);
786
791 // The rule of five.
795 operator= (const memory_pool_inclusive&)
796 = delete;
798 operator= (memory_pool_inclusive&&)
799 = delete;
800
808 virtual ~memory_pool_inclusive () override;
809
814 protected:
829 arena<void*, blocks, sizeof (T)> arena_;
830
835 public:
848 alloc (void);
849
857 try_alloc (void);
858
867
876 free (value_type* block);
877
881 };
882
883#pragma GCC diagnostic pop
884
885 } /* namespace rtos */
886} /* namespace os */
887
888// ===== Inline & template implementations ====================================
889
890namespace os
891{
892 namespace rtos
893 {
895 {
896 }
897
898 // ========================================================================
899
904 inline bool
906 {
907 return this == &rhs;
908 }
909
913 inline std::size_t
915 {
916 return blocks_;
917 }
918
922 inline std::size_t
924 {
925 return block_size_bytes_;
926 }
927
931 inline std::size_t
933 {
934 return count_;
935 }
936
940 inline bool
942 {
943 return (count () == 0);
944 }
945
949 inline bool
950 memory_pool::full (void) const
951 {
952 return (count () == capacity ());
953 }
954
958 inline void*
960 {
961 return pool_addr_;
962 }
963
964 // ========================================================================
965
991 template <typename Allocator>
993 std::size_t blocks, std::size_t block_size_bytes,
994 const attributes& attr, const allocator_type& allocator)
995 : memory_pool_allocated{ nullptr, blocks, block_size_bytes, attr,
996 allocator }
997 {
998 }
999
1025 template <typename Allocator>
1027 const char* name, std::size_t blocks, std::size_t block_size_bytes,
1028 const attributes& attr, const allocator_type& allocator)
1029 : memory_pool{ name }
1030 {
1031#if defined(OS_TRACE_RTOS_MEMPOOL)
1032 trace::printf ("%s() @%p %s %d %d\n", __func__, this, this->name (),
1033 blocks, block_size_bytes);
1034#endif
1035 if (attr.mp_pool_address != nullptr)
1036 {
1037 // Do not use any allocator at all.
1038 internal_construct_ (blocks, block_size_bytes, attr, nullptr, 0);
1039 }
1040 else
1041 {
1042 allocator_ = &allocator;
1043
1044 // If no user storage was provided via attributes,
1045 // allocate it dynamically via the allocator.
1046 allocated_pool_size_elements_
1048 typename allocator_type::value_type> (blocks,
1049 block_size_bytes)
1050 + sizeof (typename allocator_type::value_type) - 1)
1051 / sizeof (typename allocator_type::value_type);
1052
1053 allocated_pool_addr_
1054 = const_cast<allocator_type&> (allocator).allocate (
1055 allocated_pool_size_elements_);
1056
1057 internal_construct_ (
1058 blocks, block_size_bytes, attr, allocated_pool_addr_,
1059 allocated_pool_size_elements_
1060 * sizeof (typename allocator_type::value_type));
1061 }
1062 }
1063
1080 template <typename Allocator>
1082 {
1083#if defined(OS_TRACE_RTOS_MEMPOOL)
1084 trace::printf ("%s() @%p %s\n", __func__, this, name ());
1085#endif
1086 typedef typename std::allocator_traits<allocator_type>::pointer pointer;
1087
1088 if (allocated_pool_addr_ != nullptr)
1089 {
1090 static_cast<allocator_type*> (const_cast<void*> (allocator_))
1091 ->deallocate (static_cast<pointer> (allocated_pool_addr_),
1092 allocated_pool_size_elements_);
1093
1094 allocated_pool_addr_ = nullptr;
1095 }
1096 }
1097
1098 // ========================================================================
1099
1128 template <typename T, typename Allocator>
1130 std::size_t blocks, const memory_pool::attributes& attr,
1131 const allocator_type& allocator)
1132 : memory_pool_allocated<allocator_type> (blocks, sizeof (T), attr,
1133 allocator)
1134 {
1135 }
1136
1165 template <typename T, typename Allocator>
1167 const char* name, std::size_t blocks,
1168 const memory_pool::attributes& attr, const allocator_type& allocator)
1169 : memory_pool_allocated<allocator_type> (name, blocks, sizeof (T),
1170 attr, allocator)
1171 {
1172 }
1173
1192#pragma GCC diagnostic push
1193#if defined(__clang__)
1194#elif defined(__GNUC__)
1195#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
1196#endif
1197 template <typename T, typename Allocator>
1199 {
1200 }
1201#pragma GCC diagnostic pop
1202
1210 template <typename T, typename Allocator>
1213 {
1214 return static_cast<value_type*> (
1216 }
1217
1225 template <typename T, typename Allocator>
1228 {
1229 return static_cast<value_type*> (
1231 }
1232
1240 template <typename T, typename Allocator>
1243 {
1244 return static_cast<value_type*> (
1246 }
1247
1255 template <typename T, typename Allocator>
1256 inline result_t
1258 {
1260 }
1261
1262 // ========================================================================
1263
1290 template <typename T, std::size_t N>
1292 {
1293 internal_construct_ (blocks, sizeof (T), attr, &arena_, sizeof (arena_));
1294 }
1295
1322 template <typename T, std::size_t N>
1324 const attributes& attr)
1325 : memory_pool{ name }
1326 {
1327 internal_construct_ (blocks, sizeof (T), attr, &arena_, sizeof (arena_));
1328 }
1329
1343 template <typename T, std::size_t N>
1345 {
1346 }
1347
1355 template <typename T, std::size_t N>
1358 {
1359 return static_cast<value_type*> (memory_pool::alloc ());
1360 }
1361
1369 template <typename T, std::size_t N>
1372 {
1373 return static_cast<value_type*> (memory_pool::try_alloc ());
1374 }
1375
1383 template <typename T, std::size_t N>
1386 {
1387 return static_cast<value_type*> (memory_pool::timed_alloc (timeout));
1388 }
1389
1397 template <typename T, std::size_t N>
1398 inline result_t
1400 {
1401 return memory_pool::free (block);
1402 }
1403
1404 } /* namespace rtos */
1405} /* namespace os */
1406
1407#pragma GCC diagnostic pop
1408
1409// ----------------------------------------------------------------------------
1410
1411#endif /* __cplusplus */
1412
1413// ----------------------------------------------------------------------------
1414
1415#endif /* CMSIS_PLUS_RTOS_OS_MEMPOOL_H_ */
Generic clock.
Definition os-clocks.h:61
Base class for attributes.
Definition os-decls.h:559
Base class for named system objects.
Definition os-decls.h:443
const char * name(void) const
Get object name.
Definition os-decls.h:753
Priority ordered list of threads.
Definition os-lists.h:543
Standard allocator based on the RTOS system default memory manager.
Definition os-memory.h:538
Storage for a memory pool.
Definition os-mempool.h:175
T pool[(blocks *block_size_bytes+sizeof(T) - 1)/sizeof(T)]
Definition os-mempool.h:177
Memory pool attributes.
Definition os-mempool.h:99
void * mp_pool_address
Address of the user defined storage for the memory pool.
Definition os-mempool.h:143
~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:148
attributes(const attributes &)=default
attributes(attributes &&)=default
constexpr attributes()
Construct a memory pool attributes object instance.
Definition os-mempool.h:894
attributes & operator=(const attributes &)=default
Template of a synchronised memory pool with allocator.
Definition os-mempool.h:545
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:550
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:992
Template of a synchronised memory pool with block type and local storage.
Definition os-mempool.h:756
result_t free(value_type *block)
Free the memory block.
memory_pool_inclusive(const attributes &attr=initializer)
Construct a memory pool object instance.
arena< void *, blocks, sizeof(T)> arena_
Local storage for the pool.
Definition os-mempool.h:829
T value_type
Local type of message.
Definition os-mempool.h:761
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:766
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:634
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:638
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:67
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:923
void * alloc(void)
Allocate a memory block.
bool empty(void) const
Check if the memory pool is empty.
Definition os-mempool.h:941
std::size_t capacity(void) const
Get memory pool capacity.
Definition os-mempool.h:914
std::size_t count(void) const
Get blocks count.
Definition os-mempool.h:932
result_t free(void *block)
Free the memory block.
void * pool(void)
Get the pool storage address.
Definition os-mempool.h:959
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:188
virtual ~memory_pool()
Destruct the memory pool object instance.
bool operator==(const memory_pool &rhs) const
Compare memory pools.
Definition os-mempool.h:905
bool full(void) const
Check if the memory pool is full.
Definition os-mempool.h:950
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:78
static constexpr memory_pool::size_t max_size
Maximum pool size.
Definition os-mempool.h:89
uint16_t size_t
Type of memory pool size storage.
Definition os-mempool.h:79
static const attributes initializer
Default memory pool initialiser.
Definition os-mempool.h:162
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:95
System namespace.