diff --git a/docs/Doxyfile b/docs/Doxyfile index 21ec9dac5..808975cf9 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1299,14 +1299,13 @@ PREDEFINED = __DOXYGEN__ \ CH_USE_WAITEXIT=1 \ CH_USE_SEMAPHORES=1 \ CH_USE_SEMSW=1 \ - CH_USE_SEMAPHORES_TIMEOUT=1 \ CH_USE_MUTEXES=1 \ CH_USE_CONDVARS=1 \ CH_USE_CONDVARS_TIMEOUT=1 \ CH_USE_EVENTS=1 \ CH_USE_EVENTS_TIMEOUT=1 \ CH_USE_QUEUES=1 \ - CH_USE_SERIAL_FULLDUPLEX=1 \ + CH_USE_MEMCORE=1 \ CH_USE_HEAP=1 \ CH_USE_MEMPOOLS=1 \ CH_USE_MESSAGES=1 \ diff --git a/docs/src/concepts.dox b/docs/src/concepts.dox index 67b01f8b3..bab26d064 100644 --- a/docs/src/concepts.dox +++ b/docs/src/concepts.dox @@ -35,7 +35,7 @@ * @a ch\\\(). * The possible groups are: @a Sys, @a Sch, @a Time, @a VT, @a Thd, @a Sem, * @a Mtx, @a Cond, @a Evt, @a Msg, @a IQ, @a OQ, @a IO, @a Dbg, - * @a Heap, @a Pool. + * @a Core, @a Heap, @a Pool. * * @section api_suffixes API Names Suffixes * The suffix can be one of the following: diff --git a/os/kernel/include/memcore.h b/os/kernel/include/memcore.h index 8f3fe4671..c60d3ad9d 100644 --- a/os/kernel/include/memcore.h +++ b/os/kernel/include/memcore.h @@ -27,10 +27,8 @@ #ifndef _MEMCORE_H_ #define _MEMCORE_H_ -#if CH_USE_MEMCORE - /** - * @brief Memory alignment type. + * @brief Memory alignment type. */ typedef void *align_t; @@ -42,21 +40,23 @@ typedef void *align_t; typedef void *(*memgetfunc_t)(size_t size); /** - * @brief Alignment mask constant. + * @brief Alignment mask constant. */ #define MEM_ALIGN_MASK (sizeof(align_t) - 1) /** - * @brief Alignment helper macro. + * @brief Alignment helper macro. */ #define MEM_ALIGN_SIZE(p) (((size_t)(p) + MEM_ALIGN_MASK) & ~MEM_ALIGN_MASK) /** * @brief Returns whatever a pointer or memory size is aligned to - * the type @p align_t. + * the type @p align_t. */ #define MEM_IS_ALIGNED(p) (((size_t)(p) & MEM_ALIGN_MASK) == 0) +#if CH_USE_MEMCORE + #ifdef __cplusplus extern "C" { #endif diff --git a/os/kernel/include/mempools.h b/os/kernel/include/mempools.h index 38279c388..d5e612426 100644 --- a/os/kernel/include/mempools.h +++ b/os/kernel/include/mempools.h @@ -40,14 +40,19 @@ struct pool_header { * @brief Memory pool descriptor. */ typedef struct { - struct pool_header *mp_next; /**< Pointer to the header.*/ - size_t mp_object_size; /**< Memory pool objects size.*/ + struct pool_header *mp_next; /**< Pointer to the header. */ + size_t mp_object_size; /**< Memory pool objects size. */ +#if CH_USE_MEMCORE + bool_t mp_usecore; /**< Feed from the memory code + allocator if empty. */ +#endif } MemoryPool; /** * @brief Data part of a static memory pool initializer. * @details This macro should be used when statically initializing a * memory pool that is part of a bigger structure. + * * @param name the name of the memory pool variable * @param size size of the memory pool contained objects */ @@ -57,12 +62,25 @@ typedef struct { * @brief Static memory pool initializer. * @details Statically initialized memory pools require no explicit * initialization using @p chPoolInit(). + * * @param name the name of the memory pool variable * @param size size of the memory pool contained objects */ #define MEMORYPOOL_DECL(name, size) \ MemoryPool name = _MEMORYPOOL_DATA(name, size) +#if CH_USE_MEMCORE || defined(__DOXYGEN__) +/** + * @brief Enables or disables the hungry mode. + * @details If enabled, the hungry mode, makes an empty memory pool feed + * new objects from the core memory manager. + * + * @param[in] mp pointer to a @p MemoryPool structure + * @param[in] mode hungry mode flag + */ +#define chPoolSetHungryMode(mp, mode) ((mp)->mp_usecore = (mode)) +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/os/kernel/kernel.dox b/os/kernel/kernel.dox index d2936fa14..bd8870279 100644 --- a/os/kernel/kernel.dox +++ b/os/kernel/kernel.dox @@ -230,7 +230,28 @@ */ /** - * @defgroup heap Heap + * @defgroup memcore Core Memory Manager + * Core Memory Manager related APIs. + *

Operation mode

+ * The core memory manager is a simplified allocator that only allows to + * allocate memory blocks without the possibility to free them.
+ * This allocator is meant as a memory blocks provider for the other + * allocators such as: + * - C-Runtime allocator. + * - Heap allocator (see @ref heaps). + * - @ref Memory pools allocator (see @ref pools). + * . + * By having a centralized memory provider the various allocators can coexist + * and share the main memory.
+ * This allocator, alone, is also useful for very simple applications that + * just require a simple way to get memory blocks.
+ * In order to use the core memory manager APIs the @p CH_USE_MEMCORE option + * must be specified in @p chconf.h. + * @ingroup memory + */ + +/** + * @defgroup heaps Heaps * Heap Allocator related APIs. *

Operation mode

* The heap allocator implements a first-fit strategy and its APIs are diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 00e04a2d6..7177fe432 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -60,7 +60,7 @@ void core_init(void) { * sizeof(align_t). * * - * @param[in] the size of the block to be allocated + * @param[in] size the size of the block to be allocated * @return A pointer to the allocated memory block. * @retval NULL allocation failed, core memory exhausted. */ @@ -79,7 +79,7 @@ void *chCoreAlloc(size_t size) { * type @p align_t so it is not possible to allocate less than * sizeof(align_t). * - * @param[in] the size of the block to be allocated. + * @param[in] size the size of the block to be allocated. * @return A pointer to the allocated memory block. * @retval NULL allocation failed, core memory exhausted. */ diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index a8d7da818..76ef39b58 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -32,14 +32,20 @@ * * @param[out] mp pointer to a @p MemoryPool structure * @param[in] size the size of the objects contained in this memory pool, - * the minimum accepted size is the size of a pointer to void + * the minimum accepted size is the size of a pointer to void. + * + * @note The size is internally aligned to be a multiple of the @p align_t + * type size. */ void chPoolInit(MemoryPool *mp, size_t size) { chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit"); mp->mp_next = NULL; - mp->mp_object_size = size; + mp->mp_object_size = MEM_ALIGN_SIZE(size); +#if CH_USE_MEMCORE + mp->mp_usecore = FALSE; +#endif } /** @@ -56,7 +62,10 @@ void *chPoolAllocI(MemoryPool *mp) { if ((objp = mp->mp_next) != NULL) mp->mp_next = mp->mp_next->ph_next; - +#if CH_USE_MEMCORE + else if (mp->mp_usecore) + objp = chCoreAllocI(mp->mp_object_size); +#endif return objp; } @@ -81,13 +90,17 @@ void *chPoolAlloc(MemoryPool *mp) { * * @param[in] mp pointer to a @p MemoryPool structure * @param[in] objp the pointer to the object to be released or added - * @note the object is assumed to be of the right size for the specified + * + * @note The object is assumed to be of the right size for the specified * memory pool. + * @note The object is assumed to be memory aligned to the size of @p align_t + * type. */ void chPoolFreeI(MemoryPool *mp, void *objp) { struct pool_header *php = objp; - chDbgCheck((mp != NULL) && (objp != NULL), "chPoolFreeI"); + chDbgCheck((mp != NULL) && (objp != NULL) && MEM_IS_ALIGNED(objp), + "chPoolFreeI"); php->ph_next = mp->mp_next; mp->mp_next = php; diff --git a/readme.txt b/readme.txt index f361bde0c..536596684 100644 --- a/readme.txt +++ b/readme.txt @@ -7,11 +7,13 @@ Removed the old EMAC driver, updated the uIP WEB demo to use the new driver model. - NEW: Added a simple lwIP demo (web server) for the AT91SAM7X. -- NEW: Centralized memory heap manager. This simple allocator implements a +- NEW: Centralized core memory manager. This simple allocator implements a sbrk()-like API: chCoreAlloc(). The other allocators now use this manager in order to get memory blocks. - NEW: The heap allocator has been modified, now it is possible to have multiple heaps. The default heap gets its memory from the new heap manager. +- NEW: Added a "hungry" mode to the memory pools allocator, when enabled, this + mode makes a memory pool to feed memory from the core memory manager. - CHANGE: Because the changes in the allocators some API prototypes changed: chHeapAlloc(), chHeapStatus(), chThdCreateFromHeap(). - CHANGE: Because the changes in the allocators some configuration options diff --git a/test/test.h b/test/test.h index 7b261b553..c31caf633 100644 --- a/test/test.h +++ b/test/test.h @@ -47,6 +47,7 @@ struct testcase { void (*execute)(void); }; +#ifndef __DOXYGEN__ union test_buffers { struct { WORKING_AREA(waT0, THREADS_STACK_SIZE); @@ -57,6 +58,7 @@ union test_buffers { }; uint8_t buffer[WA_SIZE * 5]; }; +#endif #ifdef __cplusplus extern "C" { diff --git a/test/testheap.c b/test/testheap.c index ba839e6d4..ce127d2be 100644 --- a/test/testheap.c +++ b/test/testheap.c @@ -85,7 +85,7 @@ static void heap1_execute(void) { p1 = chHeapAlloc(NULL, SIZE); test_assert(1, p1 != NULL, "allocation failed"); chHeapFree(p1); - p1 = chHeapAlloc(NULL, 0x1000000); + p1 = chHeapAlloc(NULL, (size_t)-256); test_assert(2, p1 == NULL, "allocation not failed"); /* Initial local heap state.*/