Index: genarch/include/mm/page_ht.h
===================================================================
--- genarch/include/mm/page_ht.h	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ genarch/include/mm/page_ht.h	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -71,5 +71,5 @@
 
 extern page_mapping_operations_t ht_mapping_operations;
-extern spinlock_t page_ht_lock;
+extern mutex_t page_ht_lock;
 extern hash_table_t page_ht;
 extern hash_table_operations_t ht_operations;
Index: genarch/src/mm/as_ht.c
===================================================================
--- genarch/src/mm/as_ht.c	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ genarch/src/mm/as_ht.c	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -40,5 +40,5 @@
 #include <memstr.h>
 #include <adt/hash_table.h>
-#include <synch/spinlock.h>
+#include <synch/mutex.h>
 
 static pte_t *ht_create(int flags);
@@ -67,4 +67,5 @@
 	if (flags & FLAG_AS_KERNEL) {
 		hash_table_create(&page_ht, PAGE_HT_ENTRIES, 2, &ht_operations);
+		mutex_initialize(&page_ht_lock);
 	}
 	return NULL;
@@ -82,6 +83,6 @@
 {
 	if (lock)
-		spinlock_lock(&as->lock);
-	spinlock_lock(&page_ht_lock);
+		mutex_lock(&as->lock);
+	mutex_lock(&page_ht_lock);
 }
 
@@ -96,6 +97,6 @@
 void ht_unlock(as_t *as, bool unlock)
 {
-	spinlock_unlock(&page_ht_lock);
+	mutex_unlock(&page_ht_lock);
 	if (unlock)
-		spinlock_unlock(&as->lock);
+		mutex_unlock(&as->lock);
 }
Index: genarch/src/mm/as_pt.c
===================================================================
--- genarch/src/mm/as_pt.c	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ genarch/src/mm/as_pt.c	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -36,4 +36,5 @@
 #include <mm/frame.h>
 #include <mm/as.h>
+#include <synch/mutex.h>
 #include <arch/mm/page.h>
 #include <arch/mm/as.h>
@@ -79,5 +80,5 @@
 		 
 		ipl = interrupts_disable();
-		spinlock_lock(&AS_KERNEL->lock);		
+		mutex_lock(&AS_KERNEL->lock);		
 		src_ptl0 = (pte_t *) PA2KA((__address) AS_KERNEL->page_table);
 
@@ -87,5 +88,5 @@
 		memsetb((__address) dst_ptl0, PAGE_SIZE, 0);
 		memcpy((void *) dst, (void *) src, PAGE_SIZE - (src - (__address) src_ptl0));
-		spinlock_unlock(&AS_KERNEL->lock);
+		mutex_unlock(&AS_KERNEL->lock);
 		interrupts_restore(ipl);
 	}
@@ -105,5 +106,5 @@
 {
 	if (lock)
-		spinlock_lock(&as->lock);
+		mutex_lock(&as->lock);
 }
 
@@ -119,4 +120,4 @@
 {
 	if (unlock)
-		spinlock_unlock(&as->lock);
+		mutex_unlock(&as->lock);
 }
Index: genarch/src/mm/asid.c
===================================================================
--- genarch/src/mm/asid.c	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ genarch/src/mm/asid.c	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -58,4 +58,5 @@
 #include <arch/mm/asid.h>
 #include <synch/spinlock.h>
+#include <synch/mutex.h>
 #include <arch.h>
 #include <adt/list.h>
@@ -104,5 +105,5 @@
 		
 		as = list_get_instance(tmp, as_t, inactive_as_with_asid_link);
-		spinlock_lock(&as->lock);
+		mutex_lock_active(&as->lock);
 
 		/*
@@ -118,5 +119,5 @@
 		 */
 		as->asid = ASID_INVALID;
-		spinlock_unlock(&as->lock);
+		mutex_unlock(&as->lock);
 
 		/*
Index: genarch/src/mm/page_ht.c
===================================================================
--- genarch/src/mm/page_ht.c	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ genarch/src/mm/page_ht.c	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -62,5 +62,5 @@
  * locks.
  */
-SPINLOCK_INITIALIZE(page_ht_lock);
+mutex_t page_ht_lock;
 
 /**
Index: generic/include/mm/as.h
===================================================================
--- generic/include/mm/as.h	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ generic/include/mm/as.h	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -45,4 +45,5 @@
 #include <typedefs.h>
 #include <synch/spinlock.h>
+#include <synch/mutex.h>
 #include <adt/list.h>
 #include <adt/btree.h>
@@ -67,7 +68,8 @@
 #define AS_AREA_ATTR_PARTIAL	1	/* Not fully initialized area. */
 
-#define AS_PF_FAULT		0	/**< The page fault was not resolved by asp_page_fault(). */
+#define AS_PF_FAULT		0	/**< The page fault was not resolved by as_page_fault(). */
 #define AS_PF_OK		1	/**< The page fault was resolved by as_page_fault(). */
-#define AS_PF_DEFER		2	/**< The page fault was caused by memcpy_from_uspace(). */
+#define AS_PF_DEFER		2	/**< The page fault was caused by memcpy_from_uspace()
+					     or memcpy_to_uspace(). */
 
 /** Address space area structure.
@@ -77,5 +79,5 @@
  */
 struct as_area {
-	SPINLOCK_DECLARE(lock);
+	mutex_t lock;
 	int flags;		/**< Flags related to the memory represented by the address space area. */
 	int attributes;		/**< Attributes related to the address space area itself. */
@@ -92,8 +94,8 @@
  */
 struct as {
-	/** Protected by asidlock. Must be acquired before as->lock. */
+	/** Protected by asidlock. */
 	link_t inactive_as_with_asid_link;
 
-	SPINLOCK_DECLARE(lock);
+	mutex_t lock;
 
 	/** Number of processors on wich is this address space active. */
Index: generic/include/synch/mutex.h
===================================================================
--- generic/include/synch/mutex.h	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ generic/include/synch/mutex.h	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -45,5 +45,7 @@
 #define mutex_lock_timeout(mtx,usec) \
 	_mutex_lock_timeout((mtx),(usec),SYNCH_NON_BLOCKING)
-	
+#define mutex_lock_active(mtx) \
+	while (mutex_trylock((mtx)) != ESYNCH_OK_ATOMIC)
+
 extern void mutex_initialize(mutex_t *mtx);
 extern int _mutex_lock_timeout(mutex_t *mtx, __u32 usec, int trylock);
Index: generic/include/typedefs.h
===================================================================
--- generic/include/typedefs.h	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ generic/include/typedefs.h	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -64,16 +64,11 @@
 typedef struct futex futex_t;
 
-typedef struct chunk chunk_t;
-
 typedef struct buddy_system buddy_system_t;
 typedef struct buddy_system_operations buddy_system_operations_t;
 
-typedef enum as_area_type as_area_type_t;
 typedef struct as_area as_area_t;
 typedef struct as as_t;
 
 typedef struct link link_t;
-
-typedef char *char_ptr;
 
 typedef struct the the_t;
Index: generic/src/mm/as.c
===================================================================
--- generic/src/mm/as.c	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ generic/src/mm/as.c	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -55,4 +55,5 @@
 #include <arch/mm/asid.h>
 #include <synch/spinlock.h>
+#include <synch/mutex.h>
 #include <adt/list.h>
 #include <adt/btree.h>
@@ -75,5 +76,5 @@
 as_operations_t *as_operations = NULL;
 
-/** Address space lock. It protects inactive_as_with_asid_head. */
+/** Address space lock. It protects inactive_as_with_asid_head. Must be acquired before as_t mutex. */
 SPINLOCK_INITIALIZE(as_lock);
 
@@ -111,5 +112,5 @@
 	as = (as_t *) malloc(sizeof(as_t), 0);
 	link_initialize(&as->inactive_as_with_asid_link);
-	spinlock_initialize(&as->lock, "as_lock");
+	mutex_initialize(&as->lock);
 	btree_create(&as->as_area_btree);
 	
@@ -163,8 +164,8 @@
 	
 	ipl = interrupts_disable();
-	spinlock_lock(&as->lock);
+	mutex_lock(&as->lock);
 	
 	if (!check_area_conflicts(as, base, size, NULL)) {
-		spinlock_unlock(&as->lock);
+		mutex_unlock(&as->lock);
 		interrupts_restore(ipl);
 		return NULL;
@@ -173,5 +174,5 @@
 	a = (as_area_t *) malloc(sizeof(as_area_t), 0);
 
-	spinlock_initialize(&a->lock, "as_area_lock");
+	mutex_initialize(&a->lock);
 	
 	a->flags = flags;
@@ -182,5 +183,5 @@
 	btree_insert(&as->as_area_btree, base, (void *) a, NULL);
 
-	spinlock_unlock(&as->lock);
+	mutex_unlock(&as->lock);
 	interrupts_restore(ipl);
 
@@ -204,5 +205,5 @@
 	
 	ipl = interrupts_disable();
-	spinlock_lock(&as->lock);
+	mutex_lock(&as->lock);
 	
 	/*
@@ -211,5 +212,5 @@
 	area = find_area_and_lock(as, address);
 	if (!area) {
-		spinlock_unlock(&as->lock);
+		mutex_unlock(&as->lock);
 		interrupts_restore(ipl);
 		return ENOENT;
@@ -221,6 +222,6 @@
 		 * with memory mapped devices is not supported.
 		 */
-		spinlock_unlock(&area->lock);
-		spinlock_unlock(&as->lock);
+		mutex_unlock(&area->lock);
+		mutex_unlock(&as->lock);
 		interrupts_restore(ipl);
 		return ENOTSUP;
@@ -232,6 +233,6 @@
 		 * Zero size address space areas are not allowed.
 		 */
-		spinlock_unlock(&area->lock);
-		spinlock_unlock(&as->lock);
+		mutex_unlock(&area->lock);
+		mutex_unlock(&as->lock);
 		interrupts_restore(ipl);
 		return EPERM;
@@ -279,6 +280,6 @@
 		 */
 		if (!check_area_conflicts(as, address, pages * PAGE_SIZE, area)) {
-			spinlock_unlock(&area->lock);
-			spinlock_unlock(&as->lock);		
+			mutex_unlock(&area->lock);
+			mutex_unlock(&as->lock);		
 			interrupts_restore(ipl);
 			return EADDRNOTAVAIL;
@@ -288,6 +289,6 @@
 	area->pages = pages;
 	
-	spinlock_unlock(&area->lock);
-	spinlock_unlock(&as->lock);
+	mutex_unlock(&area->lock);
+	mutex_unlock(&as->lock);
 	interrupts_restore(ipl);
 
@@ -310,9 +311,9 @@
 
 	ipl = interrupts_disable();
-	spinlock_lock(&as->lock);
+	mutex_lock(&as->lock);
 
 	area = find_area_and_lock(as, address);
 	if (!area) {
-		spinlock_unlock(&as->lock);
+		mutex_unlock(&as->lock);
 		interrupts_restore(ipl);
 		return ENOENT;
@@ -351,5 +352,5 @@
 
 	area->attributes |= AS_AREA_ATTR_PARTIAL;
-	spinlock_unlock(&area->lock);
+	mutex_unlock(&area->lock);
 
 	/*
@@ -360,5 +361,5 @@
 	free(area);
 	
-	spinlock_unlock(&AS->lock);
+	mutex_unlock(&AS->lock);
 	interrupts_restore(ipl);
 	return 0;
@@ -398,5 +399,5 @@
 	src_as = src_task->as;
 	
-	spinlock_lock(&src_as->lock);
+	mutex_lock(&src_as->lock);
 	src_area = find_area_and_lock(src_as, src_base);
 	if (!src_area) {
@@ -405,5 +406,5 @@
 		 */
 		spinlock_unlock(&src_task->lock);
-		spinlock_unlock(&src_as->lock);
+		mutex_unlock(&src_as->lock);
 		interrupts_restore(ipl);
 		return ENOENT;
@@ -411,6 +412,6 @@
 	src_size = src_area->pages * PAGE_SIZE;
 	src_flags = src_area->flags;
-	spinlock_unlock(&src_area->lock);
-	spinlock_unlock(&src_as->lock);
+	mutex_unlock(&src_area->lock);
+	mutex_unlock(&src_as->lock);
 
 
@@ -442,9 +443,9 @@
 	 */
 	if (AS < src_as) {
-		spinlock_lock(&AS->lock);
-		spinlock_lock(&src_as->lock);
+		mutex_lock(&AS->lock);
+		mutex_lock(&src_as->lock);
 	} else {
-		spinlock_lock(&AS->lock);
-		spinlock_lock(&src_as->lock);
+		mutex_lock(&AS->lock);
+		mutex_lock(&src_as->lock);
 	}
 	
@@ -476,10 +477,10 @@
 	 * attribute.
 	 */	
-	spinlock_lock(&dst_area->lock);
+	mutex_lock(&dst_area->lock);
 	dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
-	spinlock_unlock(&dst_area->lock);
-	
-	spinlock_unlock(&AS->lock);
-	spinlock_unlock(&src_as->lock);
+	mutex_unlock(&dst_area->lock);
+	
+	mutex_unlock(&AS->lock);
+	mutex_unlock(&src_as->lock);
 	interrupts_restore(ipl);
 	
@@ -512,5 +513,5 @@
 	page_mapping_insert(as, page, frame, get_area_flags(area));
 	
-	spinlock_unlock(&area->lock);
+	mutex_unlock(&area->lock);
 	page_table_unlock(as, true);
 	interrupts_restore(ipl);
@@ -533,7 +534,10 @@
 	__address frame;
 	
+	if (!THREAD)
+		return 0;
+		
 	ASSERT(AS);
 
-	spinlock_lock(&AS->lock);
+	mutex_lock(&AS->lock);
 	area = find_area_and_lock(AS, page);	
 	if (!area) {
@@ -542,5 +546,5 @@
 		 * Signal page fault to low-level handler.
 		 */
-		spinlock_unlock(&AS->lock);
+		mutex_unlock(&AS->lock);
 		goto page_fault;
 	}
@@ -551,6 +555,6 @@
 		 * Avoid possible race by returning error.
 		 */
-		spinlock_unlock(&area->lock);
-		spinlock_unlock(&AS->lock);
+		mutex_unlock(&area->lock);
+		mutex_unlock(&AS->lock);
 		goto page_fault;		
 	}
@@ -568,6 +572,6 @@
 		if (PTE_PRESENT(pte)) {
 			page_table_unlock(AS, false);
-			spinlock_unlock(&area->lock);
-			spinlock_unlock(&AS->lock);
+			mutex_unlock(&area->lock);
+			mutex_unlock(&AS->lock);
 			return 1;
 		}
@@ -599,6 +603,6 @@
 	page_table_unlock(AS, false);
 	
-	spinlock_unlock(&area->lock);
-	spinlock_unlock(&AS->lock);
+	mutex_unlock(&area->lock);
+	mutex_unlock(&AS->lock);
 	return AS_PF_OK;
 
@@ -622,4 +626,7 @@
 /** Switch address spaces.
  *
+ * Note that this function cannot sleep as it is essentially a part of
+ * the scheduling. Sleeping here would lead to deadlock on wakeup.
+ *
  * @param old Old address space or NULL.
  * @param new New address space.
@@ -637,5 +644,5 @@
 	 */	
 	if (old) {
-		spinlock_lock(&old->lock);
+		mutex_lock_active(&old->lock);
 		ASSERT(old->refcount);
 		if((--old->refcount == 0) && (old != AS_KERNEL)) {
@@ -649,5 +656,5 @@
 			 list_append(&old->inactive_as_with_asid_link, &inactive_as_with_asid_head);
 		}
-		spinlock_unlock(&old->lock);
+		mutex_unlock(&old->lock);
 	}
 
@@ -655,5 +662,5 @@
 	 * Second, prepare the new address space.
 	 */
-	spinlock_lock(&new->lock);
+	mutex_lock_active(&new->lock);
 	if ((new->refcount++ == 0) && (new != AS_KERNEL)) {
 		if (new->asid != ASID_INVALID)
@@ -663,5 +670,5 @@
 	}
 	SET_PTL0_ADDRESS(new->page_table);
-	spinlock_unlock(&new->lock);
+	mutex_unlock(&new->lock);
 
 	if (needs_asid) {
@@ -673,7 +680,7 @@
 		
 		asid = asid_get();
-		spinlock_lock(&new->lock);
+		mutex_lock_active(&new->lock);
 		new->asid = asid;
-		spinlock_unlock(&new->lock);
+		mutex_unlock(&new->lock);
 	}
 	spinlock_unlock(&as_lock);
@@ -799,5 +806,5 @@
 	if (a) {
 		/* va is the base address of an address space area */
-		spinlock_lock(&a->lock);
+		mutex_lock(&a->lock);
 		return a;
 	}
@@ -812,9 +819,9 @@
 	for (i = 0; i < leaf->keys; i++) {
 		a = (as_area_t *) leaf->value[i];
-		spinlock_lock(&a->lock);
+		mutex_lock(&a->lock);
 		if ((a->base <= va) && (va < a->base + a->pages * PAGE_SIZE)) {
 			return a;
 		}
-		spinlock_unlock(&a->lock);
+		mutex_unlock(&a->lock);
 	}
 
@@ -825,9 +832,9 @@
 	if ((lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf))) {
 		a = (as_area_t *) lnode->value[lnode->keys - 1];
-		spinlock_lock(&a->lock);
+		mutex_lock(&a->lock);
 		if (va < a->base + a->pages * PAGE_SIZE) {
 			return a;
 		}
-		spinlock_unlock(&a->lock);
+		mutex_unlock(&a->lock);
 	}
 
@@ -874,19 +881,19 @@
 	if ((node = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf))) {
 		a = (as_area_t *) node->value[node->keys - 1];
-		spinlock_lock(&a->lock);
+		mutex_lock(&a->lock);
 		if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
-			spinlock_unlock(&a->lock);
+			mutex_unlock(&a->lock);
 			return false;
 		}
-		spinlock_unlock(&a->lock);
+		mutex_unlock(&a->lock);
 	}
 	if ((node = btree_leaf_node_right_neighbour(&as->as_area_btree, leaf))) {
 		a = (as_area_t *) node->value[0];
-		spinlock_lock(&a->lock);
+		mutex_lock(&a->lock);
 		if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
-			spinlock_unlock(&a->lock);
+			mutex_unlock(&a->lock);
 			return false;
 		}
-		spinlock_unlock(&a->lock);
+		mutex_unlock(&a->lock);
 	}
 	
@@ -898,10 +905,10 @@
 			continue;
 	
-		spinlock_lock(&a->lock);
+		mutex_lock(&a->lock);
 		if (overlaps(va, size, a->base, a->pages * PAGE_SIZE)) {
-			spinlock_unlock(&a->lock);
+			mutex_unlock(&a->lock);
 			return false;
 		}
-		spinlock_unlock(&a->lock);
+		mutex_unlock(&a->lock);
 	}
 
@@ -918,5 +925,5 @@
 }
 
-/** Return size of address space of current task pointed to by base */
+/** Return size of the address space area with given base.  */
 size_t as_get_size(__address base)
 {
@@ -929,5 +936,5 @@
 	if (src_area){
 		size = src_area->pages * PAGE_SIZE;
-		spinlock_unlock(&src_area->lock);
+		mutex_unlock(&src_area->lock);
 	} else {
 		size = 0;
Index: generic/src/proc/scheduler.c
===================================================================
--- generic/src/proc/scheduler.c	(revision 9ea6cc566be012266a2a040129f53230cff1e316)
+++ generic/src/proc/scheduler.c	(revision 1068f6a33444f5917a7f47f13b57ebe76e675eb3)
@@ -422,6 +422,4 @@
 	relink_rq(priority);		
 
-	spinlock_lock(&THREAD->lock);	
-
 	/*
 	 * If both the old and the new task are the same, lots of work is avoided.
@@ -455,4 +453,5 @@
 	}
 
+	spinlock_lock(&THREAD->lock);	
 	THREAD->state = Running;
 
