QP/C  7.2.2
Real-Time Embedded Framework
Loading...
Searching...
No Matches
qmpool.h
Go to the documentation of this file.
1/*$file${include::qmpool.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
2/*
3* Model: qpc.qm
4* File: ${include::qmpool.h}
5*
6* This code has been generated by QM 5.2.5 <www.state-machine.com/qm>.
7* DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
8*
9* This code is covered by the following QP license:
10* License # : LicenseRef-QL-dual
11* Issued to : Any user of the QP/C real-time embedded framework
12* Framework(s) : qpc
13* Support ends : 2023-12-31
14* License scope:
15*
16* Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
17*
18* SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
19*
20* This software is dual-licensed under the terms of the open source GNU
21* General Public License version 3 (or any later version), or alternatively,
22* under the terms of one of the closed source Quantum Leaps commercial
23* licenses.
24*
25* The terms of the open source GNU General Public License version 3
26* can be found at: <www.gnu.org/licenses/gpl-3.0>
27*
28* The terms of the closed source Quantum Leaps commercial licenses
29* can be found at: <www.state-machine.com/licensing>
30*
31* Redistributions in source code must retain this top-level comment block.
32* Plagiarizing this software to sidestep the license obligations is illegal.
33*
34* Contact information:
35* <www.state-machine.com/licensing>
36* <info@state-machine.com>
37*/
38/*$endhead${include::qmpool.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
39/*! @file
40* @brief QP native, platform-independent memory pool ::QMPool interface.
41*
42* @trace
43* - @tr{DVP-QP-MC3-D04_08}
44*/
45#ifndef QMPOOL_H_
46#define QMPOOL_H_
47
48/*==========================================================================*/
49#ifndef QF_MPOOL_SIZ_SIZE
50 /*! macro to override the default ::QMPoolSize size [bytes].
51 * Valid values 1U, 2U, or 4U; default 2U
52 */
53 #define QF_MPOOL_SIZ_SIZE 2U
54#endif
55#if (QF_MPOOL_SIZ_SIZE == 1U)
56
57 /*! The data type to store the block-size based on the macro
58 * #QF_MPOOL_SIZ_SIZE.
59 *
60 * @details
61 * The dynamic range of this data type determines the maximum size
62 * of blocks that can be managed by the native QF event pool.
63 */
64 typedef uint8_t QMPoolSize;
65#elif (QF_MPOOL_SIZ_SIZE == 2U)
66
67 typedef uint16_t QMPoolSize;
68#elif (QF_MPOOL_SIZ_SIZE == 4U)
69 typedef uint32_t QMPoolSize;
70#else
71 #error "QF_MPOOL_SIZ_SIZE defined incorrectly, expected 1U, 2U, or 4U"
72#endif
73
74/*==========================================================================*/
75#ifndef QF_MPOOL_CTR_SIZE
76 /*! macro to override the default ::QMPoolCtr size [bytes].
77 * Valid values 1U, 2U, or 4U; default 2U
78 */
79 #define QF_MPOOL_CTR_SIZE 2U
80#endif
81#if (QF_MPOOL_CTR_SIZE == 1U)
82
83 /*! The data type to store the block-counter based on the macro
84 * #QF_MPOOL_CTR_SIZE.
85 *
86 * @details
87 * The dynamic range of this data type determines the maximum number
88 * of blocks that can be stored in the pool.
89 */
90 typedef uint8_t QMPoolCtr;
91#elif (QF_MPOOL_CTR_SIZE == 2U)
92 typedef uint16_t QMPoolCtr;
93#elif (QF_MPOOL_CTR_SIZE == 4U)
94 typedef uint32_t QMPoolCtr;
95#else
96 #error "QF_MPOOL_CTR_SIZE defined incorrectly, expected 1U, 2U, or 4U"
97#endif
98
99/*! Memory pool element to allocate correctly aligned storage
100* for QMPool class.
101*
102* @param[in] evType_ event type (name of the subclass of ::QEvt)
103*
104* @trace
105* - @tr{DVP-QP-MC3-D04_09A}
106*/
107#define QF_MPOOL_EL(evType_) \
108 struct { void *sto_[((sizeof(evType_) - 1U)/sizeof(void*)) + 1U]; }
109
110/*==========================================================================*/
111/*$declare${QF::QMPool} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
112
113/*${QF::QMPool} ............................................................*/
114/*! @brief Native QF Memory Pool
115* @class QMPool
116*
117* @details
118* A fixed block-size memory pool is a very fast and efficient data
119* structure for dynamic allocation of fixed block-size chunks of memory.
120* A memory pool offers fast and deterministic allocation and recycling of
121* memory blocks and is not subject to fragmenation.<br>
122*
123* The ::QMPool class describes the native QF memory pool, which can be used as
124* the event pool for dynamic event allocation, or as a fast, deterministic
125* fixed block-size heap for any other objects in your application.
126*
127* @note
128* ::QMPool contains only data members for managing a memory pool, but
129* does not contain the pool storage, which must be provided externally
130* during the pool initialization.
131*
132* @note
133* The native QF event pool is configured by defining the macro
134* #QF_EPOOL_TYPE_ as ::QMPool in the specific QF port header file.
135*/
136typedef struct {
137/* private: */
138
139 /*! start of the memory managed by this memory pool
140 * @private @memberof QMPool
141 */
142 void * start;
143
144 /*! end of the memory managed by this memory pool
145 * @private @memberof QMPool
146 */
147 void * end;
148
149 /*! head of linked list of free blocks
150 * @private @memberof QMPool
151 */
152 void * volatile free_head;
153
154 /*! maximum block size (in bytes)
155 * @private @memberof QMPool
156 */
158
159 /*! total number of blocks
160 * @private @memberof QMPool
161 */
163
164 /*! number of free blocks remaining
165 * @private @memberof QMPool
166 */
167 QMPoolCtr volatile nFree;
168
169 /*! minimum number of free blocks ever present in this pool
170 * @private @memberof QMPool
171 *
172 * @details
173 * this attribute remembers the low watermark of the pool, which
174 * provides a valuable information for sizing event pools.
175 * @sa QF_getPoolMin().
176 */
178} QMPool;
179
180/* public: */
181
182/*! Initializes the native QF memory pool
183* @public @memberof QMPool
184*
185* @details
186* Initialize a fixed block-size memory pool by providing it with the pool
187* memory to manage, size of this memory, and the block size.
188*
189* @param[in,out] me current instance pointer (see @ref oop)
190* @param[in] poolSto pointer to the memory buffer for pool storage
191* @param[in] poolSize size of the storage buffer in bytes
192* @param[in] blockSize fixed-size of the memory blocks in bytes
193*
194* @precondition{qf_mem,100}
195* - the memory block must be valid
196* - the poolSize must fit at least one free block
197* - the blockSize must not be too close to the top of the dynamic range
198*
199* @attention
200* The caller of QMPool::init() must make sure that the `poolSto`
201* pointer is properly **aligned**. In particular, it must be possible to
202* efficiently store a pointer at the location pointed to by `poolSto`.
203* Internally, the QMPool_init() function rounds up the block size
204* `blockSize` so that it can fit an integer number of pointers.
205* This is done to achieve proper alignment of the blocks within the pool.
206*
207* @note
208* Due to the rounding of block size the actual capacity of the pool might
209* be less than (`poolSize` / `blockSize`). You can check the capacity
210* of the pool by calling the QF_getPoolMin() function.
211*
212* @note
213* This function is **not** protected by a critical section, because
214* it is intended to be called only during the initialization of the system,
215* when interrupts are not allowed yet.
216*
217* @note
218* Many QF ports use memory pools to implement the event pools.
219*
220* @trace
221* - @tr{DVR-QP-MC3-R11_05}
222* - @tr{DVR-QP-MC3-R17_08}
223*
224* @usage
225* The following example illustrates how to invoke QMPool_init():
226* @include qmp_init.c
227*/
228void QMPool_init(QMPool * const me,
229 void * const poolSto,
230 uint_fast32_t poolSize,
231 uint_fast16_t blockSize);
232
233/*! Obtains a memory block from a memory pool.
234* @public @memberof QMPool
235*
236* @details
237* The function allocates a memory block from the pool and returns a pointer
238* to the block back to the caller.
239*
240* @param[in,out] me current instance pointer (see @ref oop)
241* @param[in] margin the minimum number of unused blocks still available
242* in the pool after the allocation.
243* @param[in] qs_id QS-id of this state machine (for QS local filter)
244*
245* @returns
246* A pointer to a memory block or NULL if no more blocks are available in
247* the memory pool.
248*
249* @note
250* This function can be called from any task level or ISR level.
251*
252* @note
253* The memory pool `me` must be initialized before any events can
254* be requested from it. Also, the QMPool_get() function uses internally a
255* QF critical section, so you should be careful not to call it from within
256* a critical section when nesting of critical section is not supported.
257*
258* @attention
259* An allocated block must be later returned back to the **same** pool
260* from which it has been allocated.
261*
262* @sa QMPool_put()
263*
264* @trace
265* - @tr{DVR-QP-MC3-R18_03}
266* - @tr{DVR-QP-MC3-R11_05}
267* - @tr{DVR-QP-MC3-R18_03}
268*
269* @usage
270* The following example illustrates how to use QMPool_get():
271* @include qmp_use.c
272*/
273void * QMPool_get(QMPool * const me,
274 uint_fast16_t const margin,
275 uint_fast8_t const qs_id);
276
277/*! Recycles a memory block back to a memory pool.
278* @public @memberof QMPool
279*
280* @details
281* Recycle a memory block to the fixed block-size memory pool.
282*
283* @param[in,out] me current instance pointer (see @ref oop)
284* @param[in] b pointer to the memory block that is being recycled
285* @param[in] qs_id QS-id of this state machine (for QS local filter)
286*
287* @precondition{qf_mem,200}
288* - the number of free blocks cannot exceed the total # blocks
289* - the block pointer must be in range for this pool.
290*
291* @attention
292* The recycled block must be allocated from the **same** memory pool
293* to which it is returned.
294*
295* @note
296* This function can be called from any task level or ISR level.
297*
298* @sa
299* QMPool_get()
300*
301* @trace
302* - @tr{DVR-QP-MC3-R11_05}
303* - @tr{DVR-QP-MC3-R18_03}
304*
305* @usage
306* The following example illustrates how to use QMPool_put():
307* @include qmp_use.c
308*/
309void QMPool_put(QMPool * const me,
310 void * const b,
311 uint_fast8_t const qs_id);
312/*$enddecl${QF::QMPool} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
313
314#endif /* QMPOOL_H_ */
uint16_t QMPoolSize
Definition: qmpool.h:67
uint16_t QMPoolCtr
Definition: qmpool.h:92
Native QF Memory Pool.
Definition: qmpool.h:136
void QMPool_init(QMPool *const me, void *const poolSto, uint_fast32_t poolSize, uint_fast16_t blockSize)
QMPoolCtr volatile nFree
Definition: qmpool.h:167
QMPoolSize blockSize
Definition: qmpool.h:157
void * start
Definition: qmpool.h:142
void * end
Definition: qmpool.h:147
QMPoolCtr nMin
Definition: qmpool.h:177
void *volatile free_head
Definition: qmpool.h:152
QMPoolCtr nTot
Definition: qmpool.h:162