Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision 1871118c75a2375392bbb2054288202965beca01)
+++ kernel/generic/include/proc/task.h	(revision 11d2c98362478850f6d9f3d23e3a07426ab94485)
@@ -89,4 +89,5 @@
 	atomic_size_t refcount;
 	/** Number of threads that haven't exited yet. */
+	// TODO: remove
 	atomic_size_t lifecount;
 
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision 1871118c75a2375392bbb2054288202965beca01)
+++ kernel/generic/src/proc/thread.c	(revision 11d2c98362478850f6d9f3d23e3a07426ab94485)
@@ -398,7 +398,5 @@
  * Detach thread from all queues, cpus etc. and destroy it.
  *
- * @param thread  Thread to be destroyed.
- * @param irq_res Indicate whether it should unlock thread->lock
- *                in interrupts-restore mode.
+ * @param obj  Thread to be destroyed.
  *
  */
@@ -407,7 +405,25 @@
 	thread_t *thread = (thread_t *) obj;
 
-	irq_spinlock_lock(&thread->lock, true);
+	assert_link_not_used(&thread->rq_link);
+	assert_link_not_used(&thread->wq_link);
+
+	assert(thread->task);
+
+	ipl_t ipl = interrupts_disable();
+
+	/* Remove thread from task's list. */
+	irq_spinlock_lock(&thread->task->lock, false);
+	list_remove(&thread->th_link);
+	irq_spinlock_unlock(&thread->task->lock, false);
+
+	/* Remove thread from global list. */
+	irq_spinlock_lock(&threads_lock, false);
+	odict_remove(&thread->lthreads);
+	irq_spinlock_unlock(&threads_lock, false);
+
+	/* Clear cpu->fpu_owner if set to this thread. */
+	irq_spinlock_lock(&thread->lock, false);
+
 	assert((thread->state == Exiting) || (thread->state == Lingering));
-	assert(thread->task);
 	assert(thread->cpu);
 
@@ -417,15 +433,7 @@
 	irq_spinlock_unlock(&thread->cpu->lock, false);
 
-	irq_spinlock_pass(&thread->lock, &threads_lock);
-
-	odict_remove(&thread->lthreads);
-
-	irq_spinlock_pass(&threads_lock, &thread->task->lock);
-
-	/*
-	 * Detach from the containing task.
-	 */
-	list_remove(&thread->th_link);
-	irq_spinlock_unlock(&thread->task->lock, true);
+	irq_spinlock_unlock(&thread->lock, false);
+
+	interrupts_restore(ipl);
 
 	/*
@@ -433,4 +441,6 @@
 	 */
 	task_release(thread->task);
+	thread->task = NULL;
+
 	slab_free(thread_cache, thread);
 }
