Index: uspace/lib/c/generic/async/ports.c
===================================================================
--- uspace/lib/c/generic/async/ports.c	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/lib/c/generic/async/ports.c	(revision d3b2ffaddcda1e7c3db7a9f643033e62c4c947a0)
@@ -35,5 +35,4 @@
 #include <ipc/irq.h>
 #include <ipc/event.h>
-#include <futex.h>
 #include <fibril.h>
 #include <adt/hash_table.h>
Index: uspace/lib/c/generic/async/server.c
===================================================================
--- uspace/lib/c/generic/async/server.c	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/lib/c/generic/async/server.c	(revision d3b2ffaddcda1e7c3db7a9f643033e62c4c947a0)
@@ -122,4 +122,6 @@
 #include "../private/fibril.h"
 
+#define DPRINTF(...)  ((void) 0)
+
 /** Async framework global futex */
 futex_t async_futex = FUTEX_INITIALIZER;
@@ -132,5 +134,4 @@
 	link_t link;
 
-	cap_call_handle_t chandle;
 	ipc_call_t call;
 } msg_t;
@@ -164,7 +165,4 @@
 	list_t msg_queue;
 
-	/** Identification of the opening call. */
-	cap_call_handle_t chandle;
-
 	/** Call data of the opening call. */
 	ipc_call_t call;
@@ -179,4 +177,10 @@
 	void *data;
 } connection_t;
+
+/* Member of notification_t::msg_list. */
+typedef struct {
+	link_t link;
+	ipc_call_t calldata;
+} notification_msg_t;
 
 /* Notification data */
@@ -197,17 +201,6 @@
 	void *arg;
 
-	/** Data of the most recent notification. */
-	ipc_call_t calldata;
-
-	/**
-	 * How many notifications with this `imethod` arrived since it was last
-	 * handled. If `count` > 1, `calldata` only holds the data for the most
-	 * recent such notification, all the older data being lost.
-	 *
-	 * `async_spawn_notification_handler()` can be used to increase the
-	 * number of notifications that can be processed simultaneously,
-	 * reducing the likelihood of losing them when the handler blocks.
-	 */
-	long count;
+	/** List of arrived notifications. */
+	list_t msg_list;
 } notification_t;
 
@@ -249,4 +242,8 @@
 static LIST_INITIALIZE(notification_queue);
 static FIBRIL_SEMAPHORE_INITIALIZE(notification_semaphore, 0);
+
+static LIST_INITIALIZE(notification_freelist);
+static long notification_freelist_total = 0;
+static long notification_freelist_used = 0;
 
 static sysarg_t notification_avail = 0;
@@ -412,5 +409,5 @@
 	client_t *client = async_client_get(fibril_connection->in_task_id, true);
 	if (!client) {
-		ipc_answer_0(fibril_connection->chandle, ENOMEM);
+		ipc_answer_0(fibril_connection->call.cap_handle, ENOMEM);
 		return 0;
 	}
@@ -421,5 +418,5 @@
 	 * Call the connection handler function.
 	 */
-	fibril_connection->handler(fibril_connection->chandle,
+	fibril_connection->handler(fibril_connection->call.cap_handle,
 	    &fibril_connection->call, fibril_connection->data);
 
@@ -448,5 +445,5 @@
 
 		list_remove(&msg->link);
-		ipc_answer_0(msg->chandle, EHANGUP);
+		ipc_answer_0(msg->call.cap_handle, EHANGUP);
 		free(msg);
 	}
@@ -471,9 +468,8 @@
  * @param in_task_id     Identification of the incoming connection.
  * @param in_phone_hash  Identification of the incoming connection.
- * @param chandle        Handle of the opening IPC_M_CONNECT_ME_TO call.
- *                       If chandle is CAP_NIL, the connection was opened by
- *                       accepting the IPC_M_CONNECT_TO_ME call and this
- *                       function is called directly by the server.
- * @param call           Call data of the opening call.
+ * @param call           Call data of the opening call. If call is NULL,
+ *                       the connection was opened by accepting the
+ *                       IPC_M_CONNECT_TO_ME call and this function is
+ *                       called directly by the server.
  * @param handler        Connection handler.
  * @param data           Client argument to pass to the connection handler.
@@ -483,11 +479,10 @@
  */
 static fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash,
-    cap_call_handle_t chandle, ipc_call_t *call, async_port_handler_t handler,
-    void *data)
+    ipc_call_t *call, async_port_handler_t handler, void *data)
 {
 	connection_t *conn = malloc(sizeof(*conn));
 	if (!conn) {
-		if (chandle != CAP_NIL)
-			ipc_answer_0(chandle, ENOMEM);
+		if (call)
+			ipc_answer_0(call->cap_handle, ENOMEM);
 
 		return (uintptr_t) NULL;
@@ -497,5 +492,4 @@
 	conn->in_phone_hash = in_phone_hash;
 	list_initialize(&conn->msg_queue);
-	conn->chandle = chandle;
 	conn->close_chandle = CAP_NIL;
 	conn->handler = handler;
@@ -504,4 +498,6 @@
 	if (call)
 		conn->call = *call;
+	else
+		conn->call.cap_handle = CAP_NIL;
 
 	/* We will activate the fibril ASAP */
@@ -512,6 +508,6 @@
 		free(conn);
 
-		if (chandle != CAP_NIL)
-			ipc_answer_0(chandle, ENOMEM);
+		if (call)
+			ipc_answer_0(call->cap_handle, ENOMEM);
 
 		return (uintptr_t) NULL;
@@ -568,5 +564,5 @@
 	sysarg_t phone_hash = IPC_GET_ARG5(answer);
 	fid_t fid = async_new_connection(answer.in_task_id, phone_hash,
-	    CAP_NIL, NULL, handler, data);
+	    NULL, handler, data);
 	if (fid == (uintptr_t) NULL)
 		return ENOMEM;
@@ -637,6 +633,5 @@
  * timeouts are unregistered.
  *
- * @param chandle  Handle of the incoming call.
- * @param call     Data of the incoming call.
+ * @param call Data of the incoming call.
  *
  * @return False if the call doesn't match any connection.
@@ -644,5 +639,5 @@
  *
  */
-static bool route_call(cap_call_handle_t chandle, ipc_call_t *call)
+static bool route_call(ipc_call_t *call)
 {
 	assert(call);
@@ -667,10 +662,9 @@
 	}
 
-	msg->chandle = chandle;
 	msg->call = *call;
 	list_append(&msg->link, &conn->msg_queue);
 
 	if (IPC_GET_IMETHOD(*call) == IPC_M_PHONE_HUNGUP)
-		conn->close_chandle = chandle;
+		conn->close_chandle = call->cap_handle;
 
 	/* If the connection fibril is waiting for an event, activate it */
@@ -709,20 +703,34 @@
 		notification_t *notification = list_get_instance(
 		    list_first(&notification_queue), notification_t, qlink);
-		list_remove(&notification->qlink);
 
 		async_notification_handler_t handler = notification->handler;
 		void *arg = notification->arg;
-		ipc_call_t calldata = notification->calldata;
-		long count = notification->count;
-
-		notification->count = 0;
+
+		notification_msg_t *m = list_pop(&notification->msg_list,
+		    notification_msg_t, link);
+		assert(m);
+		ipc_call_t calldata = m->calldata;
+
+		notification_freelist_used--;
+
+		if (notification_freelist_total > 64 &&
+		    notification_freelist_total > 2 * notification_freelist_used) {
+			/* Going to free the structure if we have too much. */
+			notification_freelist_total--;
+		} else {
+			/* Otherwise add to freelist. */
+			list_append(&m->link, &notification_freelist);
+			m = NULL;
+		}
+
+		if (list_empty(&notification->msg_list))
+			list_remove(&notification->qlink);
 
 		futex_unlock(&notification_futex);
-
-		// FIXME: Pass count to the handler. It might be important.
-		(void) count;
 
 		if (handler)
 			handler(&calldata, arg);
+
+		free(m);
 	}
 
@@ -760,4 +768,19 @@
 	futex_lock(&notification_futex);
 
+	notification_msg_t *m = list_pop(&notification_freelist,
+	    notification_msg_t, link);
+
+	if (!m) {
+		futex_unlock(&notification_futex);
+		m = malloc(sizeof(notification_msg_t));
+		if (!m) {
+			DPRINTF("Out of memory.\n");
+			abort();
+		}
+
+		futex_lock(&notification_futex);
+		notification_freelist_total++;
+	}
+
 	ht_link_t *link = hash_table_find(&notification_hash_table,
 	    &IPC_GET_IMETHOD(*call));
@@ -765,5 +788,7 @@
 		/* Invalid notification. */
 		// TODO: Make sure this can't happen and turn it into assert.
+		notification_freelist_total--;
 		futex_unlock(&notification_futex);
+		free(m);
 		return;
 	}
@@ -772,14 +797,11 @@
 	    hash_table_get_inst(link, notification_t, htlink);
 
-	notification->count++;
-	notification->calldata = *call;
-
-	if (link_in_use(&notification->qlink)) {
-		/* Notification already queued. */
-		futex_unlock(&notification_futex);
-		return;
-	}
-
-	list_append(&notification->qlink, &notification_queue);
+	notification_freelist_used++;
+	m->calldata = *call;
+	list_append(&m->link, &notification->msg_list);
+
+	if (!link_in_use(&notification->qlink))
+		list_append(&notification->qlink, &notification_queue);
+
 	futex_unlock(&notification_futex);
 
@@ -802,4 +824,6 @@
 	notification->handler = handler;
 	notification->arg = arg;
+
+	list_initialize(&notification->msg_list);
 
 	fid_t fib = 0;
@@ -1011,5 +1035,5 @@
 	list_remove(&msg->link);
 
-	cap_call_handle_t chandle = msg->chandle;
+	cap_call_handle_t chandle = msg->call.cap_handle;
 	*call = msg->call;
 	free(msg);
@@ -1058,9 +1082,8 @@
  * Otherwise the call is routed to its connection fibril.
  *
- * @param chandle  Handle of the incoming call.
- * @param call     Data of the incoming call.
- *
- */
-static void handle_call(cap_call_handle_t chandle, ipc_call_t *call)
+ * @param call Data of the incoming call.
+ *
+ */
+static void handle_call(ipc_call_t *call)
 {
 	assert(call);
@@ -1069,5 +1092,5 @@
 		return;
 
-	if (chandle == CAP_NIL) {
+	if (call->cap_handle == CAP_NIL) {
 		if (call->flags & IPC_CALL_NOTIF) {
 			/* Kernel notification */
@@ -1087,15 +1110,15 @@
 		    async_get_port_handler(iface, 0, &data);
 
-		async_new_connection(call->in_task_id, in_phone_hash, chandle,
-		    call, handler, data);
+		async_new_connection(call->in_task_id, in_phone_hash, call,
+		    handler, data);
 		return;
 	}
 
 	/* Try to route the call through the connection hash table */
-	if (route_call(chandle, call))
+	if (route_call(call))
 		return;
 
 	/* Unknown call from unknown phone - hang it up */
-	ipc_answer_0(chandle, EHANGUP);
+	ipc_answer_0(call->cap_handle, EHANGUP);
 }
 
@@ -1178,5 +1201,5 @@
 
 		assert(rc == EOK);
-		handle_call(call.cap_handle, &call);
+		handle_call(&call);
 	}
 
@@ -1847,5 +1870,5 @@
 }
 
-_Noreturn void async_manager(void)
+__noreturn void async_manager(void)
 {
 	futex_lock(&async_futex);
Index: uspace/lib/c/generic/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/fibril_synch.c	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/lib/c/generic/fibril_synch.c	(revision d3b2ffaddcda1e7c3db7a9f643033e62c4c947a0)
@@ -44,6 +44,10 @@
 #include <stdlib.h>
 #include <stdio.h>
+#include <io/kio.h>
+
 #include "private/async.h"
 #include "private/fibril.h"
+
+static fibril_local bool deadlocked = false;
 
 static void optimize_execution_power(void)
@@ -62,4 +66,10 @@
 {
 	fibril_t *f = (fibril_t *) fibril_get_id();
+
+	if (deadlocked) {
+		kio_printf("Deadlock detected while printing deadlock. Aborting.\n");
+		abort();
+	}
+	deadlocked = true;
 
 	printf("Deadlock detected.\n");
Index: uspace/lib/c/generic/ubsan.c
===================================================================
--- uspace/lib/c/generic/ubsan.c	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/lib/c/generic/ubsan.c	(revision d3b2ffaddcda1e7c3db7a9f643033e62c4c947a0)
@@ -98,4 +98,5 @@
 #endif
 void __ubsan_handle_nonnull_return(struct nonnull_return_data *data);
+void __ubsan_handle_builtin_unreachable(struct unreachable_data *data);
 
 static void print_loc(const char *func, struct source_location *loc)
@@ -107,5 +108,5 @@
 		f += sizeof(func_prefix);
 
-	PRINTF("Undefined behavior %s at %s:%" PRIu32 " col %" PRIu32 "\n",
+	PRINTF("####### Undefined behavior %s at %s:%" PRIu32 " col %" PRIu32 "\n",
 	    f, loc->file_name, loc->line, loc->column);
 }
@@ -115,4 +116,6 @@
 {
 	print_loc(__func__, &data->loc);
+	PRINTF("Type: %s, alignment: %lu, type_check_kind: %hhu\n",
+	    data->type->type_name, data->alignment, data->type_check_kind);
 	ubsan_panic();
 }
@@ -219,2 +222,9 @@
 	ubsan_panic();
 }
+
+void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
+{
+	print_loc(__func__, &data->loc);
+	ubsan_panic();
+}
+
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/lib/c/include/async.h	(revision d3b2ffaddcda1e7c3db7a9f643033e62c4c947a0)
@@ -51,4 +51,6 @@
 #include <abi/cap.h>
 
+#include <_bits/__noreturn.h>
+
 typedef sysarg_t aid_t;
 typedef sysarg_t port_id_t;
@@ -108,5 +110,5 @@
 typedef struct async_exch async_exch_t;
 
-extern _Noreturn void async_manager(void);
+extern __noreturn void async_manager(void);
 
 #define async_get_call(data) \
Index: uspace/lib/c/include/futex.h
===================================================================
--- uspace/lib/c/include/futex.h	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/lib/c/include/futex.h	(revision d3b2ffaddcda1e7c3db7a9f643033e62c4c947a0)
@@ -45,5 +45,5 @@
 	atomic_t val;
 #ifdef CONFIG_DEBUG_FUTEX
-	_Atomic void *owner;
+	void *owner;
 #endif
 } futex_t;
Index: uspace/lib/c/include/setjmp.h
===================================================================
--- uspace/lib/c/include/setjmp.h	(revision 72c72d4a367ffdd08c3e7633b0240d085bd83925)
+++ uspace/lib/c/include/setjmp.h	(revision d3b2ffaddcda1e7c3db7a9f643033e62c4c947a0)
@@ -35,12 +35,13 @@
 
 #include <libarch/fibril_context.h>
+#include <_bits/__noreturn.h>
 
 typedef context_t jmp_buf[1];
 
 extern int __setjmp(jmp_buf) __attribute__((returns_twice));
-extern _Noreturn void __longjmp(jmp_buf, int);
+extern __noreturn void __longjmp(jmp_buf, int);
 
 #define setjmp __setjmp
-extern _Noreturn void longjmp(jmp_buf, int);
+extern __noreturn void longjmp(jmp_buf, int);
 
 #endif
