Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 98000fb4ea6015506f059c9b121e417ce991ecfd)
+++ kernel/generic/src/proc/task.c	(revision e795203e174ecc5e901f6b8f8833f9bd4364e51b)
@@ -75,4 +75,7 @@
 static task_id_t task_counter = 0;
 
+/* Forward declarations. */
+static void task_kill_internal(task_t *);
+
 /** Initialize kernel tasks support. */
 void task_init(void)
@@ -83,5 +86,5 @@
 
 /*
- * The idea behind this walker is to remember a single task different from
+ * The idea behind this walker is to kill and count all tasks different from
  * TASK.
  */
@@ -89,9 +92,12 @@
 {
 	task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
-	task_t **tp = (task_t **) arg;
-
-	if (t != TASK) { 
-		*tp = t;
-		return false;	/* stop walking */
+	unsigned *cnt = (unsigned *) arg;
+
+	if (t != TASK) {
+		(*cnt)++;
+#ifdef CONFIG_DEBUG
+		printf("[%"PRIu64"] ", t->taskid);
+#endif
+		task_kill_internal(t);
 	}
 
@@ -102,31 +108,22 @@
 void task_done(void)
 {
-	task_t *t;
+	unsigned tasks_left;
+
 	do { /* Repeat until there are any tasks except TASK */
-		
 		/* Messing with task structures, avoid deadlock */
+#ifdef CONFIG_DEBUG
+		printf("Killing tasks... ");
+#endif
 		ipl_t ipl = interrupts_disable();
 		spinlock_lock(&tasks_lock);
-		
-		t = NULL;
-		avltree_walk(&tasks_tree, task_done_walker, &t);
-		
-		if (t != NULL) {
-			task_id_t id = t->taskid;
-			
-			spinlock_unlock(&tasks_lock);
-			interrupts_restore(ipl);
-			
+		tasks_left = 0;
+		avltree_walk(&tasks_tree, task_done_walker, &tasks_left);
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		thread_sleep(1);
 #ifdef CONFIG_DEBUG
-			printf("Killing task %" PRIu64 "\n", id);
-#endif			
-			task_kill(id);
-			thread_usleep(10000);
-		} else {
-			spinlock_unlock(&tasks_lock);
-			interrupts_restore(ipl);
-		}
-		
-	} while (t != NULL);
+		printf("\n");
+#endif
+	} while (tasks_left);
 }
 
@@ -350,31 +347,8 @@
 }
 
-/** Kill task.
- *
- * This function is idempotent.
- * It signals all the task's threads to bail it out.
- *
- * @param id		ID of the task to be killed.
- *
- * @return		Zero on success or an error code from errno.h.
- */
-int task_kill(task_id_t id)
-{
-	ipl_t ipl;
-	task_t *ta;
+static void task_kill_internal(task_t *ta)
+{
 	link_t *cur;
 
-	if (id == 1)
-		return EPERM;
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&tasks_lock);
-	if (!(ta = task_find_by_id(id))) {
-		spinlock_unlock(&tasks_lock);
-		interrupts_restore(ipl);
-		return ENOENT;
-	}
-	spinlock_unlock(&tasks_lock);
-	
 	/*
 	 * Interrupt all threads.
@@ -397,6 +371,33 @@
 	}
 	spinlock_unlock(&ta->lock);
+}
+
+/** Kill task.
+ *
+ * This function is idempotent.
+ * It signals all the task's threads to bail it out.
+ *
+ * @param id		ID of the task to be killed.
+ *
+ * @return		Zero on success or an error code from errno.h.
+ */
+int task_kill(task_id_t id)
+{
+	ipl_t ipl;
+	task_t *ta;
+
+	if (id == 1)
+		return EPERM;
+	
+	ipl = interrupts_disable();
+	spinlock_lock(&tasks_lock);
+	if (!(ta = task_find_by_id(id))) {
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		return ENOENT;
+	}
+	task_kill_internal(ta);
+	spinlock_unlock(&tasks_lock);
 	interrupts_restore(ipl);
-	
 	return 0;
 }
