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