=== modified file 'uspace/lib/c/generic/malloc.c'
--- uspace/lib/c/generic/malloc.c	2012-07-01 20:27:07 +0000
+++ uspace/lib/c/generic/malloc.c	2012-07-20 15:26:03 +0000
@@ -108,6 +108,9 @@
 #define AREA_LAST_BLOCK_FOOT(area) \
 	(((uintptr_t) (area)->end) - sizeof(heap_block_foot_t))
 
+#define AREA_LAST_BLOCK_HEAD(area) \
+	((uintptr_t) BLOCK_HEAD(((heap_block_foot_t *)AREA_LAST_BLOCK_FOOT(area))))
+
 /** Get header in heap block.
  *
  */
@@ -345,10 +348,19 @@
 	if (ret != EOK)
 		return false;
 	
-	/* Add new free block */
-	size_t net_size = (size_t) (end - area->end);
-	if (net_size > 0)
-		block_init(area->end, net_size, true, area);
+	heap_block_head_t *last_head = (heap_block_head_t *) AREA_LAST_BLOCK_HEAD(area);
+	
+	if (last_head->free) {
+		/* Add the new space to the last block. */
+		size_t net_size = (size_t) (end - area->end) + last_head->size;
+		malloc_assert(net_size > 0);
+		block_init(last_head, net_size, true, area);
+	} else {
+		/* Add new free block */
+		size_t net_size = (size_t) (end - area->end);
+		if (net_size > 0)
+			block_init(area->end, net_size, true, area);
+	}
 	
 	/* Update heap area parameters */
 	area->end = end;
@@ -356,29 +368,6 @@
 	return true;
 }
 
-/** Try to enlarge any of the heap areas
- *
- * Should be called only inside the critical section.
- *
- * @param size Gross size of item to allocate (bytes).
- *
- */
-static bool heap_grow(size_t size)
-{
-	if (size == 0)
-		return true;
-	
-	/* First try to enlarge some existing area */
-	for (heap_area_t *area = first_heap_area; area != NULL;
-	    area = area->next) {
-		if (area_grow(area, size))
-			return true;
-	}
-	
-	/* Eventually try to create a new area */
-	return area_create(AREA_OVERHEAD(size));
-}
-
 /** Try to shrink heap
  *
  * Should be called only inside the critical section.
@@ -660,6 +649,45 @@
 	return NULL;
 }
 
+/** Try to enlarge any of the heap areas.
+ *  If successful, allocate block of the given size in the area.
+ *
+ * Should be called only inside the critical section.
+ *
+ * @param size Gross size of item to allocate (bytes).
+ * @param align Memory address alignment.
+ *
+ */
+static void *heap_grow_and_alloc(size_t size, size_t align)
+{
+	if (size == 0)
+		return NULL;
+		
+	/* First try to enlarge some existing area */
+	for (heap_area_t *area = first_heap_area; area != NULL;
+	    area = area->next) {
+	    
+		if (area_grow(area, size + align)) {
+			heap_block_head_t *first = (heap_block_head_t *) AREA_LAST_BLOCK_HEAD(area);
+			
+			void *addr = malloc_area(area, first, NULL, size, align);
+			malloc_assert(addr != NULL);
+			return addr;
+		}
+	}
+	
+	/* Eventually try to create a new area */
+	if (area_create(AREA_OVERHEAD(size + align))) {
+		heap_block_head_t *first = (heap_block_head_t *) AREA_FIRST_BLOCK_HEAD(last_heap_area);
+		
+		void *addr = malloc_area(last_heap_area, first, NULL, size, align);
+		malloc_assert(addr != NULL);
+		return addr;
+	}
+	
+	return NULL;
+}
+
 /** Allocate a memory block
  *
  * Should be called only inside the critical section.
@@ -678,18 +706,15 @@
 		return NULL;
 	
 	size_t falign = lcm(align, BASE_ALIGN);
-	size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
+	size_t gross_size = GROSS_SIZE(size);
 	
-	bool retry = false;
 	heap_block_head_t *split;
 	
-loop:
-	
 	/* Try the next fit approach */
 	split = next_fit;
 	
 	if (split != NULL) {
-		void *addr = malloc_area(split->area, split, NULL, real_size,
+		void *addr = malloc_area(split->area, split, NULL, gross_size,
 		    falign);
 		
 		if (addr != NULL)
@@ -702,22 +727,15 @@
 		heap_block_head_t *first = (heap_block_head_t *)
 		    AREA_FIRST_BLOCK_HEAD(area);
 		
-		void *addr = malloc_area(area, first, split, real_size,
+		void *addr = malloc_area(area, first, split, gross_size,
 		    falign);
 		
 		if (addr != NULL)
 			return addr;
 	}
 	
-	if (!retry) {
-		/* Try to grow the heap space */
-		if (heap_grow(real_size)) {
-			retry = true;
-			goto loop;
-		}
-	}
-	
-	return NULL;
+	/* Finally, try to grow heap space and allocate in the new area. */
+	return heap_grow_and_alloc(gross_size, falign);
 }
 
 /** Allocate memory by number of elements

