µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
block-pool.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_MEMORY_BLOCK_POOL_H_
29#define CMSIS_PLUS_MEMORY_BLOCK_POOL_H_
30
31// ----------------------------------------------------------------------------
32
33#if defined(__cplusplus)
34
35// ----------------------------------------------------------------------------
36
37#include <cmsis-plus/rtos/os.h>
38
39// ----------------------------------------------------------------------------
40
41#pragma GCC diagnostic push
42
43#if defined(__clang__)
44#pragma clang diagnostic ignored "-Wc++98-compat"
45#endif
46
47// ----------------------------------------------------------------------------
48
49namespace os
50{
51 namespace memory
52 {
53
54 // ========================================================================
55
73 {
74 public:
75
88 block_pool (std::size_t blocks, std::size_t block_size_bytes, void* addr,
89 std::size_t bytes);
90
99 block_pool (const char* name, std::size_t blocks,
100 std::size_t block_size_bytes, void* addr, std::size_t bytes);
101
102 protected:
103
108 block_pool (const char* name);
109
110 public:
111
116 // The rule of five.
117 block_pool (const block_pool&) = delete;
118 block_pool (block_pool&&) = delete;
120 operator= (const block_pool&) = delete;
122 operator= (block_pool&&) = delete;
123
131 virtual
132 ~block_pool () override;
133
138 protected:
139
154 void
155 internal_construct_ (std::size_t blocks, std::size_t block_size_bytes,
156 void* addr, std::size_t bytes) noexcept;
157
165 void
166 internal_reset_ (void) noexcept;
167
174 virtual void*
175 do_allocate (std::size_t bytes, std::size_t alignment) override;
176
185 virtual void
186 do_deallocate (void* addr, std::size_t bytes, std::size_t alignment)
187 noexcept override;
188
195 virtual std::size_t
196 do_max_size (void) const noexcept override;
197
205 virtual void
206 do_reset (void) noexcept override;
207
212 protected:
213
222 void* pool_addr_ = nullptr;
223
227 void* volatile first_ = nullptr;
228
232 std::size_t blocks_ = 0;
233
237 std::size_t block_size_bytes_ = 0;
238
242 volatile std::size_t count_ = 0;
243
248 };
249
250 // ========================================================================
251
264 template<typename T, std::size_t N>
266 {
267 public:
268
272 using value_type = T;
273
274 static_assert(sizeof(value_type) >= sizeof(void*),
275 "Template type T must be large enough to store a pointer.");
276
280 static const std::size_t blocks = N;
281
293
298 block_pool_typed_inclusive (const char* name);
299
300 public:
301
306 // The rule of five.
310 operator= (const block_pool_typed_inclusive&) = delete;
312 operator= (block_pool_typed_inclusive&&) = delete;
313
321 virtual
322 ~block_pool_typed_inclusive () override;
323
328 protected:
329
337 typename std::aligned_storage<sizeof(value_type), alignof(value_type)>::type arena_[blocks];
338
343 };
344
345 // ========================================================================
346
361 template<typename T, typename A = os::rtos::memory::allocator<T>>
363 {
364 public:
365
369 using value_type = T;
370
371 static_assert(sizeof(value_type) >= sizeof(void*),
372 "Template type T must be large enough to store a pointer.");
373
377 using allocator_type = A;
378
382 using allocator_traits = std::allocator_traits<A>;
383
384 // It is recommended to have the same type, but at least the types
385 // should have the same size.
386 static_assert(sizeof(value_type) == sizeof(typename allocator_traits::value_type),
387 "The allocator must be parametrised with a type of same size.");
388
400 block_pool_typed_allocated (std::size_t blocks,
401 const allocator_type& allocator =
402 allocator_type ());
403
411 block_pool_typed_allocated (const char* name, std::size_t blocks,
412 const allocator_type& allocator =
413 allocator_type ());
414
415 public:
416
421 // The rule of five.
425 operator= (const block_pool_typed_allocated&) = delete;
427 operator= (block_pool_typed_allocated&&) = delete;
428
436 virtual
437 ~block_pool_typed_allocated () override;
438
443 protected:
444
457 allocator_type* allocator_ = nullptr;
458
463 };
464
465 // -------------------------------------------------------------------------
466 } /* namespace memory */
467} /* namespace os */
468
469// ===== Inline & template implementations ====================================
470
471namespace os
472{
473 namespace memory
474 {
475
476 // ========================================================================
477
478 inline
479 block_pool::block_pool (const char* name) :
480 rtos::memory::memory_resource
481 { name }
482 {
483 ;
484 }
485
486 inline
487 block_pool::block_pool (std::size_t blocks, std::size_t block_size_bytes,
488 void* addr, std::size_t bytes) :
490 { nullptr, blocks, block_size_bytes, addr, bytes }
491 {
492 ;
493 }
494
495 inline
496 block_pool::block_pool (const char* name, std::size_t blocks,
497 std::size_t block_size_bytes, void* addr,
498 std::size_t bytes) :
499 rtos::memory::memory_resource
500 { name }
501 {
502 trace::printf ("%s(%u,%u,%p,%u) @%p %s\n", __func__, blocks,
503 block_size_bytes, addr, bytes, this, this->name ());
504
505 internal_construct_ (blocks, block_size_bytes, addr, bytes);
506 }
507
508 // ========================================================================
509
510 template<typename T, std::size_t N>
511 inline
514 {
515 ;
516 }
517
518 template<typename T, std::size_t N>
519 inline
521 const char* name) :
523 { name }
524 {
525 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
526
527 internal_construct_ (blocks, sizeof(value_type), &arena_[0],
528 sizeof(arena_));
529 }
530
531 template<typename T, std::size_t N>
533 {
534 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
535 }
536
537 // ========================================================================
538
539 template<typename T, typename A>
540 inline
542 std::size_t blocks, const allocator_type& allocator) :
543 block_pool_typed_allocated (nullptr, blocks, allocator)
544 {
545 ;
546 }
547
548 template<typename T, typename A>
550 const char* name, std::size_t blocks, const allocator_type& allocator) :
552 { name }
553 {
554 trace::printf ("%s(%u,%p) @%p %s\n", __func__, blocks, &allocator, this,
555 this->name ());
556
557 // Remember the allocator, it'll be used by the destructor.
558 allocator_ =
559 static_cast<allocator_type*> (&const_cast<allocator_type&> (allocator));
560
561 void* addr = allocator_->allocate (blocks);
562 if (addr == nullptr)
563 {
565 }
566
567 internal_construct_ (blocks, sizeof(value_type), addr,
568 blocks * sizeof(value_type));
569 }
570
571 template<typename T, typename A>
573 {
574 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
575
576 // Skip in case a derived class did the deallocation.
577 if (allocator_ != nullptr)
578 {
579 allocator_->deallocate (
580 static_cast<typename allocator_traits::pointer> (pool_addr_),
581 blocks_);
582
583 // Prevent another deallocation.
584 allocator_ = nullptr;
585 }
586 }
587
588 // --------------------------------------------------------------------------
589
590 } /* namespace memory */
591} /* namespace os */
592
593#pragma GCC diagnostic pop
594
595// ----------------------------------------------------------------------------
596
597#endif /* __cplusplus */
598
599// ----------------------------------------------------------------------------
600
601#endif /* CMSIS_PLUS_MEMORY_BLOCK_POOL_H_ */
Memory resource managing a dynamically allocated pool. of same size blocks of type T.
Definition block-pool.h:363
A allocator_type
Standard allocator type definition.
Definition block-pool.h:377
T value_type
Standard allocator type definition.
Definition block-pool.h:369
virtual ~block_pool_typed_allocated() override
Destruct the memory resource object instance.
Definition block-pool.h:572
block_pool_typed_allocated(std::size_t blocks, const allocator_type &allocator=allocator_type())
Construct a memory resource object instance.
Definition block-pool.h:541
std::allocator_traits< A > allocator_traits
Standard allocator traits definition.
Definition block-pool.h:382
Memory resource managing an internal pool. of same size blocks of type T.
Definition block-pool.h:266
block_pool_typed_inclusive(void)
Construct a memory resource object instance.
Definition block-pool.h:512
T value_type
Standard allocator type definition.
Definition block-pool.h:272
static const std::size_t blocks
Local constant based on template definition.
Definition block-pool.h:280
virtual ~block_pool_typed_inclusive() override
Destruct the memory resource object instance.
Definition block-pool.h:532
Memory resource managing a pool of same size blocks, using an existing arena.
Definition block-pool.h:73
block_pool(std::size_t blocks, std::size_t block_size_bytes, void *addr, std::size_t bytes)
Construct a memory resource object instance.
Definition block-pool.h:487
virtual void * do_allocate(std::size_t bytes, std::size_t alignment) override
Implementation of the memory allocator.
virtual std::size_t do_max_size(void) const noexcept override
Implementation of the function to get max size.
void internal_construct_(std::size_t blocks, std::size_t block_size_bytes, void *addr, std::size_t bytes) noexcept
Internal function to construct the memory resource object instance.
virtual void do_deallocate(void *addr, std::size_t bytes, std::size_t alignment) noexcept override
Implementation of the memory deallocator.
void internal_reset_(void) noexcept
Internal function to reset the memory resource object.
virtual ~block_pool() override
Destruct the memory resource object instance.
virtual void do_reset(void) noexcept override
Implementation of the function to reset the memory manager.
const char * name(void) const
Get object name.
Definition os-decls.h:774
Memory resource manager (abstract class).
Definition os-memory.h:165
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
void __throw_bad_alloc(void)
System namespace.
Single file µOS++ RTOS definitions.