Index: arch/mips32/src/mm/page.c
===================================================================
--- arch/mips32/src/mm/page.c	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ arch/mips32/src/mm/page.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -43,5 +43,5 @@
 	page_operations = &page_pt_operations;
 	
-	ptl0 = frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME);
+	ptl0 = frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME, NULL);
 	memsetb(ptl0, FRAME_SIZE, 0);
 	
Index: genarch/src/mm/page_pt.c
===================================================================
--- genarch/src/mm/page_pt.c	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ genarch/src/mm/page_pt.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -64,5 +64,5 @@
 
 	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = frame_alloc(FRAME_KA, ONE_FRAME);
+		newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
 		memsetb(newpt, PAGE_SIZE, 0);
 		SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
@@ -73,5 +73,5 @@
 
 	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = frame_alloc(FRAME_KA, ONE_FRAME);
+		newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
 		memsetb(newpt, PAGE_SIZE, 0);
 		SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
@@ -82,5 +82,5 @@
 
 	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = frame_alloc(FRAME_KA, ONE_FRAME);
+		newpt = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
 		memsetb(newpt, PAGE_SIZE, 0);
 		SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
Index: generic/include/mm/frame.h
===================================================================
--- generic/include/mm/frame.h	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ generic/include/mm/frame.h	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -39,6 +39,11 @@
 #define ONE_FRAME	0
 
-#define FRAME_KA	1	/* skip frames conflicting with user address space */
-#define FRAME_PANIC	2	/* panic on failure */
+#define FRAME_KA		1	/* skip frames conflicting with user address space */
+#define FRAME_PANIC		2	/* panic on failure */
+#define FRAME_NON_BLOCKING	4	/* do not panic and do not sleep on failure */
+
+#define FRAME_OK		0	/* frame_alloc return status */
+#define FRAME_NO_MEMORY		1	/* frame_alloc return status */
+#define FRAME_ERROR		2	/* frame_alloc return status */
 
 #define FRAME2ADDR(zone, frame)			((zone)->base + ((frame) - (zone)->frames) * FRAME_SIZE)
@@ -89,6 +94,8 @@
 extern void frame_init(void);
 extern void frame_initialize(frame_t *frame, zone_t *zone);
-__address frame_alloc(int flags, __u8 order);
+
+__address frame_alloc(int flags, __u8 order, int * status);
 extern void frame_free(__address addr);
+
 zone_t * get_zone_by_frame(frame_t * frame);
 
Index: generic/src/cpu/cpu.c
===================================================================
--- generic/src/cpu/cpu.c	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ generic/src/cpu/cpu.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -62,5 +62,5 @@
 
 		for (i=0; i < config.cpu_count; i++) {
-			cpus[i].stack = (__u8 *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME);
+			cpus[i].stack = (__u8 *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME, NULL);
 			
 			cpus[i].id = i;
Index: generic/src/mm/frame.c
===================================================================
--- generic/src/mm/frame.c	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ generic/src/mm/frame.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -84,5 +84,5 @@
  * @return Allocated frame.
  */
-__address frame_alloc(int flags, __u8 order) 
+__address frame_alloc(int flags, __u8 order, int * status) 
 {
 	ipl_t ipl;
@@ -118,4 +118,6 @@
 			panic("Can't allocate frame.\n");
 		
+		
+		
 		/*
 		 * TODO: Sleep until frames are available again.
@@ -124,4 +126,10 @@
 		interrupts_restore(ipl);
 
+		if (flags & FRAME_NON_BLOCKING) {
+			ASSERT(status != NULL);
+			*status = FRAME_NO_MEMORY;
+			return NULL;
+		}
+		
 		panic("Sleep not implemented.\n");
 		goto loop;
@@ -151,4 +159,9 @@
 	if (flags & FRAME_KA)
 		v = PA2KA(v);
+	
+	if (flags & FRAME_NON_BLOCKING) {
+		ASSERT(status != NULL);
+		*status = FRAME_OK;
+	}
 	
 	return v;
Index: generic/src/mm/vm.c
===================================================================
--- generic/src/mm/vm.c	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ generic/src/mm/vm.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -71,5 +71,5 @@
 		
 			src_ptl0 = (pte_t *) PA2KA((__address) GET_PTL0_ADDRESS());
-			dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME);
+			dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, ONE_FRAME, NULL);
 
 //			memsetb((__address) dst_ptl0, PAGE_SIZE, 0);
@@ -117,5 +117,5 @@
 		
 		for (i=0; i<size; i++)
-			a->mapping[i] = frame_alloc(0, ONE_FRAME);
+			a->mapping[i] = frame_alloc(0, ONE_FRAME, NULL);
 		
 		spinlock_initialize(&a->lock, "vm_area_lock");
Index: generic/src/proc/thread.c
===================================================================
--- generic/src/proc/thread.c	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ generic/src/proc/thread.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -174,7 +174,7 @@
 		spinlock_initialize(&t->lock, "thread_t_lock");
 	
-		frame_ks = frame_alloc(FRAME_KA, ONE_FRAME);
+		frame_ks = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
 		if (THREAD_USER_STACK & flags) {
-			frame_us = frame_alloc(FRAME_KA, ONE_FRAME);
+			frame_us = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
 		}
 
Index: kernel.config
===================================================================
--- kernel.config	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ kernel.config	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -82,4 +82,5 @@
 @ "thread/thread1" Thread test 1
 @ "mm/mapping1" Mapping test 1
+@ "mm/falloc1" Frame Allocation test 1
 @ [ARCH=mips32] "debug/mips1" Mips breakpoint-debug test 
 ! CONFIG_TEST (choice)
Index: test/mm/falloc1/test.c
===================================================================
--- test/mm/falloc1/test.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
+++ test/mm/falloc1/test.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2006 Sergey Bondari
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <print.h>
+#include <test.h>
+#include <mm/page.h>
+#include <mm/frame.h>
+#include <arch/mm/page.h>
+#include <arch/types.h>
+#include <debug.h>
+
+#define MAX_FRAMES 1024
+#define MAX_ORDER 8
+#define TEST_RUNS 4
+
+void test(void) {
+	__address frames[MAX_FRAMES];
+	int results[MAX_ORDER+1];
+	
+	int i, order, run;
+	int allocated;
+	int status;
+
+	ASSERT(TEST_RUNS > 1);
+
+	for (run=0;run<=TEST_RUNS;run++) {
+		for (order=0;order<=MAX_ORDER;order++) {
+			printf("Allocating %d frames blocks ... ", 1<<order);
+			allocated = 0;
+			for (i=0;i<MAX_FRAMES>>order;i++) {
+				frames[allocated] = frame_alloc(FRAME_NON_BLOCKING,order, &status);
+				if (status == 0) {
+					allocated++;
+				} else {
+					printf("done. ");
+					break;
+				}
+			}
+		
+			printf("%d blocks alocated.\n", allocated);
+		
+			if (run) {
+				if (results[order] != allocated) {
+					panic("Test failed. Frame leak possible.\n");
+				}
+			} else results[order] = allocated;
+			
+			printf("Deallocating ... ");
+			for (i=0;i<allocated;i++) {
+				frame_free(frames[i]);
+			}
+			printf("done.\n");
+		}
+	}
+
+
+	
+	printf("Test passed\n");
+}
+
Index: test/mm/mapping1/test.c
===================================================================
--- test/mm/mapping1/test.c	(revision 677a6d50fe04baf1fc4de579c24ea8dd8da3099b)
+++ test/mm/mapping1/test.c	(revision f275cb36e9500aaf4935ed3ac6c1ed56b5a25dc3)
@@ -48,6 +48,6 @@
 	printf("Memory management test mapping #1\n");
 
-	frame0 = frame_alloc(FRAME_KA, ONE_FRAME);
-	frame1 = frame_alloc(FRAME_KA, ONE_FRAME);	
+	frame0 = frame_alloc(FRAME_KA, ONE_FRAME, NULL);
+	frame1 = frame_alloc(FRAME_KA, ONE_FRAME, NULL);	
 
 	printf("Writing %L to physical address %P.\n", VALUE0, KA2PA(frame0));
