mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-10-01 04:12:07 +00:00
Addition to patch #5913: decrease size of memp_memory.
Added option MEMP_OVERFLOW_CHECK to check for memp elements to overflow.
This commit is contained in:
parent
cde11f9d9c
commit
a4f4e6e71d
12
CHANGELOG
12
CHANGELOG
@ -23,6 +23,14 @@ HISTORY
|
|||||||
|
|
||||||
++ New features:
|
++ New features:
|
||||||
|
|
||||||
|
2007-05-18 Simon Goldschmidt
|
||||||
|
* opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp
|
||||||
|
elements to overflow. This is achieved by adding some bytes before and after
|
||||||
|
each pool element (increasing their size, of course), filling them with a
|
||||||
|
prominent value and checking them on freeing the element.
|
||||||
|
Set it to 2 to also check every element in every pool each time memp_malloc()
|
||||||
|
or memp_free() is called (slower but more helpful).
|
||||||
|
|
||||||
2007-05-10 Simon Goldschmidt
|
2007-05-10 Simon Goldschmidt
|
||||||
* opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for
|
* opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for
|
||||||
PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce
|
PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce
|
||||||
@ -158,6 +166,10 @@ HISTORY
|
|||||||
|
|
||||||
++ Bug fixes:
|
++ Bug fixes:
|
||||||
|
|
||||||
|
2007-05-18 Simon Goldschmidt
|
||||||
|
* memp.c: addition to patch #5913: smaller pointer was returned but
|
||||||
|
memp_memory was the same size -> did not save memory.
|
||||||
|
|
||||||
2007-05-16 Simon Goldschmidt
|
2007-05-16 Simon Goldschmidt
|
||||||
* loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns
|
* loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns
|
||||||
!= ERR_OK.
|
!= ERR_OK.
|
||||||
|
156
src/core/memp.c
156
src/core/memp.c
@ -51,27 +51,58 @@
|
|||||||
|
|
||||||
struct memp {
|
struct memp {
|
||||||
struct memp *next;
|
struct memp *next;
|
||||||
|
#if MEMP_OVERFLOW_CHECK
|
||||||
|
const char *file;
|
||||||
|
int line;
|
||||||
|
#endif /* MEMP_OVERFLOW_CHECK */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MEMP_SIZE MEM_ALIGN_SIZE(sizeof(struct memp))
|
|
||||||
|
|
||||||
static struct memp *memp_tab[MEMP_MAX];
|
static struct memp *memp_tab[MEMP_MAX];
|
||||||
|
|
||||||
|
#if MEMP_OVERFLOW_CHECK
|
||||||
|
/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning
|
||||||
|
* and at the end of each element, initialize them as 0xcd and check
|
||||||
|
* them later. */
|
||||||
|
/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free,
|
||||||
|
* every single element in each pool is checked!
|
||||||
|
* This is VERY SLOW but also very helpful. */
|
||||||
|
#ifndef MEMP_SANITY_REGION_BEFORE
|
||||||
|
#define MEMP_SANITY_REGION_BEFORE MEM_ALIGN_SIZE(16)
|
||||||
|
#endif /* MEMP_SANITY_REGION_BEFORE*/
|
||||||
|
#ifndef MEMP_SANITY_REGION_AFTER
|
||||||
|
#define MEMP_SANITY_REGION_AFTER MEM_ALIGN_SIZE(16)
|
||||||
|
#endif /* MEMP_SANITY_REGION_AFTER*/
|
||||||
|
|
||||||
|
/* MEMP_SIZE: save space for struct memp and for sanity check */
|
||||||
|
#define MEMP_SIZE (MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE)
|
||||||
|
#define MEMP_ALIGN_SIZE(x) (MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER)
|
||||||
|
|
||||||
|
#else /* MEMP_OVERFLOW_CHECK */
|
||||||
|
|
||||||
|
/* No sanity checks
|
||||||
|
* We don't need to preserve the struct memp while not allocated, so we
|
||||||
|
* can save a little space and set MEMP_SIZE to 0.
|
||||||
|
*/
|
||||||
|
#define MEMP_SIZE 0
|
||||||
|
#define MEMP_ALIGN_SIZE(x) (MEM_ALIGN_SIZE(x))
|
||||||
|
|
||||||
|
#endif /* MEMP_OVERFLOW_CHECK */
|
||||||
|
|
||||||
static const u16_t memp_sizes[MEMP_MAX] = {
|
static const u16_t memp_sizes[MEMP_MAX] = {
|
||||||
MEM_ALIGN_SIZE(sizeof(struct pbuf)),
|
MEMP_ALIGN_SIZE(sizeof(struct pbuf)),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct raw_pcb)),
|
MEMP_ALIGN_SIZE(sizeof(struct raw_pcb)),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct udp_pcb)),
|
MEMP_ALIGN_SIZE(sizeof(struct udp_pcb)),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb)),
|
MEMP_ALIGN_SIZE(sizeof(struct tcp_pcb)),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen)),
|
MEMP_ALIGN_SIZE(sizeof(struct tcp_pcb_listen)),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct tcp_seg)),
|
MEMP_ALIGN_SIZE(sizeof(struct tcp_seg)),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct netbuf)),
|
MEMP_ALIGN_SIZE(sizeof(struct netbuf)),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct netconn)),
|
MEMP_ALIGN_SIZE(sizeof(struct netconn)),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct tcpip_msg)),
|
MEMP_ALIGN_SIZE(sizeof(struct tcpip_msg)),
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
MEM_ALIGN_SIZE(sizeof(struct etharp_q_entry)),
|
MEMP_ALIGN_SIZE(sizeof(struct etharp_q_entry)),
|
||||||
#endif
|
#endif
|
||||||
MEM_ALIGN_SIZE(sizeof(struct pbuf)) + MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE),
|
MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(PBUF_POOL_BUFSIZE),
|
||||||
MEM_ALIGN_SIZE(sizeof(struct sys_timeo))
|
MEMP_ALIGN_SIZE(sizeof(struct sys_timeo))
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u16_t memp_num[MEMP_MAX] = {
|
static const u16_t memp_num[MEMP_MAX] = {
|
||||||
@ -92,7 +123,7 @@ static const u16_t memp_num[MEMP_MAX] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define MEMP_TYPE_SIZE(qty, type) \
|
#define MEMP_TYPE_SIZE(qty, type) \
|
||||||
((qty) * (MEMP_SIZE + MEM_ALIGN_SIZE(sizeof(type))))
|
((qty) * (MEMP_SIZE + MEMP_ALIGN_SIZE(sizeof(type))))
|
||||||
|
|
||||||
static u8_t memp_memory[MEM_ALIGNMENT - 1 +
|
static u8_t memp_memory[MEM_ALIGNMENT - 1 +
|
||||||
MEMP_TYPE_SIZE(MEMP_NUM_PBUF, struct pbuf) +
|
MEMP_TYPE_SIZE(MEMP_NUM_PBUF, struct pbuf) +
|
||||||
@ -108,7 +139,7 @@ static u8_t memp_memory[MEM_ALIGNMENT - 1 +
|
|||||||
MEMP_TYPE_SIZE(MEMP_NUM_ARP_QUEUE, struct etharp_q_entry) +
|
MEMP_TYPE_SIZE(MEMP_NUM_ARP_QUEUE, struct etharp_q_entry) +
|
||||||
#endif
|
#endif
|
||||||
MEMP_TYPE_SIZE(PBUF_POOL_SIZE, struct pbuf) +
|
MEMP_TYPE_SIZE(PBUF_POOL_SIZE, struct pbuf) +
|
||||||
PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) +
|
PBUF_POOL_SIZE * MEMP_ALIGN_SIZE(PBUF_POOL_BUFSIZE) +
|
||||||
MEMP_TYPE_SIZE(MEMP_NUM_SYS_TIMEOUT, struct sys_timeo)];
|
MEMP_TYPE_SIZE(MEMP_NUM_SYS_TIMEOUT, struct sys_timeo)];
|
||||||
|
|
||||||
#if MEMP_SANITY_CHECK
|
#if MEMP_SANITY_CHECK
|
||||||
@ -123,7 +154,7 @@ memp_sanity(void)
|
|||||||
c = 1;
|
c = 1;
|
||||||
for (n = memp_tab[i]; n != NULL; n = n->next) {
|
for (n = memp_tab[i]; n != NULL; n = n->next) {
|
||||||
if (n == m && --c < 0) {
|
if (n == m && --c < 0) {
|
||||||
return 0; /* LW was: abort(); */
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,6 +162,68 @@ memp_sanity(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif /* MEMP_SANITY_CHECK*/
|
#endif /* MEMP_SANITY_CHECK*/
|
||||||
|
#if MEMP_OVERFLOW_CHECK
|
||||||
|
static void
|
||||||
|
memp_overflow_check_single(struct memp *p, u16_t memp_size)
|
||||||
|
{
|
||||||
|
u16_t k;
|
||||||
|
u8_t *m;
|
||||||
|
#if MEMP_SANITY_REGION_BEFORE > 0
|
||||||
|
m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE;
|
||||||
|
for (k = 0; k < MEMP_SANITY_REGION_BEFORE; k++) {
|
||||||
|
if (m[k] != 0xcd) {
|
||||||
|
LWIP_ASSERT("detected memp underflow!", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if MEMP_SANITY_REGION_AFTER > 0
|
||||||
|
m = (u8_t*)p + MEMP_SIZE + memp_size - MEMP_SANITY_REGION_AFTER;
|
||||||
|
for (k = 0; k < MEMP_SANITY_REGION_AFTER; k++) {
|
||||||
|
if (m[k] != 0xcd) {
|
||||||
|
LWIP_ASSERT("detected memp overflow!", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
memp_overflow_check(void)
|
||||||
|
{
|
||||||
|
u16_t i, j;
|
||||||
|
struct memp *p;
|
||||||
|
|
||||||
|
p = MEM_ALIGN(memp_memory);
|
||||||
|
for (i = 0; i < MEMP_MAX; ++i) {
|
||||||
|
p = p;
|
||||||
|
for (j = 0; j < memp_num[i]; ++j) {
|
||||||
|
memp_overflow_check_single(p, memp_sizes[i]);
|
||||||
|
p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
memp_overflow_init(void)
|
||||||
|
{
|
||||||
|
u16_t i, j;
|
||||||
|
struct memp *p;
|
||||||
|
u8_t *m;
|
||||||
|
|
||||||
|
p = MEM_ALIGN(memp_memory);
|
||||||
|
for (i = 0; i < MEMP_MAX; ++i) {
|
||||||
|
p = p;
|
||||||
|
for (j = 0; j < memp_num[i]; ++j) {
|
||||||
|
#if MEMP_SANITY_REGION_BEFORE > 0
|
||||||
|
m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE;
|
||||||
|
memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE);
|
||||||
|
#endif
|
||||||
|
#if MEMP_SANITY_REGION_AFTER > 0
|
||||||
|
m = (u8_t*)p + MEMP_SIZE + memp_sizes[i] - MEMP_SANITY_REGION_AFTER;
|
||||||
|
memset(m, 0xcd, MEMP_SANITY_REGION_AFTER);
|
||||||
|
#endif
|
||||||
|
p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MEMP_OVERFLOW_CHECK */
|
||||||
|
|
||||||
void
|
void
|
||||||
memp_init(void)
|
memp_init(void)
|
||||||
@ -155,10 +248,19 @@ memp_init(void)
|
|||||||
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_overflow_init();
|
||||||
|
/* check everything a first time to see if it worked */
|
||||||
|
memp_overflow_check();
|
||||||
|
#endif /* MEMP_OVERFLOW_CHECK */
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
#if MEMP_OVERFLOW_CHECK
|
||||||
|
memp_malloc_fn(memp_t type, const char* file, const int line)
|
||||||
|
#else
|
||||||
memp_malloc(memp_t type)
|
memp_malloc(memp_t type)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct memp *memp;
|
struct memp *memp;
|
||||||
SYS_ARCH_DECL_PROTECT(old_level);
|
SYS_ARCH_DECL_PROTECT(old_level);
|
||||||
@ -166,12 +268,19 @@ memp_malloc(memp_t type)
|
|||||||
LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
|
LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
|
||||||
|
|
||||||
SYS_ARCH_PROTECT(old_level);
|
SYS_ARCH_PROTECT(old_level);
|
||||||
|
#if MEMP_OVERFLOW_CHECK >= 2
|
||||||
|
memp_overflow_check();
|
||||||
|
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
|
||||||
|
|
||||||
memp = memp_tab[type];
|
memp = memp_tab[type];
|
||||||
|
|
||||||
if (memp != NULL) {
|
if (memp != NULL) {
|
||||||
memp_tab[type] = memp->next;
|
memp_tab[type] = memp->next;
|
||||||
memp->next = NULL;
|
memp->next = NULL;
|
||||||
|
#if MEMP_OVERFLOW_CHECK
|
||||||
|
memp->file = file;
|
||||||
|
memp->line = line;
|
||||||
|
#endif /* MEMP_OVERFLOW_CHECK */
|
||||||
#if MEMP_STATS
|
#if MEMP_STATS
|
||||||
++lwip_stats.memp[type].used;
|
++lwip_stats.memp[type].used;
|
||||||
if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
|
if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
|
||||||
@ -189,7 +298,7 @@ memp_malloc(memp_t type)
|
|||||||
|
|
||||||
SYS_ARCH_UNPROTECT(old_level);
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
|
|
||||||
return (void*)memp;
|
return (void*)((u8_t*)memp + MEMP_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -204,9 +313,16 @@ memp_free(memp_t type, void *mem)
|
|||||||
LWIP_ASSERT("memp_free: mem properly aligned",
|
LWIP_ASSERT("memp_free: mem properly aligned",
|
||||||
((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
|
((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
|
||||||
|
|
||||||
memp = (struct memp *)mem;
|
memp = (struct memp *)((u8_t*)mem - MEMP_SIZE);
|
||||||
|
|
||||||
SYS_ARCH_PROTECT(old_level);
|
SYS_ARCH_PROTECT(old_level);
|
||||||
|
#if MEMP_OVERFLOW_CHECK
|
||||||
|
#if MEMP_OVERFLOW_CHECK >= 2
|
||||||
|
memp_overflow_check();
|
||||||
|
#else
|
||||||
|
memp_overflow_check_single(memp, memp_sizes[type]);
|
||||||
|
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
|
||||||
|
#endif /* MEMP_OVERFLOW_CHECK */
|
||||||
|
|
||||||
#if MEMP_STATS
|
#if MEMP_STATS
|
||||||
lwip_stats.memp[type].used--;
|
lwip_stats.memp[type].used--;
|
||||||
@ -217,7 +333,7 @@ memp_free(memp_t type, void *mem)
|
|||||||
|
|
||||||
#if MEMP_SANITY_CHECK
|
#if MEMP_SANITY_CHECK
|
||||||
LWIP_ASSERT("memp sanity", memp_sanity());
|
LWIP_ASSERT("memp sanity", memp_sanity());
|
||||||
#endif
|
#endif /* MEMP_SANITY_CHECK */
|
||||||
|
|
||||||
SYS_ARCH_UNPROTECT(old_level);
|
SYS_ARCH_UNPROTECT(old_level);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,12 @@ typedef enum {
|
|||||||
|
|
||||||
void memp_init(void);
|
void memp_init(void);
|
||||||
|
|
||||||
|
#if MEMP_OVERFLOW_CHECK
|
||||||
|
void *memp_malloc_fn(memp_t type, const char* file, const int line);
|
||||||
|
#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__)
|
||||||
|
#else
|
||||||
void *memp_malloc(memp_t type);
|
void *memp_malloc(memp_t type);
|
||||||
|
#endif
|
||||||
void memp_free(memp_t type, void *mem);
|
void memp_free(memp_t type, void *mem);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -84,8 +84,18 @@ a lot of data that needs to be copied, this should be set high. */
|
|||||||
#define MEM_SIZE 1600
|
#define MEM_SIZE 1600
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* MEMP_OVERFLOW_CHECK: memp overflow protection
|
||||||
|
* reserves a configurable amount of bytes before and after each memp
|
||||||
|
* element in every pool and fills it with a prominent default value.
|
||||||
|
* MEMP_OVERFLOW_CHECK = 1 checks each element when it is freed
|
||||||
|
* MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time
|
||||||
|
* memp_malloc() or memp_free() is called (useful but slow!) */
|
||||||
|
#ifndef MEMP_OVERFLOW_CHECK
|
||||||
|
#define MEMP_OVERFLOW_CHECK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef MEMP_SANITY_CHECK
|
#ifndef MEMP_SANITY_CHECK
|
||||||
#define MEMP_SANITY_CHECK 0
|
#define MEMP_SANITY_CHECK 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
|
||||||
|
Loading…
Reference in New Issue
Block a user