|
|
|
|
@ -51,27 +51,58 @@
|
|
|
|
|
|
|
|
|
|
struct memp { |
|
|
|
|
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]; |
|
|
|
|
|
|
|
|
|
#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] = { |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct pbuf)), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct raw_pcb)), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct udp_pcb)), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb)), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen)), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct tcp_seg)), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct netbuf)), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct netconn)), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct tcpip_msg)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct pbuf)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct raw_pcb)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct udp_pcb)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct tcp_pcb)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct tcp_pcb_listen)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct tcp_seg)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct netbuf)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct netconn)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct tcpip_msg)), |
|
|
|
|
#if ARP_QUEUEING |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct etharp_q_entry)), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct etharp_q_entry)), |
|
|
|
|
#endif |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct pbuf)) + MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE), |
|
|
|
|
MEM_ALIGN_SIZE(sizeof(struct sys_timeo)) |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(PBUF_POOL_BUFSIZE), |
|
|
|
|
MEMP_ALIGN_SIZE(sizeof(struct sys_timeo)) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
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) \ |
|
|
|
|
((qty) * (MEMP_SIZE + MEM_ALIGN_SIZE(sizeof(type)))) |
|
|
|
|
((qty) * (MEMP_SIZE + MEMP_ALIGN_SIZE(sizeof(type)))) |
|
|
|
|
|
|
|
|
|
static u8_t memp_memory[MEM_ALIGNMENT - 1 +
|
|
|
|
|
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) + |
|
|
|
|
#endif |
|
|
|
|
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)]; |
|
|
|
|
|
|
|
|
|
#if MEMP_SANITY_CHECK |
|
|
|
|
@ -123,7 +154,7 @@ memp_sanity(void)
|
|
|
|
|
c = 1; |
|
|
|
|
for (n = memp_tab[i]; n != NULL; n = n->next) { |
|
|
|
|
if (n == m && --c < 0) { |
|
|
|
|
return 0; /* LW was: abort(); */ |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -131,6 +162,68 @@ memp_sanity(void)
|
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
#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 |
|
|
|
|
memp_init(void) |
|
|
|
|
@ -155,10 +248,19 @@ memp_init(void)
|
|
|
|
|
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 * |
|
|
|
|
#if MEMP_OVERFLOW_CHECK |
|
|
|
|
memp_malloc_fn(memp_t type, const char* file, const int line) |
|
|
|
|
#else |
|
|
|
|
memp_malloc(memp_t type) |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
struct memp *memp; |
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
SYS_ARCH_PROTECT(old_level); |
|
|
|
|
#if MEMP_OVERFLOW_CHECK >= 2 |
|
|
|
|
memp_overflow_check(); |
|
|
|
|
#endif /* MEMP_OVERFLOW_CHECK >= 2 */ |
|
|
|
|
|
|
|
|
|
memp = memp_tab[type]; |
|
|
|
|
|
|
|
|
|
if (memp != NULL) {
|
|
|
|
|
memp_tab[type] = memp->next;
|
|
|
|
|
memp->next = NULL; |
|
|
|
|
#if MEMP_OVERFLOW_CHECK |
|
|
|
|
memp->file = file; |
|
|
|
|
memp->line = line; |
|
|
|
|
#endif /* MEMP_OVERFLOW_CHECK */ |
|
|
|
|
#if MEMP_STATS |
|
|
|
|
++lwip_stats.memp[type].used; |
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
return (void*)memp; |
|
|
|
|
return (void*)((u8_t*)memp + MEMP_SIZE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
@ -204,9 +313,16 @@ memp_free(memp_t type, void *mem)
|
|
|
|
|
LWIP_ASSERT("memp_free: mem properly aligned", |
|
|
|
|
((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); |
|
|
|
|
|
|
|
|
|
memp = (struct memp *)mem; |
|
|
|
|
memp = (struct memp *)((u8_t*)mem - MEMP_SIZE); |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
lwip_stats.memp[type].used--;
|
|
|
|
|
@ -217,7 +333,7 @@ memp_free(memp_t type, void *mem)
|
|
|
|
|
|
|
|
|
|
#if MEMP_SANITY_CHECK |
|
|
|
|
LWIP_ASSERT("memp sanity", memp_sanity()); |
|
|
|
|
#endif |
|
|
|
|
#endif /* MEMP_SANITY_CHECK */ |
|
|
|
|
|
|
|
|
|
SYS_ARCH_UNPROTECT(old_level); |
|
|
|
|
} |
|
|
|
|
|