Another attempt to fix bug #17922

This commit is contained in:
goldsimon 2007-05-07 19:48:29 +00:00
parent 79d9b36ece
commit 824ef1ff2c
2 changed files with 64 additions and 41 deletions

View File

@ -129,6 +129,9 @@ HISTORY
++ Bug fixes: ++ Bug fixes:
2007-05-07 Simon Goldschmidt
* mem.c: Another attempt to fix bug #17922.
2007-05-04 Simon Goldschmidt 2007-05-04 Simon Goldschmidt
* pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy()
implementation so that it can be reused (don't allocate the target implementation so that it can be reused (don't allocate the target

View File

@ -66,9 +66,9 @@ struct mem {
}; };
static struct mem *ram_end; static struct mem *ram_end;
#if 1 #if 0
/* Adam original */ /* Adam original */
static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT]; static u8_t ram[MEM_SIZE + (2*sizeof(struct mem) + MEM_ALIGNMENT)];
#else #else
/* Christiaan alignment fix */ /* Christiaan alignment fix */
static u8_t *ram; static u8_t *ram;
@ -76,7 +76,7 @@ static struct mem ram_heap[1 + ( (MEM_SIZE + sizeof(struct mem) - 1) / sizeof(st
#endif #endif
#define MIN_SIZE 12 #define MIN_SIZE 12
#if 0 /* this one does not align correctly for some, resulting in crashes */ #if 1 /* this one does not align correctly for some, resulting in crashes */
#define SIZEOF_STRUCT_MEM (unsigned int)MEM_ALIGN_SIZE(sizeof(struct mem)) #define SIZEOF_STRUCT_MEM (unsigned int)MEM_ALIGN_SIZE(sizeof(struct mem))
#else #else
#define SIZEOF_STRUCT_MEM (sizeof(struct mem) + \ #define SIZEOF_STRUCT_MEM (sizeof(struct mem) + \
@ -126,7 +126,9 @@ mem_init(void)
{ {
struct mem *mem; struct mem *mem;
#if 1 LWIP_ASSERT("Sanity check alignment", (SIZEOF_STRUCT_MEM % (MEM_ALIGNMENT-1)) == 0);
#if 0
/* Adam original */ /* Adam original */
#else #else
/* Christiaan alignment fix */ /* Christiaan alignment fix */
@ -160,6 +162,7 @@ mem_free(void *rmem)
LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n")); LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n"));
return; return;
} }
LWIP_ASSERT("Sanity check alignment", (((mem_ptr_t)rmem) % (MEM_ALIGNMENT-1)) == 0);
sys_sem_wait(mem_sem); sys_sem_wait(mem_sem);
@ -244,7 +247,7 @@ mem_realloc(void *rmem, mem_size_t newsize)
return rmem; return rmem;
} }
#if 1 #if 0
/** /**
* Adam's mem_malloc(), suffers from bug #17922 * Adam's mem_malloc(), suffers from bug #17922
* Set if to 0 for alternative mem_malloc(). * Set if to 0 for alternative mem_malloc().
@ -348,57 +351,74 @@ mem_malloc(mem_size_t size)
for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE - size; ptr = ((struct mem *)&ram[ptr])->next) { for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE - size; ptr = ((struct mem *)&ram[ptr])->next) {
mem = (struct mem *)&ram[ptr]; mem = (struct mem *)&ram[ptr];
if (!mem->used) { if ((!mem->used) &&
(mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
/* mem is not used and at least perfect fit is possible */
ptr2 = ptr + SIZEOF_STRUCT_MEM + size; if (mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) > size) {
/* split large block, create empty remainder,
if (mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) >= size) { remainder must be large enough to contain data: if
/* split large block, create empty remainder */ mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
mem->next = ptr2; struct mem will fit in but no data between mem2 and mem2->next
mem->used = 1; */
ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
/* create mem2 struct */ /* create mem2 struct */
mem2 = (struct mem *)&ram[ptr2]; mem2 = (struct mem *)&ram[ptr2];
mem2->used = 0; mem2->used = 0;
mem2->next = mem->next; mem2->next = mem->next;
mem2->prev = ptr; mem2->prev = ptr;
mem->next = ptr2;
mem->used = 1;
if (mem2->next != MEM_SIZE) { if (mem2->next != MEM_SIZE) {
((struct mem *)&ram[mem2->next])->prev = ptr2; ((struct mem *)&ram[mem2->next])->prev = ptr2;
} }
} } else if (mem->next - (ptr + SIZEOF_STRUCT_MEM) > size) {
else if (mem->next - (ptr + SIZEOF_STRUCT_MEM) > size) { /* near fit: do not split but move mem->next directly behind mem */
/* near fit, no split, no mem2 creation, mem2 = (struct mem *)&ram[mem->next];
round up to mem->next */ if (mem2->used) {
ptr2 = mem->next; /* can't move mem2, splitting not possible
mem->used = 1; -> memory between mem and mem2 will be 'lost' */
} mem->used = 1;
else if (mem->next - (ptr + SIZEOF_STRUCT_MEM) == size) { } else {
/* exact fit, do not split, no mem2 creation */ mem_size_t next2;
mem->next = ptr2; /* remember the next pointer */
next2 = mem2->next;
ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
/* create mem2 struct */
mem2 = (struct mem *)&ram[ptr2];
mem2->used = 0;
/* insert the old next pointer */
mem2->next = next2;
mem2->prev = ptr;
mem->next = ptr2;
mem->used = 1;
}
} else {
/* exact fit: do not split, no mem2 creation */
mem->used = 1; mem->used = 1;
} }
if (mem->used) {
#if MEM_STATS #if MEM_STATS
lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM); lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);
if (lwip_stats.mem.max < ptr2) { if (lwip_stats.mem.max < lwip_stats.mem.used) {
lwip_stats.mem.max = ptr2; lwip_stats.mem.max = lwip_stats.mem.used;
}
#endif /* MEM_STATS */
if (mem == lfree) {
/* Find next free block after mem */
while (lfree->used && lfree != ram_end) {
lfree = (struct mem *)&ram[lfree->next];
}
LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used);
}
sys_sem_signal(mem_sem);
LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
(mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
return (u8_t *)mem + SIZEOF_STRUCT_MEM;
} }
#endif /* MEM_STATS */
if (mem == lfree) {
/* Find next free block after mem */
while (lfree->used && lfree != ram_end) {
lfree = (struct mem *)&ram[lfree->next];
}
LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used)));
}
sys_sem_signal(mem_sem);
LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
(mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
LWIP_ASSERT("Sanity check alignment", (((mem_ptr_t)mem) % (MEM_ALIGNMENT-1)) == 0);
return (u8_t *)mem + SIZEOF_STRUCT_MEM;
} }
} }
LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));