Index: Makefile
===================================================================
--- Makefile	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ Makefile	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -30,8 +30,5 @@
 #
 
-CSCOPE = cscope
-STANSE = stanse
-
-.PHONY: all config config_default distclean clean cscope stanse
+.PHONY: all config config_default distclean clean cscope
 
 all: Makefile.config config.h config.defs
@@ -39,12 +36,4 @@
 	$(MAKE) -C uspace
 	$(MAKE) -C boot
-
-stanse: Makefile.config config.h config.defs
-	$(MAKE) -C kernel clean
-	$(MAKE) -C kernel EXTRA_TOOL=stanse
-	$(STANSE) --checker ReachabilityChecker --jobfile kernel/kernel.job
-
-cscope:
-	find kernel boot uspace -regex '^.*\.[chsS]$$' | xargs $(CSCOPE) -b -k -u -f$(CSCOPE).out
 
 Makefile.config: config_default
@@ -61,8 +50,13 @@
 
 distclean: clean
-	rm -f $(CSCOPE).out Makefile.config config.h config.defs tools/*.pyc
+	rm -f Makefile.config config.h config.defs tools/*.pyc
 
 clean:
-	$(MAKE) -C kernel clean
-	$(MAKE) -C uspace clean
-	$(MAKE) -C boot clean
+	-$(MAKE) -C kernel clean
+	-$(MAKE) -C uspace clean
+	-$(MAKE) -C boot clean
+
+cscope:
+	find kernel boot uspace -regex '^.*\.[chsS]$$' -print > srclist
+	rm -f cscope.out
+	cscope -bi srclist
Index: ntrib/bazaar/mbprotect/__init__.py
===================================================================
--- contrib/bazaar/mbprotect/__init__.py	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ 	(revision )
@@ -1,72 +1,0 @@
-#
-# Copyright (c) 2009 Jiri Svoboda
-# 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.
-#
-
-"""Main Branch Protection plugin for Bazaar."""
-
-#
-# This plugin employs the pre_change_branch_tip hook to protect the main
-# branch (a.k.a. linear history) of bzr repositories from unwanted change,
-# effectively making the main branch append-only.
-# 
-# Specifically we verify that the new main branch contains the old tip.
-# This prevents a branch from inadvertently aquiring the tip of another branch.
-#
-# Install this plugin in ~/.bazaar/plugins/mbprotect
-#
-# See also http://trac.helenos.org/trac.fcgi/wiki/BazaarWorkflow
-#
-
-import bzrlib.branch
-from bzrlib.errors import TipChangeRejected
-
-def pre_change_branch_tip(params):
-    repo = params.branch.repository
-
-    # Check if the old repository was empty.
-    if params.old_revid == 'null:':
-	return
-
-    # First permitted case is appending changesets to main branch.Look for
-    # old tip in new main branch.
-    for revision_id in repo.iter_reverse_revision_history(params.new_revid):
-	if revision_id == params.old_revid:
-	    return	# Found old tip
-
-    # Another permitted case is backing out changesets. Look for new tip
-    # in old branch.
-    for revision_id in repo.iter_reverse_revision_history(params.old_revid):
-	if revision_id == params.new_revid:
-	    return	# Found new tip
-
-    # Trying to do something else. Reject the change.
-    raise TipChangeRejected('Bad tip. Read http://trac.helenos.org/trac.fcgi/' +
-	'wiki/BazaarWorkflow')
-
-# Install hook.
-bzrlib.branch.Branch.hooks.install_named_hook('pre_change_branch_tip',
-    pre_change_branch_tip, 'MB-Protect tip check')
Index: ntrib/stanse/ThreadChecker.xml
===================================================================
--- contrib/stanse/ThreadChecker.xml	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ 	(revision )
@@ -1,52 +1,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-
- Copyright (c) 2009 Martin Decky
- 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.
-
--->
-
-<threadChecker>
-	<analyseType type="local" />
-	<patterns>
-		<pattern name="lockFunction">
-			<nested>
-				<functionCall>
-					<id>_mutex_lock_timeout</id>
-					<var name="mtx" />
-				</functionCall>
-			</nested>
-		</pattern>
-		<pattern name="unlockFunction">
-			<nested>
-				<functionCall>
-					<id>mutex_unlock</id>
-					<var name="mtx" />
-				</functionCall>
-			</nested>
-		</pattern>
-	</patterns>
-</threadChecker>
Index: contrib/toolchain.sh
===================================================================
--- contrib/toolchain.sh	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ contrib/toolchain.sh	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -92,33 +92,10 @@
 }
 
-patch_binutils() {
-	PLATFORM="$1"
-	
-	if [ "${PLATFORM}" == "arm32" ] ; then
-		patch -p1 <<EOF
-diff -Naur binutils-2.20.orig/gas/config/tc-arm.c binutils-2.20/gas/config/tc-arm.c
---- binutils-2.20.orig/gas/config/tc-arm.c	2009-08-30 00:10:59.000000000 +0200
-+++ binutils-2.20/gas/config/tc-arm.c	2009-11-02 14:25:11.000000000 +0100
-@@ -2485,8 +2485,9 @@
-       know (frag->tc_frag_data.first_map == NULL);
-       frag->tc_frag_data.first_map = symbolP;
-     }
--  if (frag->tc_frag_data.last_map != NULL)
-+  if (frag->tc_frag_data.last_map != NULL) {
-     know (S_GET_VALUE (frag->tc_frag_data.last_map) < S_GET_VALUE (symbolP));
-+  }
-   frag->tc_frag_data.last_map = symbolP;
- }
-EOF
-		check_error $? "Error patching binutils"
-	fi
-}
-
 build_target() {
 	PLATFORM="$1"
 	TARGET="$2"
 	
-	BINUTILS_VERSION="2.20"
-	GCC_VERSION="4.4.2"
+	BINUTILS_VERSION="2.19.1"
+	GCC_VERSION="4.4.1"
 	
 	BINUTILS="binutils-${BINUTILS_VERSION}.tar.bz2"
@@ -142,8 +119,8 @@
 	
 	echo ">>> Downloading tarballs"
-	download_check "${BINUTILS_SOURCE}" "${BINUTILS}" "ee2d3e996e9a2d669808713360fa96f8"
-	download_check "${GCC_SOURCE}" "${GCC_CORE}" "d50ec5af20508974411d0c83c5f4e396"
-	download_check "${GCC_SOURCE}" "${GCC_OBJC}" "d8d26187d386a0591222a580b5a5b3d3"
-	download_check "${GCC_SOURCE}" "${GCC_CPP}" "43b1e4879eb282dc4b05e4c016d356d7"
+	download_check "${BINUTILS_SOURCE}" "${BINUTILS}" "09a8c5821a2dfdbb20665bc0bd680791"
+	download_check "${GCC_SOURCE}" "${GCC_CORE}" "d19693308aa6b2052e14c071111df59f"
+	download_check "${GCC_SOURCE}" "${GCC_OBJC}" "f7b2a606394036e81433b2f4c3251cba"
+	download_check "${GCC_SOURCE}" "${GCC_CPP}" "d449047b5761348ceec23739f5553e0b"
 	
 	echo ">>> Removing previous content"
@@ -165,5 +142,4 @@
 	cd "${BINUTILSDIR}"
 	check_error $? "Change directory failed."
-	patch_binutils "${PLATFORM}"
 	./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
 	check_error $? "Error configuring binutils."
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/Makefile	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -33,8 +33,7 @@
 all: ../version ../Makefile.config ../config.h ../config.defs
 	-[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
-	$(MAKE) -f Makefile.build EXTRA_TOOL=$(EXTRA_TOOL)
+	$(MAKE) -f Makefile.build
 
 clean:
-	rm -f $(DEPEND) $(DEPEND_PREV) $(RAW) $(BIN) $(MAP) $(JOB) $(MAP_PREV) $(DISASM) $(DUMP) $(REAL_MAP).* $(ARCH_INCLUDE) $(GENARCH_INCLUDE) arch/*/_link.ld
+	rm -f $(DEPEND) $(DEPEND_PREV) $(RAW) $(BIN) $(MAP) $(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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/Makefile.build	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -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 = gcc
+	GCC = $(CC)
 	AS = $(BINUTILS_PREFIX)as
 	LD = $(BINUTILS_PREFIX)ld
@@ -168,5 +168,4 @@
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
-
 
 ## Generic kernel sources
@@ -385,7 +384,4 @@
 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
 
 #
@@ -394,7 +390,4 @@
 %.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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/Makefile.common	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -36,5 +36,4 @@
 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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/amd64/include/mm/page.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -177,23 +177,5 @@
 #define PFERR_CODE_ID		(1 << 4)
 
-/** 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)
+static inline 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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/amd64/include/types.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -82,4 +82,22 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/amd64/src/amd64.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -67,5 +67,4 @@
 #include <ddi/irq.h>
 #include <sysinfo/sysinfo.h>
-#include <memstr.h>
 
 /** Disable I/O on non-privileged levels
Index: kernel/arch/arm32/include/atomic.h
===================================================================
--- kernel/arch/arm32/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/arm32/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -37,6 +37,4 @@
 #define KERN_arm32_ATOMIC_H_
 
-#include <arch/asm.h>
-
 /** Atomic addition.
  *
@@ -49,14 +47,19 @@
 static inline long atomic_add(atomic_t *val, int i)
 {
-	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);
+	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"
+	);
 	
 	return ret;
Index: kernel/arch/arm32/include/mm/page.h
===================================================================
--- kernel/arch/arm32/include/mm/page.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/arm32/include/mm/page.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -75,5 +75,5 @@
 /* Get PTE address accessors for each level. */
 #define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
-	((pte_t *) ((((pte_t *)(ptl0))[(i)].l0).coarse_table_addr << 10))
+	((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).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_t *)(ptl3))[(i)].l1).frame_base_addr << 12))
+	((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12))
 
 /* Set PTE address accessors for each level. */
 #define SET_PTL0_ADDRESS_ARCH(ptl0) \
-	(set_ptl0_addr((pte_t *) (ptl0)))
+	(set_ptl0_addr((pte_level0_t *) (ptl0)))
 #define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
-	(((pte_t *) (ptl0))[(i)].l0.coarse_table_addr = (a) >> 10)
+	(((pte_level0_t *) (ptl0))[(i)].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_t *) (ptl3))[(i)].l1.frame_base_addr = (a) >> 12)
+	(((pte_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12)
 
 /* Get PTE flags accessors for each level. */
 #define GET_PTL1_FLAGS_ARCH(ptl0, i) \
-	get_pt_level0_flags((pte_t *) (ptl0), (size_t) (i))
+	get_pt_level0_flags((pte_level0_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_t *) (ptl3), (size_t) (i))
+	get_pt_level1_flags((pte_level1_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_t *) (ptl0), (size_t) (i), (x))
+	set_pt_level0_flags((pte_level0_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_t *) (ptl3), (size_t) (i), (x))
+	set_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i), (x))
 
 /* Macros for querying the last-level PTE entries. */
@@ -115,9 +115,10 @@
 	(*((uint32_t *) (pte)) != 0)
 #define PTE_PRESENT_ARCH(pte) \
-	(((pte_t *) (pte))->l0.descriptor_type != 0)
+	(((pte_level0_t *) (pte))->descriptor_type != 0)
 #define PTE_GET_FRAME_ARCH(pte) \
-	(((pte_t *) (pte))->l1.frame_base_addr << FRAME_WIDTH)
+	(((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH)
 #define PTE_WRITABLE_ARCH(pte) \
-	(((pte_t *) (pte))->l1.access_permission_0 == PTE_AP_USER_RW_KERNEL_RW)
+	(((pte_level1_t *) (pte))->access_permission_0 == \
+	    PTE_AP_USER_RW_KERNEL_RW)
 #define PTE_EXECUTABLE_ARCH(pte) \
 	1
@@ -158,8 +159,4 @@
 } ATTRIBUTE_PACKED pte_level1_t;
 
-typedef union {
-	pte_level0_t l0;
-	pte_level1_t l1;
-} pte_t;
 
 /* Level 1 page tables access permissions */
@@ -194,5 +191,5 @@
  * @param pt    Pointer to the page table to set.
  */   
-static inline void set_ptl0_addr(pte_t *pt)
+static inline void set_ptl0_addr(pte_level0_t *pt)
 {
 	asm volatile (
@@ -208,7 +205,7 @@
  *  @param i      Index of the entry to return.
  */
-static inline int get_pt_level0_flags(pte_t *pt, size_t i)
-{
-	pte_level0_t *p = &pt[i].l0;
+static inline int get_pt_level0_flags(pte_level0_t *pt, size_t i)
+{
+	pte_level0_t *p = &pt[i];
 	int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT);
 
@@ -223,7 +220,7 @@
  *  @param i      Index of the entry to return.
  */
-static inline int get_pt_level1_flags(pte_t *pt, size_t i)
-{
-	pte_level1_t *p = &pt[i].l1;
+static inline int get_pt_level1_flags(pte_level1_t *pt, size_t i)
+{
+	pte_level1_t *p = &pt[i];
 
 	int dt = p->descriptor_type;
@@ -248,7 +245,7 @@
  *  @param flags  new flags
  */
-static inline void set_pt_level0_flags(pte_t *pt, size_t i, int flags)
-{
-	pte_level0_t *p = &pt[i].l0;
+static inline void set_pt_level0_flags(pte_level0_t *pt, size_t i, int flags)
+{
+	pte_level0_t *p = &pt[i];
 
 	if (flags & PAGE_NOT_PRESENT) {
@@ -276,7 +273,7 @@
  *  @param flags  New flags.
  */  
-static inline void set_pt_level1_flags(pte_t *pt, size_t i, int flags)
-{
-	pte_level1_t *p = &pt[i].l1;
+static inline void set_pt_level1_flags(pte_level1_t *pt, size_t i, int flags)
+{
+	pte_level1_t *p = &pt[i];
 	
 	if (flags & PAGE_NOT_PRESENT) {
Index: kernel/arch/arm32/include/types.h
===================================================================
--- kernel/arch/arm32/include/types.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/arm32/include/types.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -87,4 +87,13 @@
 #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/mm/as.c
===================================================================
--- kernel/arch/arm32/src/mm/as.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/arm32/src/mm/as.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -36,5 +36,4 @@
 #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>
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ia32/include/mm/page.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -146,21 +146,5 @@
 #define PFERR_CODE_RSVD		(1 << 3)	
 
-/** 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)
+static inline 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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ia32/include/types.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -80,4 +80,20 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ia32/src/ia32.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -68,5 +68,4 @@
 #include <sysinfo/sysinfo.h>
 #include <arch/boot/boot.h>
-#include <memstr.h>
 
 #ifdef CONFIG_SMP
Index: kernel/arch/ia64/src/cpu/cpu.c
===================================================================
--- kernel/arch/ia64/src/cpu/cpu.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ia64/src/cpu/cpu.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -37,5 +37,4 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/mips32/include/mm/page.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -141,19 +141,5 @@
 #include <arch/exception.h>
 
-/** 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)
+static inline 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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/mips32/include/types.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -80,4 +80,17 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ppc32/include/mm/page.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -131,16 +131,5 @@
 #include <arch/interrupt.h>
 
-/** 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)
+static inline 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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ppc32/include/types.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -82,4 +82,15 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ppc32/src/mm/as.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -35,5 +35,4 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ppc32/src/mm/tlb.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -38,5 +38,4 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/ppc32/src/ppc32.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -44,5 +44,4 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/arch/sparc64/src/mm/tlb.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -37,5 +37,4 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/genarch/include/mm/as_pt.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -36,5 +36,6 @@
 #define KERN_AS_PT_H_
 
-#include <arch/mm/page.h>
+#include <mm/mm.h>
+#include <arch/types.h>
 
 #define AS_PAGE_TABLE
Index: kernel/genarch/include/mm/page_pt.h
===================================================================
--- kernel/genarch/include/mm/page_pt.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/genarch/include/mm/page_pt.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -44,8 +44,7 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/genarch/src/drivers/via-cuda/cuda.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -41,5 +41,4 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/genarch/src/fb/fb.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -41,5 +41,4 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/include/arch.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -39,5 +39,4 @@
 #include <proc/thread.h>
 #include <proc/task.h>
-#include <mm/as.h>
 
 #define DEFAULT_CONTEXT		0
Index: kernel/generic/include/context.h
===================================================================
--- kernel/generic/include/context.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/include/context.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -51,29 +51,17 @@
 /** Save register context.
  *
- * Save the current register context (including stack pointer) to a context
- * structure. A subsequent call to context_restore() will return to the same
+ * Save current register context (including stack pointers)
+ * to context structure.
+ *
+ * Note that call to context_restore() will return at the same
  * address as the corresponding call to context_save().
  *
- * Note that context_save_arch() must reuse the stack frame of the function
- * which called context_save(). We guarantee this by:
+ * This MUST be a macro, gcc -O0 does not inline functions even
+ * if they are marked inline and context_save_arch must be called
+ * from level <= that when context_restore is called.
  *
- *   a) implementing context_save_arch() in assembly so that it does not create
- *      its own stack frame, and by
- *   b) defining context_save() as a macro because the inline keyword is just a
- *      hint for the compiler, not a real constraint; the application of a macro
- *      will definitely not create a stack frame either.
+ * @param c Context structure.
  *
- * To imagine what could happen if there were some extra stack frames created
- * either by context_save() or context_save_arch(), we need to realize that the
- * sp saved in the contex_t structure points to the current stack frame as it
- * existed when context_save_arch() was executing. After the return from
- * context_save_arch() and context_save(), any extra stack frames created by
- * these functions will be destroyed and their contents sooner or later
- * overwritten by functions called next. Any attempt to restore to a context
- * saved like that would therefore lead to a disaster.
- *
- * @param c		Context structure.
- *
- * @return		context_save() returns 1, context_restore() returns 0.
+ * @return context_save() returns 1, context_restore() returns 0.
  */
 #define context_save(c)   context_save_arch(c)
@@ -81,12 +69,13 @@
 /** Restore register context.
  *
- * Restore a previously saved register context (including stack pointer) from
- * a context structure.
+ * Restore previously saved register context (including stack pointers)
+ * from context structure.
  *
- * Note that this function does not normally return.  Instead, it returns to the
- * same address as the corresponding call to context_save(), the only difference
- * being return value.
+ * Note that this function does not normally return.
+ * Instead, it returns at the same address as the
+ * corresponding call to context_save(), the only
+ * difference being return value.
  *
- * @param c		Context structure.
+ * @param c Context structure.
  */
 static inline void context_restore(context_t *c)
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/include/ipc/ipc.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -51,12 +51,14 @@
 /** 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 << 1)
+#define IPC_CALL_DISCARD_ANSWER	(1 << 2)
 /** Call was forwarded */
-#define IPC_CALL_FORWARDED	(1 << 2)
+#define IPC_CALL_FORWARDED	(1 << 3)
 /** Identify connect_me_to answer */
-#define IPC_CALL_CONN_ME_TO	(1 << 3)
+#define IPC_CALL_CONN_ME_TO	(1 << 4)
 /** Interrupt notification */
-#define IPC_CALL_NOTIF		(1 << 4)
+#define IPC_CALL_NOTIF		(1 << 5)
 
 /*
@@ -265,7 +267,4 @@
 	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;
@@ -317,31 +316,25 @@
 } call_t;
 
-
-extern answerbox_t *ipc_phone_0;
-
-
 extern void ipc_init(void);
-
-extern call_t * ipc_call_alloc(int);
-extern void ipc_call_free(call_t *);
-
+extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int);
+extern void ipc_answer(answerbox_t *, 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 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_answerbox_init(answerbox_t *, struct task *);
-
-extern void ipc_cleanup(void);
 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 void ipc_print_task(task_id_t);
+extern answerbox_t *ipc_phone_0;
 
 #endif
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/include/proc/task.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -55,5 +55,4 @@
 #include <udebug/udebug.h>
 #include <ipc/kbox.h>
-#include <mm/as.h>
 
 #define TASK_NAME_BUFLEN	20
@@ -99,6 +98,4 @@
 	 */
 	atomic_t active_calls;
-	/** List of synchronous answerboxes. */
-	link_t sync_box_head;
 
 #ifdef CONFIG_UDEBUG
@@ -135,5 +132,4 @@
 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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/include/proc/thread.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -225,33 +225,34 @@
 
 extern void thread_init(void);
-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 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 void thread_exit(void) __attribute__((noreturn));
 
 #ifndef thread_create_arch
-extern void thread_create_arch(thread_t *);
+extern void thread_create_arch(thread_t *t);
 #endif
 #ifndef thr_constructor_arch
-extern void thr_constructor_arch(thread_t *);
+extern void thr_constructor_arch(thread_t *t);
 #endif
 #ifndef thr_destructor_arch
-extern void thr_destructor_arch(thread_t *);
-#endif
-
-extern void thread_sleep(uint32_t);
-extern void thread_usleep(uint32_t);
+extern void thr_destructor_arch(thread_t *t);
+#endif
+
+extern void thread_sleep(uint32_t sec);
+extern void thread_usleep(uint32_t usec);
 
 #define thread_join(t) \
 	thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
-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 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 void thread_print_list(void);
-extern void thread_destroy(thread_t *);
+extern void thread_destroy(thread_t *t);
 extern void thread_update_accounting(void);
-extern bool thread_exists(thread_t *);
+extern bool thread_exists(thread_t *t);
 
 /** Fpu context slab cache. */
@@ -259,9 +260,8 @@
 
 /* Thread syscall prototypes. */
-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);
+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);
 
 #endif
Index: kernel/generic/include/string.h
===================================================================
--- kernel/generic/include/string.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/include/string.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -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_to_str(char *dest, size_t size, const wchar_t *src);
+extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
 extern char *str_chr(const char *str, wchar_t ch);
Index: kernel/generic/include/synch/futex.h
===================================================================
--- kernel/generic/include/synch/futex.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/include/synch/futex.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -38,4 +38,6 @@
 #include <arch/types.h>
 #include <synch/waitq.h>
+#include <genarch/mm/page_ht.h>
+#include <genarch/mm/page_pt.h>
 
 /** Kernel-side futex structure. */
@@ -52,6 +54,7 @@
 
 extern void futex_init(void);
-extern unative_t sys_futex_sleep(uintptr_t);
-extern unative_t sys_futex_wakeup(uintptr_t);
+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 void futex_cleanup(void);
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/include/syscall/syscall.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -43,5 +43,4 @@
 	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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/console/console.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -319,15 +319,15 @@
 	
 	if (size > PAGE_SIZE)
-		return (unative_t) ELIMIT;
+		return ELIMIT;
 	
 	if (size > 0) {
 		data = (char *) malloc(size + 1, 0);
 		if (!data)
-			return (unative_t) ENOMEM;
+			return ENOMEM;
 		
 		rc = copy_from_uspace(data, buf, size);
 		if (rc) {
 			free(data);
-			return (unative_t) rc;
+			return rc;
 		}
 		data[size] = 0;
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/console/kconsole.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -289,5 +289,5 @@
 			
 			char tmp[STR_BOUNDS(MAX_CMDLINE)];
-			wstr_to_str(tmp, position - beg + 1, current + beg);
+			wstr_nstr(tmp, current + beg, position - beg + 1);
 			
 			int found;
@@ -665,5 +665,5 @@
 		
 		char cmdline[STR_BOUNDS(MAX_CMDLINE)];
-		wstr_to_str(cmdline, STR_BOUNDS(MAX_CMDLINE), tmp);
+		wstr_nstr(cmdline, tmp, STR_BOUNDS(MAX_CMDLINE));
 		
 		if ((!kcon) && (len == 4) && (str_lcmp(cmdline, "exit", 4) == 0))
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/ipc/ipc.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -62,5 +62,4 @@
 
 static slab_cache_t *ipc_call_slab;
-static slab_cache_t *ipc_answerbox_slab;
 
 /** Initialize a call structure.
@@ -97,4 +96,15 @@
 }
 
+/** 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.
  *
@@ -103,4 +113,5 @@
 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)
@@ -119,5 +130,4 @@
 	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);
@@ -169,41 +179,15 @@
 int ipc_call_sync(phone_t *phone, call_t *request)
 {
-	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);
+	answerbox_t sync_box; 
+
+	ipc_answerbox_init(&sync_box, TASK);
 
 	/* 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)) {
-	    	/* The answerbox and the call will be freed by ipc_cleanup(). */
+	if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT,
+	    SYNCH_FLAGS_INTERRUPTIBLE))
 		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;
 }
@@ -536,5 +520,4 @@
 	int i;
 	call_t *call;
-	ipl_t ipl;
 
 	/* Disconnect all our phones ('ipc_phone_hangup') */
@@ -562,19 +545,5 @@
 	spinlock_unlock(&TASK->answerbox.lock);
 	
-	/* 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 */
+	/* Wait for all async answers to arrive */
 	while (1) {
 		/* Go through all phones, until all are FREE... */
@@ -583,8 +552,6 @@
 		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 
@@ -607,4 +574,5 @@
 		ASSERT((call->flags & IPC_CALL_ANSWERED) ||
 		    (call->flags & IPC_CALL_NOTIF));
+		ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
 		
 		/*
@@ -625,6 +593,4 @@
 	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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/ipc/irq.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -418,4 +418,5 @@
 		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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/ipc/sysipc.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -61,5 +61,5 @@
 { \
 	if (phoneid > IPC_MAX_PHONES) { \
-		err \
+		err; \
 	} \
 	phone = &TASK->phones[phoneid]; \
@@ -122,4 +122,5 @@
 	case IPC_M_DATA_READ:
 		return 1;
+		break;
 	default:
 		return 0;
@@ -375,5 +376,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) ||
@@ -530,42 +531,39 @@
     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;);
-
-	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);
+	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);
 	/*
 	 * 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) {
-			/* The call will be freed by ipc_cleanup(). */
+		if (rc != EOK)
 			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_call_free(call);
+		IPC_SET_RETVAL(call.data, res);
+	}
+	rc = STRUCT_TO_USPACE(&data->args, &call.data.args);
 	if (rc != 0)
 		return rc;
@@ -586,38 +584,32 @@
     ipc_data_t *reply)
 {
-	call_t *call;
+	call_t call;
 	phone_t *phone;
 	int res;
 	int rc;
 
-	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);
+	ipc_call_static_init(&call);
+	rc = copy_from_uspace(&call.data.args, &question->args,
+	    sizeof(call.data.args));
+	if (rc != 0)
 		return (unative_t) rc;
-	}
-
-
-	if (!(res = request_preprocess(call, phone))) {
+
+	GET_CHECK_PHONE(phone, phoneid, return ENOENT);
+
+	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) {
-			/* The call will be freed by ipc_cleanup(). */
+		if (rc != EOK)
 			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_call_free(call);
+		IPC_SET_RETVAL(call.data, res);
+
+	rc = STRUCT_TO_USPACE(&reply->args, &call.data.args);
 	if (rc != 0)
 		return rc;
@@ -666,5 +658,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);
@@ -705,5 +697,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);
@@ -755,5 +747,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);
@@ -960,5 +952,5 @@
 	phone_t *phone;
 
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+	GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
 	if (ipc_phone_hangup(phone))
@@ -999,4 +991,6 @@
 
 	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;
@@ -1011,4 +1005,6 @@
 	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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/lib/elf.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -163,4 +163,5 @@
 	case PT_LOAD:
 		return load_segment(entry, elf, as);
+		break;
 	case PT_DYNAMIC:
 	case PT_INTERP:
@@ -181,4 +182,5 @@
 	default:
 		return EE_UNSUPPORTED;
+		break;
 	}
 	return EE_OK;
Index: kernel/generic/src/lib/string.c
===================================================================
--- kernel/generic/src/lib/string.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/lib/string.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -537,5 +537,5 @@
  * null-terminated and containing only complete characters.
  *
- * @param dest   Destination buffer.
+ * @param dst   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 dest   Destination buffer.
+ * @param dst   Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
@@ -596,32 +596,36 @@
 }
 
-/** 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)
-{
+/** 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;
+	
 	wchar_t ch;
-	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;
+	size_t src_idx = 0;
+	size_t dst_off = 0;
 	
 	while ((ch = src[src_idx++]) != 0) {
-		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
+		if (chr_encode(ch, dst, &dst_off, size) != EOK)
 			break;
 	}
-
-	dest[dest_off] = '\0';
+	
+	if (dst_off >= size)
+		dst[size - 1] = 0;
+	else
+		dst[dst_off] = 0;
 }
 
Index: kernel/generic/src/mm/backend_phys.c
===================================================================
--- kernel/generic/src/mm/backend_phys.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/mm/backend_phys.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -40,5 +40,4 @@
 #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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/proc/task.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -54,5 +54,4 @@
 #include <func.h>
 #include <string.h>
-#include <memstr.h>
 #include <syscall/copy.h>
 #include <macros.h>
@@ -76,9 +75,6 @@
 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. */
@@ -87,6 +83,4 @@
 	TASK = NULL;
 	avltree_create(&tasks_tree);
-	task_slab = slab_cache_create("task_slab", sizeof(task_t), 0,
-	    tsk_constructor, NULL, 0);
 }
 
@@ -134,72 +128,65 @@
 }
 
-int tsk_constructor(void *obj, int kmflags)
-{
-	task_t *ta = obj;
+/** Create new task with no threads.
+ *
+ * @param as		Task's address space.
+ * @param name		Symbolic name (a copy is made).
+ *
+ * @return		New task's structure.
+ *
+ */
+task_t *task_create(as_t *as, char *name)
+{
+	ipl_t ipl;
+	task_t *ta;
 	int i;
+	
+	ta = (task_t *) malloc(sizeof(task_t), 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);
-	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);
+	ta->context = CONTEXT;
+
+	ta->capabilities = 0;
+	ta->cycles = 0;
+
+#ifdef CONFIG_UDEBUG
+	/* Init debugging stuff */
+	udebug_task_init(&ta->udebug);
+
+	/* 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]);
-
-#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.
- *
- * @param as		Task's address space.
- * @param name		Symbolic name (a copy is made).
- *
- * @return		New task's structure.
- *
- */
-task_t *task_create(as_t *as, char *name)
-{
-	ipl_t ipl;
-	task_t *ta;
-	
-	ta = (task_t *) slab_alloc(task_slab, 0);
-	task_create_arch(ta);
-	ta->as = as;
-	memcpy(ta->name, name, TASK_NAME_BUFLEN);
-	ta->name[TASK_NAME_BUFLEN - 1] = 0;
-
-	ta->context = CONTEXT;
-	ta->capabilities = 0;
-	ta->cycles = 0;
-
-#ifdef CONFIG_UDEBUG
-	/* Init debugging stuff */
-	udebug_task_init(&ta->udebug);
-
-	/* Init kbox stuff */
-	ta->kb.finished = false;
-#endif
-
-	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;
@@ -242,5 +229,5 @@
 		as_destroy(t->as);
 	
-	slab_free(task_slab, t);
+	free(t);
 	TASK = NULL;
 }
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/proc/thread.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -501,12 +501,5 @@
 void thread_sleep(uint32_t sec)
 {
-	/* 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;
-	}
+	thread_usleep(sec * 1000000);
 }
 
@@ -582,7 +575,7 @@
 {
 	waitq_t wq;
-	
+				  
 	waitq_initialize(&wq);
-	
+
 	(void) waitq_sleep_timeout(&wq, usec, SYNCH_FLAGS_NON_BLOCKING);
 }
@@ -819,11 +812,4 @@
 }
 
-/** 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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/synch/futex.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -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,11 +102,13 @@
 /** Sleep in futex wait queue.
  *
- * @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)
+ * @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)
 {
 	futex_t *futex;
@@ -138,5 +140,7 @@
 	udebug_stoppable_begin();
 #endif
-	rc = waitq_sleep_timeout(&futex->wq, 0, SYNCH_FLAGS_INTERRUPTIBLE); 
+	rc = waitq_sleep_timeout(&futex->wq, usec, flags |
+	    SYNCH_FLAGS_INTERRUPTIBLE);
+
 #ifdef CONFIG_UDEBUG
 	udebug_stoppable_end();
@@ -147,7 +151,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)
@@ -186,7 +190,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)
@@ -280,8 +284,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)
@@ -292,8 +296,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)
@@ -309,5 +313,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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/syscall/syscall.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -111,5 +111,4 @@
 	(syshandler_t) sys_thread_exit,
 	(syshandler_t) sys_thread_get_id,
-	(syshandler_t) sys_thread_usleep,
 	
 	(syshandler_t) sys_task_get_id,
@@ -118,5 +117,5 @@
 	
 	/* Synchronization related syscalls. */
-	(syshandler_t) sys_futex_sleep,
+	(syshandler_t) sys_futex_sleep_timeout,
 	(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 fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -50,5 +50,4 @@
 #include <udebug/udebug.h>
 #include <udebug/udebug_ops.h>
-#include <memstr.h>
 
 /**
Index: tools/config.py
===================================================================
--- tools/config.py	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ tools/config.py	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -227,8 +227,5 @@
 	
 	timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
-	
-	sys.stderr.write("Fetching current revision identifier ... ")
 	version = subprocess.Popen(['bzr', 'version-info', '--custom', '--template={clean}:{revno}:{revision_id}'], stdout = subprocess.PIPE).communicate()[0].split(':')
-	sys.stderr.write("OK\n")
 	
 	if (len(version) == 3):
Index: ols/jobfile.py
===================================================================
--- tools/jobfile.py	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ 	(revision )
@@ -1,59 +1,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2009 Martin Decky
-# 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.
-#
-"""
-Add a source/object file pair to a Stanse jobfile
-"""
-
-import sys
-import os
-import fcntl
-
-def usage(prname):
-	"Print usage syntax"
-	print prname + " <JOBFILE> <SOURCE> <OBJECT> [OPTIONS ...]"
-
-def main():
-	if (len(sys.argv) < 4):
-		usage(sys.argv[0])
-		return
-	
-	jobfname = sys.argv[1]
-	srcfname = sys.argv[2]
-	objfname = sys.argv[3]
-	cwd = os.getcwd()
-	options = " ".join(sys.argv[4:])
-	
-	jobfile = file(jobfname, "a")
-	fcntl.lockf(jobfile, fcntl.LOCK_EX)
-	jobfile.write("{%s},{%s},{%s},{%s}\n" % (srcfname, objfname, cwd, options))
-	fcntl.lockf(jobfile, fcntl.LOCK_UN)
-	jobfile.close()
-
-if __name__ == '__main__':
-	main()
Index: uspace/app/bdsh/input.c
===================================================================
--- uspace/app/bdsh/input.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/app/bdsh/input.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -38,5 +38,4 @@
 #include <vfs/vfs.h>
 #include <errno.h>
-#include <assert.h>
 #include <bool.h>
 
@@ -48,26 +47,5 @@
 #include "exec.h"
 
-#define HISTORY_LEN 10
-
-typedef struct {
-	wchar_t buffer[INPUT_MAX];
-	int col0, row0;
-	int con_cols, con_rows;
-	int nc;
-	int pos;
-
-	char *history[1 + HISTORY_LEN];
-	int hnum;
-	int hpos;
-} tinput_t;
-
-typedef enum {
-	seek_backward = -1,
-	seek_forward = 1
-} seek_dir_t;
-
-static tinput_t tinput;
-
-static char *tinput_read(tinput_t *ti);
+static void read_line(char *, int);
 
 /* Tokenizes input from console, sees if the first word is a built-in, if so
@@ -121,323 +99,52 @@
 }
 
-static void tinput_display_tail(tinput_t *ti, int start, int pad)
-{
-	int i;
-
-	console_goto(fphone(stdout), (ti->col0 + start) % ti->con_cols,
-	    ti->row0 + (ti->col0 + start) / ti->con_cols);
-	printf("%ls", ti->buffer + start);
-	for (i = 0; i < pad; ++i)
-		putchar(' ');
-	fflush(stdout);
-}
-
-static char *tinput_get_str(tinput_t *ti)
-{
-	return wstr_to_astr(ti->buffer);
-}
-
-static void tinput_position_caret(tinput_t *ti)
-{
-	console_goto(fphone(stdout), (ti->col0 + ti->pos) % ti->con_cols,
-	    ti->row0 + (ti->col0 + ti->pos) / ti->con_cols);
-}
-
-/** Update row0 in case the screen could have scrolled. */
-static void tinput_update_origin(tinput_t *ti)
-{
-	int width, rows;
-
-	width = ti->col0 + ti->nc;
-	rows = (width / ti->con_cols) + 1;
- 
-	/* Update row0 if the screen scrolled. */
-	if (ti->row0 + rows > ti->con_rows)
-		ti->row0 = ti->con_rows - rows;	
-}
-
-static void tinput_insert_char(tinput_t *ti, wchar_t c)
-{
-	int i;
-	int new_width, new_height;
-
-	if (ti->nc == INPUT_MAX)
-		return;
-
-	new_width = ti->col0 + ti->nc + 1;
-	if (new_width % ti->con_cols == 0) {
-		/* Advancing to new line. */
-		new_height = (new_width / ti->con_cols) + 1;
-		if (new_height >= ti->con_rows)
-			return; /* Disallow text longer than 1 page for now. */
-	}
-
-	for (i = ti->nc; i > ti->pos; --i)
-		ti->buffer[i] = ti->buffer[i - 1];
-
-	ti->buffer[ti->pos] = c;
-	ti->pos += 1;
-	ti->nc += 1;
-	ti->buffer[ti->nc] = '\0';
-
-	tinput_display_tail(ti, ti->pos - 1, 0);
-	tinput_update_origin(ti);
-	tinput_position_caret(ti);
-}
-
-static void tinput_backspace(tinput_t *ti)
-{
-	int i;
-
-	if (ti->pos == 0)
-		return;
-
-	for (i = ti->pos; i < ti->nc; ++i)
-		ti->buffer[i - 1] = ti->buffer[i];
-	ti->pos -= 1;
-	ti->nc -= 1;
-	ti->buffer[ti->nc] = '\0';
-
-	tinput_display_tail(ti, ti->pos, 1);
-	tinput_position_caret(ti);
-}
-
-static void tinput_delete(tinput_t *ti)
-{
-	if (ti->pos == ti->nc)
-		return;
-
-	ti->pos += 1;
-	tinput_backspace(ti);
-}
-
-static void tinput_seek_cell(tinput_t *ti, seek_dir_t dir)
-{
-	if (dir == seek_forward) {
-		if (ti->pos < ti->nc)
-			ti->pos += 1;
-	} else {
-		if (ti->pos > 0)
-			ti->pos -= 1;
-	}
-
-	tinput_position_caret(ti);
-}
-
-static void tinput_seek_word(tinput_t *ti, seek_dir_t dir)
-{
-	if (dir == seek_forward) {
-		if (ti->pos == ti->nc)
-			return;
-
-		while (1) {
-			ti->pos += 1;
-
-			if (ti->pos == ti->nc)
-				break;
-
-			if (ti->buffer[ti->pos - 1] == ' ' &&
-			    ti->buffer[ti->pos] != ' ')
-				break;
-		}
-	} else {
-		if (ti->pos == 0)
-			return;
-
-		while (1) {
-			ti->pos -= 1;
-
-			if (ti->pos == 0)
-				break;
-
-			if (ti->buffer[ti->pos - 1] == ' ' &&
-			    ti->buffer[ti->pos] != ' ')
-				break;
-		}
-
-	}
-
-	tinput_position_caret(ti);
-}
-
-static void tinput_seek_vertical(tinput_t *ti, seek_dir_t dir)
-{
-	if (dir == seek_forward) {
-		if (ti->pos + ti->con_cols <= ti->nc)
-			ti->pos = ti->pos + ti->con_cols;
-	} else {
-		if (ti->pos - ti->con_cols >= 0)
-			ti->pos = ti->pos - ti->con_cols;
-	}
-
-	tinput_position_caret(ti);
-}
-
-static void tinput_seek_max(tinput_t *ti, seek_dir_t dir)
-{
-	if (dir == seek_backward)
-		ti->pos = 0;
-	else
-		ti->pos = ti->nc;
-
-	tinput_position_caret(ti);
-}
-
-static void tinput_history_insert(tinput_t *ti, char *str)
-{
-	int i;
-
-	if (ti->hnum < HISTORY_LEN) {
-		ti->hnum += 1;
-	} else {
-		if (ti->history[HISTORY_LEN] != NULL)
-			free(ti->history[HISTORY_LEN]);
-	}
-
-	for (i = ti->hnum; i > 1; --i)
-		ti->history[i] = ti->history[i - 1];
-
-	ti->history[1] = str_dup(str);
-
-	if (ti->history[0] != NULL) {
-		free(ti->history[0]);
-		ti->history[0] = NULL;
-	}
-}
-
-static void tinput_set_str(tinput_t *ti, char *str)
-{
-	str_to_wstr(ti->buffer, INPUT_MAX, str);
-	ti->nc = wstr_length(ti->buffer);
-	ti->pos = ti->nc;
-}
-
-static void tinput_history_seek(tinput_t *ti, int offs)
-{
-	int pad;
-
-	if (ti->hpos + offs < 0 || ti->hpos + offs > ti->hnum)
-		return;
-
-	if (ti->history[ti->hpos] != NULL) {
-		free(ti->history[ti->hpos]);
-		ti->history[ti->hpos] = NULL;
-	}
-
-	ti->history[ti->hpos] = tinput_get_str(ti);
-	ti->hpos += offs;
-
-	pad = ti->nc - str_length(ti->history[ti->hpos]);
-	if (pad < 0) pad = 0;
-
-	tinput_set_str(ti, ti->history[ti->hpos]);
-	tinput_display_tail(ti, 0, pad);
-	tinput_update_origin(ti);
-	tinput_position_caret(ti);
-}
-
-static void tinput_init(tinput_t *ti)
-{
-	ti->hnum = 0;
-	ti->hpos = 0;
-	ti->history[0] = NULL;
-}
-
-static char *tinput_read(tinput_t *ti)
+static void read_line(char *buffer, int n)
 {
 	console_event_t ev;
-	char *str;
+	size_t offs, otmp;
+	wchar_t dec;
 
-	fflush(stdout);
-
-	if (console_get_size(fphone(stdin), &ti->con_cols, &ti->con_rows) != EOK)
-		return NULL;
-	if (console_get_pos(fphone(stdin), &ti->col0, &ti->row0) != EOK)
-		return NULL;
-
-	ti->pos = 0;
-	ti->nc = 0;
-	ti->buffer[0] = '\0';
-
+	offs = 0;
 	while (true) {
 		fflush(stdout);
 		if (!console_get_event(fphone(stdin), &ev))
-			return NULL;
+			return;
 		
 		if (ev.type != KEY_PRESS)
 			continue;
-
-		if ((ev.mods & KM_CTRL) != 0 &&
-		    (ev.mods & (KM_ALT | KM_SHIFT)) == 0) {
-			switch (ev.key) {
-			case KC_LEFT:
-				tinput_seek_word(ti, seek_backward);
-				break;
-			case KC_RIGHT:
-				tinput_seek_word(ti, seek_forward);
-				break;
-			case KC_UP:
-				tinput_seek_vertical(ti, seek_backward);
-				break;
-			case KC_DOWN:
-				tinput_seek_vertical(ti, seek_forward);
-				break;
+		
+		if (ev.key == KC_ENTER || ev.key == KC_NENTER)
+			break;
+		if (ev.key == KC_BACKSPACE) {
+			if (offs > 0) {
+				/*
+				 * Back up until we reach valid start of
+				 * character.
+				 */
+				while (offs > 0) {
+					--offs; otmp = offs;
+					dec = str_decode(buffer, &otmp, n);
+					if (dec != U_SPECIAL)
+						break;
+				}
+				putchar('\b');
 			}
+			continue;
 		}
-
-		if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
-			switch (ev.key) {
-			case KC_ENTER:
-			case KC_NENTER:
-				goto done;
-			case KC_BACKSPACE:
-				tinput_backspace(ti);
-				break;
-			case KC_DELETE:
-				tinput_delete(ti);
-				break;
-			case KC_LEFT:
-				tinput_seek_cell(ti, seek_backward);
-				break;
-			case KC_RIGHT:
-				tinput_seek_cell(ti, seek_forward);
-				break;
-			case KC_HOME:
-				tinput_seek_max(ti, seek_backward);
-				break;
-			case KC_END:
-				tinput_seek_max(ti, seek_forward);
-				break;
-			case KC_UP:
-				tinput_history_seek(ti, +1);
-				break;
-			case KC_DOWN:
-				tinput_history_seek(ti, -1);
-				break;
-			}
-		}
-
 		if (ev.c >= ' ') {
-			tinput_insert_char(ti, ev.c);
+			if (chr_encode(ev.c, buffer, &offs, n - 1) == EOK)
+				putchar(ev.c);
 		}
 	}
-
-done:
-	ti->pos = ti->nc;
-	tinput_position_caret(ti);
 	putchar('\n');
-
-	str = tinput_get_str(ti);
-	if (str_cmp(str, "") != 0)
-		tinput_history_insert(ti, str);
-
-	ti->hpos = 0;
-
-	return str;
+	buffer[offs] = '\0';
 }
 
+/* TODO:
+ * Implement something like editline() / readline(), if even
+ * just for command history and making arrows work. */
 void get_input(cliuser_t *usr)
 {
-	char *str;
+	char line[INPUT_MAX];
 
 	fflush(stdout);
@@ -447,18 +154,11 @@
 	console_set_style(fphone(stdout), STYLE_NORMAL);
 
-	str = tinput_read(&tinput);
+	read_line(line, INPUT_MAX);
+	/* Make sure we don't have rubbish or a C/R happy user */
+	if (str_cmp(line, "") == 0 || str_cmp(line, "\n") == 0)
+		return;
+	usr->line = str_dup(line);
 
-	/* Check for empty input. */
-	if (str_cmp(str, "") == 0) {
-		free(str);
-		return;
-	}
-
-	usr->line = str;
 	return;
 }
 
-void input_init(void)
-{
-	tinput_init(&tinput);
-}
Index: uspace/app/bdsh/input.h
===================================================================
--- uspace/app/bdsh/input.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/app/bdsh/input.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -8,5 +8,4 @@
 extern void get_input(cliuser_t *);
 extern int tok_input(cliuser_t *);
-extern void input_init(void);
 
 #endif
Index: uspace/app/bdsh/scli.c
===================================================================
--- uspace/app/bdsh/scli.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/app/bdsh/scli.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -64,7 +64,4 @@
 	usr->prompt = (char *) NULL;
 	usr->lasterr = 0;
-
-	input_init();
-
 	return (int) cli_set_prompt(usr);
 }
Index: uspace/app/edit/edit.c
===================================================================
--- uspace/app/edit/edit.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/app/edit/edit.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -36,5 +36,4 @@
 
 #include <stdio.h>
-#include <stdlib.h>
 #include <sys/types.h>
 #include <vfs/vfs.h>
@@ -102,15 +101,10 @@
 #define ED_INFTY 65536
 
-/** Maximum filename length that can be entered. */
-#define INFNAME_MAX_LEN 128
-
 static void key_handle_unmod(console_event_t const *ev);
 static void key_handle_ctrl(console_event_t const *ev);
 static int file_save(char const *fname);
-static void file_save_as(void);
 static int file_insert(char *fname);
 static int file_save_range(char const *fname, spt_t const *spos,
     spt_t const *epos);
-static char *filename_prompt(char const *prompt, char const *init_value);
 static void pane_text_display(void);
 static void pane_row_display(void);
@@ -156,15 +150,15 @@
 
 	if (argc == 2) {
-		doc.file_name = str_dup(argv[1]);
+		doc.file_name = argv[1];
 	} else if (argc > 1) {
 		printf("Invalid arguments.\n");
 		return -2;
 	} else {
-		doc.file_name = NULL;
+		doc.file_name = "/edit.txt";
 	}
 
 	new_file = false;
 
-	if (doc.file_name == NULL || file_insert(doc.file_name) != EOK)
+	if (file_insert(doc.file_name) != EOK)
 		new_file = true;
 
@@ -176,6 +170,6 @@
 	pane_text_display();
 	pane_status_display();
-	if (new_file && doc.file_name != NULL)
-		status_display("File not found. Starting empty file.");
+	if (new_file)
+		status_display("File not found. Created empty file.");
 	pane_caret_display();
 
@@ -272,11 +266,5 @@
 		break;
 	case KC_S:
-		if (doc.file_name != NULL)
-			file_save(doc.file_name);
-		else
-			file_save_as();
-		break;
-	case KC_E:
-		file_save_as();
+		(void) file_save(doc.file_name);
 		break;
 	default:
@@ -284,4 +272,5 @@
 	}
 }
+
 
 /** Save the document. */
@@ -296,104 +285,7 @@
 
 	rc = file_save_range(fname, &sp, &ep);
-
-	switch (rc) {
-	case EINVAL:
-		status_display("Error opening file!");
-		break;
-	case EIO:
-		status_display("Error writing data!");
-		break;
-	default:
-		status_display("File saved.");
-		break;
-	}
+	status_display("File saved.");
 
 	return rc;
-}
-
-/** Change document name and save. */
-static void file_save_as(void)
-{
-	char *old_fname, *fname;
-	int rc;
-
-	old_fname = (doc.file_name != NULL) ? doc.file_name : "";
-	fname = filename_prompt("Save As", old_fname);
-	if (fname == NULL) {
-		status_display("Save cancelled.");
-		return;
-	}
-
-	rc = file_save(fname);
-	if (rc != EOK)
-		return;
-
-	if (doc.file_name != NULL)
-		free(doc.file_name);
-	doc.file_name = fname;
-}
-
-/** Ask for a file name. */
-static char *filename_prompt(char const *prompt, char const *init_value)
-{
-	console_event_t ev;
-	char *str;
-	wchar_t buffer[INFNAME_MAX_LEN + 1];
-	int max_len;
-	int nc;
-	bool done;
-
-	asprintf(&str, "%s: %s", prompt, init_value);
-	status_display(str);
-	console_goto(con, 1 + str_length(str), scr_rows - 1);
-	free(str);
-
-	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
-
-	max_len = min(INFNAME_MAX_LEN, scr_columns - 4 - str_length(prompt));
-	str_to_wstr(buffer, max_len + 1, init_value);
-	nc = wstr_length(buffer);
-	done = false;
-
-	while (!done) {
-		console_get_event(con, &ev);
-
-		if (ev.type == KEY_PRESS) {
-			/* Handle key press. */
-			if (((ev.mods & KM_ALT) == 0) &&
-			     (ev.mods & KM_CTRL) != 0) {
-				;
-			} else if ((ev.mods & (KM_CTRL | KM_ALT)) == 0) {
-				switch (ev.key) {
-				case KC_ESCAPE:
-					return NULL;
-				case KC_BACKSPACE:
-					if (nc > 0) {
-						putchar('\b');
-						fflush(stdout);
-						--nc;
-					}
-					break;
-				case KC_ENTER:
-					done = true;
-					break;
-				default:
-					if (ev.c >= 32 && nc < max_len) {
-						putchar(ev.c);
-						fflush(stdout);
-						buffer[nc++] = ev.c;
-					}
-					break;
-				}
-			}
-		}
-	}
-
-	buffer[nc] = '\0';
-	str = wstr_to_astr(buffer);
-
-	console_set_color(con, COLOR_BLACK, COLOR_WHITE, 0);
-
-	return str;
 }
 
@@ -467,6 +359,5 @@
 	} while (!spt_equal(&bep, epos));
 
-	if (fclose(f) != EOK)
-		return EIO;
+	fclose(f);
 
 	return EOK;
@@ -582,5 +473,4 @@
 	spt_t caret_pt;
 	coord_t coord;
-	char *fname;
 	int n;
 
@@ -588,10 +478,8 @@
 	spt_get_coord(&caret_pt, &coord);
 
-	fname = (doc.file_name != NULL) ? doc.file_name : "<unnamed>";
-
 	console_goto(con, 0, scr_rows - 1);
 	console_set_color(con, COLOR_WHITE, COLOR_BLACK, 0);
-	n = printf(" %d, %d: File '%s'. Ctrl-Q Quit  Ctrl-S Save  "
-	    "Ctrl-E Save As", coord.row, coord.column, fname);
+	n = printf(" %d, %d: File '%s'. Ctrl-S Save  Ctrl-Q Quit",
+	    coord.row, coord.column, doc.file_name);
 	printf("%*s", scr_columns - 1 - n, "");
 	fflush(stdout);
Index: uspace/lib/libc/arch/amd64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/amd64/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/arch/amd64/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -37,8 +37,4 @@
 #ifndef LIBC_amd64_ATOMIC_H_
 #define LIBC_amd64_ATOMIC_H_
-
-#define LIBC_ARCH_ATOMIC_H_
-
-#include <atomicdflt.h>
 
 static inline void atomic_inc(atomic_t *val) {
Index: uspace/lib/libc/arch/arm32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/arm32/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/arch/arm32/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -37,30 +37,4 @@
 #define LIBC_arm32_ATOMIC_H_
 
-#include <bool.h>
-
-typedef struct atomic {
-	volatile long count;
-} atomic_t;
-
-static inline void atomic_set(atomic_t *val, long i)
-{
-        val->count = i;
-}
-
-static inline long atomic_get(atomic_t *val)
-{
-        return val->count;
-}
-
-static inline bool cas(atomic_t *val, long ov, long nv)
-{
-	/* FIXME: is not atomic */
-	if (val->count == ov) {
-		val->count = nv;
-		return true;
-	}
-	return false;
-}
-
 /** Atomic addition.
  *
@@ -75,5 +49,4 @@
 	volatile long * mem = &(val->count);
 
-	/* FIXME: is not atomic, is broken */
 	asm volatile (
 	"1:\n"
Index: uspace/lib/libc/arch/ia32/Makefile.inc
===================================================================
--- uspace/lib/libc/arch/ia32/Makefile.inc	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/arch/ia32/Makefile.inc	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -39,5 +39,4 @@
 	arch/$(UARCH)/src/setjmp.S
 
-GCC_CFLAGS += -march=pentium
 LFLAGS += -N
 
Index: uspace/lib/libc/arch/ia32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/ia32/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/arch/ia32/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -35,8 +35,4 @@
 #ifndef LIBC_ia32_ATOMIC_H_
 #define LIBC_ia32_ATOMIC_H_
-
-#define LIBC_ARCH_ATOMIC_H_
-
-#include <atomicdflt.h>
 
 static inline void atomic_inc(atomic_t *val) {
Index: uspace/lib/libc/arch/ia64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/arch/ia64/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -35,8 +35,4 @@
 #ifndef LIBC_ia64_ATOMIC_H_
 #define LIBC_ia64_ATOMIC_H_
-
-#define LIBC_ARCH_ATOMIC_H_
-
-#include <atomicdflt.h>
 
 static inline void atomic_inc(atomic_t *val)
Index: uspace/lib/libc/arch/mips32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/mips32/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/arch/mips32/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -36,8 +36,4 @@
 #ifndef LIBC_mips32_ATOMIC_H_
 #define LIBC_mips32_ATOMIC_H_
-
-#define LIBC_ARCH_ATOMIC_H_
-
-#include <atomicdflt.h>
 
 #define atomic_inc(x)	((void) atomic_add(x, 1))
Index: uspace/lib/libc/arch/ppc32/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/ppc32/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/arch/ppc32/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -35,8 +35,4 @@
 #ifndef LIBC_ppc32_ATOMIC_H_
 #define LIBC_ppc32_ATOMIC_H_
-
-#define LIBC_ARCH_ATOMIC_H_
-
-#include <atomicdflt.h>
 
 static inline void atomic_inc(atomic_t *val)
Index: uspace/lib/libc/arch/sparc64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/sparc64/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/arch/sparc64/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -36,7 +36,4 @@
 #define LIBC_sparc64_ATOMIC_H_
 
-#define LIBC_ARCH_ATOMIC_H_
-
-#include <atomicdflt.h>
 #include <sys/types.h>
 
Index: uspace/lib/libc/generic/async.c
===================================================================
--- uspace/lib/libc/generic/async.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/generic/async.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -392,18 +392,4 @@
 	/* If nothing in queue, wait until something arrives */
 	while (list_empty(&conn->msg_queue)) {
-		if (conn->close_callid) {
-			/*
-			 * Handle the case when the connection was already
-			 * closed by the client but the server did not notice
-			 * the first IPC_M_PHONE_HUNGUP call and continues to
-			 * call async_get_call_timeout(). Repeat
-			 * IPC_M_PHONE_HUNGUP until the caller notices. 
-			 */
-			memset(call, 0, sizeof(ipc_call_t));
-			IPC_SET_METHOD(*call, IPC_M_PHONE_HUNGUP);
-			futex_up(&async_futex);
-			return conn->close_callid;
-		}
-
 		if (usecs)
 			async_insert_timeout(&conn->wdata);
@@ -542,5 +528,5 @@
 	list_initialize(&conn->msg_queue);
 	conn->callid = callid;
-	conn->close_callid = 0;
+	conn->close_callid = false;
 	
 	if (call)
Index: uspace/lib/libc/generic/futex.c
===================================================================
--- uspace/lib/libc/generic/futex.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/generic/futex.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -36,5 +36,49 @@
 #include <atomic.h>
 #include <libc.h>
+#include <stdio.h>
 #include <sys/types.h>
+#include <kernel/synch/synch.h>
+
+/*
+ * Note about race conditions.
+ * Because of non-atomic nature of operations performed sequentially on the
+ * futex counter and the futex wait queue, there is a race condition:
+ *
+ * (wq->missed_wakeups == 1) && (futex->count = 1)
+ *
+ * Scenario 1 (wait queue timeout vs. futex_up()):
+ * 1. assume wq->missed_wakeups == 0 && futex->count == -1
+ *    (ie. thread A sleeping, thread B in the critical section)
+ * 2. A receives timeout and gets removed from the wait queue
+ * 3. B wants to leave the critical section and calls futex_up()
+ * 4. B thus changes futex->count from -1 to 0
+ * 5. B has to call SYS_FUTEX_WAKEUP syscall to wake up the sleeping thread
+ * 6. B finds the wait queue empty and changes wq->missed_wakeups from 0 to 1
+ * 7. A fixes futex->count (i.e. the number of waiting threads) by changing it
+ *    from 0 to 1
+ *
+ * Scenario 2 (conditional down operation vs. futex_up)
+ * 1. assume wq->missed_wakeups == 0 && futex->count == 0
+ *    (i.e. thread A is in the critical section)
+ * 2. thread B performs futex_trydown() operation and changes futex->count from
+ *    0 to -1
+ *    B is now obliged to call SYS_FUTEX_SLEEP syscall
+ * 3. A wants to leave the critical section and does futex_up()
+ * 4. A thus changes futex->count from -1 to 0 and must call SYS_FUTEX_WAKEUP
+ *    syscall
+ * 5. B finds the wait queue empty and immediatelly aborts the conditional sleep
+ * 6. No thread is queueing in the wait queue so wq->missed_wakeups changes from
+ *    0 to 1
+ * 6. B fixes futex->count (i.e. the number of waiting threads) by changing it
+ *    from 0 to 1
+ *
+ * Both scenarios allow two threads to be in the critical section
+ * simultaneously. One without kernel intervention and the other through
+ * wq->missed_wakeups being 1.
+ *
+ * To mitigate this problem, futex_down_timeout() detects that the syscall
+ * didn't sleep in the wait queue, fixes the futex counter and RETRIES the
+ * whole operation again.
+ */
 
 /** Initialize futex counter.
@@ -48,28 +92,81 @@
 }
 
+int futex_down(futex_t *futex)
+{
+	return futex_down_timeout(futex, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE);
+}
+
+int futex_trydown(futex_t *futex)
+{
+	return futex_down_timeout(futex, SYNCH_NO_TIMEOUT,
+	    SYNCH_FLAGS_NON_BLOCKING);
+}
+
 /** Try to down the futex.
  *
  * @param futex		Futex.
- * @return		Non-zero if the futex was acquired.
- * @return		Zero if the futex was not acquired.
+ * @param usec		Microseconds to wait. Zero value means sleep without
+ * 			timeout.
+ * @param flags		Select mode of operation. See comment for
+ * 			waitq_sleep_timeout(). 
+ *
+ * @return		ENOENT if there is no such virtual address. One of
+ * 			ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED on success or
+ * 			ESYNCH_TIMEOUT if the lock was not acquired because of
+ * 			a timeout or ESYNCH_WOULD_BLOCK if the operation could
+ * 			not be carried out atomically (if requested so).
  */
-int futex_trydown(futex_t *futex)
+int futex_down_timeout(futex_t *futex, uint32_t usec, int flags)
 {
-	return cas(futex, 1, 0);
-}
+	int rc;
+	
+	while (atomic_predec(futex) < 0) {
+		rc = __SYSCALL3(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count,
+		    (sysarg_t) usec, (sysarg_t) flags);
+		
+		switch (rc) {
+		case ESYNCH_OK_ATOMIC:
+			/*
+			 * Because of a race condition between timeout and
+			 * futex_up() and between conditional
+			 * futex_down_timeout() and futex_up(), we have to give
+			 * up and try again in this special case.
+			 */
+			atomic_inc(futex);
+			break;
 
-/** Down the futex.
- *
- * @param futex		Futex.
- * @return		ENOENT if there is no such virtual address.
- * @return		Zero in the uncontended case. 
- * @return		Otherwise one of ESYNCH_OK_ATOMIC or ESYNCH_OK_BLOCKED.
- */
-int futex_down(futex_t *futex)
-{
-	if (atomic_predec(futex) < 0)
-		return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
+		case ESYNCH_TIMEOUT:
+			atomic_inc(futex);
+			return ESYNCH_TIMEOUT;
+			break;
 
-	return 0;
+		case ESYNCH_WOULD_BLOCK:
+			/*
+			 * The conditional down operation should be implemented
+			 * this way. The userspace-only variant tends to
+			 * accumulate missed wakeups in the kernel futex wait
+			 * queue.
+			 */
+			atomic_inc(futex);
+			return ESYNCH_WOULD_BLOCK;
+			break;
+
+		case ESYNCH_OK_BLOCKED:
+			/*
+			 * Enter the critical section.
+			 * The futex counter has already been incremented for
+			 * us.
+			 */
+			return ESYNCH_OK_BLOCKED;
+			break;
+		default:
+			return rc;
+		}
+	}
+
+	/*
+	 * Enter the critical section.
+	 */
+	return ESYNCH_OK_ATOMIC;
 }
 
@@ -77,10 +174,14 @@
  *
  * @param futex		Futex.
- * @return		ENOENT if there is no such virtual address.
- * @return		Zero in the uncontended case.
+ *
+ * @return		ENOENT if there is no such virtual address. Otherwise
+ * 			zero.
  */
 int futex_up(futex_t *futex)
 {
-	if (atomic_postinc(futex) < 0)
+	long val;
+	
+	val = atomic_postinc(futex);
+	if (val < 0)
 		return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
 		
Index: uspace/lib/libc/generic/io/console.c
===================================================================
--- uspace/lib/libc/generic/io/console.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/generic/io/console.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -94,17 +94,4 @@
 }
 
-int console_get_pos(int phone, int *col, int *row)
-{
-	ipcarg_t col_v;
-	ipcarg_t row_v;
-	int rc;
-
-	rc = async_req_0_2(phone, CONSOLE_GET_POS, &col_v, &row_v);
-
-	*col = (int) col_v;
-	*row = (int) row_v;
-	return rc;
-}
-
 void console_goto(int phone, int col, int row)
 {
Index: uspace/lib/libc/generic/io/klog.c
===================================================================
--- uspace/lib/libc/generic/io/klog.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/generic/io/klog.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -42,10 +42,5 @@
 size_t klog_write(const void *buf, size_t size)
 {
-	ssize_t ret = (ssize_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
-	
-	if (ret >= 0)
-		return (size_t) ret;
-	
-	return 0;
+	return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
 }
 
Index: uspace/lib/libc/generic/string.c
===================================================================
--- uspace/lib/libc/generic/string.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/generic/string.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -471,5 +471,5 @@
  * null-terminated and containing only complete characters.
  *
- * @param dest   Destination buffer.
+ * @param dst   Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
@@ -505,5 +505,5 @@
  * have to be null-terminated.
  *
- * @param dest   Destination buffer.
+ * @param dst   Destination buffer.
  * @param count Size of the destination buffer (must be > 0).
  * @param src   Source string.
@@ -537,5 +537,5 @@
  * null-terminated and containing only complete characters.
  *
- * @param dest   Destination buffer.
+ * @param dst   Destination buffer.
  * @param count Size of the destination buffer.
  * @param src   Source string.
@@ -549,113 +549,36 @@
 }
 
-/** 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)
-{
+/** 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;
+	
 	wchar_t ch;
-	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;
-
+	size_t src_idx = 0;
+	size_t dst_off = 0;
+	
 	while ((ch = src[src_idx++]) != 0) {
-		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
+		if (chr_encode(ch, dst, &dst_off, size) != EOK)
 			break;
 	}
-
-	dest[dest_off] = '\0';
-}
-
-/** Convert wide string to new string.
- *
- * Convert wide string @a src to string. Space for the new string is allocated
- * on the heap.
- *
- * @param src	Source wide string.
- * @return	New string.
- */
-char *wstr_to_astr(const wchar_t *src)
-{
-	char dbuf[STR_BOUNDS(1)];
-	char *str;
-	wchar_t ch;
-
-	size_t src_idx;
-	size_t dest_off;
-	size_t dest_size;
-
-	/* Compute size of encoded string. */
-
-	src_idx = 0;
-	dest_size = 0;
-
-	while ((ch = src[src_idx++]) != 0) {
-		dest_off = 0;
-		if (chr_encode(ch, dbuf, &dest_off, STR_BOUNDS(1)) != EOK)
-			break;
-		dest_size += dest_off;
-	}
-
-	str = malloc(dest_size + 1);
-	if (str == NULL)
-		return NULL;
-
-	/* Encode string. */
-
-	src_idx = 0;
-	dest_off = 0;
-
-	while ((ch = src[src_idx++]) != 0) {
-		if (chr_encode(ch, str, &dest_off, dest_size) != EOK)
-			break;
-	}
-
-	str[dest_size] = '\0';
-	return str;
-}
-
-
-/** Convert string to wide string.
- *
- * Convert string @a src to wide string. The output is written to the
- * buffer specified by @a dest and @a dlen. @a dlen must be non-zero
- * and the wide string written will always be null-terminated.
- *
- * @param dest	Destination buffer.
- * @param dlen	Length of destination buffer (number of wchars).
- * @param src	Source string.
- */
-void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
-{
-	size_t offset;
-	size_t di;
-	wchar_t c;
-
-	assert(dlen > 0);
-
-	offset = 0;
-	di = 0;
-
-	do {
-		if (di >= dlen - 1)
-			break;
-
-		c = str_decode(src, &offset, STR_NO_LIMIT);
-		dest[di++] = c;
-	} while (c != '\0');
-
-	dest[dlen - 1] = '\0';
+	
+	if (dst_off >= size)
+		dst[size - 1] = 0;
+	else
+		dst[dst_off] = 0;
 }
 
Index: uspace/lib/libc/generic/time.c
===================================================================
--- uspace/lib/libc/generic/time.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/generic/time.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -31,5 +31,5 @@
  */
 /** @file
- */
+ */ 
 
 #include <sys/time.h>
@@ -40,7 +40,7 @@
 #include <unistd.h>
 #include <atomic.h>
+#include <futex.h>
 #include <sysinfo.h>
 #include <ipc/services.h>
-#include <libc.h>
 
 #include <sysinfo.h>
@@ -189,20 +189,27 @@
 
 /** Wait unconditionally for specified number of microseconds */
-int usleep(useconds_t usec)
-{
-	(void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
+int usleep(unsigned long usec)
+{
+	atomic_t futex = FUTEX_INITIALIZER;
+
+	futex_initialize(&futex, 0);
+	futex_down_timeout(&futex, usec, 0);
 	return 0;
 }
 
 /** Wait unconditionally for specified number of seconds */
-unsigned int sleep(unsigned int sec)
-{
+unsigned int sleep(unsigned int seconds)
+{
+	atomic_t futex = FUTEX_INITIALIZER;
+
+	futex_initialize(&futex, 0);
+	
 	/* Sleep in 1000 second steps to support
 	   full argument range */
-	while (sec > 0) {
-		unsigned int period = (sec > 1000) ? 1000 : sec;
+	while (seconds > 0) {
+		unsigned int period = (seconds > 1000) ? 1000 : seconds;
 	
-		usleep(period * 1000000);
-		sec -= period;
+		futex_down_timeout(&futex, period * 1000000, 0);
+		seconds -= period;
 	}
 	return 0;
Index: uspace/lib/libc/generic/vfs/canonify.c
===================================================================
--- uspace/lib/libc/generic/vfs/canonify.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/generic/vfs/canonify.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -142,5 +142,5 @@
 	t->start[-1] = '\0';
 }
-/** Eat the extra '/'.
+/** Eat the extra '/'..
  *
  * @param t		The current TK_SLASH token.
@@ -288,15 +288,9 @@
  *
  * A file system path is canonical, if the following holds:
- *
- * 1) the path is absolute
- *    (i.e. a/b/c is not canonical)
- * 2) there is no trailing slash in the path if it has components
- *    (i.e. /a/b/c/ is not canonical)
- * 3) there is no extra slash in the path
- *    (i.e. /a//b/c is not canonical)
- * 4) there is no '.' component in the path
- *    (i.e. /a/./b/c is not canonical)
- * 5) there is no '..' component in the path
- *    (i.e. /a/b/../c is not canonical)
+ * 1) the path is absolute (i.e. a/b/c is not canonical)
+ * 2) there is no trailing slash in the path (i.e. /a/b/c is not canonical)
+ * 3) there is no extra slash in the path (i.e. /a//b/c is not canonical)
+ * 4) there is no '.' component in the path (i.e. /a/./b/c is not canonical)
+ * 5) there is no '..' component in the path (i.e. /a/b/../c is not canonical) 
  *
  * This function makes a potentially non-canonical file system path canonical.
Index: uspace/lib/libc/include/atomic.h
===================================================================
--- uspace/lib/libc/include/atomic.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/include/atomic.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2009 Jakub Jermar
+ * Copyright (c) 2006 Jakub Jermar
  * All rights reserved.
  *
@@ -36,5 +36,19 @@
 #define LIBC_ATOMIC_H_
 
+typedef struct atomic {
+	volatile long count;
+} atomic_t;
+
 #include <libarch/atomic.h>
+
+static inline void atomic_set(atomic_t *val, long i)
+{
+        val->count = i;
+}
+
+static inline long atomic_get(atomic_t *val)
+{
+        return val->count;
+}
 
 #endif
Index: pace/lib/libc/include/atomicdflt.h
===================================================================
--- uspace/lib/libc/include/atomicdflt.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ 	(revision )
@@ -1,66 +1,0 @@
-/*
- * Copyright (c) 2006 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 libc
- * @{
- */
-/** @file
- */
-
-#ifndef LIBC_ATOMICDFLT_H_
-#define LIBC_ATOMICDFLT_H_
-
-#ifndef LIBC_ARCH_ATOMIC_H_
-#error This file cannot be included directly, include atomic.h instead.
-#endif
-
-#include <bool.h>
-
-typedef struct atomic {
-	volatile long count;
-} atomic_t;
-
-static inline void atomic_set(atomic_t *val, long i)
-{
-        val->count = i;
-}
-
-static inline long atomic_get(atomic_t *val)
-{
-        return val->count;
-}
-
-static inline bool cas(atomic_t *val, long ov, long nv)
-{
-	return __sync_bool_compare_and_swap(&val->count, ov, nv);
-}
-
-#endif
-
-/** @}
- */
Index: uspace/lib/libc/include/futex.h
===================================================================
--- uspace/lib/libc/include/futex.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/include/futex.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -46,4 +46,5 @@
 extern int futex_down(futex_t *futex);
 extern int futex_trydown(futex_t *futex);
+extern int futex_down_timeout(futex_t *futex, uint32_t usec, int flags);
 extern int futex_up(futex_t *futex);
 
Index: uspace/lib/libc/include/io/console.h
===================================================================
--- uspace/lib/libc/include/io/console.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/include/io/console.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -69,5 +69,4 @@
 
 extern int console_get_size(int phone, int *cols, int *rows);
-extern int console_get_pos(int phone, int *col, int *row);
 extern void console_goto(int phone, int col, int row);
 
Index: uspace/lib/libc/include/ipc/console.h
===================================================================
--- uspace/lib/libc/include/ipc/console.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/include/ipc/console.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -43,5 +43,4 @@
 	CONSOLE_GET_COLOR_CAP,
 	CONSOLE_GET_EVENT,
-	CONSOLE_GET_POS,
 	CONSOLE_GOTO,
 	CONSOLE_CLEAR,
Index: uspace/lib/libc/include/string.h
===================================================================
--- uspace/lib/libc/include/string.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/include/string.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -73,7 +73,5 @@
 extern void str_append(char *dest, size_t size, const char *src);
 
-extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
-extern char *wstr_to_astr(const wchar_t *src);
-extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
+extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
 extern char *str_chr(const char *str, wchar_t ch);
Index: uspace/lib/libc/include/unistd.h
===================================================================
--- uspace/lib/libc/include/unistd.h	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/lib/libc/include/unistd.h	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -51,6 +51,4 @@
 #endif
 
-typedef uint32_t useconds_t;
-
 extern int dup2(int oldfd, int newfd);
 
@@ -70,6 +68,6 @@
 
 extern void _exit(int status) __attribute__ ((noreturn));
-extern int usleep(useconds_t uses);
-extern unsigned int sleep(unsigned int se);
+extern int usleep(unsigned long usec);
+extern unsigned int sleep(unsigned int seconds);
 
 #endif
Index: uspace/srv/console/console.c
===================================================================
--- uspace/srv/console/console.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/srv/console/console.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -601,8 +601,4 @@
 				    IPC_GET_ARG2(call));
 			break;
-		case CONSOLE_GET_POS:
-			arg1 = cons->scr.position_x;
-			arg2 = cons->scr.position_y;
-			break;
 		case CONSOLE_GET_SIZE:
 			arg1 = fb_info.cols;
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/srv/fs/fat/fat_ops.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -363,14 +363,9 @@
 				}
 				rc = fat_node_get_core(&nodep, idx);
+				assert(rc == EOK);
 				fibril_mutex_unlock(&idx->lock);
-				if (rc != EOK) {
-					(void) block_put(b);
-					return rc;
-				}
+				(void) block_put(b);
 				*rfn = FS_NODE(nodep);
-				rc = block_put(b);
-				if (rc != EOK)
-					(void) fat_node_put(*rfn);
-				return rc;
+				return EOK;
 			}
 		}
@@ -1077,18 +1072,9 @@
 			rc = fat_block_get(&b, bs, nodep, pos / bps,
 			    BLOCK_FLAGS_NONE);
-			if (rc != EOK) {
-				fat_node_put(fn);
-				ipc_answer_0(callid, rc);
-				ipc_answer_0(rid, rc);
-				return;
-			}
+			assert(rc == EOK);
 			(void) async_data_read_finalize(callid, b->data + pos % bps,
 			    bytes);
 			rc = block_put(b);
-			if (rc != EOK) {
-				fat_node_put(fn);
-				ipc_answer_0(rid, rc);
-				return;
-			}
+			assert(rc == EOK);
 		}
 	} else {
@@ -1114,6 +1100,5 @@
 			rc = fat_block_get(&b, bs, nodep, bnum,
 			    BLOCK_FLAGS_NONE);
-			if (rc != EOK)
-				goto err;
+			assert(rc == EOK);
 			for (o = pos % (bps / sizeof(fat_dentry_t));
 			    o < bps / sizeof(fat_dentry_t);
@@ -1126,6 +1111,5 @@
 				case FAT_DENTRY_LAST:
 					rc = block_put(b);
-					if (rc != EOK)
-						goto err;
+					assert(rc == EOK);
 					goto miss;
 				default:
@@ -1133,26 +1117,17 @@
 					fat_dentry_name_get(d, name);
 					rc = block_put(b);
-					if (rc != EOK)
-						goto err;
+					assert(rc == EOK);
 					goto hit;
 				}
 			}
 			rc = block_put(b);
-			if (rc != EOK)
-				goto err;
+			assert(rc == EOK);
 			bnum++;
 		}
 miss:
-		rc = fat_node_put(fn);
-		ipc_answer_0(callid, rc != EOK ? rc : ENOENT);
-		ipc_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
-		return;
-
-err:
-		(void) fat_node_put(fn);
-		ipc_answer_0(callid, rc);
-		ipc_answer_0(rid, rc);
-		return;
-
+		fat_node_put(fn);
+		ipc_answer_0(callid, ENOENT);
+		ipc_answer_1(rid, ENOENT, 0);
+		return;
 hit:
 		(void) async_data_read_finalize(callid, name, str_size(name) + 1);
@@ -1160,6 +1135,6 @@
 	}
 
-	rc = fat_node_put(fn);
-	ipc_answer_1(rid, rc, (ipcarg_t)bytes);
+	fat_node_put(fn);
+	ipc_answer_1(rid, EOK, (ipcarg_t)bytes);
 }
 
@@ -1172,5 +1147,5 @@
 	fat_node_t *nodep;
 	fat_bs_t *bs;
-	size_t bytes, size;
+	size_t bytes;
 	block_t *b;
 	uint16_t bps;
@@ -1195,5 +1170,5 @@
 	size_t len;
 	if (!async_data_write_receive(&callid, &len)) {
-		(void) fat_node_put(fn);
+		fat_node_put(fn);
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -1226,33 +1201,18 @@
 		 */
 		rc = fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos);
-		if (rc != EOK) {
-			(void) fat_node_put(fn);
-			ipc_answer_0(callid, rc);
-			ipc_answer_0(rid, rc);
-			return;
-		}
+		assert(rc == EOK);
 		rc = fat_block_get(&b, bs, nodep, pos / bps, flags);
-		if (rc != EOK) {
-			(void) fat_node_put(fn);
-			ipc_answer_0(callid, rc);
-			ipc_answer_0(rid, rc);
-			return;
-		}
+		assert(rc == EOK);
 		(void) async_data_write_finalize(callid, b->data + pos % bps,
 		    bytes);
 		b->dirty = true;		/* need to sync block */
 		rc = block_put(b);
-		if (rc != EOK) {
-			(void) fat_node_put(fn);
-			ipc_answer_0(rid, rc);
-			return;
-		}
+		assert(rc == EOK);
 		if (pos + bytes > nodep->size) {
 			nodep->size = pos + bytes;
 			nodep->dirty = true;	/* need to sync node */
 		}
-		size = nodep->size;
-		rc = fat_node_put(fn);
-		ipc_answer_2(rid, rc, bytes, nodep->size);
+		ipc_answer_2(rid, EOK, bytes, nodep->size);	
+		fat_node_put(fn);
 		return;
 	} else {
@@ -1261,4 +1221,5 @@
 		 * clusters for the node and zero them out.
 		 */
+		int status;
 		unsigned nclsts;
 		fat_cluster_t mcl, lcl; 
@@ -1266,40 +1227,23 @@
 		nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc;
 		/* create an independent chain of nclsts clusters in all FATs */
-		rc = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
-		if (rc != EOK) {
+		status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);
+		if (status != EOK) {
 			/* could not allocate a chain of nclsts clusters */
-			(void) fat_node_put(fn);
-			ipc_answer_0(callid, rc);
-			ipc_answer_0(rid, rc);
+			fat_node_put(fn);
+			ipc_answer_0(callid, status);
+			ipc_answer_0(rid, status);
 			return;
 		}
 		/* zero fill any gaps */
 		rc = fat_fill_gap(bs, nodep, mcl, pos);
-		if (rc != EOK) {
-			(void) fat_free_clusters(bs, dev_handle, mcl);
-			(void) fat_node_put(fn);
-			ipc_answer_0(callid, rc);
-			ipc_answer_0(rid, rc);
-			return;
-		}
+		assert(rc == EOK);
 		rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc,
 		    flags);
-		if (rc != EOK) {
-			(void) fat_free_clusters(bs, dev_handle, mcl);
-			(void) fat_node_put(fn);
-			ipc_answer_0(callid, rc);
-			ipc_answer_0(rid, rc);
-			return;
-		}
+		assert(rc == EOK);
 		(void) async_data_write_finalize(callid, b->data + pos % bps,
 		    bytes);
 		b->dirty = true;		/* need to sync block */
 		rc = block_put(b);
-		if (rc != EOK) {
-			(void) fat_free_clusters(bs, dev_handle, mcl);
-			(void) fat_node_put(fn);
-			ipc_answer_0(rid, rc);
-			return;
-		}
+		assert(rc == EOK);
 		/*
 		 * Append the cluster chain starting in mcl to the end of the
@@ -1307,14 +1251,9 @@
 		 */
 		rc = fat_append_clusters(bs, nodep, mcl);
-		if (rc != EOK) {
-			(void) fat_free_clusters(bs, dev_handle, mcl);
-			(void) fat_node_put(fn);
-			ipc_answer_0(rid, rc);
-			return;
-		}
-		nodep->size = size = pos + bytes;
+		assert(rc == EOK);
+		nodep->size = pos + bytes;
 		nodep->dirty = true;		/* need to sync node */
-		rc = fat_node_put(fn);
-		ipc_answer_2(rid, rc, bytes, size);
+		ipc_answer_2(rid, EOK, bytes, nodep->size);
+		fat_node_put(fn);
 		return;
 	}
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision fbcfc4dae9c8bbb7a192b0d0050fd7e51c5faf32)
+++ uspace/srv/vfs/vfs_file.c	(revision cb3d641acfaba056443f5a2ae15d649889c2c7a7)
@@ -89,5 +89,5 @@
 	unsigned int i;
 	if (desc)
-		i = MAX_OPEN_FILES - 1;
+		i = MAX_OPEN_FILES;
 	else
 		i = 0;
@@ -111,5 +111,5 @@
 			i--;
 		} else {
-			if (i == MAX_OPEN_FILES - 1)
+			if (i == MAX_OPEN_FILES)
 				break;
 			
