ChibiOS/RT  5.1.0
chmempools.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
3 
4  This file is part of ChibiOS.
5 
6  ChibiOS is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  ChibiOS is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /**
21  * @file chmempools.h
22  * @brief Memory Pools macros and structures.
23  *
24  * @addtogroup pools
25  * @{
26  */
27 
28 #ifndef CHMEMPOOLS_H
29 #define CHMEMPOOLS_H
30 
31 #if !defined(CH_CFG_USE_MEMPOOLS)
32 #define CH_CFG_USE_MEMPOOLS FALSE
33 #endif
34 
35 #if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__)
36 
37 /*===========================================================================*/
38 /* Module constants. */
39 /*===========================================================================*/
40 
41 /*===========================================================================*/
42 /* Module pre-compile time settings. */
43 /*===========================================================================*/
44 
45 /*===========================================================================*/
46 /* Derived constants and error checks. */
47 /*===========================================================================*/
48 
49 #if CH_CFG_USE_MEMCORE == FALSE
50 #error "CH_CFG_USE_MEMPOOLS requires CH_CFG_USE_MEMCORE"
51 #endif
52 
53 /*===========================================================================*/
54 /* Module data structures and types. */
55 /*===========================================================================*/
56 
57 /**
58  * @brief Memory pool free object header.
59  */
60 struct pool_header {
61  struct pool_header *next; /**< @brief Pointer to the next pool
62  header in the list. */
63 };
64 
65 /**
66  * @brief Memory pool descriptor.
67  */
68 typedef struct {
69  struct pool_header *next; /**< @brief Pointer to the header. */
70  size_t object_size; /**< @brief Memory pool objects
71  size. */
72  unsigned align; /**< @brief Required alignment. */
73  memgetfunc_t provider; /**< @brief Memory blocks provider
74  for this pool. */
76 
77 #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
78 /**
79  * @brief Guarded memory pool descriptor.
80  */
81 typedef struct {
82  semaphore_t sem; /**< @brief Counter semaphore guarding
83  the memory pool. */
84  memory_pool_t pool; /**< @brief The memory pool itself. */
86 #endif /* CH_CFG_USE_SEMAPHORES == TRUE */
87 
88 /*===========================================================================*/
89 /* Module macros. */
90 /*===========================================================================*/
91 
92 /**
93  * @brief Data part of a static memory pool initializer.
94  * @details This macro should be used when statically initializing a
95  * memory pool that is part of a bigger structure.
96  *
97  * @param[in] name the name of the memory pool variable
98  * @param[in] size size of the memory pool contained objects
99  * @param[in] align required memory alignment
100  * @param[in] provider memory provider function for the memory pool
101  */
102 #define _MEMORYPOOL_DATA(name, size, align, provider) \
103  {NULL, size, align, provider}
104 
105 /**
106  * @brief Static memory pool initializer.
107  * @details Statically initialized memory pools require no explicit
108  * initialization using @p chPoolInit().
109  *
110  * @param[in] name the name of the memory pool variable
111  * @param[in] size size of the memory pool contained objects
112  * @param[in] align required memory alignment
113  * @param[in] provider memory provider function for the memory pool or @p NULL
114  * if the pool is not allowed to grow automatically
115  */
116 #define MEMORYPOOL_DECL(name, size, align, provider) \
117  memory_pool_t name = _MEMORYPOOL_DATA(name, size, align, provider)
118 
119 #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
120 /**
121  * @brief Data part of a static guarded memory pool initializer.
122  * @details This macro should be used when statically initializing a
123  * memory pool that is part of a bigger structure.
124  *
125  * @param[in] name the name of the memory pool variable
126  * @param[in] size size of the memory pool contained objects
127  * @param[in] align required memory alignment
128  */
129 #define _GUARDEDMEMORYPOOL_DATA(name, size, align) { \
130  _SEMAPHORE_DATA(name.sem, (cnt_t)0), \
131  _MEMORYPOOL_DATA(NULL, size, align, NULL) \
132 }
133 
134 /**
135  * @brief Static guarded memory pool initializer.
136  * @details Statically initialized guarded memory pools require no explicit
137  * initialization using @p chGuardedPoolInit().
138  *
139  * @param[in] name the name of the guarded memory pool variable
140  * @param[in] size size of the memory pool contained objects
141  * @param[in] align required memory alignment
142  */
143 #define GUARDEDMEMORYPOOL_DECL(name, size, align) \
144  guarded_memory_pool_t name = _GUARDEDMEMORYPOOL_DATA(name, size, align)
145 #endif /* CH_CFG_USE_SEMAPHORES == TRUE */
146 
147 /*===========================================================================*/
148 /* External declarations. */
149 /*===========================================================================*/
150 
151 #ifdef __cplusplus
152 extern "C" {
153 #endif
154  void chPoolObjectInitAligned(memory_pool_t *mp, size_t size,
155  unsigned align, memgetfunc_t provider);
156  void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n);
157  void *chPoolAllocI(memory_pool_t *mp);
158  void *chPoolAlloc(memory_pool_t *mp);
159  void chPoolFreeI(memory_pool_t *mp, void *objp);
160  void chPoolFree(memory_pool_t *mp, void *objp);
161 #if CH_CFG_USE_SEMAPHORES == TRUE
163  size_t size,
164  unsigned align);
165  void chGuardedPoolLoadArray(guarded_memory_pool_t *gmp, void *p, size_t n);
167  sysinterval_t timeout);
169  sysinterval_t timeout);
170  void chGuardedPoolFree(guarded_memory_pool_t *gmp, void *objp);
171 #endif
172 #ifdef __cplusplus
173 }
174 #endif
175 
176 /*===========================================================================*/
177 /* Module inline functions. */
178 /*===========================================================================*/
179 
180 /**
181  * @brief Initializes an empty memory pool.
182  *
183  * @param[out] mp pointer to a @p memory_pool_t structure
184  * @param[in] size the size of the objects contained in this memory pool,
185  * the minimum accepted size is the size of a pointer to
186  * void.
187  * @param[in] provider memory provider function for the memory pool or
188  * @p NULL if the pool is not allowed to grow
189  * automatically
190  *
191  * @init
192  */
193 static inline void chPoolObjectInit(memory_pool_t *mp,
194  size_t size,
195  memgetfunc_t provider) {
196 
197  chPoolObjectInitAligned(mp, size, PORT_NATURAL_ALIGN, provider);
198 }
199 
200 /**
201  * @brief Adds an object to a memory pool.
202  * @pre The memory pool must be already been initialized.
203  * @pre The added object must be of the right size for the specified
204  * memory pool.
205  * @pre The added object must be properly aligned.
206  * @note This function is just an alias for @p chPoolFree() and has been
207  * added for clarity.
208  *
209  * @param[in] mp pointer to a @p memory_pool_t structure
210  * @param[in] objp the pointer to the object to be added
211  *
212  * @api
213  */
214 static inline void chPoolAdd(memory_pool_t *mp, void *objp) {
215 
216  chPoolFree(mp, objp);
217 }
218 
219 /**
220  * @brief Adds an object to a memory pool.
221  * @pre The memory pool must be already been initialized.
222  * @pre The added object must be of the right size for the specified
223  * memory pool.
224  * @pre The added object must be properly aligned.
225  * @note This function is just an alias for @p chPoolFreeI() and has been
226  * added for clarity.
227  *
228  * @param[in] mp pointer to a @p memory_pool_t structure
229  * @param[in] objp the pointer to the object to be added
230  *
231  * @iclass
232  */
233 static inline void chPoolAddI(memory_pool_t *mp, void *objp) {
234 
235  chPoolFreeI(mp, objp);
236 }
237 
238 #if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
239 /**
240  * @brief Initializes an empty guarded memory pool.
241  *
242  * @param[out] gmp pointer to a @p guarded_memory_pool_t structure
243  * @param[in] size the size of the objects contained in this guarded
244  * memory pool, the minimum accepted size is the size
245  * of a pointer to void.
246  *
247  * @init
248  */
250  size_t size) {
251 
252  chGuardedPoolObjectInitAligned(gmp, size, PORT_NATURAL_ALIGN);
253 }
254 
255 /**
256  * @brief Allocates an object from a guarded memory pool.
257  * @pre The guarded memory pool must be already been initialized.
258  *
259  * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
260  * @return The pointer to the allocated object.
261  * @retval NULL if the pool is empty.
262  *
263  * @iclass
264  */
265 static inline void *chGuardedPoolAllocI(guarded_memory_pool_t *gmp) {
266  void *p;
267 
268  p = chPoolAllocI(&gmp->pool);
269  if (p != NULL) {
270  chSemFastWaitI(&gmp->sem);
271  chDbgAssert(chSemGetCounterI(&gmp->sem) >= (cnt_t)0,
272  "semaphore out of sync");
273  }
274  return p;
275 }
276 
277 /**
278  * @brief Releases an object into a guarded memory pool.
279  * @pre The guarded memory pool must already be initialized.
280  * @pre The freed object must be of the right size for the specified
281  * guarded memory pool.
282  * @pre The added object must be properly aligned.
283  *
284  * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
285  * @param[in] objp the pointer to the object to be released
286  *
287  * @iclass
288  */
289 static inline void chGuardedPoolFreeI(guarded_memory_pool_t *gmp, void *objp) {
290 
291  chPoolFreeI(&gmp->pool, objp);
292  chSemSignalI(&gmp->sem);
293 }
294 
295 /**
296  * @brief Releases an object into a guarded memory pool.
297  * @pre The guarded memory pool must already be initialized.
298  * @pre The freed object must be of the right size for the specified
299  * guarded memory pool.
300  * @pre The added object must be properly aligned.
301  *
302  * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
303  * @param[in] objp the pointer to the object to be released
304  *
305  * @sclass
306  */
307 static inline void chGuardedPoolFreeS(guarded_memory_pool_t *gmp, void *objp) {
308 
309  chGuardedPoolFreeI(gmp, objp);
311 }
312 
313 /**
314  * @brief Adds an object to a guarded memory pool.
315  * @pre The guarded memory pool must be already been initialized.
316  * @pre The added object must be of the right size for the specified
317  * guarded memory pool.
318  * @pre The added object must be properly aligned.
319  * @note This function is just an alias for @p chGuardedPoolFree() and
320  * has been added for clarity.
321  *
322  * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
323  * @param[in] objp the pointer to the object to be added
324  *
325  * @api
326  */
327 static inline void chGuardedPoolAdd(guarded_memory_pool_t *gmp, void *objp) {
328 
329  chGuardedPoolFree(gmp, objp);
330 }
331 
332 /**
333  * @brief Adds an object to a guarded memory pool.
334  * @pre The guarded memory pool must be already been initialized.
335  * @pre The added object must be of the right size for the specified
336  * guarded memory pool.
337  * @pre The added object must be properly aligned.
338  * @note This function is just an alias for @p chGuardedPoolFreeI() and
339  * has been added for clarity.
340  *
341  * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
342  * @param[in] objp the pointer to the object to be added
343  *
344  * @iclass
345  */
346 static inline void chGuardedPoolAddI(guarded_memory_pool_t *gmp, void *objp) {
347 
348  chGuardedPoolFreeI(gmp, objp);
349 }
350 
351 /**
352  * @brief Adds an object to a guarded memory pool.
353  * @pre The guarded memory pool must be already been initialized.
354  * @pre The added object must be of the right size for the specified
355  * guarded memory pool.
356  * @pre The added object must be properly aligned.
357  * @note This function is just an alias for @p chGuardedPoolFreeI() and
358  * has been added for clarity.
359  *
360  * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
361  * @param[in] objp the pointer to the object to be added
362  *
363  * @sclass
364  */
365 static inline void chGuardedPoolAddS(guarded_memory_pool_t *gmp, void *objp) {
366 
367  chGuardedPoolFreeS(gmp, objp);
368 }
369 #endif /* CH_CFG_USE_SEMAPHORES == TRUE */
370 
371 #endif /* CH_CFG_USE_MEMPOOLS == TRUE */
372 
373 #endif /* CHMEMPOOLS_H */
374 
375 /** @} */
Memory pool descriptor.
Definition: chmempools.h:68
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:150
static void chPoolObjectInit(memory_pool_t *mp, size_t size, memgetfunc_t provider)
Initializes an empty memory pool.
Definition: chmempools.h:193
void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n)
Loads a memory pool with an array of static objects.
Definition: chmempools.c:103
void chPoolFree(memory_pool_t *mp, void *objp)
Releases an object into a memory pool.
Definition: chmempools.c:202
void * chGuardedPoolAllocTimeout(guarded_memory_pool_t *gmp, sysinterval_t timeout)
Allocates an object from a guarded memory pool.
Definition: chmempools.c:297
memgetfunc_t provider
Memory blocks provider for this pool.
Definition: chmempools.h:73
static void chSemFastWaitI(semaphore_t *sp)
Decreases the semaphore counter.
Definition: chsem.h:118
unsigned align
Required alignment.
Definition: chmempools.h:72
Memory pool free object header.
Definition: chmempools.h:60
memory_pool_t pool
The memory pool itself.
Definition: chmempools.h:84
static void chGuardedPoolAdd(guarded_memory_pool_t *gmp, void *objp)
Adds an object to a guarded memory pool.
Definition: chmempools.h:327
static void chGuardedPoolObjectInit(guarded_memory_pool_t *gmp, size_t size)
Initializes an empty guarded memory pool.
Definition: chmempools.h:249
static void * chGuardedPoolAllocI(guarded_memory_pool_t *gmp)
Allocates an object from a guarded memory pool.
Definition: chmempools.h:265
void chGuardedPoolLoadArray(guarded_memory_pool_t *gmp, void *p, size_t n)
Loads a guarded memory pool with an array of static objects.
Definition: chmempools.c:242
size_t object_size
Memory pool objects size.
Definition: chmempools.h:70
static void chGuardedPoolFreeI(guarded_memory_pool_t *gmp, void *objp)
Releases an object into a guarded memory pool.
Definition: chmempools.h:289
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition: chschd.c:456
void * chPoolAlloc(memory_pool_t *mp)
Allocates an object from a memory pool.
Definition: chmempools.c:155
static void chGuardedPoolAddI(guarded_memory_pool_t *gmp, void *objp)
Adds an object to a guarded memory pool.
Definition: chmempools.h:346
struct pool_header * next
Pointer to the header.
Definition: chmempools.h:69
struct pool_header * next
Pointer to the next pool header in the list.
Definition: chmempools.h:61
Semaphore structure.
Definition: chsem.h:52
void * chPoolAllocI(memory_pool_t *mp)
Allocates an object from a memory pool.
Definition: chmempools.c:126
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:127
void chGuardedPoolObjectInitAligned(guarded_memory_pool_t *gmp, size_t size, unsigned align)
Initializes an empty guarded memory pool.
Definition: chmempools.c:221
void * chGuardedPoolAllocTimeoutS(guarded_memory_pool_t *gmp, sysinterval_t timeout)
Allocates an object from a guarded memory pool.
Definition: chmempools.c:270
void chGuardedPoolFree(guarded_memory_pool_t *gmp, void *objp)
Releases an object into a guarded memory pool.
Definition: chmempools.c:320
static void chPoolAddI(memory_pool_t *mp, void *objp)
Adds an object to a memory pool.
Definition: chmempools.h:233
semaphore_t sem
Counter semaphore guarding the memory pool.
Definition: chmempools.h:82
void chPoolObjectInitAligned(memory_pool_t *mp, size_t size, unsigned align, memgetfunc_t provider)
Initializes an empty memory pool.
Definition: chmempools.c:77
void *(* memgetfunc_t)(size_t size, unsigned align)
Memory get function.
Definition: chmemcore.h:75
Guarded memory pool descriptor.
Definition: chmempools.h:81
static void chPoolAdd(memory_pool_t *mp, void *objp)
Adds an object to a memory pool.
Definition: chmempools.h:214
static cnt_t chSemGetCounterI(const semaphore_t *sp)
Returns the semaphore counter current value.
Definition: chsem.h:149
void chSemSignalI(semaphore_t *sp)
Performs a signal operation on a semaphore.
Definition: chsem.c:319
static void chGuardedPoolAddS(guarded_memory_pool_t *gmp, void *objp)
Adds an object to a guarded memory pool.
Definition: chmempools.h:365
void chPoolFreeI(memory_pool_t *mp, void *objp)
Releases an object into a memory pool.
Definition: chmempools.c:177
static void chGuardedPoolFreeS(guarded_memory_pool_t *gmp, void *objp)
Releases an object into a guarded memory pool.
Definition: chmempools.h:307