µ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-2023 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/mit/.
11 */
12
13#ifndef CMSIS_PLUS_RTOS_OS_MEMPOOL_H_
14#define CMSIS_PLUS_RTOS_OS_MEMPOOL_H_
15
16// ----------------------------------------------------------------------------
17
18#if defined(__cplusplus)
19
20// ----------------------------------------------------------------------------
21
22#if defined(OS_USE_OS_APP_CONFIG_H)
23#include <cmsis-plus/os-app-config.h>
24#endif
25
28
30
31// ----------------------------------------------------------------------------
32
33#pragma GCC diagnostic push
34#if defined(__clang__)
35#pragma clang diagnostic ignored "-Wc++98-compat"
36#pragma clang diagnostic ignored "-Wdocumentation-unknown-command"
37#endif
38
39// ----------------------------------------------------------------------------
40
41namespace os
42{
43 namespace rtos
44 {
45
46 // ========================================================================
47
48#pragma GCC diagnostic push
49#if defined(__clang__)
50#pragma clang diagnostic ignored "-Wpadded"
51#elif defined(__GNUC__)
52#pragma GCC diagnostic ignored "-Wpadded"
53#endif
54
61#pragma GCC diagnostic push
62#if defined(__clang__)
63#elif defined(__GNUC__)
64#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
65#pragma GCC diagnostic ignored "-Wsuggest-final-types"
66#endif
68 {
69 public:
70
71 // ======================================================================
72
80 using size_t = uint16_t;
81
88 static constexpr memory_pool::size_t max_size =
89 static_cast<memory_pool::size_t> (0 - 1);
90
91 // ======================================================================
92
99 {
100 public:
101
112 constexpr
113 attributes ();
114
115 // The rule of five.
116 attributes (const attributes&) = default;
117 attributes (attributes&&) = default;
119 operator= (const attributes&) = default;
121 operator= (attributes&&) = default;
122
126 ~attributes () = default;
127
132 public:
133
139 // Public members; no accessors and mutators required.
140 // Warning: must match the type & order of the C file header.
144 void* mp_pool_address = nullptr;
145
149 std::size_t mp_pool_size_bytes = 0;
150
151 // Add more attributes here.
152
157 }; /* class attributes */
158
164
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
202
216 memory_pool (std::size_t blocks, std::size_t block_size_bytes,
217 const attributes& attr = initializer,
218 const allocator_type& allocator = allocator_type ());
228 memory_pool (const char* name, std::size_t blocks,
229 std::size_t block_size_bytes, const attributes& attr =
231 const allocator_type& allocator = allocator_type ());
232
233 protected:
234
239 // Internal constructors, used from templates.
240 memory_pool ();
241 memory_pool (const char* name);
242
247 public:
248
253 // The rule of five.
254 memory_pool (const memory_pool&) = delete;
255 memory_pool (memory_pool&&) = delete;
257 operator= (const memory_pool&) = delete;
259 operator= (memory_pool&&) = delete;
260
265 public:
266
270 virtual
271 ~memory_pool ();
272
287 bool
288 operator== (const memory_pool& rhs) const;
289
294 public:
295
307 void*
308 alloc (void);
309
316 void*
317 try_alloc (void);
318
324 void*
326
334 free (void* block);
335
342 std::size_t
343 capacity (void) const;
344
351 std::size_t
352 count (void) const;
353
360 std::size_t
361 block_size (void) const;
362
370 bool
371 empty (void) const;
372
380 bool
381 full (void) const;
382
391 reset (void);
392
399 void*
400 pool (void);
401
406 protected:
407
425 void
426 internal_construct_ (std::size_t blocks, std::size_t block_size_bytes,
427 const attributes& attr, void* pool_address,
428 std::size_t pool_size_bytes);
429
437 void
438 internal_init_ (void);
439
446 void*
447 internal_try_first_ (void);
448
457 protected:
458
468#if !defined(OS_USE_RTOS_PORT_MEMORY_POOL)
476 clock* clock_ = nullptr;
477#endif
482 void* pool_addr_ = nullptr;
487 void* allocated_pool_addr_ = nullptr;
488
492 const void* allocator_ = nullptr;
493
494#if defined(OS_USE_RTOS_PORT_MEMORY_POOL)
495 friend class port::memory_pool;
496 os_mempool_port_data_t port_;
497#endif
498
503 std::size_t pool_size_bytes_ = 0;
507 std::size_t allocated_pool_size_elements_ = 0;
508
512 memory_pool::size_t blocks_ = 0;
513
517 memory_pool::size_t block_size_bytes_ = 0;
518
522 volatile memory_pool::size_t count_ = 0;
523
527 void* volatile first_ = nullptr;
528
537 };
538#pragma GCC diagnostic pop
539
540 // ========================================================================
541
547 template<typename Allocator = memory::allocator<void*>>
549 {
550 public:
551
555 using allocator_type = Allocator;
556
570 memory_pool_allocated (std::size_t blocks, std::size_t block_size_bytes,
571 const attributes& attr = initializer,
572 const allocator_type& allocator =
573 allocator_type ());
574
584 memory_pool_allocated (const char* name, std::size_t blocks,
585 std::size_t block_size_bytes,
586 const attributes& attr = initializer,
587 const allocator_type& allocator =
588 allocator_type ());
589
594 // The rule of five.
598 operator= (const memory_pool_allocated&) = delete;
600 operator= (memory_pool_allocated&&) = delete;
601
609 virtual
611
616 };
617
618 // ========================================================================
619
626#pragma GCC diagnostic push
627#if defined(__clang__)
628#elif defined(__GNUC__)
629#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
630#pragma GCC diagnostic ignored "-Wsuggest-final-types"
631#endif
632 template<typename T, typename Allocator = memory::allocator<void*>>
633 class memory_pool_typed : public memory_pool_allocated<Allocator>
634 {
635 public:
636
640 using value_type = T;
644 using allocator_type = Allocator;
645
658 memory_pool_typed (std::size_t blocks,
659 const memory_pool::attributes& attr =
661 const allocator_type& allocator = allocator_type ());
662
671 memory_pool_typed (const char* name, std::size_t blocks,
672 const memory_pool::attributes& attr =
674 const allocator_type& allocator = allocator_type ());
675
680 // The rule of five.
681 memory_pool_typed (const memory_pool_typed&) = delete;
684 operator= (const memory_pool_typed&) = delete;
686 operator= (memory_pool_typed&&) = delete;
687
695 virtual
696 ~memory_pool_typed () override;
697
702 public:
703
716 alloc (void);
717
725 try_alloc (void);
726
734
743 free (value_type* block);
744
749 };
750#pragma GCC diagnostic pop
751
752 // ========================================================================
753
760 template<typename T, std::size_t N>
762 {
763 public:
764
768 using value_type = T;
769
773 static const std::size_t blocks = N;
774
785
791 memory_pool_inclusive (const char* name, const attributes& attr =
793
798 // The rule of five.
802 operator= (const memory_pool_inclusive&) = delete;
804 operator= (memory_pool_inclusive&&) = delete;
805
813 virtual
814 ~memory_pool_inclusive () override;
815
820 protected:
821
835 arena<void*, blocks, sizeof(T)> arena_;
836
841 public:
842
855 alloc (void);
856
864 try_alloc (void);
865
873
882 free (value_type* block);
883
888 };
889
890#pragma GCC diagnostic pop
891
892 } /* namespace rtos */
893} /* namespace os */
894
895// ===== Inline & template implementations ====================================
896
897namespace os
898{
899 namespace rtos
900 {
901 constexpr
903 {
904 }
905
906 // ========================================================================
907
912 inline bool
914 {
915 return this == &rhs;
916 }
917
921 inline std::size_t
923 {
924 return blocks_;
925 }
926
930 inline std::size_t
932 {
933 return block_size_bytes_;
934 }
935
939 inline std::size_t
941 {
942 return count_;
943 }
944
948 inline bool
950 {
951 return (count () == 0);
952 }
953
957 inline bool
958 memory_pool::full (void) const
959 {
960 return (count () == capacity ());
961 }
962
966 inline void*
968 {
969 return pool_addr_;
970 }
971
972 // ========================================================================
973
999 template<typename Allocator>
1000 inline
1002 std::size_t blocks, std::size_t block_size_bytes,
1003 const attributes& attr, const allocator_type& allocator) :
1005 { nullptr, blocks, block_size_bytes, attr, allocator }
1006 {
1007 }
1008
1034 template<typename Allocator>
1036 const char* name, std::size_t blocks, std::size_t block_size_bytes,
1037 const attributes& attr, const allocator_type& allocator) :
1039 { name }
1040 {
1041#if defined(OS_TRACE_RTOS_MEMPOOL)
1042 trace::printf ("%s() @%p %s %d %d\n", __func__, this, this->name (),
1043 blocks, block_size_bytes);
1044#endif
1045 if (attr.mp_pool_address != nullptr)
1046 {
1047 // Do not use any allocator at all.
1048 internal_construct_ (blocks, block_size_bytes, attr, nullptr, 0);
1049 }
1050 else
1051 {
1052 allocator_ = &allocator;
1053
1054 // If no user storage was provided via attributes,
1055 // allocate it dynamically via the allocator.
1056 allocated_pool_size_elements_ = (compute_allocated_size_bytes<
1057 typename allocator_type::value_type> (blocks, block_size_bytes)
1058 + sizeof(typename allocator_type::value_type) - 1)
1059 / sizeof(typename allocator_type::value_type);
1060
1061 allocated_pool_addr_ =
1062 const_cast<allocator_type&> (allocator).allocate (
1063 allocated_pool_size_elements_);
1064
1065 internal_construct_ (
1066 blocks,
1067 block_size_bytes,
1068 attr,
1069 allocated_pool_addr_,
1070 allocated_pool_size_elements_
1071 * sizeof(typename allocator_type::value_type));
1072 }
1073 }
1074
1091 template<typename Allocator>
1093 {
1094#if defined(OS_TRACE_RTOS_MEMPOOL)
1095 trace::printf ("%s() @%p %s\n", __func__, this, name ());
1096#endif
1097 typedef typename std::allocator_traits<allocator_type>::pointer pointer;
1098
1099 if (allocated_pool_addr_ != nullptr)
1100 {
1101 static_cast<allocator_type*> (const_cast<void*> (allocator_))->deallocate (
1102 static_cast<pointer> (allocated_pool_addr_),
1103 allocated_pool_size_elements_);
1104
1105 allocated_pool_addr_ = nullptr;
1106 }
1107 }
1108
1109 // ========================================================================
1110
1139 template<typename T, typename Allocator>
1140 inline
1142 std::size_t blocks, const memory_pool::attributes& attr,
1143 const allocator_type& allocator) :
1144 memory_pool_allocated<allocator_type> (blocks, sizeof(T), attr,
1145 allocator)
1146 {
1147 }
1148
1177 template<typename T, typename Allocator>
1178 inline
1180 const char* name, std::size_t blocks,
1181 const memory_pool::attributes& attr, const allocator_type& allocator) :
1182 memory_pool_allocated<allocator_type> (name, blocks, sizeof(T), attr,
1183 allocator)
1184 {
1185 }
1186
1205#pragma GCC diagnostic push
1206#if defined(__clang__)
1207#elif defined(__GNUC__)
1208#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
1209#endif
1210 template<typename T, typename Allocator>
1212 {
1213 }
1214#pragma GCC diagnostic pop
1215
1223 template<typename T, typename Allocator>
1226 {
1228 }
1229
1237 template<typename T, typename Allocator>
1240 {
1242 }
1243
1251 template<typename T, typename Allocator>
1254 {
1256 timeout));
1257 }
1258
1266 template<typename T, typename Allocator>
1267 inline result_t
1269 {
1271 }
1272
1273 // ========================================================================
1274
1301 template<typename T, std::size_t N>
1303 const attributes& attr)
1304 {
1305 internal_construct_ (blocks, sizeof(T), attr, &arena_, sizeof(arena_));
1306 }
1307
1334 template<typename T, std::size_t N>
1336 const char* name, const attributes& attr) :
1338 { name }
1339 {
1340 internal_construct_ (blocks, sizeof(T), attr, &arena_, sizeof(arena_));
1341 }
1342
1356 template<typename T, std::size_t N>
1358 {
1359 }
1360
1368 template<typename T, std::size_t N>
1371 {
1372 return static_cast<value_type*> (memory_pool::alloc ());
1373 }
1374
1382 template<typename T, std::size_t N>
1385 {
1386 return static_cast<value_type*> (memory_pool::try_alloc ());
1387 }
1388
1396 template<typename T, std::size_t N>
1399 {
1400 return static_cast<value_type*> (memory_pool::timed_alloc (timeout));
1401 }
1402
1410 template<typename T, std::size_t N>
1411 inline result_t
1413 {
1414 return memory_pool::free (block);
1415 }
1416
1417 } /* namespace rtos */
1418} /* namespace os */
1419
1420#pragma GCC diagnostic pop
1421
1422// ----------------------------------------------------------------------------
1423
1424#endif /* __cplusplus */
1425
1426// ----------------------------------------------------------------------------
1427
1428#endif /* CMSIS_PLUS_RTOS_OS_MEMPOOL_H_ */
Generic clock.
Definition os-clocks.h:59
Base class for attributes.
Definition os-decls.h:563
Base class for named system objects.
Definition os-decls.h:445
const char * name(void) const
Get object name.
Definition os-decls.h:759
Priority ordered list of threads.
Definition os-lists.h:550
Standard allocator based on the RTOS system default memory manager.
Definition os-memory.h:540
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:144
~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:149
attributes(const attributes &)=default
attributes(attributes &&)=default
constexpr attributes()
Construct a memory pool attributes object instance.
Definition os-mempool.h:902
attributes & operator=(const attributes &)=default
Template of a synchronised memory pool with allocator.
Definition os-mempool.h:549
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:555
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.
Template of a synchronised memory pool with block type and local storage.
Definition os-mempool.h:762
arena< void *, blocks, sizeof(T)> arena_
Local storage for the pool.
Definition os-mempool.h:835
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:768
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:773
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:634
result_t free(value_type *block)
Free the memory block.
T value_type
Standard allocator type definition.
Definition os-mempool.h:640
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:644
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:68
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:931
void * alloc(void)
Allocate a memory block.
bool empty(void) const
Check if the memory pool is empty.
Definition os-mempool.h:949
std::size_t capacity(void) const
Get memory pool capacity.
Definition os-mempool.h:922
std::size_t count(void) const
Get blocks count.
Definition os-mempool.h:940
result_t free(void *block)
Free the memory block.
void * pool(void)
Get the pool storage address.
Definition os-mempool.h:967
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:913
bool full(void) const
Check if the memory pool is full.
Definition os-mempool.h:958
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition os-clocks.h:76
static constexpr memory_pool::size_t max_size
Maximum pool size.
Definition os-mempool.h:88
uint16_t size_t
Type of memory pool size storage.
Definition os-mempool.h:80
static const attributes initializer
Default memory pool initialiser.
Definition os-mempool.h:163
uint32_t result_t
Type of values returned by RTOS functions.
Definition os-decls.h:96
System namespace.