µ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.cpp
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#if defined(OS_USE_OS_APP_CONFIG_H)
14#include <cmsis-plus/os-app-config.h>
15#endif
16
18#include <cmsis-plus/rtos/os.h>
19
20// ----------------------------------------------------------------------------
21
22#if defined(__clang__)
23#pragma clang diagnostic ignored "-Wc++98-compat"
24#endif
25
26// ----------------------------------------------------------------------------
27
28namespace os
29{
30 namespace memory
31 {
32
33 // ========================================================================
34
36 {
37 trace::printf ("%s() @%p %s\n", __func__, this, this->name ());
38 }
39
40#pragma GCC diagnostic push
41#if defined(__clang__)
42#pragma clang diagnostic ignored "-Wunused-parameter"
43#elif defined(__GNUC__)
44#pragma GCC diagnostic ignored "-Wunused-parameter"
45#endif
46
47 void*
48 block_pool::do_allocate (std::size_t bytes, std::size_t alignment)
49 {
50 assert(bytes <= block_size_bytes_);
51
52 if (first_ == nullptr)
53 {
54 return nullptr;
55 }
56
57 void* p = static_cast<void*> (first_);
58 first_ = *(static_cast<void**> (first_));
59
60#pragma GCC diagnostic push
61#if defined(__clang__)
62#pragma clang diagnostic ignored "-Wdeprecated-volatile"
63#elif defined(__GNUC__)
64#pragma GCC diagnostic ignored "-Wvolatile"
65#endif
66 ++count_;
67#pragma GCC diagnostic pop
68
69 // Update statistics.
70 // What is subtracted from free is added to allocated.
72
73#if defined(OS_TRACE_LIBCPP_MEMORY_RESOURCE)
74 trace::printf ("%s(%u,%u)=%p,%u @%p %s\n", __func__, bytes, alignment, p,
75 block_size_bytes_, this, name ());
76#endif
77
78 return p;
79 }
80
81 void
82 block_pool::do_deallocate (void* addr, std::size_t bytes,
83 std::size_t alignment) noexcept
84 {
85#if defined(OS_TRACE_LIBCPP_MEMORY_RESOURCE)
86 trace::printf ("%s(%p,%u,%u) @%p %s\n", __func__, addr, bytes, alignment,
87 this, name ());
88#endif
89
90 if ((addr < pool_addr_)
91 || (addr
92 >= (static_cast<char*> (pool_addr_) + blocks_ * block_size_bytes_)))
93 {
94 assert(false);
95 return;
96 }
97
98 // Perform a push_front() on the single linked LIFO list,
99 // i.e. add the block to the beginning of the list.
100
101 // Link previous list to this block; may be null, but it does
102 // not matter.
103 *(static_cast<void**> (addr)) = first_;
104
105 // Now this block is the first in the free list..
106 first_ = addr;
107
108#pragma GCC diagnostic push
109#if defined(__clang__)
110#pragma clang diagnostic ignored "-Wdeprecated-volatile"
111#elif defined(__GNUC__)
112#pragma GCC diagnostic ignored "-Wvolatile"
113#endif
114 --count_;
115#pragma GCC diagnostic pop
116
117 // Update statistics.
118 // What is subtracted from allocated is added to free.
119 internal_decrease_allocated_statistics (block_size_bytes_);
120 }
121
122#pragma GCC diagnostic push
123
124 std::size_t
125 block_pool::do_max_size (void) const noexcept
126 {
127 return block_size_bytes_ * blocks_;
128 }
129
130 void
131 block_pool::do_reset (void) noexcept
132 {
133#if defined(OS_TRACE_LIBCPP_MEMORY_RESOURCE)
134 trace::printf ("%s() @%p %s\n", __func__, this, name ());
135#endif
136 internal_reset_ ();
137 }
138
139 void
141 std::size_t block_size_bytes, void* addr,
142 std::size_t bytes) noexcept
143 {
144 blocks_ = blocks;
145
146 block_size_bytes_ = rtos::memory::align_size (block_size_bytes,
147 alignof(void*));
148 assert(block_size_bytes_ >= sizeof(void*));
149
150 assert(addr != nullptr);
151 pool_addr_ = addr;
152
153 std::size_t align_sz = bytes;
154
155 void* res;
156 // Possibly adjust the last two parameters.
157 res = std::align (alignof(void*), blocks * block_size_bytes_, pool_addr_,
158 align_sz);
159
160 // std::align() will fail if it cannot fit the adjusted block size.
161 if (res != nullptr)
162 {
163 assert(res != nullptr);
164 }
165
166 // The extra assert is made redundant by std::align().
167 // assert(blocks * block_size_bytes_ <= align_sz);
168
169 total_bytes_ = blocks_ * block_size_bytes_;
170
171 internal_reset_ ();
172 }
173
174 void
176 {
177 // Construct a linked list of blocks. Store the pointer at
178 // the beginning of each block. Each block
179 // will hold the address of the next free block, or nullptr at the end.
180 char* p = static_cast<char*> (pool_addr_);
181 for (std::size_t i = 1; i < blocks_; ++i)
182 {
183 // Compute the address of the next block;
184 char* pn = p + block_size_bytes_;
185
186 // Make this block point to the next one.
187 *(static_cast<void**> (static_cast<void*> (p))) = pn;
188 // Advance pointer
189 p = pn;
190 }
191
192 // Mark end of list.
193 *(static_cast<void**> (static_cast<void*> (p))) = nullptr;
194
195 first_ = pool_addr_; // Pointer to first block.
196
197 count_ = 0; // No allocated blocks.
198
199 allocated_bytes_ = 0;
200 max_allocated_bytes_ = 0;
201 free_bytes_ = total_bytes_;
202 allocated_chunks_ = 0;
203 free_chunks_ = blocks_;
204
205 }
206
207 // --------------------------------------------------------------------------
208 } /* namespace memory */
209} /* namespace os */
210
211// ----------------------------------------------------------------------------
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:759
void internal_increase_allocated_statistics(std::size_t bytes) noexcept
Update statistics after allocation.
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
constexpr std::size_t align_size(std::size_t size, std::size_t align) noexcept
Helper function to align size values.
Definition os-memory.h:86
System namespace.
Single file µOS++ RTOS definitions.