aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/common/oslib/include/chmempools.h103
-rw-r--r--os/common/oslib/src/chmempools.c139
-rw-r--r--readme.txt1
3 files changed, 235 insertions, 8 deletions
diff --git a/os/common/oslib/include/chmempools.h b/os/common/oslib/include/chmempools.h
index 2d582f48a..2dfe40e20 100644
--- a/os/common/oslib/include/chmempools.h
+++ b/os/common/oslib/include/chmempools.h
@@ -69,6 +69,17 @@ typedef struct {
for this pool. */
} memory_pool_t;
+#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Guarded memory pool descriptor.
+ */
+typedef struct {
+ semaphore_t sem; /**< @brief Counter semaphore quarding
+ the memory pool. */
+ memory_pool_t pool; /**< @brief The memory pool itself. */
+} guarded_memory_pool_t;
+#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
+
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
@@ -86,18 +97,46 @@ typedef struct {
{NULL, size, provider}
/**
- * @brief Static memory pool initializer in hungry mode.
+ * @brief Static memory pool initializer.
* @details Statically initialized memory pools require no explicit
* initialization using @p chPoolInit().
*
- * @param[in] name the name of the memory pool variable
- * @param[in] size size of the memory pool contained objects
- * @param[in] provider memory provider function for the memory pool or @p NULL
- * if the pool is not allowed to grow automatically
+ * @param[in] name the name of the memory pool variable
+ * @param[in] size size of the memory pool contained objects
+ * @param[in] provider memory provider function for the memory pool or @p NULL
+ * if the pool is not allowed to grow automatically
*/
#define MEMORYPOOL_DECL(name, size, provider) \
memory_pool_t name = _MEMORYPOOL_DATA(name, size, provider)
+#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Data part of a static guarded memory pool initializer.
+ * @details This macro should be used when statically initializing a
+ * memory pool that is part of a bigger structure.
+ *
+ * @param[in] name the name of the memory pool variable
+ * @param[in] size size of the memory pool contained objects
+ */
+#define _GUARDEDMEMORYPOOL_DATA(name, size) { \
+ _SEMAPHORE_DATA(name.sem, (cnt_t)0), \
+ NULL, \
+ size, \
+ NULL \
+}
+
+/**
+ * @brief Static guarded memory pool initializer.
+ * @details Statically initialized guardedmemory pools require no explicit
+ * initialization using @p chGuardedPoolInit().
+ *
+ * @param[in] name the name of the guarded memory pool variable
+ * @param[in] size size of the memory pool contained objects
+ */
+#define GUARDEDMEMORYPOOL_DECL(name, size) \
+ memory_pool_t name = _MEMORYPOOL_DATA(name, size)
+#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -111,6 +150,16 @@ extern "C" {
void *chPoolAlloc(memory_pool_t *mp);
void chPoolFreeI(memory_pool_t *mp, void *objp);
void chPoolFree(memory_pool_t *mp, void *objp);
+#if CH_CFG_USE_SEMAPHORES == TRUE
+ void chGuardedPoolObjectInit(guarded_memory_pool_t *gmp, size_t size);
+ void chGuardedPoolLoadArray(guarded_memory_pool_t *gmp, void *p, size_t n);
+ void *chGuardedPoolAllocTimeoutS(guarded_memory_pool_t *gmp,
+ systime_t timeout);
+ void *chGuardedPoolAllocTimeout(guarded_memory_pool_t *gmp,
+ systime_t timeout);
+ void chGuardedPoolFreeI(guarded_memory_pool_t *gmp, void *objp);
+ void chGuardedPoolFree(guarded_memory_pool_t *gmp, void *objp);
+#endif
#ifdef __cplusplus
}
#endif
@@ -146,7 +195,7 @@ static inline void chPoolAdd(memory_pool_t *mp, void *objp) {
* memory pool.
* @pre The added object must be memory aligned to the size of
* @p stkalign_t type.
- * @note This function is just an alias for @p chPoolFree() and has been
+ * @note This function is just an alias for @p chPoolFreeI() and has been
* added for clarity.
*
* @param[in] mp pointer to a @p memory_pool_t structure
@@ -161,6 +210,48 @@ static inline void chPoolAddI(memory_pool_t *mp, void *objp) {
chPoolFreeI(mp, objp);
}
+#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Adds an object to a guarded memory pool.
+ * @pre The guarded memory pool must be already been initialized.
+ * @pre The added object must be of the right size for the specified
+ * guarded memory pool.
+ * @pre The added object must be properly aligned.
+ * @note This function is just an alias for @p chGuardedPoolFree() and
+ * has been added for clarity.
+ *
+ * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
+ * @param[in] objp the pointer to the object to be added
+ *
+ * @api
+ */
+static inline void chGuardedPoolAdd(guarded_memory_pool_t *gmp, void *objp) {
+
+ chGuardedPoolFree(gmp, objp);
+}
+
+/**
+ * @brief Adds an object to a guarded memory pool.
+ * @pre The guarded memory pool must be already been initialized.
+ * @pre The added object must be of the right size for the specified
+ * guarded memory pool.
+ * @pre The added object must be properly aligned.
+ * @note This function is just an alias for @p chGuardedPoolFreeI() and
+ * has been added for clarity.
+ *
+ * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
+ * @param[in] objp the pointer to the object to be added
+ *
+ * @iclass
+ */
+static inline void chGuardedPoolAddI(guarded_memory_pool_t *gmp, void *objp) {
+
+ chDbgCheckClassI();
+
+ chGuardedPoolFreeI(gmp, objp);
+}
+#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
+
#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
#endif /* _CHMEMPOOLS_H_ */
diff --git a/os/common/oslib/src/chmempools.c b/os/common/oslib/src/chmempools.c
index c29fde8f4..29ca2e0dc 100644
--- a/os/common/oslib/src/chmempools.c
+++ b/os/common/oslib/src/chmempools.c
@@ -162,7 +162,7 @@ void *chPoolAlloc(memory_pool_t *mp) {
* @pre The memory pool must be already been initialized.
* @pre The freed object must be of the right size for the specified
* memory pool.
- * @pre The object must be properly aligned to contain a pointer to void.
+ * @pre The added object must be properly aligned.
*
* @param[in] mp pointer to a @p memory_pool_t structure
* @param[in] objp the pointer to the object to be released
@@ -184,7 +184,7 @@ void chPoolFreeI(memory_pool_t *mp, void *objp) {
* @pre The memory pool must be already been initialized.
* @pre The freed object must be of the right size for the specified
* memory pool.
- * @pre The object must be properly aligned to contain a pointer to void.
+ * @pre The added object must be properly aligned.
*
* @param[in] mp pointer to a @p memory_pool_t structure
* @param[in] objp the pointer to the object to be released
@@ -198,6 +198,141 @@ void chPoolFree(memory_pool_t *mp, void *objp) {
chSysUnlock();
}
+#if CH_CFG_USE_SEMAPHORES == TRUE
+/**
+ * @brief Initializes an empty guarded memory pool.
+ *
+ * @param[out] gmp pointer to a @p guarded_memory_pool_t structure
+ * @param[in] size the size of the objects contained in this guarded
+ * memory pool, the minimum accepted size is the size
+ * of a pointer to void.
+ *
+ * @init
+ */
+void chGuardedPoolObjectInit(guarded_memory_pool_t *gmp, size_t size) {
+
+ chPoolObjectInit(&gmp->pool, size, NULL);
+ chSemObjectInit(&gmp->sem, (cnt_t)0);
+}
+
+/**
+ * @brief Loads a guarded memory pool with an array of static objects.
+ * @pre The guarded memory pool must be already been initialized.
+ * @pre The array elements must be of the right size for the specified
+ * guarded memory pool.
+ * @post The guarded memory pool contains the elements of the input array.
+ *
+ * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
+ * @param[in] p pointer to the array first element
+ * @param[in] n number of elements in the array
+ *
+ * @api
+ */
+void chGuardedPoolLoadArray(guarded_memory_pool_t *gmp, void *p, size_t n) {
+
+ chDbgCheck((gmp != NULL) && (n != 0U));
+
+ while (n != 0U) {
+ chGuardedPoolAdd(gmp, p);
+ /*lint -save -e9087 [11.3] Safe cast.*/
+ p = (void *)(((uint8_t *)p) + gmp->pool.object_size);
+ /*lint -restore*/
+ n--;
+ }
+}
+
+/**
+ * @brief Allocates an object from a guarded memory pool.
+ * @pre The guarded memory pool must be already been initialized.
+ *
+ * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The pointer to the allocated object.
+ * @retval NULL if the operation timed out.
+ *
+ * @sclass
+ */
+void *chGuardedPoolAllocTimeoutS(guarded_memory_pool_t *gmp,
+ systime_t timeout) {
+ msg_t msg;
+
+ msg = chSemWaitTimeoutS(&gmp->sem, timeout);
+ if (msg != MSG_OK) {
+ return NULL;
+ }
+
+ return chPoolAllocI(&gmp->pool);
+}
+
+/**
+ * @brief Allocates an object from a guarded memory pool.
+ * @pre The guarded memory pool must be already been initialized.
+ *
+ * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
+ * @param[in] timeout the number of ticks before the operation timeouts,
+ * the following special values are allowed:
+ * - @a TIME_IMMEDIATE immediate timeout.
+ * - @a TIME_INFINITE no timeout.
+ * .
+ * @return The pointer to the allocated object.
+ * @retval NULL if the operation timed out.
+ *
+ * @api
+ */
+void *chGuardedPoolAllocTimeout(guarded_memory_pool_t *gmp,
+ systime_t timeout) {
+ void *p;
+
+ chSysLock();
+ p = chGuardedPoolAllocTimeoutS(gmp, timeout);
+ chSysUnlock();
+
+ return p;
+}
+
+/**
+ * @brief Releases an object into a guarded memory pool.
+ * @pre The guarded memory pool must be already been initialized.
+ * @pre The freed object must be of the right size for the specified
+ * guarded memory pool.
+ * @pre The added object must be properly aligned.
+ *
+ * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
+ * @param[in] objp the pointer to the object to be released
+ *
+ * @iclass
+ */
+void chGuardedPoolFreeI(guarded_memory_pool_t *gmp, void *objp) {
+
+ chPoolFreeI(&gmp->pool, objp);
+ chSemSignalI(&gmp->sem);
+}
+
+/**
+ * @brief Releases an object into a guarded memory pool.
+ * @pre The guarded memory pool must be already been initialized.
+ * @pre The freed object must be of the right size for the specified
+ * guarded memory pool.
+ * @pre The added object must be properly aligned.
+ *
+ * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
+ * @param[in] objp the pointer to the object to be released
+ *
+ * @api
+ */
+void chGuardedPoolFree(guarded_memory_pool_t *gmp, void *objp) {
+
+ chSysLock();
+ chGuardedPoolFreeI(gmp, objp);
+ chSchRescheduleS();
+ chSysUnlock();
+}
+#endif
+
#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
/** @} */
diff --git a/readme.txt b/readme.txt
index 56904fdfd..0febf1b46 100644
--- a/readme.txt
+++ b/readme.txt
@@ -79,6 +79,7 @@
*****************************************************************************
*** Next ***
+- LIB: Added Guarded Memory Pools to RT and NIL.
- NIL: Updated the NIL test suite by generating the code using the new system.
- RT: Removed I/O Queues and Streams interface, now those exists (much
improved) inside the HAL.