Index: generic/include/proc/task.h
===================================================================
--- generic/include/proc/task.h	(revision 2cb5e6478ff8e1d5cf947da6398d6e2d496c27e4)
+++ generic/include/proc/task.h	(revision 7509ddc323e8b88a1dfd5b12a23bda20b9ea901e)
@@ -41,9 +41,19 @@
 /** Task structure. */
 struct task {
+	/** Task lock.
+	 *
+	 * Must be acquired before threads_lock and thread lock of any of its threads.
+	 */
 	SPINLOCK_DECLARE(lock);
+	
 	char *name;
 	link_t th_head;		/**< List of threads contained in this task. */
 	as_t *as;		/**< Address space. */
 	task_id_t taskid;	/**< Unique identity of task */
+
+	/** If this is true, new threads can become part of the task. */
+	bool accept_new_threads;
+
+	count_t refcount;	/**< Number of references (i.e. threads). */
 
 	cap_t capabilities;	/**< Task capabilities. */
@@ -71,6 +81,9 @@
 extern void task_init(void);
 extern task_t *task_create(as_t *as, char *name);
+extern void task_destroy(task_t *t);
 extern task_t *task_run_program(void *program_addr, char *name);
 extern task_t *task_find_by_id(task_id_t id);
+extern int task_kill(task_id_t id);
+
 
 #ifndef task_create_arch
Index: generic/include/proc/thread.h
===================================================================
--- generic/include/proc/thread.h	(revision 2cb5e6478ff8e1d5cf947da6398d6e2d496c27e4)
+++ generic/include/proc/thread.h	(revision 7509ddc323e8b88a1dfd5b12a23bda20b9ea901e)
@@ -73,6 +73,4 @@
 	 *
 	 * Protects the whole thread structure except list links above.
-	 * Must be acquired before T.lock for each T of type task_t.
-	 * 
 	 */
 	SPINLOCK_DECLARE(lock);
@@ -99,5 +97,11 @@
 	/** True if this thread is executing copy_to_uspace(). False otherwise. */
 	bool in_copy_to_uspace;
-
+	
+	/**
+	 * If true, the thread will not go to sleep at all and will
+	 * call thread_exit() before returning to userspace.
+	 */
+	bool interrupted;			
+	
 	bool detached;				/**< If true, thread_join_timeout() cannot be used on this thread. */
 	waitq_t join_wq;			/**< Waitq for thread_join_timeout(). */
Index: generic/src/proc/task.c
===================================================================
--- generic/src/proc/task.c	(revision 2cb5e6478ff8e1d5cf947da6398d6e2d496c27e4)
+++ generic/src/proc/task.c	(revision 7509ddc323e8b88a1dfd5b12a23bda20b9ea901e)
@@ -48,4 +48,5 @@
 #include <print.h>
 #include <elf.h>
+#include <errno.h>
 #include <syscall/copy.h>
 
@@ -57,4 +58,6 @@
 btree_t tasks_btree;
 static task_id_t task_counter = 0;
+
+static void ktask_cleanup(void *);
 
 /** Initialize tasks
@@ -95,5 +98,8 @@
 	ta->name = name;
 
+	ta->refcount = 0;
+
 	ta->capabilities = 0;
+	ta->accept_new_threads = true;
 	
 	ipc_answerbox_init(&ta->answerbox);
@@ -128,4 +134,12 @@
 }
 
+/** Destroy task.
+ *
+ * @param t Task to be destroyed.
+ */
+void task_destroy(task_t *t)
+{
+}
+
 /** Create new task with 1 thread and run it
  *
@@ -206,4 +220,58 @@
 	
 	return (task_t *) btree_search(&tasks_btree, (btree_key_t) id, &leaf);
+}
+
+/** Kill task.
+ *
+ * @param id ID of the task to be killed.
+ *
+ * @return 0 on success or an error code from errno.h
+ */
+int task_kill(task_id_t id)
+{
+	ipl_t ipl;
+	task_t *ta;
+	thread_t *t;
+	link_t *cur;
+	
+	ipl = interrupts_disable();
+	spinlock_lock(&tasks_lock);
+
+	if (!(ta = task_find_by_id(id))) {
+		spinlock_unlock(&tasks_lock);
+		interrupts_restore(ipl);
+		return ENOENT;
+	}
+	
+	spinlock_lock(&ta->lock);
+	ta->refcount++;
+	spinlock_unlock(&ta->lock);
+	
+	t = thread_create(ktask_cleanup, NULL, ta, 0, "ktask_cleanup");
+	
+	spinlock_lock(&ta->lock);
+	ta->refcount--;
+	
+	for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
+		thread_t *thr;
+		bool  sleeping = false;
+		
+		thr = list_get_instance(cur, thread_t, th_link);
+		if (thr == t)
+			continue;
+			
+		spinlock_lock(&thr->lock);
+		thr->interrupted = true;
+		if (thr->state == Sleeping)
+			sleeping = true;
+		spinlock_unlock(&thr->lock);
+		
+		if (sleeping)
+			waitq_interrupt_sleep(thr);
+	}
+	
+	thread_ready(t);
+	
+	return 0;
 }
 
@@ -244,2 +312,14 @@
 	interrupts_restore(ipl);
 }
+
+/** Kernel thread used to cleanup the task. */
+void ktask_cleanup(void *arg)
+{
+	/*
+	 * TODO:
+	 * Wait until it is save to cleanup the task (i.e. all other threads exit)
+	 * and do the cleanup (e.g. close IPC communication and release used futexes).
+	 * When this thread exits, the task refcount drops to zero and the task structure is
+	 * cleaned.
+	 */
+}
Index: generic/src/proc/thread.c
===================================================================
--- generic/src/proc/thread.c	(revision 2cb5e6478ff8e1d5cf947da6398d6e2d496c27e4)
+++ generic/src/proc/thread.c	(revision 7509ddc323e8b88a1dfd5b12a23bda20b9ea901e)
@@ -234,4 +234,6 @@
 void thread_destroy(thread_t *t)
 {
+	bool destroy_task = false;	
+
 	ASSERT(t->state == Exiting);
 	ASSERT(t->task);
@@ -242,4 +244,10 @@
 		t->cpu->fpu_owner=NULL;
 	spinlock_unlock(&t->cpu->lock);
+
+	spinlock_unlock(&t->lock);
+
+	spinlock_lock(&threads_lock);
+	btree_remove(&threads_btree, (btree_key_t) ((__address ) t), NULL);
+	spinlock_unlock(&threads_lock);
 
 	/*
@@ -248,11 +256,12 @@
 	spinlock_lock(&t->task->lock);
 	list_remove(&t->th_link);
-	spinlock_unlock(&t->task->lock);
-	
-	spinlock_unlock(&t->lock);
-	
-	spinlock_lock(&threads_lock);
-	btree_remove(&threads_btree, (btree_key_t) ((__address ) t), NULL);
-	spinlock_unlock(&threads_lock);
+	if (--t->task->refcount == 0) {
+		t->task->accept_new_threads = false;
+		destroy_task = true;
+	}
+	spinlock_unlock(&t->task->lock);	
+	
+	if (destroy_task)
+		task_destroy(t->task);
 	
 	slab_free(thread_slab, t);
@@ -320,5 +329,6 @@
 	t->in_copy_from_uspace = false;
 	t->in_copy_to_uspace = false;
-	
+
+	t->interrupted = false;	
 	t->detached = false;
 	waitq_initialize(&t->join_wq);
@@ -330,12 +340,4 @@
 	t->fpu_context_exists = 0;
 	t->fpu_context_engaged = 0;
-	
-	/*
-	 * Register this thread in the system-wide list.
-	 */
-	ipl = interrupts_disable();
-	spinlock_lock(&threads_lock);
-	btree_insert(&threads_btree, (btree_key_t) ((__address) t), (void *) t, NULL);
-	spinlock_unlock(&threads_lock);
 	
 	/*
@@ -343,6 +345,20 @@
 	 */
 	spinlock_lock(&task->lock);
+	if (!task->accept_new_threads) {
+		spinlock_unlock(&task->lock);
+		slab_free(thread_slab, t);
+		return NULL;
+	}
 	list_append(&t->th_link, &task->th_head);
+	task->refcount++;
 	spinlock_unlock(&task->lock);
+
+	/*
+	 * Register this thread in the system-wide list.
+	 */
+	ipl = interrupts_disable();
+	spinlock_lock(&threads_lock);
+	btree_insert(&threads_btree, (btree_key_t) ((__address) t), (void *) t, NULL);
+	spinlock_unlock(&threads_lock);
 	
 	interrupts_restore(ipl);
Index: generic/src/synch/waitq.c
===================================================================
--- generic/src/synch/waitq.c	(revision 2cb5e6478ff8e1d5cf947da6398d6e2d496c27e4)
+++ generic/src/synch/waitq.c	(revision 7509ddc323e8b88a1dfd5b12a23bda20b9ea901e)
@@ -312,4 +312,10 @@
 	spinlock_lock(&THREAD->lock);
 
+	if (THREAD->interrupted) {
+		spinlock_unlock(&THREAD->lock);
+		spinlock_unlock(&wq->lock);
+		return ESYNCH_INTERRUPTED;
+	}
+
 	if (flags & SYNCH_FLAGS_INTERRUPTIBLE) {
 		/*
Index: generic/src/syscall/syscall.c
===================================================================
--- generic/src/syscall/syscall.c	(revision 2cb5e6478ff8e1d5cf947da6398d6e2d496c27e4)
+++ generic/src/syscall/syscall.c	(revision 7509ddc323e8b88a1dfd5b12a23bda20b9ea901e)
@@ -91,8 +91,24 @@
 			 __native a4, __native id)
 {
+	__native rc;
+	ipl_t ipl;
+	bool exit = false;
+
 	if (id < SYSCALL_END)
-		return syscall_table[id](a1,a2,a3,a4);
+		rc = syscall_table[id](a1,a2,a3,a4);
 	else
 		panic("Undefined syscall %d", id);
+		
+	ipl = interrupts_disable();
+	spinlock_lock(&THREAD->lock);
+	if (THREAD->interrupted)
+		exit = true;
+	spinlock_unlock(&THREAD->lock);
+	interrupts_restore(ipl);
+	
+	if (exit)
+		thread_exit();
+	
+	return rc;
 }
 
