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