=== 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-19 20:36:54 +0000
@@ -320,11 +320,12 @@
  *
  * @param area Heap area to grow.
  * @param size Gross size to grow (bytes).
+ * @param align Requested alignment of the new area.
  *
  * @return True if successful.
  *
  */
-static bool area_grow(heap_area_t *area, size_t size)
+static bool area_grow(heap_area_t *area, size_t size, size_t align)
 {
 	if (size == 0)
 		return true;
@@ -332,7 +333,8 @@
 	area_check(area);
 	
 	/* New heap area size */
-	size_t gross_size = (size_t) (area->end - area->start) + size;
+	void *aligned_end = ((void*)ALIGN_UP((uintptr_t)area->end + 1, align));
+	size_t gross_size = (size_t) (aligned_end - area->start) + size;
 	size_t asize = ALIGN_UP(gross_size, PAGE_SIZE);
 	void *end = (void *) ((uintptr_t) area->start + asize);
 	
@@ -356,29 +358,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 +639,42 @@
 	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_FIRST_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 +693,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 +714,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

