Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision ba25c4bbca58a62473323b0e9c57e9cb14bcbf5a)
+++ kernel/generic/include/proc/thread.h	(revision 83789ea27b9086d9e279dc3811225605763d64a3)
@@ -121,8 +121,4 @@
 	/** Wait queue in which this thread sleeps. */
 	waitq_t *sleep_queue;
-	/** Timeout used for timeoutable sleeping.  */
-	timeout_t sleep_timeout;
-	/** Flag signalling sleep timeout in progress. */
-	volatile bool timeout_pending;
 
 	/**
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision ba25c4bbca58a62473323b0e9c57e9cb14bcbf5a)
+++ kernel/generic/src/proc/thread.c	(revision 83789ea27b9086d9e279dc3811225605763d64a3)
@@ -360,9 +360,7 @@
 	thread->state = Entering;
 
-	timeout_initialize(&thread->sleep_timeout);
 	thread->sleep_interruptible = false;
 	thread->sleep_composable = false;
 	thread->sleep_queue = NULL;
-	thread->timeout_pending = false;
 
 	thread->in_copy_from_uspace = false;
@@ -500,12 +498,5 @@
 	}
 
-restart:
 	irq_spinlock_lock(&THREAD->lock, true);
-	if (THREAD->timeout_pending) {
-		/* Busy waiting for timeouts in progress */
-		irq_spinlock_unlock(&THREAD->lock, true);
-		goto restart;
-	}
-
 	THREAD->state = Exiting;
 	irq_spinlock_unlock(&THREAD->lock, true);
Index: kernel/generic/src/synch/waitq.c
===================================================================
--- kernel/generic/src/synch/waitq.c	(revision ba25c4bbca58a62473323b0e9c57e9cb14bcbf5a)
+++ kernel/generic/src/synch/waitq.c	(revision 83789ea27b9086d9e279dc3811225605763d64a3)
@@ -121,5 +121,4 @@
 	}
 
-	thread->timeout_pending = false;
 	irq_spinlock_unlock(&thread->lock, false);
 
@@ -172,8 +171,4 @@
 			goto grab_locks;
 		}
-
-		if ((thread->timeout_pending) &&
-		    (timeout_unregister(&thread->sleep_timeout)))
-			thread->timeout_pending = false;
 
 		list_remove(&thread->wq_link);
@@ -270,29 +265,5 @@
 ipl_t waitq_sleep_prepare(waitq_t *wq)
 {
-	ipl_t ipl;
-
-restart:
-	ipl = interrupts_disable();
-
-	if (THREAD) {  /* Needed during system initiailzation */
-		/*
-		 * Busy waiting for a delayed timeout.
-		 * This is an important fix for the race condition between
-		 * a delayed timeout and a next call to waitq_sleep_timeout().
-		 * Simply, the thread is not allowed to go to sleep if
-		 * there are timeouts in progress.
-		 *
-		 */
-		irq_spinlock_lock(&THREAD->lock, false);
-
-		if (THREAD->timeout_pending) {
-			irq_spinlock_unlock(&THREAD->lock, false);
-			interrupts_restore(ipl);
-			goto restart;
-		}
-
-		irq_spinlock_unlock(&THREAD->lock, false);
-	}
-
+	ipl_t ipl = interrupts_disable();
 	irq_spinlock_lock(&wq->lock, false);
 	return ipl;
@@ -374,4 +345,7 @@
 	irq_spinlock_lock(&THREAD->lock, false);
 
+	timeout_t timeout;
+	timeout_initialize(&timeout);
+
 	THREAD->sleep_composable = (flags & SYNCH_FLAGS_FUTEX);
 
@@ -395,4 +369,7 @@
 			THREAD->last_cycle = get_cycle();
 			irq_spinlock_unlock(&THREAD->lock, false);
+			if (usec) {
+				timeout_unregister(&timeout);
+			}
 			return EINTR;
 		}
@@ -409,7 +386,5 @@
 		}
 
-		THREAD->timeout_pending = true;
-		timeout_register(&THREAD->sleep_timeout, (uint64_t) usec,
-		    waitq_sleep_timed_out, THREAD);
+		timeout_register(&timeout, (uint64_t) usec, waitq_sleep_timed_out, THREAD);
 	}
 
@@ -433,4 +408,8 @@
 	/* wq->lock is released in scheduler_separated_stack() */
 	scheduler();
+
+	if (usec) {
+		timeout_unregister(&timeout);
+	}
 
 	return EOK;
@@ -560,8 +539,4 @@
 	list_remove(&thread->wq_link);
 
-	if ((thread->timeout_pending) &&
-	    (timeout_unregister(&thread->sleep_timeout)))
-		thread->timeout_pending = false;
-
 	thread->sleep_queue = NULL;
 	irq_spinlock_unlock(&thread->lock, false);
Index: kernel/generic/src/time/timeout.c
===================================================================
--- kernel/generic/src/time/timeout.c	(revision ba25c4bbca58a62473323b0e9c57e9cb14bcbf5a)
+++ kernel/generic/src/time/timeout.c	(revision 83789ea27b9086d9e279dc3811225605763d64a3)
@@ -128,4 +128,8 @@
 bool timeout_unregister(timeout_t *timeout)
 {
+	if (atomic_load_explicit(&timeout->finished, memory_order_acquire))
+		/* The timeout fired and finished already, no need to check the list. */
+		return false;
+
 	assert(timeout->cpu);
 
