Introduced the option MEM_USE_POOLS to use 4 pools with different sized elements instead of a heap. This both prevents memory fragmentation and gives a higher speed at the cost of more memory consumption. Turned off by default.

This commit is contained in:
goldsimon
2007-06-21 20:12:11 +00:00
parent 065b8c945b
commit 0c18e653e8
6 changed files with 171 additions and 11 deletions

View File

@@ -48,7 +48,79 @@
#include "lwip/stats.h"
#if (MEM_LIBC_MALLOC == 0)
#if !MEM_LIBC_MALLOC
#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.
*
* @param size the size in bytes of the memory needed
* @return a pointer to the allocated memory or NULL if the pool is empty
*/
void *
mem_malloc(mem_size_t size)
{
struct mem_helper *element;
int poolnr = -1;
for (poolnr = MEMP_MEM_POOL_1; poolnr < (MEMP_MEM_POOL_1 + MEM_POOL_COUNT); poolnr++) {
if ((size + sizeof(struct mem_helper)) <= memp_sizes[poolnr]) {
break;
}
}
if (poolnr == -1) {
LWIP_ASSERT("mem_malloc(): no pool is that big!", 0);
return NULL;
}
element = (struct mem_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! */
return NULL;
}
element->poolnr = poolnr;
element++;
return element;
}
/**
* Free memory previously allocated by mem_malloc. Loads the pool number
* and calls memp_free with that pool number to put the element back into
* its pool
*
* @param rmem the memory element to free
*/
void
mem_free(void *rmem)
{
struct mem_helper *hmem = (struct mem_helper*)rmem;
LWIP_ASSERT("rmem != NULL", (rmem != NULL));
LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == MEM_ALIGN(rmem)));
hmem--;
LWIP_ASSERT("hmem != NULL", (hmem != NULL));
LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == MEM_ALIGN(hmem)));
LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX));
memp_free(hmem->poolnr, hmem);
}
#else /* MEM_USE_POOLS */
/* lwIP replacement for your libc malloc() */
/* This does not have to be aligned since for getting its size,
@@ -427,5 +499,5 @@ mem_malloc(mem_size_t size)
return NULL;
}
#endif /* MEM_LIBC_MALLOC == 0 */
#endif /* MEM_USE_POOLS */
#endif /* !MEM_LIBC_MALLOC */

View File

@@ -99,7 +99,10 @@ static struct memp *memp_tab[MEMP_MAX];
#endif /* MEMP_OVERFLOW_CHECK */
static const u16_t memp_sizes[MEMP_MAX] = {
#if !MEM_USE_POOLS
static
#endif
const u16_t memp_sizes[MEMP_MAX] = {
MEMP_ALIGN_SIZE(sizeof(struct pbuf)),
MEMP_ALIGN_SIZE(sizeof(struct raw_pcb)),
MEMP_ALIGN_SIZE(sizeof(struct udp_pcb)),
@@ -113,7 +116,13 @@ static const u16_t memp_sizes[MEMP_MAX] = {
MEMP_ALIGN_SIZE(sizeof(struct etharp_q_entry)),
#endif
MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(PBUF_POOL_BUFSIZE),
MEMP_ALIGN_SIZE(sizeof(struct sys_timeo))
MEMP_ALIGN_SIZE(sizeof(struct sys_timeo)),
#if MEM_USE_POOLS
MEMP_ALIGN_SIZE(MEM_POOL_SIZE_1),
MEMP_ALIGN_SIZE(MEM_POOL_SIZE_2),
MEMP_ALIGN_SIZE(MEM_POOL_SIZE_3),
MEMP_ALIGN_SIZE(MEM_POOL_SIZE_4),
#endif
};
static const u16_t memp_num[MEMP_MAX] = {
@@ -130,7 +139,13 @@ static const u16_t memp_num[MEMP_MAX] = {
MEMP_NUM_ARP_QUEUE,
#endif
PBUF_POOL_SIZE,
MEMP_NUM_SYS_TIMEOUT
MEMP_NUM_SYS_TIMEOUT,
#if MEM_USE_POOLS
MEM_POOL_NUM_1,
MEM_POOL_NUM_2,
MEM_POOL_NUM_3,
MEM_POOL_NUM_4,
#endif
};
#define MEMP_TYPE_SIZE(qty, type) \
@@ -150,8 +165,15 @@ static u8_t memp_memory[MEM_ALIGNMENT - 1 +
MEMP_TYPE_SIZE(MEMP_NUM_ARP_QUEUE, struct etharp_q_entry) +
#endif
MEMP_TYPE_SIZE(PBUF_POOL_SIZE, struct pbuf) +
PBUF_POOL_SIZE * MEMP_ALIGN_SIZE(PBUF_POOL_BUFSIZE) +
MEMP_TYPE_SIZE(MEMP_NUM_SYS_TIMEOUT, struct sys_timeo)];
((PBUF_POOL_SIZE) * MEMP_ALIGN_SIZE(PBUF_POOL_BUFSIZE)) +
MEMP_TYPE_SIZE(MEMP_NUM_SYS_TIMEOUT, struct sys_timeo)
#if MEM_USE_POOLS
+ ((MEM_POOL_NUM_1) * MEMP_ALIGN_SIZE(MEM_POOL_SIZE_1))
+ ((MEM_POOL_NUM_2) * MEMP_ALIGN_SIZE(MEM_POOL_SIZE_2))
+ ((MEM_POOL_NUM_3) * MEMP_ALIGN_SIZE(MEM_POOL_SIZE_3))
+ ((MEM_POOL_NUM_4) * MEMP_ALIGN_SIZE(MEM_POOL_SIZE_4))
#endif
];
#if MEMP_SANITY_CHECK
/**