Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/ipc/ipc.c	(revision 58d5803d422309587aa1e5c37ec90f119d64af5d)
@@ -62,4 +62,5 @@
 
 static slab_cache_t *ipc_call_slab;
+static slab_cache_t *ipc_answerbox_slab;
 
 /** Initialize a call structure.
@@ -96,15 +97,4 @@
 }
 
-/** Initialize a statically allocated call structure.
- *
- * @param call		Statically allocated kernel call structure to be
- *			initialized.
- */
-void ipc_call_static_init(call_t *call)
-{
-	_ipc_call_init(call);
-	call->flags |= IPC_CALL_STATIC_ALLOC;
-}
-
 /** Deallocate a call structure.
  *
@@ -113,5 +103,4 @@
 void ipc_call_free(call_t *call)
 {
-	ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
 	/* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
 	if (call->buffer)
@@ -130,4 +119,5 @@
 	spinlock_initialize(&box->irq_lock, "ipc_box_irqlock");
 	waitq_initialize(&box->wq);
+	link_initialize(&box->sync_box_link);
 	list_initialize(&box->connected_phones);
 	list_initialize(&box->calls);
@@ -179,15 +169,41 @@
 int ipc_call_sync(phone_t *phone, call_t *request)
 {
-	answerbox_t sync_box; 
-
-	ipc_answerbox_init(&sync_box, TASK);
+	answerbox_t *sync_box; 
+	ipl_t ipl;
+
+	sync_box = slab_alloc(ipc_answerbox_slab, 0);
+	ipc_answerbox_init(sync_box, TASK);
+
+	/*
+	 * Put the answerbox on the TASK's list of synchronous answerboxes so
+	 * that it can be cleaned up if the call is interrupted.
+	 */
+	ipl = interrupts_disable();
+	spinlock_lock(&TASK->lock);
+	list_append(&sync_box->sync_box_link, &TASK->sync_box_head);
+	spinlock_unlock(&TASK->lock);
+	interrupts_restore(ipl);
 
 	/* We will receive data in a special box. */
-	request->callerbox = &sync_box;
+	request->callerbox = sync_box;
 
 	ipc_call(phone, request);
-	if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT,
-	    SYNCH_FLAGS_INTERRUPTIBLE))
+	if (!ipc_wait_for_call(sync_box, SYNCH_NO_TIMEOUT,
+	    SYNCH_FLAGS_INTERRUPTIBLE)) {
+	    	/* The answerbox and the call will be freed by ipc_cleanup(). */
 		return EINTR;
+	}
+
+	/*
+	 * The answer arrived without interruption so we can remove the
+	 * answerbox from the TASK's list of synchronous answerboxes.
+	 */
+	(void) interrupts_disable();
+	spinlock_lock(&TASK->lock);
+	list_remove(&sync_box->sync_box_link);
+	spinlock_unlock(&TASK->lock);
+	interrupts_restore(ipl);
+
+	slab_free(ipc_answerbox_slab, sync_box);
 	return EOK;
 }
@@ -520,4 +536,5 @@
 	int i;
 	call_t *call;
+	ipl_t ipl;
 
 	/* Disconnect all our phones ('ipc_phone_hangup') */
@@ -545,5 +562,19 @@
 	spinlock_unlock(&TASK->answerbox.lock);
 	
-	/* Wait for all async answers to arrive */
+	/* Wait for all answers to interrupted synchronous calls to arrive */
+	ipl = interrupts_disable();
+	while (!list_empty(&TASK->sync_box_head)) {
+		answerbox_t *box = list_get_instance(TASK->sync_box_head.next,
+		    answerbox_t, sync_box_link);
+
+		list_remove(&box->sync_box_link);
+		call = ipc_wait_for_call(box, SYNCH_NO_TIMEOUT,
+		    SYNCH_FLAGS_NONE);
+		ipc_call_free(call);
+		slab_free(ipc_answerbox_slab, box);
+	}
+	interrupts_restore(ipl);
+
+	/* Wait for all answers to asynchronous calls to arrive */
 	while (1) {
 		/* Go through all phones, until all are FREE... */
@@ -552,6 +583,8 @@
 		for (i = 0; i < IPC_MAX_PHONES; i++) {
 			if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
-			    atomic_get(&TASK->phones[i].active_calls) == 0)
+			    atomic_get(&TASK->phones[i].active_calls) == 0) {
 				TASK->phones[i].state = IPC_PHONE_FREE;
+				TASK->phones[i].callee = NULL;
+			}
 			
 			/* Just for sure, we might have had some 
@@ -574,5 +607,4 @@
 		ASSERT((call->flags & IPC_CALL_ANSWERED) ||
 		    (call->flags & IPC_CALL_NOTIF));
-		ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC));
 		
 		/*
@@ -593,4 +625,6 @@
 	ipc_call_slab = slab_cache_create("ipc_call", sizeof(call_t), 0, NULL,
 	    NULL, 0);
+	ipc_answerbox_slab = slab_cache_create("ipc_answerbox",
+	    sizeof(answerbox_t), 0, NULL, NULL, 0);
 }
 
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/ipc/irq.c	(revision 58d5803d422309587aa1e5c37ec90f119d64af5d)
@@ -418,5 +418,4 @@
 		case CMD_ACCEPT:
 			return IRQ_ACCEPT;
-			break;
 		case CMD_DECLINE:
 		default:
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/ipc/sysipc.c	(revision 58d5803d422309587aa1e5c37ec90f119d64af5d)
@@ -61,5 +61,5 @@
 { \
 	if (phoneid > IPC_MAX_PHONES) { \
-		err; \
+		err \
 	} \
 	phone = &TASK->phones[phoneid]; \
@@ -122,5 +122,4 @@
 	case IPC_M_DATA_READ:
 		return 1;
-		break;
 	default:
 		return 0;
@@ -376,5 +375,5 @@
 		phone_t *cloned_phone;
 		GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data),
-		    return ENOENT);
+		    return ENOENT;);
 		phones_lock(cloned_phone, phone);
 		if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
@@ -531,39 +530,42 @@
     unative_t arg1, unative_t arg2, unative_t arg3, ipc_data_t *data)
 {
-	call_t call;
+	call_t *call;
 	phone_t *phone;
 	int res;
 	int rc;
 	
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT);
-
-	ipc_call_static_init(&call);
-	IPC_SET_METHOD(call.data, method);
-	IPC_SET_ARG1(call.data, arg1);
-	IPC_SET_ARG2(call.data, arg2);
-	IPC_SET_ARG3(call.data, arg3);
+	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+
+	call = ipc_call_alloc(0);
+	IPC_SET_METHOD(call->data, method);
+	IPC_SET_ARG1(call->data, arg1);
+	IPC_SET_ARG2(call->data, arg2);
+	IPC_SET_ARG3(call->data, arg3);
 	/*
 	 * To achieve deterministic behavior, zero out arguments that are beyond
 	 * the limits of the fast version.
 	 */
-	IPC_SET_ARG4(call.data, 0);
-	IPC_SET_ARG5(call.data, 0);
-
-	if (!(res = request_preprocess(&call, phone))) {
+	IPC_SET_ARG4(call->data, 0);
+	IPC_SET_ARG5(call->data, 0);
+
+	if (!(res = request_preprocess(call, phone))) {
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_begin();
 #endif
-		rc = ipc_call_sync(phone, &call);
+		rc = ipc_call_sync(phone, call);
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_end();
 #endif
-		if (rc != EOK)
+		if (rc != EOK) {
+			/* The call will be freed by ipc_cleanup(). */
 			return rc;
-		process_answer(&call);
+		}
+		process_answer(call);
 
 	} else {
-		IPC_SET_RETVAL(call.data, res);
-	}
-	rc = STRUCT_TO_USPACE(&data->args, &call.data.args);
+		IPC_SET_RETVAL(call->data, res);
+	}
+	rc = STRUCT_TO_USPACE(&data->args, &call->data.args);
+	ipc_call_free(call);
 	if (rc != 0)
 		return rc;
@@ -584,32 +586,38 @@
     ipc_data_t *reply)
 {
-	call_t call;
+	call_t *call;
 	phone_t *phone;
 	int res;
 	int rc;
 
-	ipc_call_static_init(&call);
-	rc = copy_from_uspace(&call.data.args, &question->args,
-	    sizeof(call.data.args));
-	if (rc != 0)
+	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
+
+	call = ipc_call_alloc(0);
+	rc = copy_from_uspace(&call->data.args, &question->args,
+	    sizeof(call->data.args));
+	if (rc != 0) {
+		ipc_call_free(call);
 		return (unative_t) rc;
-
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT);
-
-	if (!(res = request_preprocess(&call, phone))) {
+	}
+
+
+	if (!(res = request_preprocess(call, phone))) {
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_begin();
 #endif
-		rc = ipc_call_sync(phone, &call);
+		rc = ipc_call_sync(phone, call);
 #ifdef CONFIG_UDEBUG
 		udebug_stoppable_end();
 #endif
-		if (rc != EOK)
+		if (rc != EOK) {
+			/* The call will be freed by ipc_cleanup(). */
 			return rc;
-		process_answer(&call);
+		}
+		process_answer(call);
 	} else 
-		IPC_SET_RETVAL(call.data, res);
-
-	rc = STRUCT_TO_USPACE(&reply->args, &call.data.args);
+		IPC_SET_RETVAL(call->data, res);
+
+	rc = STRUCT_TO_USPACE(&reply->args, &call->data.args);
+	ipc_call_free(call);
 	if (rc != 0)
 		return rc;
@@ -658,5 +666,5 @@
 		return IPC_CALLRET_TEMPORARY;
 
-	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
+	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;);
 
 	call = ipc_call_alloc(0);
@@ -697,5 +705,5 @@
 		return IPC_CALLRET_TEMPORARY;
 
-	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL);
+	GET_CHECK_PHONE(phone, phoneid, return IPC_CALLRET_FATAL;);
 
 	call = ipc_call_alloc(0);
@@ -747,5 +755,5 @@
 	call->flags |= IPC_CALL_FORWARDED;
 
-	GET_CHECK_PHONE(phone, phoneid, { 
+	GET_CHECK_PHONE(phone, phoneid, {
 		IPC_SET_RETVAL(call->data, EFORWARD);
 		ipc_answer(&TASK->answerbox, call);
@@ -952,5 +960,5 @@
 	phone_t *phone;
 
-	GET_CHECK_PHONE(phone, phoneid, return ENOENT);
+	GET_CHECK_PHONE(phone, phoneid, return ENOENT;);
 
 	if (ipc_phone_hangup(phone))
@@ -991,6 +999,4 @@
 
 	if (call->flags & IPC_CALL_NOTIF) {
-		ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
-
 		/* Set in_phone_hash to the interrupt counter */
 		call->data.phone = (void *) call->priv;
@@ -1005,6 +1011,4 @@
 	if (call->flags & IPC_CALL_ANSWERED) {
 		process_answer(call);
-
-		ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
 
 		if (call->flags & IPC_CALL_DISCARD_ANSWER) {
Index: kernel/generic/src/lib/elf.c
===================================================================
--- kernel/generic/src/lib/elf.c	(revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/lib/elf.c	(revision 58d5803d422309587aa1e5c37ec90f119d64af5d)
@@ -163,5 +163,4 @@
 	case PT_LOAD:
 		return load_segment(entry, elf, as);
-		break;
 	case PT_DYNAMIC:
 	case PT_INTERP:
@@ -182,5 +181,4 @@
 	default:
 		return EE_UNSUPPORTED;
-		break;
 	}
 	return EE_OK;
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 3da11f37e6b8b0d64576fbe67ae8bf361a41793d)
+++ kernel/generic/src/proc/task.c	(revision 58d5803d422309587aa1e5c37ec90f119d64af5d)
@@ -75,6 +75,9 @@
 static task_id_t task_counter = 0;
 
+static slab_cache_t *task_slab;
+
 /* Forward declarations. */
 static void task_kill_internal(task_t *);
+static int tsk_constructor(void *, int);
 
 /** Initialize kernel tasks support. */
@@ -83,4 +86,6 @@
 	TASK = NULL;
 	avltree_create(&tasks_tree);
+	task_slab = slab_cache_create("task_slab", sizeof(task_t), 0,
+	    tsk_constructor, NULL, 0);
 }
 
@@ -128,4 +133,33 @@
 }
 
+int tsk_constructor(void *obj, int kmflags)
+{
+	task_t *ta = obj;
+	int i;
+
+	atomic_set(&ta->refcount, 0);
+	atomic_set(&ta->lifecount, 0);
+	atomic_set(&ta->active_calls, 0);
+
+	spinlock_initialize(&ta->lock, "task_ta_lock");
+	mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
+
+	list_initialize(&ta->th_head);
+	list_initialize(&ta->sync_box_head);
+
+	ipc_answerbox_init(&ta->answerbox, ta);
+	for (i = 0; i < IPC_MAX_PHONES; i++)
+		ipc_phone_init(&ta->phones[i]);
+
+#ifdef CONFIG_UDEBUG
+	/* Init kbox stuff */
+	ta->kb.thread = NULL;
+	ipc_answerbox_init(&ta->kb.box, ta);
+	mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
+#endif
+
+	return 0;
+}
+
 /** Create new task with no threads.
  *
@@ -140,21 +174,12 @@
 	ipl_t ipl;
 	task_t *ta;
-	int i;
-	
-	ta = (task_t *) malloc(sizeof(task_t), 0);
-
+	
+	ta = (task_t *) slab_alloc(task_slab, 0);
 	task_create_arch(ta);
-
-	spinlock_initialize(&ta->lock, "task_ta_lock");
-	list_initialize(&ta->th_head);
 	ta->as = as;
-
 	memcpy(ta->name, name, TASK_NAME_BUFLEN);
 	ta->name[TASK_NAME_BUFLEN - 1] = 0;
 
-	atomic_set(&ta->refcount, 0);
-	atomic_set(&ta->lifecount, 0);
 	ta->context = CONTEXT;
-
 	ta->capabilities = 0;
 	ta->cycles = 0;
@@ -165,28 +190,15 @@
 
 	/* Init kbox stuff */
-	ipc_answerbox_init(&ta->kb.box, ta);
-	ta->kb.thread = NULL;
-	mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
 	ta->kb.finished = false;
 #endif
 
-	ipc_answerbox_init(&ta->answerbox, ta);
-	for (i = 0; i < IPC_MAX_PHONES; i++)
-		ipc_phone_init(&ta->phones[i]);
-	if ((ipc_phone_0) && (context_check(ipc_phone_0->task->context,
-	    ta->context)))
+	if ((ipc_phone_0) &&
+	    (context_check(ipc_phone_0->task->context, ta->context)))
 		ipc_phone_connect(&ta->phones[0], ipc_phone_0);
-	atomic_set(&ta->active_calls, 0);
-
-	mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
+
 	btree_create(&ta->futexes);
 	
 	ipl = interrupts_disable();
-
-	/*
-	 * Increment address space reference count.
-	 */
 	atomic_inc(&as->refcount);
-
 	spinlock_lock(&tasks_lock);
 	ta->taskid = ++task_counter;
@@ -229,5 +241,5 @@
 		as_destroy(t->as);
 	
-	free(t);
+	slab_free(task_slab, t);
 	TASK = NULL;
 }
