void *
mem_malloc(mem_size_t size)
{
+ void *ret;
struct memp_malloc_helper *element;
memp_t poolnr;
- mem_size_t required_size = size + sizeof(struct memp_malloc_helper);
+ mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) {
#if MEM_USE_POOLS_TRY_BIGGER_POOL
/* save the pool number this element came from */
element->poolnr = poolnr;
/* and return a pointer to the memory directly after the struct memp_malloc_helper */
- element++;
+ ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper));
- return element;
+ return ret;
}
/**
void
mem_free(void *rmem)
{
- struct memp_malloc_helper *hmem = (struct memp_malloc_helper*)rmem;
+ struct memp_malloc_helper *hmem;
LWIP_ASSERT("rmem != NULL", (rmem != NULL));
LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem)));
/* get the original struct memp_malloc_helper */
- hmem--;
+ hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)));
LWIP_ASSERT("hmem != NULL", (hmem != NULL));
LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem)));
static struct mem *lfree;
/** concurrent access protection */
+#if !NO_SYS
static sys_mutex_t mem_mutex;
+#endif
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
sys_mutex_lock(&mem_mutex);
LWIP_MEM_ALLOC_PROTECT();
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
- /* run as long as a mem_free disturbed mem_malloc */
+ /* run as long as a mem_free disturbed mem_malloc or mem_trim */
do {
local_mem_free_count = 0;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
mem_free_count = 0;
LWIP_MEM_ALLOC_UNPROTECT();
- /* allow mem_free to run */
+ /* allow mem_free or mem_trim to run */
LWIP_MEM_ALLOC_PROTECT();
if (mem_free_count != 0) {
- local_mem_free_count = mem_free_count;
+ /* If mem_free or mem_trim have run, we have to restart since they
+ could have altered our current struct mem. */
+ local_mem_free_count = 1;
+ break;
}
- mem_free_count = 0;
#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
if ((!mem->used) &&
mem->used = 1;
MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram));
}
-
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+mem_malloc_adjust_lfree:
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
if (mem == lfree) {
+ struct mem *cur = lfree;
/* Find next free block after mem and update lowest free pointer */
- while (lfree->used && lfree != ram_end) {
+ while (cur->used && cur != ram_end) {
+#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT
+ mem_free_count = 0;
LWIP_MEM_ALLOC_UNPROTECT();
/* prevent high interrupt latency... */
LWIP_MEM_ALLOC_PROTECT();
- lfree = (struct mem *)(void *)&ram[lfree->next];
+ if (mem_free_count != 0) {
+ /* If mem_free or mem_trim have run, we have to restart since they
+ could have altered our current struct mem or lfree. */
+ goto mem_malloc_adjust_lfree;
+ }
+#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */
+ cur = (struct mem *)(void *)&ram[cur->next];
}
+ lfree = cur;
LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));
}
LWIP_MEM_ALLOC_UNPROTECT();