Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/Makefile	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -33,7 +33,8 @@
 all: ../version ../Makefile.config ../config.h ../config.defs
 	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
-	$(MAKE) -f Makefile.build
+	$(MAKE) -f Makefile.build EXTRA_TOOL=$(EXTRA_TOOL)
 
 clean:
-	rm -f $(DEPEND) $(DEPEND_PREV) $(RAW) $(BIN) $(MAP) $(MAP_PREV) $(DISASM) $(DUMP) $(REAL_MAP).* $(ARCH_INCLUDE) $(GENARCH_INCLUDE) arch/*/_link.ld
+	rm -f $(DEPEND) $(DEPEND_PREV) $(RAW) $(BIN) $(MAP) $(JOB) $(MAP_PREV) $(DISASM) $(DUMP) $(REAL_MAP).* $(ARCH_INCLUDE) $(GENARCH_INCLUDE) arch/*/_link.ld
 	find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
+	find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o.preproc' -follow -exec rm \{\} \;
Index: kernel/Makefile.build
===================================================================
--- kernel/Makefile.build	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/Makefile.build	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -91,5 +91,5 @@
 ## Cross-platform assembly to start a symtab.data section
 #
-SYMTAB_SECTION=".section symtab.data, \"a\", $(ATSIGN)progbits;"
+SYMTAB_SECTION = ".section symtab.data, \"a\", $(ATSIGN)progbits;"
 
 ## Simple detection for the type of the host system
@@ -110,5 +110,5 @@
 ifeq ($(COMPILER),gcc_native)
 	CC = gcc
-	GCC = $(CC)
+	GCC = gcc
 	AS = $(BINUTILS_PREFIX)as
 	LD = $(BINUTILS_PREFIX)ld
@@ -168,4 +168,5 @@
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
+
 
 ## Generic kernel sources
@@ -384,4 +385,7 @@
 test/fpu/%.o: test/fpu/%.c $(DEPEND)
 	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) -c $< -o $@
+ifeq ($(EXTRA_TOOL),stanse)
+	../tools/jobfile.py $(JOB) $< $@ $(DEFS) $(CFLAGS) $(EXTRA_FLAGS)
+endif
 
 #
@@ -390,4 +394,7 @@
 %.o: %.c $(DEPEND)
 	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c $< -o $@
+ifeq ($(EXTRA_TOOL),stanse)
+	../tools/jobfile.py $(JOB) $< $@ $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS)
+endif
 
 $(REAL_MAP).o: $(REAL_MAP).bin
Index: kernel/Makefile.common
===================================================================
--- kernel/Makefile.common	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/Makefile.common	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -36,4 +36,5 @@
 BIN = kernel.bin
 MAP = kernel.map
+JOB = kernel.job
 MAP_PREV = $(MAP).prev
 DISASM = kernel.disasm
Index: kernel/arch/amd64/include/mm/page.h
===================================================================
--- kernel/arch/amd64/include/mm/page.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/amd64/include/mm/page.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -177,5 +177,23 @@
 #define PFERR_CODE_ID		(1 << 4)
 
-static inline int get_pt_flags(pte_t *pt, size_t i)
+/** Page Table Entry. */
+typedef struct {
+	unsigned present : 1;
+	unsigned writeable : 1;
+	unsigned uaccessible : 1;
+	unsigned page_write_through : 1;
+	unsigned page_cache_disable : 1;
+	unsigned accessed : 1;
+	unsigned dirty : 1;
+	unsigned unused: 1;
+	unsigned global : 1;
+	unsigned soft_valid : 1;		/**< Valid content even if present bit is cleared. */
+	unsigned avl : 2;
+	unsigned addr_12_31 : 30;
+	unsigned addr_32_51 : 21;
+	unsigned no_execute : 1;
+} __attribute__ ((packed)) pte_t;
+
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/amd64/include/types.h
===================================================================
--- kernel/arch/amd64/include/types.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/amd64/include/types.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -82,22 +82,4 @@
 #define PRIxn "llx"
 
-/** Page Table Entry. */
-typedef struct {
-	unsigned present : 1;
-	unsigned writeable : 1;
-	unsigned uaccessible : 1;
-	unsigned page_write_through : 1;
-	unsigned page_cache_disable : 1;
-	unsigned accessed : 1;
-	unsigned dirty : 1;
-	unsigned unused: 1;
-	unsigned global : 1;
-	unsigned soft_valid : 1;		/**< Valid content even if present bit is cleared. */
-	unsigned avl : 2;
-	unsigned addr_12_31 : 30;
-	unsigned addr_32_51 : 21;
-	unsigned no_execute : 1;
-} __attribute__ ((packed)) pte_t;
-
 #endif
 
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/amd64/src/amd64.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -67,4 +67,5 @@
 #include <ddi/irq.h>
 #include <sysinfo/sysinfo.h>
+#include <memstr.h>
 
 /** Disable I/O on non-privileged levels
Index: kernel/arch/amd64/src/interrupt.c
===================================================================
--- kernel/arch/amd64/src/interrupt.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/amd64/src/interrupt.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -98,4 +98,11 @@
 }
 
+static void de_fault(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "Divide error.");
+	decode_istate(n, istate);
+	panic("Divide error.");
+}
+
 /** General Protection Fault. */
 static void gp_fault(int n, istate_t *istate)
@@ -200,4 +207,5 @@
 	}
 	
+	exc_register(0, "de_fault", (iroutine) de_fault);
 	exc_register(7, "nm_fault", (iroutine) nm_fault);
 	exc_register(12, "ss_fault", (iroutine) ss_fault);
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/Makefile.inc	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -61,5 +61,6 @@
 	arch/$(KARCH)/src/mm/page.c \
 	arch/$(KARCH)/src/mm/tlb.c \
-	arch/$(KARCH)/src/mm/page_fault.c
+	arch/$(KARCH)/src/mm/page_fault.c \
+	arch/$(KARCH)/src/ras.c
 
 ifeq ($(MACHINE),testarm)
Index: kernel/arch/arm32/include/atomic.h
===================================================================
--- kernel/arch/arm32/include/atomic.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/include/atomic.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -37,4 +37,6 @@
 #define KERN_arm32_ATOMIC_H_
 
+#include <arch/asm.h>
+
 /** Atomic addition.
  *
@@ -47,19 +49,14 @@
 static inline long atomic_add(atomic_t *val, int i)
 {
-	int ret;
-	volatile long *mem = &(val->count);
-	
-	asm volatile (
-		"1:\n"
-			"ldr r2, [%[mem]]\n"
-			"add r3, r2, %[i]\n"
-			"str r3, %[ret]\n"
-			"swp r3, r3, [%[mem]]\n"
-			"cmp r3, r2\n"
-			"bne 1b\n"
-		: [ret] "=m" (ret)
-		: [mem] "r" (mem), [i] "r" (i)
-		: "r3", "r2"
-	);
+	long ret;
+
+	/*
+	 * This implementation is for UP pre-ARMv6 systems where we do not have
+	 * the LDREX and STREX instructions.
+	 */
+	ipl_t ipl = interrupts_disable();
+	val->count += i;
+	ret = val->count;
+	interrupts_restore(ipl);
 	
 	return ret;
Index: kernel/arch/arm32/include/mm/as.h
===================================================================
--- kernel/arch/arm32/include/mm/as.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/include/mm/as.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -54,5 +54,4 @@
 #define as_destructor_arch(as)			(as != as)
 #define as_create_arch(as, flags)		(as != as)
-#define as_install_arch(as)
 #define as_deinstall_arch(as)
 #define as_invalidate_translation_cache(as, page, cnt)
Index: kernel/arch/arm32/include/mm/page.h
===================================================================
--- kernel/arch/arm32/include/mm/page.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/include/mm/page.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -75,5 +75,5 @@
 /* Get PTE address accessors for each level. */
 #define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
-	((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).coarse_table_addr << 10))
+	((pte_t *) ((((pte_t *)(ptl0))[(i)].l0).coarse_table_addr << 10))
 #define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
 	(ptl1)
@@ -81,19 +81,19 @@
 	(ptl2)
 #define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
-	((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12))
+	((uintptr_t) ((((pte_t *)(ptl3))[(i)].l1).frame_base_addr << 12))
 
 /* Set PTE address accessors for each level. */
 #define SET_PTL0_ADDRESS_ARCH(ptl0) \
-	(set_ptl0_addr((pte_level0_t *) (ptl0)))
+	(set_ptl0_addr((pte_t *) (ptl0)))
 #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
-	(((pte_level0_t *) (ptl0))[(i)].coarse_table_addr = (a) >> 10)
+	(((pte_t *) (ptl0))[(i)].l0.coarse_table_addr = (a) >> 10)
 #define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
 #define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
 #define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
-	(((pte_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12)
+	(((pte_t *) (ptl3))[(i)].l1.frame_base_addr = (a) >> 12)
 
 /* Get PTE flags accessors for each level. */
 #define GET_PTL1_FLAGS_ARCH(ptl0, i) \
-	get_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i))
+	get_pt_level0_flags((pte_t *) (ptl0), (size_t) (i))
 #define GET_PTL2_FLAGS_ARCH(ptl1, i) \
 	PAGE_PRESENT
@@ -101,13 +101,13 @@
 	PAGE_PRESENT
 #define GET_FRAME_FLAGS_ARCH(ptl3, i) \
-	get_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i))
+	get_pt_level1_flags((pte_t *) (ptl3), (size_t) (i))
 
 /* Set PTE flags accessors for each level. */
 #define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
-	set_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i), (x))
+	set_pt_level0_flags((pte_t *) (ptl0), (size_t) (i), (x))
 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
 #define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
 #define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
-	set_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i), (x))
+	set_pt_level1_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
 /* Macros for querying the last-level PTE entries. */
@@ -115,10 +115,9 @@
 	(*((uint32_t *) (pte)) != 0)
 #define PTE_PRESENT_ARCH(pte) \
-	(((pte_level0_t *) (pte))->descriptor_type != 0)
+	(((pte_t *) (pte))->l0.descriptor_type != 0)
 #define PTE_GET_FRAME_ARCH(pte) \
-	(((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH)
+	(((pte_t *) (pte))->l1.frame_base_addr << FRAME_WIDTH)
 #define PTE_WRITABLE_ARCH(pte) \
-	(((pte_level1_t *) (pte))->access_permission_0 == \
-	    PTE_AP_USER_RW_KERNEL_RW)
+	(((pte_t *) (pte))->l1.access_permission_0 == PTE_AP_USER_RW_KERNEL_RW)
 #define PTE_EXECUTABLE_ARCH(pte) \
 	1
@@ -159,4 +158,8 @@
 } ATTRIBUTE_PACKED pte_level1_t;
 
+typedef union {
+	pte_level0_t l0;
+	pte_level1_t l1;
+} pte_t;
 
 /* Level 1 page tables access permissions */
@@ -191,5 +194,5 @@
  * @param pt    Pointer to the page table to set.
  */   
-static inline void set_ptl0_addr(pte_level0_t *pt)
+static inline void set_ptl0_addr(pte_t *pt)
 {
 	asm volatile (
@@ -205,7 +208,7 @@
  *  @param i      Index of the entry to return.
  */
-static inline int get_pt_level0_flags(pte_level0_t *pt, size_t i)
-{
-	pte_level0_t *p = &pt[i];
+static inline int get_pt_level0_flags(pte_t *pt, size_t i)
+{
+	pte_level0_t *p = &pt[i].l0;
 	int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT);
 
@@ -220,7 +223,7 @@
  *  @param i      Index of the entry to return.
  */
-static inline int get_pt_level1_flags(pte_level1_t *pt, size_t i)
-{
-	pte_level1_t *p = &pt[i];
+static inline int get_pt_level1_flags(pte_t *pt, size_t i)
+{
+	pte_level1_t *p = &pt[i].l1;
 
 	int dt = p->descriptor_type;
@@ -245,7 +248,7 @@
  *  @param flags  new flags
  */
-static inline void set_pt_level0_flags(pte_level0_t *pt, size_t i, int flags)
-{
-	pte_level0_t *p = &pt[i];
+static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
+{
+	pte_level0_t *p = &pt[i].l0;
 
 	if (flags & PAGE_NOT_PRESENT) {
@@ -273,7 +276,7 @@
  *  @param flags  New flags.
  */  
-static inline void set_pt_level1_flags(pte_level1_t *pt, size_t i, int flags)
-{
-	pte_level1_t *p = &pt[i];
+static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
+{
+	pte_level1_t *p = &pt[i].l1;
 	
 	if (flags & PAGE_NOT_PRESENT) {
Index: kernel/arch/arm32/include/ras.h
===================================================================
--- kernel/arch/arm32/include/ras.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
+++ kernel/arch/arm32/include/ras.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar 
+ * 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.
+ */
+
+/** @addtogroup arm32
+ * @{
+ */
+/** @file
+ *  @brief Declarations related to Restartable Atomic Sequences.
+ */
+
+#ifndef KERN_arm32_RAS_H_
+#define KERN_arm32_RAS_H_
+
+#include <arch/exception.h>
+#include <arch/types.h>
+
+#define RAS_START	0
+#define RAS_END		1
+
+extern uintptr_t *ras_page;
+
+extern void ras_init(void);
+extern void ras_check(int, istate_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/arm32/include/types.h
===================================================================
--- kernel/arch/arm32/include/types.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/include/types.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -87,13 +87,4 @@
 #define PRIxn "x"	/**< Format for hexadecimal (u)native_t. */
 
-/** Page table entry.
- *
- *  We have different structs for level 0 and level 1 page table entries.
- *  See page.h for definition of pte_level*_t.
- */
-typedef struct {
-	unsigned dummy : 32;
-} pte_t;
-
 #endif
 
Index: kernel/arch/arm32/src/arm32.c
===================================================================
--- kernel/arch/arm32/src/arm32.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/src/arm32.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -48,4 +48,5 @@
 #include <macros.h>
 #include <string.h>
+#include <arch/ras.h>
 
 #ifdef MACHINE_testarm
@@ -88,4 +89,7 @@
 	exception_init();
 	interrupt_init();
+
+	/* Initialize Restartable Atomic Sequences support. */
+	ras_init();
 	
 	machine_output_init();
@@ -136,5 +140,4 @@
 	uint8_t *stck;
 	
-	tlb_invalidate_all();
 	stck = &THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA];
 	supervisor_sp = (uintptr_t) stck;
Index: kernel/arch/arm32/src/exc_handler.S
===================================================================
--- kernel/arch/arm32/src/exc_handler.S	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/src/exc_handler.S	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -148,5 +148,5 @@
 	mov r0, #0
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -156,5 +156,5 @@
 	mov r0, #5
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -164,5 +164,5 @@
 	mov r0, #6
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -171,5 +171,5 @@
 	mov r0, #1
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -179,5 +179,5 @@
 	mov r0, #3
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -187,5 +187,5 @@
 	mov r0, #4
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check 
 	LOAD_REGS_FROM_STACK
 
@@ -195,5 +195,5 @@
 	mov r0, #2
 	mov r1, r13
-	bl exc_dispatch
+	bl ras_check
 	LOAD_REGS_FROM_STACK
 
Index: kernel/arch/arm32/src/mm/as.c
===================================================================
--- kernel/arch/arm32/src/mm/as.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/src/mm/as.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -36,6 +36,8 @@
 #include <arch/mm/as.h>
 #include <genarch/mm/as_pt.h>
+#include <genarch/mm/page_pt.h>
 #include <genarch/mm/asid_fifo.h>
 #include <mm/as.h>
+#include <mm/tlb.h>
 #include <arch.h>
 
@@ -49,4 +51,9 @@
 }
 
+void as_install_arch(as_t *as)
+{
+	tlb_invalidate_all();
+}
+
 /** @}
  */
Index: kernel/arch/arm32/src/ras.c
===================================================================
--- kernel/arch/arm32/src/ras.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
+++ kernel/arch/arm32/src/ras.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009 Jakub Jermar 
+ * 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.
+ */
+
+/** @addtogroup arm32
+ * @{
+ */
+/** @file
+ *  @brief Kernel part of Restartable Atomic Sequences support.
+ */
+
+#include <arch/ras.h>
+#include <mm/mm.h>
+#include <mm/frame.h>
+#include <mm/page.h>
+#include <mm/tlb.h>
+#include <mm/asid.h>
+#include <interrupt.h>
+#include <arch/exception.h>
+#include <arch.h>
+#include <memstr.h>
+#include <arch/types.h>
+
+uintptr_t *ras_page = NULL;
+
+void ras_init(void)
+{
+	ras_page = frame_alloc(ONE_FRAME, FRAME_KA);
+	memsetb(ras_page, FRAME_SIZE, 0); 
+	ras_page[RAS_START] = 0;
+	ras_page[RAS_END] = 0xffffffff;
+	/*
+	 * Userspace needs to be able to write to this page. The page is 
+	 * cached in TLB as PAGE_KERNEL. Purge it from TLB and map it
+	 * read/write PAGE_USER.
+	 */
+	tlb_invalidate_pages(ASID_KERNEL, (uintptr_t)ras_page, 1);
+	page_table_lock(AS, true);
+	page_mapping_insert(AS, (uintptr_t)ras_page, (uintptr_t)KA2PA(ras_page),
+	    PAGE_READ | PAGE_WRITE | PAGE_USER);
+	page_table_unlock(AS, true);
+}
+
+void ras_check(int n, istate_t *istate)
+{
+	uintptr_t rewrite_pc = istate->pc;
+
+	if (istate_from_uspace(istate)) {
+		if (ras_page[RAS_START]) {
+			if ((ras_page[RAS_START] < istate->pc) &&
+			    (ras_page[RAS_END] > istate->pc)) {
+				rewrite_pc = ras_page[RAS_START];
+			}
+			ras_page[RAS_START] = 0;
+			ras_page[RAS_END] = 0xffffffff;
+		}	
+	}
+
+	exc_dispatch(n, istate);
+
+	istate->pc = rewrite_pc;
+}
+
Index: kernel/arch/arm32/src/userspace.c
===================================================================
--- kernel/arch/arm32/src/userspace.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/arm32/src/userspace.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -35,4 +35,5 @@
 
 #include <userspace.h>
+#include <arch/ras.h>
 
 /** Struct for holding all general purpose registers.
@@ -74,8 +75,11 @@
 	ustate.r1 = 0;
 
+	/* pass the RAS page address in %r2 */
+	ustate.r2 = (uintptr_t) ras_page;
+
 	/* clear other registers */
-	ustate.r2 = ustate.r3  = ustate.r4  = ustate.r5 =
-	    ustate.r6  = ustate.r7  = ustate.r8  = ustate.r9 = ustate.r10 = 
-	    ustate.r11 = ustate.r12 = ustate.lr = 0;
+	ustate.r3  = ustate.r4  = ustate.r5 = ustate.r6 = ustate.r7 =
+	    ustate.r8 = ustate.r9 = ustate.r10 = ustate.r11 = ustate.r12 =
+	    ustate.lr = 0;
 
 	/* set user stack */
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ia32/include/mm/page.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -146,5 +146,21 @@
 #define PFERR_CODE_RSVD		(1 << 3)	
 
-static inline int get_pt_flags(pte_t *pt, size_t i)
+/** Page Table Entry. */
+typedef struct {
+	unsigned present : 1;
+	unsigned writeable : 1;
+	unsigned uaccessible : 1;
+	unsigned page_write_through : 1;
+	unsigned page_cache_disable : 1;
+	unsigned accessed : 1;
+	unsigned dirty : 1;
+	unsigned pat : 1;
+	unsigned global : 1;
+	unsigned soft_valid : 1;	/**< Valid content even if the present bit is not set. */
+	unsigned avl : 2;
+	unsigned frame_address : 20;
+} __attribute__ ((packed)) pte_t;
+
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/ia32/include/types.h
===================================================================
--- kernel/arch/ia32/include/types.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ia32/include/types.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -80,20 +80,4 @@
 #define PRIxn "x"	/**< Format for hexadecimal (u)native_t. */
 
-/** Page Table Entry. */
-typedef struct {
-	unsigned present : 1;
-	unsigned writeable : 1;
-	unsigned uaccessible : 1;
-	unsigned page_write_through : 1;
-	unsigned page_cache_disable : 1;
-	unsigned accessed : 1;
-	unsigned dirty : 1;
-	unsigned pat : 1;
-	unsigned global : 1;
-	unsigned soft_valid : 1;	/**< Valid content even if the present bit is not set. */
-	unsigned avl : 2;
-	unsigned frame_address : 20;
-} __attribute__ ((packed)) pte_t;
-
 #endif
 
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ia32/src/ia32.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -68,4 +68,5 @@
 #include <sysinfo/sysinfo.h>
 #include <arch/boot/boot.h>
+#include <memstr.h>
 
 #ifdef CONFIG_SMP
Index: kernel/arch/ia32/src/interrupt.c
===================================================================
--- kernel/arch/ia32/src/interrupt.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ia32/src/interrupt.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -98,4 +98,12 @@
 }
 
+static void de_fault(int n, istate_t *istate)
+{
+	fault_if_from_uspace(istate, "Divide error.");
+
+	decode_istate(istate);
+	panic("Divide error.");
+}
+
 /** General Protection Fault. */
 static void gp_fault(int n __attribute__((unused)), istate_t *istate)
@@ -215,4 +223,5 @@
 	}
 	
+	exc_register(0, "de_fault", (iroutine) de_fault);
 	exc_register(7, "nm_fault", (iroutine) nm_fault);
 	exc_register(12, "ss_fault", (iroutine) ss_fault);
Index: kernel/arch/ia64/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia64/src/cpu/cpu.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ia64/src/cpu/cpu.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -37,4 +37,5 @@
 #include <arch/register.h>
 #include <print.h>
+#include <memstr.h>
 
 void cpu_arch_init(void)
Index: kernel/arch/mips32/include/mm/page.h
===================================================================
--- kernel/arch/mips32/include/mm/page.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/mips32/include/mm/page.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -141,5 +141,19 @@
 #include <arch/exception.h>
 
-static inline int get_pt_flags(pte_t *pt, size_t i)
+/** Page Table Entry. */
+typedef struct {
+	unsigned g : 1;			/**< Global bit. */
+	unsigned p : 1;			/**< Present bit. */
+	unsigned d : 1;			/**< Dirty bit. */
+	unsigned cacheable : 1;		/**< Cacheable bit. */
+	unsigned : 1;			/**< Unused. */
+	unsigned soft_valid : 1;	/**< Valid content even if not present. */
+	unsigned pfn : 24;		/**< Physical frame number. */
+	unsigned w : 1;			/**< Page writable bit. */
+	unsigned a : 1;			/**< Accessed bit. */
+} pte_t;
+
+
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/mips32/include/types.h
===================================================================
--- kernel/arch/mips32/include/types.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/mips32/include/types.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -80,17 +80,4 @@
 #define PRIxn "x"	/**< Format for hexadecimal (u)native_t. */
 
-/** Page Table Entry. */
-typedef struct {
-	unsigned g : 1;			/**< Global bit. */
-	unsigned p : 1;			/**< Present bit. */
-	unsigned d : 1;			/**< Dirty bit. */
-	unsigned cacheable : 1;		/**< Cacheable bit. */
-	unsigned : 1;			/**< Unused. */
-	unsigned soft_valid : 1;	/**< Valid content even if not present. */
-	unsigned pfn : 24;		/**< Physical frame number. */
-	unsigned w : 1;			/**< Page writable bit. */
-	unsigned a : 1;			/**< Accessed bit. */
-} pte_t;
-
 #endif
 
Index: kernel/arch/ppc32/include/mm/page.h
===================================================================
--- kernel/arch/ppc32/include/mm/page.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ppc32/include/mm/page.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -131,5 +131,16 @@
 #include <arch/interrupt.h>
 
-static inline int get_pt_flags(pte_t *pt, size_t i)
+/** Page Table Entry. */
+typedef struct {
+	unsigned present : 1;             /**< Present bit. */
+	unsigned page_write_through : 1;  /**< Write thought caching. */
+	unsigned page_cache_disable : 1;  /**< No caching. */
+	unsigned accessed : 1;            /**< Accessed bit. */
+	unsigned global : 1;              /**< Global bit. */
+	unsigned valid : 1;               /**< Valid content even if not present. */
+	unsigned pfn : 20;                /**< Physical frame number. */
+} pte_t;
+
+static inline unsigned int get_pt_flags(pte_t *pt, size_t i)
 {
 	pte_t *p = &pt[i];
Index: kernel/arch/ppc32/include/types.h
===================================================================
--- kernel/arch/ppc32/include/types.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ppc32/include/types.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -82,15 +82,4 @@
 #define PRIxn "x"
 
-/** Page Table Entry. */
-typedef struct {
-	unsigned present : 1;             /**< Present bit. */
-	unsigned page_write_through : 1;  /**< Write thought caching. */
-	unsigned page_cache_disable : 1;  /**< No caching. */
-	unsigned accessed : 1;            /**< Accessed bit. */
-	unsigned global : 1;              /**< Global bit. */
-	unsigned valid : 1;               /**< Valid content even if not present. */
-	unsigned pfn : 20;                /**< Physical frame number. */
-} pte_t;
-
 #endif
 
Index: kernel/arch/ppc32/src/mm/as.c
===================================================================
--- kernel/arch/ppc32/src/mm/as.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ppc32/src/mm/as.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -35,4 +35,5 @@
 #include <arch/mm/as.h>
 #include <genarch/mm/as_pt.h>
+#include <genarch/mm/page_pt.h>
 #include <genarch/mm/asid_fifo.h>
 #include <arch.h>
Index: kernel/arch/ppc32/src/mm/tlb.c
===================================================================
--- kernel/arch/ppc32/src/mm/tlb.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ppc32/src/mm/tlb.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -38,4 +38,5 @@
 #include <interrupt.h>
 #include <mm/as.h>
+#include <mm/page.h>
 #include <arch.h>
 #include <print.h>
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/ppc32/src/ppc32.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -44,4 +44,5 @@
 #include <genarch/ofw/pci.h>
 #include <userspace.h>
+#include <mm/page.h>
 #include <proc/uarg.h>
 #include <console/console.h>
Index: kernel/arch/sparc64/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tlb.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/arch/sparc64/src/mm/tlb.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -37,4 +37,5 @@
 #include <mm/as.h>
 #include <mm/asid.h>
+#include <genarch/mm/page_ht.h>
 #include <arch/mm/frame.h>
 #include <arch/mm/page.h>
Index: kernel/genarch/include/mm/as_pt.h
===================================================================
--- kernel/genarch/include/mm/as_pt.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/genarch/include/mm/as_pt.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -36,6 +36,5 @@
 #define KERN_AS_PT_H_
 
-#include <mm/mm.h>
-#include <arch/types.h>
+#include <arch/mm/page.h>
 
 #define AS_PAGE_TABLE
Index: kernel/genarch/include/mm/page_pt.h
===================================================================
--- kernel/genarch/include/mm/page_pt.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/genarch/include/mm/page_pt.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -44,7 +44,8 @@
 #define KERN_PAGE_PT_H_
 
-#include <arch/types.h>
 #include <mm/as.h>
 #include <mm/page.h>
+#include <arch/mm/page.h>
+#include <arch/types.h>
 
 /*
Index: kernel/genarch/src/drivers/via-cuda/cuda.c
===================================================================
--- kernel/genarch/src/drivers/via-cuda/cuda.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/genarch/src/drivers/via-cuda/cuda.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -41,4 +41,5 @@
 #include <ddi/device.h>
 #include <synch/spinlock.h>
+#include <memstr.h>
 
 static irq_ownership_t cuda_claim(irq_t *irq);
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/genarch/src/fb/fb.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -41,4 +41,5 @@
 #include <console/console.h>
 #include <sysinfo/sysinfo.h>
+#include <mm/page.h>
 #include <mm/slab.h>
 #include <align.h>
Index: kernel/generic/include/arch.h
===================================================================
--- kernel/generic/include/arch.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/include/arch.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -39,4 +39,5 @@
 #include <proc/thread.h>
 #include <proc/task.h>
+#include <mm/as.h>
 
 #define DEFAULT_CONTEXT		0
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/include/ipc/ipc.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -51,14 +51,12 @@
 /** This is answer to a call */
 #define IPC_CALL_ANSWERED	(1 << 0)
-/** This call will not be freed on error */
-#define IPC_CALL_STATIC_ALLOC	(1 << 1)
 /** Answer will not be passed to userspace, will be discarded */
-#define IPC_CALL_DISCARD_ANSWER	(1 << 2)
+#define IPC_CALL_DISCARD_ANSWER (1 << 1)
 /** Call was forwarded */
-#define IPC_CALL_FORWARDED	(1 << 3)
+#define IPC_CALL_FORWARDED	(1 << 2)
 /** Identify connect_me_to answer */
-#define IPC_CALL_CONN_ME_TO	(1 << 4)
+#define IPC_CALL_CONN_ME_TO	(1 << 3)
 /** Interrupt notification */
-#define IPC_CALL_NOTIF		(1 << 5)
+#define IPC_CALL_NOTIF		(1 << 4)
 
 /*
@@ -267,4 +265,7 @@
 	waitq_t wq;
 
+	/** Linkage for the list of task's synchronous answerboxes. */
+	link_t sync_box_link;
+
 	/** Phones connected to this answerbox. */
 	link_t connected_phones;
@@ -316,25 +317,31 @@
 } call_t;
 
+
+extern answerbox_t *ipc_phone_0;
+
+
 extern void ipc_init(void);
-extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int);
-extern void ipc_answer(answerbox_t *, call_t *);
+
+extern call_t * ipc_call_alloc(int);
+extern void ipc_call_free(call_t *);
+
 extern int ipc_call(phone_t *, call_t *);
 extern int ipc_call_sync(phone_t *, call_t *);
+extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int);
+extern int ipc_forward(call_t *, phone_t *, answerbox_t *, int);
+extern void ipc_answer(answerbox_t *, call_t *);
+
 extern void ipc_phone_init(phone_t *);
 extern void ipc_phone_connect(phone_t *, answerbox_t *);
-extern void ipc_call_free(call_t *);
-extern call_t * ipc_call_alloc(int);
+extern int ipc_phone_hangup(phone_t *);
+
 extern void ipc_answerbox_init(answerbox_t *, struct task *);
-extern void ipc_call_static_init(call_t *);
-extern void task_print_list(void);
-extern int ipc_forward(call_t *, phone_t *, answerbox_t *, int);
+
 extern void ipc_cleanup(void);
-extern int ipc_phone_hangup(phone_t *);
 extern void ipc_backsend_err(phone_t *, call_t *, unative_t);
-extern void ipc_print_task(task_id_t);
 extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
 extern void ipc_cleanup_call_list(link_t *);
 
-extern answerbox_t *ipc_phone_0;
+extern void ipc_print_task(task_id_t);
 
 #endif
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/include/proc/task.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -55,4 +55,5 @@
 #include <udebug/udebug.h>
 #include <ipc/kbox.h>
+#include <mm/as.h>
 
 #define TASK_NAME_BUFLEN	20
@@ -98,4 +99,6 @@
 	 */
 	atomic_t active_calls;
+	/** List of synchronous answerboxes. */
+	link_t sync_box_head;
 
 #ifdef CONFIG_UDEBUG
@@ -132,4 +135,5 @@
 extern int task_kill(task_id_t id);
 extern uint64_t task_get_accounting(task_t *t);
+extern void task_print_list(void);
 
 extern void cap_set(task_t *t, cap_t caps);
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/include/proc/thread.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -225,34 +225,33 @@
 
 extern void thread_init(void);
-extern thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
-    int flags, char *name, bool uncounted);
-extern void thread_attach(thread_t *t, task_t *task);
-extern void thread_ready(thread_t *t);
+extern thread_t *thread_create(void (*)(void *), void *, task_t *, int, char *,
+    bool);
+extern void thread_attach(thread_t *, task_t *);
+extern void thread_ready(thread_t *);
 extern void thread_exit(void) __attribute__((noreturn));
 
 #ifndef thread_create_arch
-extern void thread_create_arch(thread_t *t);
+extern void thread_create_arch(thread_t *);
 #endif
 #ifndef thr_constructor_arch
-extern void thr_constructor_arch(thread_t *t);
+extern void thr_constructor_arch(thread_t *);
 #endif
 #ifndef thr_destructor_arch
-extern void thr_destructor_arch(thread_t *t);
-#endif
-
-extern void thread_sleep(uint32_t sec);
-extern void thread_usleep(uint32_t usec);
+extern void thr_destructor_arch(thread_t *);
+#endif
+
+extern void thread_sleep(uint32_t);
+extern void thread_usleep(uint32_t);
 
 #define thread_join(t) \
 	thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
-extern int thread_join_timeout(thread_t *t, uint32_t usec, int flags);
-extern void thread_detach(thread_t *t);
-
-extern void thread_register_call_me(void (* call_me)(void *),
-    void *call_me_with);
+extern int thread_join_timeout(thread_t *, uint32_t, int);
+extern void thread_detach(thread_t *);
+
+extern void thread_register_call_me(void (*)(void *), void *);
 extern void thread_print_list(void);
-extern void thread_destroy(thread_t *t);
+extern void thread_destroy(thread_t *);
 extern void thread_update_accounting(void);
-extern bool thread_exists(thread_t *t);
+extern bool thread_exists(thread_t *);
 
 /** Fpu context slab cache. */
@@ -260,8 +259,9 @@
 
 /* Thread syscall prototypes. */
-extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg,
-    char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id);
-extern unative_t sys_thread_exit(int uspace_status);
-extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);
+extern unative_t sys_thread_create(uspace_arg_t *, char *, size_t,
+    thread_id_t *);
+extern unative_t sys_thread_exit(int);
+extern unative_t sys_thread_get_id(thread_id_t *);
+extern unative_t sys_thread_usleep(uint32_t);
 
 #endif
Index: kernel/generic/include/string.h
===================================================================
--- kernel/generic/include/string.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/include/string.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -87,5 +87,5 @@
 extern void str_cpy(char *dest, size_t size, const char *src);
 extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
-extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
+extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
 
 extern char *str_chr(const char *str, wchar_t ch);
Index: kernel/generic/include/synch/futex.h
===================================================================
--- kernel/generic/include/synch/futex.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/include/synch/futex.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -38,6 +38,4 @@
 #include <arch/types.h>
 #include <synch/waitq.h>
-#include <genarch/mm/page_ht.h>
-#include <genarch/mm/page_pt.h>
 
 /** Kernel-side futex structure. */
@@ -54,7 +52,6 @@
 
 extern void futex_init(void);
-extern unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec,
-    int flags);
-extern unative_t sys_futex_wakeup(uintptr_t uaddr);
+extern unative_t sys_futex_sleep(uintptr_t);
+extern unative_t sys_futex_wakeup(uintptr_t);
 
 extern void futex_cleanup(void);
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/include/syscall/syscall.h	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -43,4 +43,5 @@
 	SYS_THREAD_EXIT,
 	SYS_THREAD_GET_ID,
+	SYS_THREAD_USLEEP,
 	
 	SYS_TASK_GET_ID,
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/console/console.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -319,15 +319,15 @@
 	
 	if (size > PAGE_SIZE)
-		return ELIMIT;
+		return (unative_t) ELIMIT;
 	
 	if (size > 0) {
 		data = (char *) malloc(size + 1, 0);
 		if (!data)
-			return ENOMEM;
+			return (unative_t) ENOMEM;
 		
 		rc = copy_from_uspace(data, buf, size);
 		if (rc) {
 			free(data);
-			return rc;
+			return (unative_t) rc;
 		}
 		data[size] = 0;
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/console/kconsole.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -289,5 +289,5 @@
 			
 			char tmp[STR_BOUNDS(MAX_CMDLINE)];
-			wstr_nstr(tmp, current + beg, position - beg + 1);
+			wstr_to_str(tmp, position - beg + 1, current + beg);
 			
 			int found;
@@ -665,5 +665,5 @@
 		
 		char cmdline[STR_BOUNDS(MAX_CMDLINE)];
-		wstr_nstr(cmdline, tmp, STR_BOUNDS(MAX_CMDLINE));
+		wstr_to_str(cmdline, STR_BOUNDS(MAX_CMDLINE), tmp);
 		
 		if ((!kcon) && (len == 4) && (str_lcmp(cmdline, "exit", 4) == 0))
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/ipc/ipc.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -62,4 +62,5 @@
 
 static slab_cache_t *ipc_call_slab;
+static slab_cache_t *ipc_answerbox_slab;
 
 /** Initialize a call structure.
@@ -96,15 +97,4 @@
 }
 
-/** Initialize a statically allocated call structure.
- *
- * @param call		Statically allocated kernel call structure to be
- *			initialized.
- */
-void ipc_call_static_init(call_t *call)
-{
-	_ipc_call_init(call);
-	call->flags |= IPC_CALL_STATIC_ALLOC;
-}
-
 /** Deallocate a call structure.
  *
@@ -113,5 +103,4 @@
 void ipc_call_free(call_t *call)
 {
-	ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
 	/* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
 	if (call->buffer)
@@ -130,4 +119,5 @@
 	spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
 	waitq_initialize(&box->wq);
+	link_initialize(&box->sync_box_link);
 	list_initialize(&box->connected_phones);
 	list_initialize(&box->calls);
@@ -179,15 +169,41 @@
 int ipc_call_sync(phone_t *phone, call_t *request)
 {
-	answerbox_t sync_box; 
-
-	ipc_answerbox_init(&sync_box, TASK);
+	answerbox_t *sync_box; 
+	ipl_t ipl;
+
+	sync_box = slab_alloc(ipc_answerbox_slab, 0);
+	ipc_answerbox_init(sync_box, TASK);
+
+	/*
+	 * Put the answerbox on the TASK's list of synchronous answerboxes so
+	 * that it can be cleaned up if the call is interrupted.
+	 */
+	ipl = interrupts_disable();
+	spinlock_lock(&TASK->lock);
+	list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
+	spinlock_unlock(&TASK->lock);
+	interrupts_restore(ipl);
 
 	/* We will receive data in a special box. */
-	request->callerbox = &sync_box;
+	request->callerbox = sync_box;
 
 	ipc_call(phone, request);
-	if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT,
-	    SYNCH_FLAGS_INTERRUPTIBLE))
+	if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
+	    SYNCH_FLAGS_INTERRUPTIBLE)) {
+	    	/* The answerbox and the call will be freed by ipc_cleanup(). */
 		return EINTR;
+	}
+
+	/*
+	 * The answer arrived without interruption so we can remove the
+	 * answerbox from the TASK's list of synchronous answerboxes.
+	 */
+	(void) interrupts_disable();
+	spinlock_lock(&TASK->lock);
+	list_remove(&sync_box->sync_box_link);
+	spinlock_unlock(&TASK->lock);
+	interrupts_restore(ipl);
+
+	slab_free(ipc_answerbox_slab, sync_box);
 	return EOK;
 }
@@ -520,4 +536,5 @@
 	int i;
 	call_t *call;
+	ipl_t ipl;
 
 	/* Disconnect all our phones ('ipc_phone_hangup') */
@@ -545,5 +562,19 @@
 	spinlock_unlock(&TASK->answerbox.lock);
 	
-	/* Wait for all async answers to arrive */
+	/* Wait for all answers to interrupted synchronous calls to arrive */
+	ipl = interrupts_disable();
+	while (!list_empty(&TASK->sync_box_head)) {
+		answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
+		    answerbox_t, sync_box_link);
+
+		list_remove(&box->sync_box_link);
+		call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
+		    SYNCH_FLAGS_NONE);
+		ipc_call_free(call);
+		slab_free(ipc_answerbox_slab, box);
+	}
+	interrupts_restore(ipl);
+
+	/* Wait for all answers to asynchronous calls to arrive */
 	while (1) {
 		/* Go through all phones, until all are FREE... */
@@ -552,6 +583,8 @@
 		for (i = 0; i < IPC_MAX_PHONES; i++) {
 			if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
-			    atomic_get(&TASK->phones[i].active_calls) == 0)
+			    atomic_get(&TASK->phones[i].active_calls) == 0) {
 				TASK->phones[i].state = IPC_PHONE_FREE;
+				TASK->phones[i].callee = NULL;
+			}
 			
 			/* Just for sure, we might have had some 
@@ -574,5 +607,4 @@
 		ASSERT((call->flags & IPC_CALL_ANSWERED) ||
 		    (call->flags & IPC_CALL_NOTIF));
-		ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
 		
 		/*
@@ -593,4 +625,6 @@
 	ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL,
 	    NULL, 0);
+	ipc_answerbox_slab = slab_cache_create("ipc_answerbox",
+	    sizeof(answerbox_t), 0, NULL, NULL, 0);
 }
 
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/ipc/irq.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -418,5 +418,4 @@
 		case CMD_ACCEPT:
 			return IRQ_ACCEPT;
-			break;
 		case CMD_DECLINE:
 		default:
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/ipc/sysipc.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -61,5 +61,5 @@
 { \
 	if (phoneid > IPC_MAX_PHONES) { \
-		err; \
+		err \
 	} \
 	phone = &TASK->phones[phoneid]; \
@@ -122,5 +122,4 @@
 	case IPC_M_DATA_READ:
 		return 1;
-		break;
 	default:
 		return 0;
@@ -376,5 +375,5 @@
 		phone_t *cloned_phone;
 		GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data),
-		    return ENOENT);
+		    return ENOENT;);
 		phones_lock(cloned_phone, phone);
 		if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
@@ -531,39 +530,42 @@
     unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data)
 {
-	call_t call;
+	call_t *call;
 	phone_t *phone;
 	int res;
 	int rc;
 	
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT);
-
-	ipc_call_static_init(&call);
-	IPC_SET_METHOD(call.data, method);
-	IPC_SET_ARG1(call.data, arg1);
-	IPC_SET_ARG2(call.data, arg2);
-	IPC_SET_ARG3(call.data, arg3);
+	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+
+	call = ipc_call_alloc(0);
+	IPC_SET_METHOD(call->data, method);
+	IPC_SET_ARG1(call->data, arg1);
+	IPC_SET_ARG2(call->data, arg2);
+	IPC_SET_ARG3(call->data, arg3);
 	/*
 	 * To achieve deterministic behavior, zero out arguments that are beyond
 	 * the limits of the fast version.
 	 */
-	IPC_SET_ARG4(call.data, 0);
-	IPC_SET_ARG5(call.data, 0);
-
-	if (!(res = request_preprocess(&call, phone))) {
+	IPC_SET_ARG4(call->data, 0);
+	IPC_SET_ARG5(call->data, 0);
+
+	if (!(res = request_preprocess(call, phone))) {
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_begin();
 #endif
-		rc = ipc_call_sync(phone, &call);
+		rc = ipc_call_sync(phone, call);
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_end();
 #endif
-		if (rc != EOK)
+		if (rc != EOK) {
+			/* The call will be freed by ipc_cleanup(). */
 			return rc;
-		process_answer(&call);
+		}
+		process_answer(call);
 
 	} else {
-		IPC_SET_RETVAL(call.data, res);
-	}
-	rc = STRUCT_TO_USPACE(&data->args, &call.data.args);
+		IPC_SET_RETVAL(call->data, res);
+	}
+	rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
+	ipc_call_free(call);
 	if (rc != 0)
 		return rc;
@@ -584,32 +586,38 @@
     ipc_data_t *reply)
 {
-	call_t call;
+	call_t *call;
 	phone_t *phone;
 	int res;
 	int rc;
 
-	ipc_call_static_init(&call);
-	rc = copy_from_uspace(&call.data.args, &question->args,
-	    sizeof(call.data.args));
-	if (rc != 0)
+	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+
+	call = ipc_call_alloc(0);
+	rc = copy_from_uspace(&call->data.args, &question->args,
+	    sizeof(call->data.args));
+	if (rc != 0) {
+		ipc_call_free(call);
 		return (unative_t) rc;
-
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT);
-
-	if (!(res = request_preprocess(&call, phone))) {
+	}
+
+
+	if (!(res = request_preprocess(call, phone))) {
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_begin();
 #endif
-		rc = ipc_call_sync(phone, &call);
+		rc = ipc_call_sync(phone, call);
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_end();
 #endif
-		if (rc != EOK)
+		if (rc != EOK) {
+			/* The call will be freed by ipc_cleanup(). */
 			return rc;
-		process_answer(&call);
+		}
+		process_answer(call);
 	} else 
-		IPC_SET_RETVAL(call.data, res);
-
-	rc = STRUCT_TO_USPACE(&reply->args, &call.data.args);
+		IPC_SET_RETVAL(call->data, res);
+
+	rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
+	ipc_call_free(call);
 	if (rc != 0)
 		return rc;
@@ -658,5 +666,5 @@
 		return IPC_CALLRET_TEMPORARY;
 
-	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
+	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;);
 
 	call = ipc_call_alloc(0);
@@ -697,5 +705,5 @@
 		return IPC_CALLRET_TEMPORARY;
 
-	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
+	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;);
 
 	call = ipc_call_alloc(0);
@@ -747,5 +755,5 @@
 	call->flags |= IPC_CALL_FORWARDED;
 
-	GET_CHECK_PHONE(phone, phoneid, { 
+	GET_CHECK_PHONE(phone, phoneid, {
 		IPC_SET_RETVAL(call->data, EFORWARD);
 		ipc_answer(&TASK->answerbox, call);
@@ -952,5 +960,5 @@
 	phone_t *phone;
 
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT);
+	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
 
 	if (ipc_phone_hangup(phone))
@@ -991,6 +999,4 @@
 
 	if (call->flags & IPC_CALL_NOTIF) {
-		ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
-
 		/* Set in_phone_hash to the interrupt counter */
 		call->data.phone = (void *) call->priv;
@@ -1005,6 +1011,4 @@
 	if (call->flags & IPC_CALL_ANSWERED) {
 		process_answer(call);
-
-		ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
 
 		if (call->flags & IPC_CALL_DISCARD_ANSWER) {
Index: kernel/generic/src/lib/elf.c
===================================================================
--- kernel/generic/src/lib/elf.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/lib/elf.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -163,5 +163,4 @@
 	case PT_LOAD:
 		return load_segment(entry, elf, as);
-		break;
 	case PT_DYNAMIC:
 	case PT_INTERP:
@@ -182,5 +181,4 @@
 	default:
 		return EE_UNSUPPORTED;
-		break;
 	}
 	return EE_OK;
Index: kernel/generic/src/lib/string.c
===================================================================
--- kernel/generic/src/lib/string.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/lib/string.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -537,5 +537,5 @@
  * null-terminated and containing only complete characters.
  *
- * @param dst   Destination buffer.
+ * @param dest   Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
@@ -571,5 +571,5 @@
  * have to be null-terminated.
  *
- * @param dst   Destination buffer.
+ * @param dest   Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
@@ -596,36 +596,32 @@
 }
 
-/** Copy NULL-terminated wide string to string
- *
- * Copy source wide string @a src to destination buffer @a dst.
- * No more than @a size bytes are written. NULL-terminator is always
- * written after the last succesfully copied character (i.e. if the
- * destination buffer is has at least 1 byte, it will be always
- * NULL-terminated).
- *
- * @param src   Source wide string.
- * @param dst   Destination buffer.
- * @param count Size of the destination buffer.
- *
- */
-void wstr_nstr(char *dst, const wchar_t *src, size_t size)
-{
-	/* No space for the NULL-terminator in the buffer */
-	if (size == 0)
-		return;
-	
+/** Convert wide string to string.
+ *
+ * Convert wide string @a src to string. The output is written to the buffer
+ * specified by @a dest and @a size. @a size must be non-zero and the string
+ * written will always be well-formed.
+ *
+ * @param dest	Destination buffer.
+ * @param size	Size of the destination buffer.
+ * @param src	Source wide string.
+ */
+void wstr_to_str(char *dest, size_t size, const wchar_t *src)
+{
 	wchar_t ch;
-	size_t src_idx = 0;
-	size_t dst_off = 0;
+	size_t src_idx;
+	size_t dest_off;
+
+	/* There must be space for a null terminator in the buffer. */
+	ASSERT(size > 0);
+
+	src_idx = 0;
+	dest_off = 0;
 	
 	while ((ch = src[src_idx++]) != 0) {
-		if (chr_encode(ch, dst, &dst_off, size) != EOK)
+		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
-	
-	if (dst_off >= size)
-		dst[size - 1] = 0;
-	else
-		dst[dst_off] = 0;
+
+	dest[dest_off] = '\0';
 }
 
Index: kernel/generic/src/mm/backend_phys.c
===================================================================
--- kernel/generic/src/mm/backend_phys.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/mm/backend_phys.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -40,4 +40,5 @@
 #include <arch/types.h>
 #include <mm/as.h>
+#include <mm/page.h>
 #include <mm/frame.h>
 #include <mm/slab.h>
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/proc/task.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -54,4 +54,5 @@
 #include <func.h>
 #include <string.h>
+#include <memstr.h>
 #include <syscall/copy.h>
 #include <macros.h>
@@ -75,6 +76,9 @@
 static task_id_t task_counter = 0;
 
+static slab_cache_t *task_slab;
+
 /* Forward declarations. */
 static void task_kill_internal(task_t *);
+static int tsk_constructor(void *, int);
 
 /** Initialize kernel tasks support. */
@@ -83,4 +87,6 @@
 	TASK = NULL;
 	avltree_create(&tasks_tree);
+	task_slab = slab_cache_create("task_slab", sizeof(task_t), 0,
+	    tsk_constructor, NULL, 0);
 }
 
@@ -128,4 +134,33 @@
 }
 
+int tsk_constructor(void *obj, int kmflags)
+{
+	task_t *ta = obj;
+	int i;
+
+	atomic_set(&ta->refcount, 0);
+	atomic_set(&ta->lifecount, 0);
+	atomic_set(&ta->active_calls, 0);
+
+	spinlock_initialize(&ta->lock, "task_ta_lock");
+	mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
+
+	list_initialize(&ta->th_head);
+	list_initialize(&ta->sync_box_head);
+
+	ipc_answerbox_init(&ta->answerbox, ta);
+	for (i = 0; i < IPC_MAX_PHONES; i++)
+		ipc_phone_init(&ta->phones[i]);
+
+#ifdef CONFIG_UDEBUG
+	/* Init kbox stuff */
+	ta->kb.thread = NULL;
+	ipc_answerbox_init(&ta->kb.box, ta);
+	mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
+#endif
+
+	return 0;
+}
+
 /** Create new task with no threads.
  *
@@ -140,21 +175,12 @@
 	ipl_t ipl;
 	task_t *ta;
-	int i;
-	
-	ta = (task_t *) malloc(sizeof(task_t), 0);
-
+	
+	ta = (task_t *) slab_alloc(task_slab, 0);
 	task_create_arch(ta);
-
-	spinlock_initialize(&ta->lock, "task_ta_lock");
-	list_initialize(&ta->th_head);
 	ta->as = as;
-
 	memcpy(ta->name, name, TASK_NAME_BUFLEN);
 	ta->name[TASK_NAME_BUFLEN - 1] = 0;
 
-	atomic_set(&ta->refcount, 0);
-	atomic_set(&ta->lifecount, 0);
 	ta->context = CONTEXT;
-
 	ta->capabilities = 0;
 	ta->cycles = 0;
@@ -165,28 +191,15 @@
 
 	/* Init kbox stuff */
-	ipc_answerbox_init(&ta->kb.box, ta);
-	ta->kb.thread = NULL;
-	mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
 	ta->kb.finished = false;
 #endif
 
-	ipc_answerbox_init(&ta->answerbox, ta);
-	for (i = 0; i < IPC_MAX_PHONES; i++)
-		ipc_phone_init(&ta->phones[i]);
-	if ((ipc_phone_0) && (context_check(ipc_phone_0->task->context,
-	    ta->context)))
+	if ((ipc_phone_0) &&
+	    (context_check(ipc_phone_0->task->context, ta->context)))
 		ipc_phone_connect(&ta->phones[0], ipc_phone_0);
-	atomic_set(&ta->active_calls, 0);
-
-	mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
+
 	btree_create(&ta->futexes);
 	
 	ipl = interrupts_disable();
-
-	/*
-	 * Increment address space reference count.
-	 */
 	atomic_inc(&as->refcount);
-
 	spinlock_lock(&tasks_lock);
 	ta->taskid = ++task_counter;
@@ -229,5 +242,5 @@
 		as_destroy(t->as);
 	
-	free(t);
+	slab_free(task_slab, t);
 	TASK = NULL;
 }
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/proc/thread.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -501,5 +501,12 @@
 void thread_sleep(uint32_t sec)
 {
-	thread_usleep(sec * 1000000);
+	/* Sleep in 1000 second steps to support
+	   full argument range */
+	while (sec > 0) {
+		uint32_t period = (sec > 1000) ? 1000 : sec;
+	
+		thread_usleep(period * 1000000);
+		sec -= period;
+	}
 }
 
@@ -575,7 +582,7 @@
 {
 	waitq_t wq;
-				  
+	
 	waitq_initialize(&wq);
-
+	
 	(void) waitq_sleep_timeout(&wq, usec, SYNCH_FLAGS_NON_BLOCKING);
 }
@@ -812,4 +819,11 @@
 }
 
+/** Syscall wrapper for sleeping. */
+unative_t sys_thread_usleep(uint32_t usec)
+{
+	thread_usleep(usec);
+	return 0;
+}
+
 /** @}
  */
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/synch/futex.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -90,5 +90,5 @@
 /** Initialize kernel futex structure.
  *
- * @param futex Kernel futex structure.
+ * @param futex		Kernel futex structure.
  */
 void futex_initialize(futex_t *futex)
@@ -102,13 +102,11 @@
 /** Sleep in futex wait queue.
  *
- * @param uaddr Userspace address of the futex counter.
- * @param usec If non-zero, number of microseconds this thread is willing to
- *     sleep.
- * @param flags Select mode of operation.
- *
- * @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See
- *     synch.h. If there is no physical mapping for uaddr ENOENT is returned.
- */
-unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags)
+ * @param uaddr		Userspace address of the futex counter.
+ *
+ * @return		If there is no physical mapping for uaddr ENOENT is
+ *			returned. Otherwise returns a wait result as defined in
+ *			synch.h.
+ */
+unative_t sys_futex_sleep(uintptr_t uaddr)
 {
 	futex_t *futex;
@@ -140,7 +138,5 @@
 	udebug_stoppable_begin();
 #endif
-	rc = waitq_sleep_timeout(&futex->wq, usec, flags |
-	    SYNCH_FLAGS_INTERRUPTIBLE);
-
+	rc = waitq_sleep_timeout(&futex->wq, 0, SYNCH_FLAGS_INTERRUPTIBLE); 
 #ifdef CONFIG_UDEBUG
 	udebug_stoppable_end();
@@ -151,7 +147,7 @@
 /** Wakeup one thread waiting in futex wait queue.
  *
- * @param uaddr Userspace address of the futex counter.
- *
- * @return ENOENT if there is no physical mapping for uaddr.
+ * @param uaddr		Userspace address of the futex counter.
+ *
+ * @return		ENOENT if there is no physical mapping for uaddr.
  */
 unative_t sys_futex_wakeup(uintptr_t uaddr)
@@ -190,7 +186,7 @@
  * If the structure does not exist already, a new one is created.
  *
- * @param paddr Physical address of the userspace futex counter.
- *
- * @return Address of the kernel futex structure.
+ * @param paddr		Physical address of the userspace futex counter.
+ *
+ * @return		Address of the kernel futex structure.
  */
 futex_t *futex_find(uintptr_t paddr)
@@ -284,8 +280,8 @@
 /** Compute hash index into futex hash table.
  *
- * @param key Address where the key (i.e. physical address of futex counter) is
- *     stored.
- *
- * @return Index into futex hash table.
+ * @param key		Address where the key (i.e. physical address of futex
+ *			counter) is stored.
+ *
+ * @return		Index into futex hash table.
  */
 size_t futex_ht_hash(unative_t *key)
@@ -296,8 +292,8 @@
 /** Compare futex hash table item with a key.
  *
- * @param key Address where the key (i.e. physical address of futex counter) is
- *     stored.
- *
- * @return True if the item matches the key. False otherwise.
+ * @param key		Address where the key (i.e. physical address of futex
+ *			counter) is stored.
+ *
+ * @return		True if the item matches the key. False otherwise.
  */
 bool futex_ht_compare(unative_t *key, size_t keys, link_t *item)
@@ -313,5 +309,5 @@
 /** Callback for removal items from futex hash table.
  *
- * @param item Item removed from the hash table.
+ * @param item		Item removed from the hash table.
  */
 void futex_ht_remove_callback(link_t *item)
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/syscall/syscall.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -62,13 +62,9 @@
 
 #ifdef CONFIG_UDEBUG
-	bool debug;
-
 	/*
 	 * Early check for undebugged tasks. We do not lock anything as this
-	 * test need not be precise in either way.
+	 * test need not be precise in either direction.
 	 */
-	debug = THREAD->udebug.active;
-	
-	if (debug) {
+	if (THREAD->udebug.active) {
 		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
 	}
@@ -87,5 +83,5 @@
 	
 #ifdef CONFIG_UDEBUG
-	if (debug) {
+	if (THREAD->udebug.active) {
 		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
 	
@@ -111,4 +107,5 @@
 	(syshandler_t) sys_thread_exit,
 	(syshandler_t) sys_thread_get_id,
+	(syshandler_t) sys_thread_usleep,
 	
 	(syshandler_t) sys_task_get_id,
@@ -117,5 +114,5 @@
 	
 	/* Synchronization related syscalls. */
-	(syshandler_t) sys_futex_sleep_timeout,
+	(syshandler_t) sys_futex_sleep,
 	(syshandler_t) sys_futex_wakeup,
 	(syshandler_t) sys_smc_coherence,
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision 245e8399f3d58ad45fc1730f6b948b33ae3ab8df)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision bb2dbf88d72dd244fa90e89382fa5ad58f348fba)
@@ -50,4 +50,5 @@
 #include <udebug/udebug.h>
 #include <udebug/udebug_ops.h>
+#include <memstr.h>
 
 /**
