Dynamic memory manager.
This is a lightweight replacement for the standard C library malloc().
If you want to use the standard C library malloc() instead, define MEM_LIBC_MALLOC to 1 in your lwipopts.h
To let mem_malloc() use pools (prevents fragmentation and is much faster than a heap but might waste some memory), define MEM_USE_POOLS to 1, define MEM_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list of pools like this (more pools can be added between _START and _END):
Define three pools with sizes 256, 512, and 1512 bytes LWIP_MALLOC_MEMPOOL_START LWIP_MALLOC_MEMPOOL(20, 256) LWIP_MALLOC_MEMPOOL(10, 512) LWIP_MALLOC_MEMPOOL(5, 1512) LWIP_MALLOC_MEMPOOL_END
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include "lwip/err.h"
#include <string.h>
Data Structures | |
struct | mem |
The heap is made up as a list of structs of this type. More... | |
Macros | |
#define | LWIP_MEM_ALLOC_DECL_PROTECT() |
#define | LWIP_MEM_ALLOC_PROTECT() |
#define | LWIP_MEM_ALLOC_UNPROTECT() |
#define | LWIP_MEM_FREE_DECL_PROTECT() |
#define | LWIP_MEM_FREE_PROTECT() sys_mutex_lock(&mem_mutex) |
#define | LWIP_MEM_FREE_UNPROTECT() sys_mutex_unlock(&mem_mutex) |
#define | LWIP_RAM_HEAP_POINTER ram_heap |
#define | MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) |
#define | MIN_SIZE 12 |
All allocated blocks will be MIN_SIZE bytes big, at least! MIN_SIZE can be overridden to suit your needs. More... | |
#define | MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) |
#define | SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) |
Functions | |
void * | mem_calloc (mem_size_t count, mem_size_t size) |
Contiguously allocates enough space for count objects that are size bytes of memory each and returns a pointer to the allocated memory. More... | |
void | mem_free (void *rmem) |
Put a struct mem back on the heap. More... | |
void | mem_init (void) |
Zero the heap and initialize start, end and lowest-free. More... | |
void * | mem_malloc (mem_size_t size) |
Adam's mem_malloc() plus solution for bug #17922 Allocate a block of memory with a minimum of 'size' bytes. More... | |
void * | mem_trim (void *rmem, mem_size_t newsize) |
Shrink memory returned by mem_malloc(). More... | |
static void | plug_holes (struct mem *mem) |
"Plug holes" by combining adjacent empty struct mems. More... | |
Variables | |
static struct mem * | lfree |
pointer to the lowest free block, this is used for faster search More... | |
static sys_mutex_t | mem_mutex |
concurrent access protection More... | |
static u8_t * | ram |
pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array More... | |
static struct mem * | ram_end |
the last entry, always unused! More... | |
u8_t | ram_heap [MEM_SIZE_ALIGNED+(2 *SIZEOF_STRUCT_MEM)+MEM_ALIGNMENT] |
If you want to relocate the heap to external memory, simply define LWIP_RAM_HEAP_POINTER as a void-pointer to that location. More... | |
#define LWIP_MEM_ALLOC_DECL_PROTECT | ( | ) |
Referenced by mem_malloc().
#define LWIP_MEM_ALLOC_PROTECT | ( | ) |
Referenced by mem_malloc().
#define LWIP_MEM_ALLOC_UNPROTECT | ( | ) |
Referenced by mem_malloc().
#define LWIP_MEM_FREE_DECL_PROTECT | ( | ) |
Referenced by mem_free(), and mem_trim().
#define LWIP_MEM_FREE_PROTECT | ( | ) | sys_mutex_lock(&mem_mutex) |
Referenced by mem_free(), and mem_trim().
#define LWIP_MEM_FREE_UNPROTECT | ( | ) | sys_mutex_unlock(&mem_mutex) |
Referenced by mem_free(), and mem_trim().
#define LWIP_RAM_HEAP_POINTER ram_heap |
Referenced by mem_init().
#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) |
Referenced by mem_init(), mem_malloc(), mem_trim(), and plug_holes().
#define MIN_SIZE 12 |
All allocated blocks will be MIN_SIZE bytes big, at least! MIN_SIZE can be overridden to suit your needs.
Smaller values save space, larger values could prevent too small blocks to fragment the RAM too much.
#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) |
Referenced by mem_malloc(), and mem_trim().
#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) |
Referenced by mem_free(), mem_init(), mem_malloc(), and mem_trim().
void* mem_calloc | ( | mem_size_t | count, |
mem_size_t | size | ||
) |
Contiguously allocates enough space for count objects that are size bytes of memory each and returns a pointer to the allocated memory.
The allocated memory is filled with bytes of value zero.
count | number of objects to allocate |
size | size of the objects to allocate |
References mem_malloc().
void mem_free | ( | void * | rmem | ) |
Put a struct mem back on the heap.
rmem | is the data portion of a struct mem as returned by a previous call to mem_malloc() |
References LWIP_ASSERT, LWIP_DBG_LEVEL_SERIOUS, LWIP_DBG_LEVEL_SEVERE, LWIP_DBG_TRACE, LWIP_DEBUGF, LWIP_MEM_FREE_DECL_PROTECT, LWIP_MEM_FREE_PROTECT, LWIP_MEM_FREE_UNPROTECT, MEM_ALIGNMENT, MEM_DEBUG, MEM_STATS_DEC_USED, MEM_STATS_INC, mem::next, NULL, plug_holes(), SIZEOF_STRUCT_MEM, SYS_ARCH_DECL_PROTECT(), SYS_ARCH_PROTECT(), SYS_ARCH_UNPROTECT(), and mem::used.
Referenced by mem_free_callback(), and pbuf_free().
void mem_init | ( | void | ) |
Zero the heap and initialize start, end and lowest-free.
References ERR_OK, LWIP_ASSERT, LWIP_MEM_ALIGN, LWIP_RAM_HEAP_POINTER, MEM_ALIGNMENT, MEM_SIZE_ALIGNED, MEM_STATS_AVAIL, mem::next, mem::prev, ram, SIZEOF_STRUCT_MEM, sys_mutex_new(), and mem::used.
Referenced by lwip_init().
void* mem_malloc | ( | mem_size_t | size | ) |
Adam's mem_malloc() plus solution for bug #17922 Allocate a block of memory with a minimum of 'size' bytes.
size | is the minimum size of the requested block in bytes. |
Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT).
References lfree, LWIP_ASSERT, LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF, LWIP_MEM_ALIGN_SIZE, LWIP_MEM_ALLOC_DECL_PROTECT, LWIP_MEM_ALLOC_PROTECT, LWIP_MEM_ALLOC_UNPROTECT, MEM_ALIGNMENT, MEM_DEBUG, MEM_SIZE_ALIGNED, MEM_STATS_INC, MEM_STATS_INC_USED, MIN_SIZE_ALIGNED, mem::next, NULL, mem::prev, ptr, S16_F, SIZEOF_STRUCT_MEM, sys_mutex_lock(), sys_mutex_unlock(), and mem::used.
Referenced by mem_calloc(), and pbuf_alloc().
void* mem_trim | ( | void * | rmem, |
mem_size_t | newsize | ||
) |
Shrink memory returned by mem_malloc().
rmem | pointer to memory allocated by mem_malloc the is to be shrinked |
newsize | required size after shrinking (needs to be smaller than or equal to the previous size) |
References LWIP_ASSERT, LWIP_DBG_LEVEL_SEVERE, LWIP_DEBUGF, LWIP_MEM_ALIGN_SIZE, LWIP_MEM_FREE_DECL_PROTECT, LWIP_MEM_FREE_PROTECT, LWIP_MEM_FREE_UNPROTECT, MEM_DEBUG, MEM_SIZE_ALIGNED, MEM_STATS_DEC_USED, MEM_STATS_INC, MIN_SIZE_ALIGNED, mem::next, NULL, mem::prev, ptr, ram, SIZEOF_STRUCT_MEM, SYS_ARCH_DECL_PROTECT(), SYS_ARCH_PROTECT(), SYS_ARCH_UNPROTECT(), and mem::used.
Referenced by pbuf_realloc().
|
static |
"Plug holes" by combining adjacent empty struct mems.
After this function is through, there should not exist one empty struct mem pointing to another empty struct mem.
mem | this points to a struct mem which just has been freed |
this function is only called by mem_free() and mem_trim()
This assumes access to the heap is protected by the calling function already.
References LWIP_ASSERT, MEM_SIZE_ALIGNED, mem::next, mem::prev, and mem::used.
Referenced by mem_free().
|
static |
pointer to the lowest free block, this is used for faster search
Referenced by mem_malloc().
|
static |
concurrent access protection
|
static |
pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array
Referenced by mem_init(), and mem_trim().
|
static |
the last entry, always unused!
u8_t ram_heap[MEM_SIZE_ALIGNED+(2 *SIZEOF_STRUCT_MEM)+MEM_ALIGNMENT] |
If you want to relocate the heap to external memory, simply define LWIP_RAM_HEAP_POINTER as a void-pointer to that location.
If so, make sure the memory at that location is big enough (see below on how that space is calculated). the heap. we need one struct mem at the end and some room for alignment