Index: uspace/lib/libc/arch/amd64/include/atomic.h
===================================================================
--- uspace/lib/libc/arch/amd64/include/atomic.h	(revision 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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 2a5af223633736d7b866a2f1a951142fe72dc78b)
+++ 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
