diff --git a/CHANGELOG b/CHANGELOG index dac0ea5a..95b8d9cf 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,10 @@ HISTORY ++ New features: + 2009-04-25 Simon Goldschmidt + * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next + bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). + 2009-04-21 Simon Goldschmidt * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static hosts table. New configuration options DNS_LOCAL_HOSTLIST and @@ -88,6 +92,11 @@ HISTORY ++ Bugfixes: + 2009-04-25 Simon Goldschmidt + * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation + when debugging": memp_sizes contained the wrong sizes (including sanity + regions); memp pools for MEM_USE_POOLS were too small + 2009-04-24 Simon Goldschmidt, Frédéric Bernon * inet.c: patch #6765: Fix a small problem with the last changes (incorrect behavior, with with ip address string not ended by a '\0', a space or a diff --git a/src/core/mem.c b/src/core/mem.c index 2ee5cfc7..b5f13ab3 100644 --- a/src/core/mem.c +++ b/src/core/mem.c @@ -67,14 +67,6 @@ #if MEM_USE_POOLS /* lwIP head implemented with different sized pools */ -/** - * This structure is used to save the pool one element came from. - */ -struct mem_helper -{ - memp_t poolnr; -}; - /** * Allocate memory: determine the smallest pool that is big enough * to contain an element of 'size' and get an element from that pool. @@ -85,13 +77,17 @@ struct mem_helper void * mem_malloc(mem_size_t size) { - struct mem_helper *element; + struct memp_malloc_helper *element; memp_t poolnr; + mem_size_t required_size = size + sizeof(struct memp_malloc_helper); for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr++) { +#if MEM_USE_POOLS_TRY_BIGGER_POOL +again: +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ /* is this pool big enough to hold an element of the required size - plus a struct mem_helper that saves the pool this element came from? */ - if ((size + sizeof(struct mem_helper)) <= memp_sizes[poolnr]) { + plus a struct memp_malloc_helper that saves the pool this element came from? */ + if (required_size <= memp_sizes[poolnr]) { break; } } @@ -99,17 +95,23 @@ mem_malloc(mem_size_t size) LWIP_ASSERT("mem_malloc(): no pool is that big!", 0); return NULL; } - element = (struct mem_helper*)memp_malloc(poolnr); + element = (struct memp_malloc_helper*)memp_malloc(poolnr); if (element == NULL) { /* No need to DEBUGF or ASSERT: This error is already taken care of in memp.c */ - /** @todo: we could try a bigger pool if this one is empty! */ +#if MEM_USE_POOLS_TRY_BIGGER_POOL + /** Try a bigger pool if this one is empty! */ + if (poolnr < MEMP_POOL_LAST) { + poolnr++; + goto again; + } +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ return NULL; } /* save the pool number this element came from */ element->poolnr = poolnr; - /* and return a pointer to the memory directly after the struct mem_helper */ + /* and return a pointer to the memory directly after the struct memp_malloc_helper */ element++; return element; @@ -125,12 +127,12 @@ mem_malloc(mem_size_t size) void mem_free(void *rmem) { - struct mem_helper *hmem = (struct mem_helper*)rmem; + struct memp_malloc_helper *hmem = (struct memp_malloc_helper*)rmem; LWIP_ASSERT("rmem != NULL", (rmem != NULL)); LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); - /* get the original struct mem_helper */ + /* get the original struct memp_malloc_helper */ hmem--; LWIP_ASSERT("hmem != NULL", (hmem != NULL)); diff --git a/src/core/memp.c b/src/core/memp.c index 01793ab5..dfc32213 100644 --- a/src/core/memp.c +++ b/src/core/memp.c @@ -122,7 +122,7 @@ static struct memp *memp_tab[MEMP_MAX]; static #endif const u16_t memp_sizes[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) MEMP_ALIGN_SIZE(size), +#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), #include "lwip/memp_std.h" }; @@ -193,7 +193,7 @@ memp_overflow_check_element(struct memp *p, u16_t memp_size) } #endif #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE + memp_size - MEMP_SANITY_REGION_AFTER_ALIGNED; + m = (u8_t*)p + MEMP_SIZE + memp_size; for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) { if (m[k] != 0xcd) { LWIP_ASSERT("detected memp overflow!", 0); @@ -218,7 +218,7 @@ memp_overflow_check_all(void) p = p; for (j = 0; j < memp_num[i]; ++j) { memp_overflow_check_element(p, memp_sizes[i]); - p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i]); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); } } } @@ -242,10 +242,10 @@ memp_overflow_init(void) memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); #endif #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE + memp_sizes[i] - MEMP_SANITY_REGION_AFTER_ALIGNED; + m = (u8_t*)p + MEMP_SIZE + memp_sizes[i]; memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); #endif - p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i]); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); } } } @@ -277,7 +277,11 @@ memp_init(void) for (j = 0; j < memp_num[i]; ++j) { memp->next = memp_tab[i]; memp_tab[i] = memp; - memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]); + memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] +#if MEMP_OVERFLOW_CHECK + + MEMP_SANITY_REGION_AFTER_ALIGNED +#endif + ); } } #if MEMP_OVERFLOW_CHECK @@ -317,8 +321,8 @@ memp_malloc_fn(memp_t type, const char* file, const int line) memp = memp_tab[type]; - if (memp != NULL) { - memp_tab[type] = memp->next; + if (memp != NULL) { + memp_tab[type] = memp->next; #if MEMP_OVERFLOW_CHECK memp->next = NULL; memp->file = file; diff --git a/src/include/lwip/memp.h b/src/include/lwip/memp.h index 45b1f39b..f0d07399 100644 --- a/src/include/lwip/memp.h +++ b/src/include/lwip/memp.h @@ -89,6 +89,14 @@ extern const u16_t memp_sizes[MEMP_MAX]; #else /* MEMP_MEM_MALLOC */ +#if MEM_USE_POOLS +/** This structure is used to save the pool one element came from. */ +struct memp_malloc_helper +{ + memp_t poolnr; +}; +#endif /* MEM_USE_POOLS */ + void memp_init(void); #if MEMP_OVERFLOW_CHECK diff --git a/src/include/lwip/memp_std.h b/src/include/lwip/memp_std.h index c314bf87..34469032 100644 --- a/src/include/lwip/memp_std.h +++ b/src/include/lwip/memp_std.h @@ -10,8 +10,9 @@ * above, then will declare #2 & #3 to be just standard mempools. */ #ifndef LWIP_MALLOC_MEMPOOL -/* This treats "malloc pools" just like any other pool */ -#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, size, "MALLOC_"#size) +/* This treats "malloc pools" just like any other pool. + The pools are a little bigger to provide 'size' as the amount of user data. */ +#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size) #define LWIP_MALLOC_MEMPOOL_START #define LWIP_MALLOC_MEMPOOL_END #endif /* LWIP_MALLOC_MEMPOOL */ diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 984d0235..ebb3c9ab 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -149,11 +149,20 @@ * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set * of memory pools of various sizes. When mem_malloc is called, an element of * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. */ #ifndef MEM_USE_POOLS #define MEM_USE_POOLS 0 #endif +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + /** * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h * that defines additional pools beyond the "standard" ones required