diff options
author | Giovanni Di Sirio <gdisirio@gmail.com> | 2016-03-18 10:00:27 +0000 |
---|---|---|
committer | Giovanni Di Sirio <gdisirio@gmail.com> | 2016-03-18 10:00:27 +0000 |
commit | a1480d01d1110f74f157d5caea0b5d619d859b91 (patch) | |
tree | d892add54dbef907f01040b7838da8359d052775 /os | |
parent | 3a48ef2df6ad7864e55c6b32f5450ea3d28d0943 (diff) | |
download | ChibiOS-a1480d01d1110f74f157d5caea0b5d619d859b91.tar.gz ChibiOS-a1480d01d1110f74f157d5caea0b5d619d859b91.tar.bz2 ChibiOS-a1480d01d1110f74f157d5caea0b5d619d859b91.zip |
Added Guarded Memory Pools to RT and NIL.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9134 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r-- | os/common/oslib/include/chmempools.h | 103 | ||||
-rw-r--r-- | os/common/oslib/src/chmempools.c | 139 |
2 files changed, 234 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 */
/** @} */
|