Index: mem.c
===================================================================
RCS file: /sources/lwip/lwip/src/core/mem.c,v
retrieving revision 1.31
diff -u -r1.31 mem.c
--- mem.c	30 Mar 2007 08:47:04 -0000	1.31
+++ mem.c	3 May 2007 17:45:51 -0000
@@ -68,7 +68,7 @@
 static struct mem *ram_end;
 #if 1
 /* 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
 /* Christiaan alignment fix */
 static u8_t *ram;
@@ -244,7 +244,7 @@
   return rmem;
 }
 
-#if 1
+#if 0
 /**
  * Adam's mem_malloc(), suffers from bug #17922
  * Set if to 0 for alternative mem_malloc().
@@ -348,57 +348,73 @@
   for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE - size; ptr = ((struct mem *)&ram[ptr])->next) {
     mem = (struct mem *)&ram[ptr];
 
-    if (!mem->used) {
-
-      ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
-
-      if (mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) >= size) {
-        /* split large block, create empty remainder */
-        mem->next = ptr2;
-        mem->used = 1;
+    if ((!mem->used) &&
+        (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
+      /* mem is not used and at least perfect fit is possible */
+
+      if (mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) > size) {
+        /* split large block, create empty remainder,
+           remainder must be large enough to contain data: if
+           mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size,
+           struct mem will fit in but no data between mem2 and mem2->next
+         */
+        ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
         /* create mem2 struct */
         mem2 = (struct mem *)&ram[ptr2];
         mem2->used = 0;
         mem2->next = mem->next;
         mem2->prev = ptr;
+        mem->next = ptr2;
+        mem->used = 1;
 
         if (mem2->next != MEM_SIZE) {
           ((struct mem *)&ram[mem2->next])->prev = ptr2;
         }
-      }
-      else if (mem->next - (ptr + SIZEOF_STRUCT_MEM) > size) {
-        /* near fit, no split, no mem2 creation,
-           round up to mem->next */
-        ptr2 = mem->next;
-        mem->used = 1;
-      }
-      else if (mem->next - (ptr + SIZEOF_STRUCT_MEM) == size) {
-        /* exact fit, do not split, no mem2 creation */
-        mem->next = ptr2;
+      } else if (mem->next - (ptr + SIZEOF_STRUCT_MEM) > size) {
+        /* near fit: do not split but move mem->next directly behind mem */
+        mem2 = (struct mem *)&ram[mem->next];
+        if (mem2->used) {
+          /* can't move mem2, splitting not possible
+             -> memory between mem and mem2 will be 'lost' */
+          mem->used = 1;
+        } else {
+          mem_size_t next2;
+          /* 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;
       }
 
-      if (mem->used) {
 #if MEM_STATS
-        lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);
-        if (lwip_stats.mem.max < ptr2) {
-          lwip_stats.mem.max = ptr2;
-        }
+      lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM);
+      if (lwip_stats.mem.max < lwip_stats.mem.used) {
+        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);
+      if (mem == lfree) {
+        /* Find next free block after mem */
+        while (lfree->used && lfree != ram_end) {
+          lfree = (struct mem *)&ram[lfree->next];
         }
-        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;
+        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);
+      return (u8_t *)mem + SIZEOF_STRUCT_MEM;
     }
   }
   LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size));
