Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision 6a0e568427978c583cc81ec4a2e002711f89b081)
+++ kernel/generic/include/proc/thread.h	(revision 286da52c77dc3bd30ef7b617138baded44d5dbb5)
@@ -186,5 +186,5 @@
 extern void thread_attach(thread_t *, task_t *);
 extern void thread_start(thread_t *);
-extern void thread_ready(thread_t *);
+extern void thread_requeue_sleeping(thread_t *);
 extern void thread_exit(void) __attribute__((noreturn));
 extern void thread_interrupt(thread_t *);
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision 6a0e568427978c583cc81ec4a2e002711f89b081)
+++ kernel/generic/src/proc/scheduler.c	(revision 286da52c77dc3bd30ef7b617138baded44d5dbb5)
@@ -311,6 +311,7 @@
 
 	irq_spinlock_lock(&THREAD->lock, false);
+	assert(THREAD->cpu == CPU);
+
 	THREAD->state = Running;
-	THREAD->cpu = CPU;
 	THREAD->priority = rq_index;  /* Correct rq index */
 
@@ -365,4 +366,61 @@
 }
 
+static void add_to_rq(thread_t *thread, cpu_t *cpu, int i)
+{
+	/* Add to the appropriate runqueue. */
+	runq_t *rq = &cpu->rq[i];
+
+	irq_spinlock_lock(&rq->lock, false);
+	list_append(&thread->rq_link, &rq->rq);
+	rq->n++;
+	irq_spinlock_unlock(&rq->lock, false);
+
+	atomic_inc(&nrdy);
+	atomic_inc(&cpu->nrdy);
+}
+
+/** Requeue a thread that was just preempted on this CPU.
+ */
+static void thread_requeue_preempted(thread_t *thread)
+{
+	irq_spinlock_lock(&thread->lock, false);
+
+	assert(thread->state == Running);
+	assert(thread->cpu == CPU);
+
+	int i = (thread->priority < RQ_COUNT - 1) ?
+	    ++thread->priority : thread->priority;
+
+	thread->state = Ready;
+
+	irq_spinlock_unlock(&thread->lock, false);
+
+	add_to_rq(thread, CPU, i);
+}
+
+void thread_requeue_sleeping(thread_t *thread)
+{
+	ipl_t ipl = interrupts_disable();
+
+	irq_spinlock_lock(&thread->lock, false);
+
+	assert(thread->state == Sleeping || thread->state == Entering);
+
+	thread->priority = 0;
+	thread->state = Ready;
+
+	/* Prefer the CPU on which the thread ran last */
+	if (!thread->cpu)
+		thread->cpu = CPU;
+
+	cpu_t *cpu = thread->cpu;
+
+	irq_spinlock_unlock(&thread->lock, false);
+
+	add_to_rq(thread, cpu, 0);
+
+	interrupts_restore(ipl);
+}
+
 static void cleanup_after_thread(thread_t *thread, state_t out_state)
 {
@@ -374,5 +432,5 @@
 	switch (out_state) {
 	case Running:
-		thread_ready(thread);
+		thread_requeue_preempted(thread);
 		break;
 
@@ -398,5 +456,5 @@
 			assert(expected == SLEEP_WOKE);
 			/* The thread has already been woken up, requeue immediately. */
-			thread_ready(thread);
+			thread_requeue_sleeping(thread);
 		}
 		break;
@@ -447,9 +505,4 @@
 	 */
 	after_thread_ran_arch();
-
-	if (new_state == Sleeping) {
-		/* Prefer the thread after it's woken up. */
-		THREAD->priority = -1;
-	}
 
 	irq_spinlock_unlock(&THREAD->lock, false);
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 6a0e568427978c583cc81ec4a2e002711f89b081)
+++ kernel/generic/src/proc/thread.c	(revision 286da52c77dc3bd30ef7b617138baded44d5dbb5)
@@ -210,42 +210,5 @@
 {
 	assert(thread->state == Entering);
-	thread_ready(thread_ref(thread));
-}
-
-/** Make thread ready
- *
- * Switch thread to the ready state. Consumes reference passed by the caller.
- *
- * @param thread Thread to make ready.
- *
- */
-void thread_ready(thread_t *thread)
-{
-	// TODO: move this to scheduler.c
-	irq_spinlock_lock(&thread->lock, true);
-
-	assert(thread->state != Ready);
-
-	int i = (thread->priority < RQ_COUNT - 1) ?
-	    ++thread->priority : thread->priority;
-
-	/* Prefer the CPU on which the thread ran last */
-	cpu_t *cpu = thread->cpu ? thread->cpu : CPU;
-
-	thread->state = Ready;
-
-	irq_spinlock_pass(&thread->lock, &(cpu->rq[i].lock));
-
-	/*
-	 * Append thread to respective ready queue
-	 * on respective processor.
-	 */
-
-	list_append(&thread->rq_link, &cpu->rq[i].rq);
-	cpu->rq[i].n++;
-	irq_spinlock_unlock(&(cpu->rq[i].lock), true);
-
-	atomic_inc(&nrdy);
-	atomic_inc(&cpu->nrdy);
+	thread_requeue_sleeping(thread_ref(thread));
 }
 
@@ -613,5 +576,5 @@
 		 * the waking thread by the sleeper in thread_wait_finish().
 		 */
-		thread_ready(thread);
+		thread_requeue_sleeping(thread);
 	}
 }
@@ -1064,5 +1027,6 @@
 		thread_attach(thread, TASK);
 #endif
-		thread_ready(thread);
+		thread_start(thread);
+		thread_put(thread);
 
 		return 0;
