Index: Makefile
===================================================================
--- Makefile	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ Makefile	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -43,5 +43,5 @@
 	$(MAKE) -C kernel clean
 	$(MAKE) -C kernel EXTRA_TOOL=stanse
-	$(STANSE) --checker ReachabilityChecker --checker ThreadChecker:contrib/$(STANSE)/ThreadChecker.xml --jobfile kernel/kernel.job
+	$(STANSE) --checker ReachabilityChecker --jobfile kernel/kernel.job
 
 cscope:
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/amd64/src/amd64.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -67,4 +67,5 @@
 #include <ddi/irq.h>
 #include <sysinfo/sysinfo.h>
+#include <memstr.h>
 
 /** Disable I/O on non-privileged levels
Index: kernel/arch/arm32/include/atomic.h
===================================================================
--- kernel/arch/arm32/include/atomic.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/arm32/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -37,4 +37,6 @@
 #define KERN_arm32_ATOMIC_H_
 
+#include <arch/asm.h>
+
 /** Atomic addition.
  *
@@ -47,19 +49,14 @@
 static inline long atomic_add(atomic_t *val, int i)
 {
-	int ret;
-	volatile long *mem = &(val->count);
-	
-	asm volatile (
-		"1:\n"
-			"ldr r2, [%[mem]]\n"
-			"add r3, r2, %[i]\n"
-			"str r3, %[ret]\n"
-			"swp r3, r3, [%[mem]]\n"
-			"cmp r3, r2\n"
-			"bne 1b\n"
-		: [ret] "=m" (ret)
-		: [mem] "r" (mem), [i] "r" (i)
-		: "r3", "r2"
-	);
+	long ret;
+
+	/*
+	 * This implementation is for UP pre-ARMv6 systems where we do not have
+	 * the LDREX and STREX instructions.
+	 */
+	ipl_t ipl = interrupts_disable();
+	val->count += i;
+	ret = val->count;
+	interrupts_restore(ipl);
 	
 	return ret;
Index: kernel/arch/arm32/src/mm/as.c
===================================================================
--- kernel/arch/arm32/src/mm/as.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/arm32/src/mm/as.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -36,4 +36,5 @@
 #include <arch/mm/as.h>
 #include <genarch/mm/as_pt.h>
+#include <genarch/mm/page_pt.h>
 #include <genarch/mm/asid_fifo.h>
 #include <mm/as.h>
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/ia32/src/ia32.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -68,4 +68,5 @@
 #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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/ia64/src/cpu/cpu.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -37,4 +37,5 @@
 #include <arch/register.h>
 #include <print.h>
+#include <memstr.h>
 
 void cpu_arch_init(void)
Index: kernel/arch/ppc32/src/mm/as.c
===================================================================
--- kernel/arch/ppc32/src/mm/as.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/ppc32/src/mm/as.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -35,4 +35,5 @@
 #include <arch/mm/as.h>
 #include <genarch/mm/as_pt.h>
+#include <genarch/mm/page_pt.h>
 #include <genarch/mm/asid_fifo.h>
 #include <arch.h>
Index: kernel/arch/ppc32/src/mm/tlb.c
===================================================================
--- kernel/arch/ppc32/src/mm/tlb.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/ppc32/src/mm/tlb.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -38,4 +38,5 @@
 #include <interrupt.h>
 #include <mm/as.h>
+#include <mm/page.h>
 #include <arch.h>
 #include <print.h>
Index: kernel/arch/ppc32/src/ppc32.c
===================================================================
--- kernel/arch/ppc32/src/ppc32.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/ppc32/src/ppc32.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -44,4 +44,5 @@
 #include <genarch/ofw/pci.h>
 #include <userspace.h>
+#include <mm/page.h>
 #include <proc/uarg.h>
 #include <console/console.h>
Index: kernel/arch/sparc64/src/mm/tlb.c
===================================================================
--- kernel/arch/sparc64/src/mm/tlb.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/arch/sparc64/src/mm/tlb.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -37,4 +37,5 @@
 #include <mm/as.h>
 #include <mm/asid.h>
+#include <genarch/mm/page_ht.h>
 #include <arch/mm/frame.h>
 #include <arch/mm/page.h>
Index: kernel/genarch/src/drivers/via-cuda/cuda.c
===================================================================
--- kernel/genarch/src/drivers/via-cuda/cuda.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/genarch/src/drivers/via-cuda/cuda.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -41,4 +41,5 @@
 #include <ddi/device.h>
 #include <synch/spinlock.h>
+#include <memstr.h>
 
 static irq_ownership_t cuda_claim(irq_t *irq);
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/genarch/src/fb/fb.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -41,4 +41,5 @@
 #include <console/console.h>
 #include <sysinfo/sysinfo.h>
+#include <mm/page.h>
 #include <mm/slab.h>
 #include <align.h>
Index: kernel/generic/include/arch.h
===================================================================
--- kernel/generic/include/arch.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/include/arch.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -39,4 +39,5 @@
 #include <proc/thread.h>
 #include <proc/task.h>
+#include <mm/as.h>
 
 #define DEFAULT_CONTEXT		0
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/include/proc/task.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -55,4 +55,5 @@
 #include <udebug/udebug.h>
 #include <ipc/kbox.h>
+#include <mm/as.h>
 
 #define TASK_NAME_BUFLEN	20
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/include/proc/thread.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -225,34 +225,33 @@
 
 extern void thread_init(void);
-extern thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
-    int flags, char *name, bool uncounted);
-extern void thread_attach(thread_t *t, task_t *task);
-extern void thread_ready(thread_t *t);
+extern thread_t *thread_create(void (*)(void *), void *, task_t *, int, char *,
+    bool);
+extern void thread_attach(thread_t *, task_t *);
+extern void thread_ready(thread_t *);
 extern void thread_exit(void) __attribute__((noreturn));
 
 #ifndef thread_create_arch
-extern void thread_create_arch(thread_t *t);
+extern void thread_create_arch(thread_t *);
 #endif
 #ifndef thr_constructor_arch
-extern void thr_constructor_arch(thread_t *t);
+extern void thr_constructor_arch(thread_t *);
 #endif
 #ifndef thr_destructor_arch
-extern void thr_destructor_arch(thread_t *t);
-#endif
-
-extern void thread_sleep(uint32_t sec);
-extern void thread_usleep(uint32_t usec);
+extern void thr_destructor_arch(thread_t *);
+#endif
+
+extern void thread_sleep(uint32_t);
+extern void thread_usleep(uint32_t);
 
 #define thread_join(t) \
 	thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
-extern int thread_join_timeout(thread_t *t, uint32_t usec, int flags);
-extern void thread_detach(thread_t *t);
-
-extern void thread_register_call_me(void (* call_me)(void *),
-    void *call_me_with);
+extern int thread_join_timeout(thread_t *, uint32_t, int);
+extern void thread_detach(thread_t *);
+
+extern void thread_register_call_me(void (*)(void *), void *);
 extern void thread_print_list(void);
-extern void thread_destroy(thread_t *t);
+extern void thread_destroy(thread_t *);
 extern void thread_update_accounting(void);
-extern bool thread_exists(thread_t *t);
+extern bool thread_exists(thread_t *);
 
 /** Fpu context slab cache. */
@@ -260,8 +259,9 @@
 
 /* Thread syscall prototypes. */
-extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg,
-    char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id);
-extern unative_t sys_thread_exit(int uspace_status);
-extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);
+extern unative_t sys_thread_create(uspace_arg_t *, char *, size_t,
+    thread_id_t *);
+extern unative_t sys_thread_exit(int);
+extern unative_t sys_thread_get_id(thread_id_t *);
+extern unative_t sys_thread_usleep(uint32_t);
 
 #endif
Index: kernel/generic/include/synch/futex.h
===================================================================
--- kernel/generic/include/synch/futex.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/include/synch/futex.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -38,6 +38,4 @@
 #include <arch/types.h>
 #include <synch/waitq.h>
-#include <genarch/mm/page_ht.h>
-#include <genarch/mm/page_pt.h>
 
 /** Kernel-side futex structure. */
@@ -54,7 +52,6 @@
 
 extern void futex_init(void);
-extern unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec,
-    int flags);
-extern unative_t sys_futex_wakeup(uintptr_t uaddr);
+extern unative_t sys_futex_sleep(uintptr_t);
+extern unative_t sys_futex_wakeup(uintptr_t);
 
 extern void futex_cleanup(void);
Index: kernel/generic/include/syscall/syscall.h
===================================================================
--- kernel/generic/include/syscall/syscall.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/include/syscall/syscall.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -43,4 +43,5 @@
 	SYS_THREAD_EXIT,
 	SYS_THREAD_GET_ID,
+	SYS_THREAD_USLEEP,
 	
 	SYS_TASK_GET_ID,
Index: kernel/generic/src/mm/backend_phys.c
===================================================================
--- kernel/generic/src/mm/backend_phys.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/src/mm/backend_phys.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -40,4 +40,5 @@
 #include <arch/types.h>
 #include <mm/as.h>
+#include <mm/page.h>
 #include <mm/frame.h>
 #include <mm/slab.h>
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/src/proc/task.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -54,4 +54,5 @@
 #include <func.h>
 #include <string.h>
+#include <memstr.h>
 #include <syscall/copy.h>
 #include <macros.h>
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/src/proc/thread.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -501,5 +501,12 @@
 void thread_sleep(uint32_t sec)
 {
-	thread_usleep(sec * 1000000);
+	/* Sleep in 1000 second steps to support
+	   full argument range */
+	while (sec > 0) {
+		uint32_t period = (sec > 1000) ? 1000 : sec;
+	
+		thread_usleep(period * 1000000);
+		sec -= period;
+	}
 }
 
@@ -575,7 +582,7 @@
 {
 	waitq_t wq;
-				  
+	
 	waitq_initialize(&wq);
-
+	
 	(void) waitq_sleep_timeout(&wq, usec, SYNCH_FLAGS_NON_BLOCKING);
 }
@@ -812,4 +819,11 @@
 }
 
+/** Syscall wrapper for sleeping. */
+unative_t sys_thread_usleep(uint32_t usec)
+{
+	thread_usleep(usec);
+	return 0;
+}
+
 /** @}
  */
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/src/synch/futex.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -90,5 +90,5 @@
 /** Initialize kernel futex structure.
  *
- * @param futex Kernel futex structure.
+ * @param futex		Kernel futex structure.
  */
 void futex_initialize(futex_t *futex)
@@ -102,13 +102,11 @@
 /** Sleep in futex wait queue.
  *
- * @param uaddr Userspace address of the futex counter.
- * @param usec If non-zero, number of microseconds this thread is willing to
- *     sleep.
- * @param flags Select mode of operation.
- *
- * @return One of ESYNCH_TIMEOUT, ESYNCH_OK_ATOMIC and ESYNCH_OK_BLOCKED. See
- *     synch.h. If there is no physical mapping for uaddr ENOENT is returned.
- */
-unative_t sys_futex_sleep_timeout(uintptr_t uaddr, uint32_t usec, int flags)
+ * @param uaddr		Userspace address of the futex counter.
+ *
+ * @return		If there is no physical mapping for uaddr ENOENT is
+ *			returned. Otherwise returns a wait result as defined in
+ *			synch.h.
+ */
+unative_t sys_futex_sleep(uintptr_t uaddr)
 {
 	futex_t *futex;
@@ -140,7 +138,5 @@
 	udebug_stoppable_begin();
 #endif
-	rc = waitq_sleep_timeout(&futex->wq, usec, flags |
-	    SYNCH_FLAGS_INTERRUPTIBLE);
-
+	rc = waitq_sleep_timeout(&futex->wq, 0, SYNCH_FLAGS_INTERRUPTIBLE); 
 #ifdef CONFIG_UDEBUG
 	udebug_stoppable_end();
@@ -151,7 +147,7 @@
 /** Wakeup one thread waiting in futex wait queue.
  *
- * @param uaddr Userspace address of the futex counter.
- *
- * @return ENOENT if there is no physical mapping for uaddr.
+ * @param uaddr		Userspace address of the futex counter.
+ *
+ * @return		ENOENT if there is no physical mapping for uaddr.
  */
 unative_t sys_futex_wakeup(uintptr_t uaddr)
@@ -190,7 +186,7 @@
  * If the structure does not exist already, a new one is created.
  *
- * @param paddr Physical address of the userspace futex counter.
- *
- * @return Address of the kernel futex structure.
+ * @param paddr		Physical address of the userspace futex counter.
+ *
+ * @return		Address of the kernel futex structure.
  */
 futex_t *futex_find(uintptr_t paddr)
@@ -284,8 +280,8 @@
 /** Compute hash index into futex hash table.
  *
- * @param key Address where the key (i.e. physical address of futex counter) is
- *     stored.
- *
- * @return Index into futex hash table.
+ * @param key		Address where the key (i.e. physical address of futex
+ *			counter) is stored.
+ *
+ * @return		Index into futex hash table.
  */
 size_t futex_ht_hash(unative_t *key)
@@ -296,8 +292,8 @@
 /** Compare futex hash table item with a key.
  *
- * @param key Address where the key (i.e. physical address of futex counter) is
- *     stored.
- *
- * @return True if the item matches the key. False otherwise.
+ * @param key		Address where the key (i.e. physical address of futex
+ *			counter) is stored.
+ *
+ * @return		True if the item matches the key. False otherwise.
  */
 bool futex_ht_compare(unative_t *key, size_t keys, link_t *item)
@@ -313,5 +309,5 @@
 /** Callback for removal items from futex hash table.
  *
- * @param item Item removed from the hash table.
+ * @param item		Item removed from the hash table.
  */
 void futex_ht_remove_callback(link_t *item)
Index: kernel/generic/src/syscall/syscall.c
===================================================================
--- kernel/generic/src/syscall/syscall.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/src/syscall/syscall.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -62,13 +62,9 @@
 
 #ifdef CONFIG_UDEBUG
-	bool debug;
-
 	/*
 	 * Early check for undebugged tasks. We do not lock anything as this
-	 * test need not be precise in either way.
+	 * test need not be precise in either direction.
 	 */
-	debug = THREAD->udebug.active;
-	
-	if (debug) {
+	if (THREAD->udebug.active) {
 		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
 	}
@@ -87,5 +83,5 @@
 	
 #ifdef CONFIG_UDEBUG
-	if (debug) {
+	if (THREAD->udebug.active) {
 		udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
 	
@@ -111,4 +107,5 @@
 	(syshandler_t) sys_thread_exit,
 	(syshandler_t) sys_thread_get_id,
+	(syshandler_t) sys_thread_usleep,
 	
 	(syshandler_t) sys_task_get_id,
@@ -117,5 +114,5 @@
 	
 	/* Synchronization related syscalls. */
-	(syshandler_t) sys_futex_sleep_timeout,
+	(syshandler_t) sys_futex_sleep,
 	(syshandler_t) sys_futex_wakeup,
 	(syshandler_t) sys_smc_coherence,
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -50,4 +50,5 @@
 #include <udebug/udebug.h>
 #include <udebug/udebug_ops.h>
+#include <memstr.h>
 
 /**
Index: uspace/lib/libc/arch/amd64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/amd64/include/atomic.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/arch/amd64/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -37,4 +37,8 @@
 #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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/arch/arm32/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -37,4 +37,30 @@
 #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.
  *
@@ -49,4 +75,5 @@
 	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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/arch/ia32/Makefile.inc	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -39,4 +39,5 @@
 	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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/arch/ia32/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -35,4 +35,8 @@
 #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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/arch/ia64/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -35,4 +35,8 @@
 #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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/arch/mips32/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -36,4 +36,8 @@
 #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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/arch/ppc32/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -35,4 +35,8 @@
 #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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/arch/sparc64/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -36,4 +36,7 @@
 #define LIBC_sparc64_ATOMIC_H_
 
+#define LIBC_ARCH_ATOMIC_H_
+
+#include <atomicdflt.h>
 #include <sys/types.h>
 
Index: uspace/lib/libc/generic/futex.c
===================================================================
--- uspace/lib/libc/generic/futex.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/generic/futex.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -36,49 +36,5 @@
 #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.
@@ -92,81 +48,28 @@
 }
 
-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.
- * @param usec		Microseconds to wait. Zero value means sleep without
- * 			timeout.
- * @param flags		Select mode of operation. See comment for
- * 			waitq_sleep_timeout(). 
+ * @return		Non-zero if the futex was acquired.
+ * @return		Zero if the futex was not acquired.
+ */
+int futex_trydown(futex_t *futex)
+{
+	return cas(futex, 1, 0);
+}
+
+/** Down the futex.
  *
- * @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).
+ * @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_timeout(futex_t *futex, uint32_t usec, int flags)
+int futex_down(futex_t *futex)
 {
-	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;
+	if (atomic_predec(futex) < 0)
+		return __SYSCALL1(SYS_FUTEX_SLEEP, (sysarg_t) &futex->count);
 
-		case ESYNCH_TIMEOUT:
-			atomic_inc(futex);
-			return ESYNCH_TIMEOUT;
-			break;
-
-		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;
+	return 0;
 }
 
@@ -174,14 +77,10 @@
  *
  * @param futex		Futex.
- *
- * @return		ENOENT if there is no such virtual address. Otherwise
- * 			zero.
+ * @return		ENOENT if there is no such virtual address.
+ * @return		Zero in the uncontended case.
  */
 int futex_up(futex_t *futex)
 {
-	long val;
-	
-	val = atomic_postinc(futex);
-	if (val < 0)
+	if (atomic_postinc(futex) < 0)
 		return __SYSCALL1(SYS_FUTEX_WAKEUP, (sysarg_t) &futex->count);
 		
Index: uspace/lib/libc/generic/io/io.c
===================================================================
--- uspace/lib/libc/generic/io/io.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/generic/io/io.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -341,9 +341,14 @@
 size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
 {
-	size_t left = size * nmemb;
-	size_t done = 0;
-	
+	size_t left, done;
+
+	if (size == 0 || nmemb == 0)
+		return 0;
+
 	/* Make sure no data is pending write. */
 	_fflushbuf(stream);
+
+	left = size * nmemb;
+	done = 0;
 	
 	while ((left > 0) && (!stream->error) && (!stream->eof)) {
@@ -365,7 +370,13 @@
 static size_t _fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
 {
-	size_t left = size * nmemb;
-	size_t done = 0;
-	
+	size_t left;
+	size_t done;
+
+	if (size == 0 || nmemb == 0)
+		return 0;
+
+	left = size * nmemb;
+	done = 0;
+
 	while ((left > 0) && (!stream->error)) {
 		ssize_t wr;
@@ -421,5 +432,8 @@
 	uint8_t b;
 	bool need_flush;
-	
+
+	if (size == 0 || nmemb == 0)
+		return 0;
+
 	/* If not buffered stream, write out directly. */
 	if (stream->btype == _IONBF) {
Index: uspace/lib/libc/generic/time.c
===================================================================
--- uspace/lib/libc/generic/time.c	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/generic/time.c	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -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,27 +189,20 @@
 
 /** Wait unconditionally for specified number of microseconds */
-int usleep(unsigned long usec)
-{
-	atomic_t futex = FUTEX_INITIALIZER;
-
-	futex_initialize(&futex, 0);
-	futex_down_timeout(&futex, usec, 0);
+int usleep(useconds_t usec)
+{
+	(void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
 	return 0;
 }
 
 /** Wait unconditionally for specified number of seconds */
-unsigned int sleep(unsigned int seconds)
-{
-	atomic_t futex = FUTEX_INITIALIZER;
-
-	futex_initialize(&futex, 0);
-	
+unsigned int sleep(unsigned int sec)
+{
 	/* Sleep in 1000 second steps to support
 	   full argument range */
-	while (seconds > 0) {
-		unsigned int period = (seconds > 1000) ? 1000 : seconds;
+	while (sec > 0) {
+		unsigned int period = (sec > 1000) ? 1000 : sec;
 	
-		futex_down_timeout(&futex, period * 1000000, 0);
-		seconds -= period;
+		usleep(period * 1000000);
+		sec -= period;
 	}
 	return 0;
Index: uspace/lib/libc/include/atomic.h
===================================================================
--- uspace/lib/libc/include/atomic.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/include/atomic.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2006 Jakub Jermar
+ * Copyright (c) 2009 Jakub Jermar
  * All rights reserved.
  *
@@ -36,19 +36,5 @@
 #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: uspace/lib/libc/include/atomicdflt.h
===================================================================
--- uspace/lib/libc/include/atomicdflt.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
+++ uspace/lib/libc/include/atomicdflt.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -0,0 +1,66 @@
+/*
+ * 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 bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/include/futex.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -46,5 +46,4 @@
 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/unistd.h
===================================================================
--- uspace/lib/libc/include/unistd.h	(revision bc77bfaaa1de8f4e04f3bd368053d94e5311c2a6)
+++ uspace/lib/libc/include/unistd.h	(revision 034bf0e27f6439c8ee9425abd454c308f7f0ea84)
@@ -51,4 +51,6 @@
 #endif
 
+typedef uint32_t useconds_t;
+
 extern int dup2(int oldfd, int newfd);
 
@@ -68,6 +70,6 @@
 
 extern void _exit(int status) __attribute__ ((noreturn));
-extern int usleep(unsigned long usec);
-extern unsigned int sleep(unsigned int seconds);
+extern int usleep(useconds_t uses);
+extern unsigned int sleep(unsigned int se);
 
 #endif
