Index: kernel/generic/include/cpu.h
===================================================================
--- kernel/generic/include/cpu.h	(revision dfa4be625ce02c0a9d62197b2b62b4c8d6043bf3)
+++ kernel/generic/include/cpu.h	(revision a5b5f170deb56b04c049c3366dc51a4379025eb8)
@@ -78,5 +78,4 @@
 
 	struct thread *prev_thread;
-	state_t exiting_state;
 } cpu_local_t;
 
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision dfa4be625ce02c0a9d62197b2b62b4c8d6043bf3)
+++ kernel/generic/include/proc/thread.h	(revision a5b5f170deb56b04c049c3366dc51a4379025eb8)
@@ -193,5 +193,9 @@
 	bool stolen;
 
-	/** Thread state. */
+	/**
+	 * Thread state (state_t).
+	 * This is atomic because we read it via some commands for debug output,
+	 * otherwise it could just be a regular local.
+	 */
 	atomic_int_fast32_t state;
 
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision dfa4be625ce02c0a9d62197b2b62b4c8d6043bf3)
+++ kernel/generic/src/proc/scheduler.c	(revision a5b5f170deb56b04c049c3366dc51a4379025eb8)
@@ -383,4 +383,5 @@
 static void thread_requeue_preempted(thread_t *thread)
 {
+	assert(interrupts_disabled());
 	assert(atomic_get_unordered(&thread->state) == Running);
 	assert(atomic_get_unordered(&thread->cpu) == CPU);
@@ -420,5 +421,5 @@
 }
 
-static void cleanup_after_thread(thread_t *thread, state_t out_state)
+static void cleanup_after_thread(thread_t *thread)
 {
 	assert(CURRENT->mutex_locks == 0);
@@ -427,5 +428,5 @@
 	int expected;
 
-	switch (out_state) {
+	switch (atomic_get_unordered(&thread->state)) {
 	case Running:
 		thread_requeue_preempted(thread);
@@ -462,5 +463,5 @@
 		 */
 		panic("tid%" PRIu64 ": unexpected state %s.",
-		    thread->tid, thread_states[out_state]);
+		    thread->tid, thread_states[atomic_get_unordered(&thread->state)]);
 		break;
 	}
@@ -501,6 +502,4 @@
 	 */
 	after_thread_ran_arch();
-
-	CPU_LOCAL->exiting_state = new_state;
 
 	if (new_thread) {
@@ -527,5 +526,5 @@
 	/* Check if we need to clean up after another thread. */
 	if (CPU_LOCAL->prev_thread) {
-		cleanup_after_thread(CPU_LOCAL->prev_thread, CPU_LOCAL->exiting_state);
+		cleanup_after_thread(CPU_LOCAL->prev_thread);
 		CPU_LOCAL->prev_thread = NULL;
 	}
@@ -573,5 +572,5 @@
 		assert(interrupts_disabled());
 
-		cleanup_after_thread(THREAD, CPU_LOCAL->exiting_state);
+		cleanup_after_thread(THREAD);
 
 		/*
@@ -601,5 +600,5 @@
 	/* Check if we need to clean up after another thread. */
 	if (CPU_LOCAL->prev_thread) {
-		cleanup_after_thread(CPU_LOCAL->prev_thread, CPU_LOCAL->exiting_state);
+		cleanup_after_thread(CPU_LOCAL->prev_thread);
 		CPU_LOCAL->prev_thread = NULL;
 	}
