Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision 8addb24acd8c8ad903505217be1dba5c2812d7a9)
+++ kernel/generic/include/cpu.h	(revision aae2869ce92cf8890c7625c4b51691f02993d436)
@@ -76,4 +76,5 @@
 	/** Can only be accessed when interrupts are disabled. */
 	uint64_t current_clock_tick;
+	uint64_t preempt_deadline;  /* < when should the currently running thread be preempted */
 
 	/**
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision 8addb24acd8c8ad903505217be1dba5c2812d7a9)
+++ kernel/generic/include/proc/thread.h	(revision aae2869ce92cf8890c7625c4b51691f02993d436)
@@ -177,7 +177,4 @@
 	bool uspace;
 
-	/** Ticks before preemption. */
-	uint64_t ticks;
-
 	/** Thread accounting. */
 	uint64_t ucycles;
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 8addb24acd8c8ad903505217be1dba5c2812d7a9)
+++ kernel/generic/src/proc/scheduler.c	(revision aae2869ce92cf8890c7625c4b51691f02993d436)
@@ -236,6 +236,11 @@
 
 		thread->cpu = CPU;
-		thread->ticks = us2ticks((i + 1) * 10000);
 		thread->priority = i;  /* Correct rq index */
+
+		/* Time allocation in microseconds. */
+		uint64_t time_to_run = (i + 1) * 10000;
+
+		/* This is safe because interrupts are disabled. */
+		CPU->preempt_deadline = CPU->current_clock_tick + us2ticks(time_to_run);
 
 		/*
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 8addb24acd8c8ad903505217be1dba5c2812d7a9)
+++ kernel/generic/src/proc/thread.c	(revision aae2869ce92cf8890c7625c4b51691f02993d436)
@@ -372,5 +372,4 @@
 	thread->thread_code = func;
 	thread->thread_arg = arg;
-	thread->ticks = -1;
 	thread->ucycles = 0;
 	thread->kcycles = 0;
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision 8addb24acd8c8ad903505217be1dba5c2812d7a9)
+++ kernel/generic/src/time/clock.c	(revision aae2869ce92cf8890c7625c4b51691f02993d436)
@@ -184,20 +184,9 @@
 
 	if (THREAD) {
-		uint64_t ticks;
-
 		irq_spinlock_lock(&CPU->lock, false);
 		CPU->needs_relink += 1 + missed_clock_ticks;
 		irq_spinlock_unlock(&CPU->lock, false);
 
-		irq_spinlock_lock(&THREAD->lock, false);
-		if ((ticks = THREAD->ticks)) {
-			if (ticks >= 1 + missed_clock_ticks)
-				THREAD->ticks -= 1 + missed_clock_ticks;
-			else
-				THREAD->ticks = 0;
-		}
-		irq_spinlock_unlock(&THREAD->lock, false);
-
-		if (ticks == 0 && PREEMPTION_ENABLED) {
+		if (current_clock_tick >= CPU->preempt_deadline && PREEMPTION_ENABLED) {
 			scheduler();
 #ifdef CONFIG_UDEBUG
