X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fstruct%2Fheap.c;h=4c00bd7ca0ed1ebd3b24a6048b6b8f26b8112d24;hb=HEAD;hp=2375c1f140ebcd2267090f4285edd91c295fdf56;hpb=2d8af52f104df99da4e64987081c7d4d08ac278a;p=bertos.git diff --git a/bertos/struct/heap.c b/bertos/struct/heap.c index 2375c1f1..4c00bd7c 100644 --- a/bertos/struct/heap.c +++ b/bertos/struct/heap.c @@ -32,34 +32,31 @@ * * \brief Heap subsystem (public interface). * - * \version $Id: heap.c 1532 2008-08-04 07:21:26Z bernie $ * \author Bernie Innocenti */ #include "heap.h" -#include // IS_POW2() -#include // ASSERT() - -#include // memset() - -/* NOTE: struct size must be a 2's power! */ -typedef struct _MemChunk -{ - struct _MemChunk *next; - size_t size; -} MemChunk; - -STATIC_ASSERT(IS_POW2(sizeof(MemChunk))); +#include // ASSERT() +#include // memset() #define FREE_FILL_CODE 0xDEAD #define ALLOC_FILL_CODE 0xBEEF + +/* + * This function prototype is deprecated, will change in: + * void heap_init(struct Heap* h, heap_buf_t* memory, size_t size) + * in the next BeRTOS release. + */ void heap_init(struct Heap* h, void* memory, size_t size) { -#ifdef _DEBUG + #ifdef _DEBUG memset(memory, FREE_FILL_CODE, size); -#endif + #endif + + ASSERT2(((size_t)memory % alignof(heap_buf_t)) == 0, + "memory buffer is unaligned, please use the HEAP_DEFINE_BUF() macro to declare heap buffers!\n"); /* Initialize heap with a single big chunk */ h->FreeList = (MemChunk *)memory; @@ -129,9 +126,9 @@ void heap_freemem(struct Heap* h, void *mem, size_t size) if (!size) size = sizeof(MemChunk); - /* Special case: first chunk in the free list */ + /* Special cases: first chunk in the free list or memory completely full */ ASSERT((uint8_t*)mem != (uint8_t*)h->FreeList); - if (((uint8_t *)mem) < ((uint8_t *)h->FreeList)) + if (((uint8_t *)mem) < ((uint8_t *)h->FreeList) || !h->FreeList) { /* Insert memory block before the current free list head */ prev = (MemChunk *)mem; @@ -186,8 +183,30 @@ void heap_freemem(struct Heap* h, void *mem, size_t size) } } +/** + * Returns the number of free bytes in a heap. + * \param h the heap to check. + * + * \note The returned value is the sum of all free memory regions + * in the heap. + * Those regions are likely to be *not* contiguous, + * so a successive allocation may fail even if the + * requested amount of memory is lower than the current free space. + */ +size_t heap_freeSpace(struct Heap *h) +{ + size_t free_mem = 0; + for (MemChunk *chunk = h->FreeList; chunk; chunk = chunk->next) + free_mem += chunk->size; + + return free_mem; +} + #if CONFIG_HEAP_MALLOC +/** + * Standard malloc interface + */ void *heap_malloc(struct Heap* h, size_t size) { size_t *mem; @@ -199,6 +218,9 @@ void *heap_malloc(struct Heap* h, size_t size) return mem; } +/** + * Standard calloc interface + */ void *heap_calloc(struct Heap* h, size_t size) { void *mem;