Index: console/console.c
===================================================================
--- console/console.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ console/console.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -26,4 +26,6 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+/* TODO: remove */
+#include <stdio.h>
 
 
@@ -92,15 +94,15 @@
 static void clrscr(void)
 {
-	nsend_call(fb_info.phone, FB_CLEAR, 0);
+	async_msg(fb_info.phone, FB_CLEAR, 0);
 }
 
 static void curs_visibility(int v)
 {
-	send_call(fb_info.phone, FB_CURSOR_VISIBILITY, v); 
+	async_msg(fb_info.phone, FB_CURSOR_VISIBILITY, v); 
 }
 
 static void curs_goto(int row, int col)
 {
-	nsend_call_2(fb_info.phone, FB_CURSOR_GOTO, row, col); 
+	async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col); 
 	
 }
@@ -108,15 +110,15 @@
 static void set_style(style_t *style)
 {
-	nsend_call_2(fb_info.phone, FB_SET_STYLE, style->fg_color, style->bg_color); 
+	async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color, style->bg_color); 
 }
 
 static void set_style_col(int fgcolor, int bgcolor)
 {
-	nsend_call_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor); 
+	async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor); 
 }
 
 static void prtchr(char c, int row, int col)
 {
-	nsend_call_3(fb_info.phone, FB_PUTCHAR, c, row, col);
+	async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
 	
 }
@@ -166,5 +168,5 @@
 		screenbuffer_clear_line(scr, scr->top_line++);
 		if (console == active_console)
-			nsend_call(fb_info.phone, FB_SCROLL, 1);
+			async_msg(fb_info.phone, FB_SCROLL, 1);
 	}
 	
@@ -186,5 +188,5 @@
        
 	/* Save screen */
-	newpmap = sync_send(fb_info.phone, FB_VP2PIXMAP, 0, NULL);
+	newpmap = async_req(fb_info.phone, FB_VP2PIXMAP, 0, NULL);
 	if (newpmap < 0)
 		return -1;
@@ -192,7 +194,7 @@
 	if (oldpixmap != -1) {
 		/* Show old screen */
-		nsend_call_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap);
+		async_msg_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap);
 		/* Drop old pixmap */
-		nsend_call(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);
+		async_msg(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);
 	}
 	
@@ -237,5 +239,4 @@
 		console_pixmap = -1;
 	}
-	
 	active_console = newcons;
 	gcons_change_console(newcons);
@@ -245,5 +246,4 @@
 	curs_goto(conn->screenbuffer.position_y, conn->screenbuffer.position_x);
 	curs_visibility(0);
-	
 	if (interbuffer) {
 		for (i = 0; i < conn->screenbuffer.size_x; i++)
@@ -251,5 +251,5 @@
 				interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
 		/* This call can preempt, but we are already at the end */
-		j = sync_send_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);		
+		j = async_req_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);		
 	};
 	
@@ -302,8 +302,10 @@
 //			if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
 			if ((c >= 0x101) && (c < 0x101 + CONSOLE_COUNT)) {
+				async_serialize_start();
 				if (c == 0x112)
 					change_console(KERNEL_CONSOLE);
 				else
 					change_console(c - 0x101);
+				async_serialize_end();
 				break;
 			}
@@ -322,5 +324,5 @@
 		default:
 			retval = ENOENT;
-		}		
+		}
 		ipc_answer_fast(callid, retval, 0, 0);
 	}
@@ -341,7 +343,8 @@
 	}
 	conn = &connections[consnum];
-	
+	conn->used = 1;
+	
+	async_serialize_start();
 	gcons_notify_connect(consnum);
-	conn->used = 1;
 	conn->client_phone = IPC_GET_ARG3(call);
 	screenbuffer_clear(&conn->screenbuffer);
@@ -349,11 +352,15 @@
 	/* Accept the connection */
 	ipc_answer_fast(iid,0,0,0);
-	
+
 	while (1) {
+		async_serialize_end();
 		callid = async_get_call(&call);
+		async_serialize_start();
+
 		arg1 = arg2 = 0;
 		switch (IPC_GET_METHOD(call)) {
 		case IPC_M_PHONE_HUNGUP:
 			gcons_notify_disconnect(consnum);
+			
 			/* Answer all pending requests */
 			while (conn->keyrequest_counter > 0) {		
@@ -365,4 +372,5 @@
 			/* Commit hangup */
 			ipc_answer_fast(callid, 0,0,0);
+			async_serialize_end();
 			return;
 		case CONSOLE_PUTCHAR:
@@ -373,5 +381,5 @@
 			/* Send message to fb */
 			if (consnum == active_console) {
-				send_call(fb_info.phone, FB_CLEAR, 0); 
+				async_msg(fb_info.phone, FB_CLEAR, 0); 
 			}
 			
@@ -392,5 +400,5 @@
 			break;
 		case CONSOLE_FLUSH:
-			sync_send_2(fb_info.phone, FB_FLUSH, 0, 0, NULL, NULL);		
+			async_req_2(fb_info.phone, FB_FLUSH, 0, 0, NULL, NULL);		
 			break;
 		case CONSOLE_SET_STYLE:
@@ -460,5 +468,5 @@
 	gcons_init(fb_info.phone);
 	/* Synchronize, the gcons can have something in queue */
-	sync_send(fb_info.phone, FB_FLUSH, 0, NULL);
+	async_req(fb_info.phone, FB_FLUSH, 0, NULL);
 
 	
Index: console/gcons.c
===================================================================
--- console/gcons.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ console/gcons.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -76,5 +76,5 @@
 static void vp_switch(int vp)
 {
-	nsend_call(fbphone,FB_VIEWPORT_SWITCH, vp);
+	async_msg(fbphone,FB_VIEWPORT_SWITCH, vp);
 }
 
@@ -91,5 +91,5 @@
 static void clear(void)
 {
-	nsend_call(fbphone, FB_CLEAR, 0);
+	async_msg(fbphone, FB_CLEAR, 0);
 	
 }
@@ -97,5 +97,5 @@
 static void set_style(int fgcolor, int bgcolor)
 {
-	nsend_call_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor);
+	async_msg_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor);
 }
 
@@ -103,5 +103,5 @@
 static void tran_putch(char c, int row, int col)
 {
-	nsend_call_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);
+	async_msg_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);
 }
 
@@ -115,5 +115,5 @@
 	vp_switch(cstatus_vp[consnum]);
 	if (ic_pixmaps[state] != -1)
-		nsend_call_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum], ic_pixmaps[state]);
+		async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum], ic_pixmaps[state]);
 
  	if (state != CONS_DISCONNECTED && state != CONS_KERNEL && state != CONS_DISCONNECTED_SEL) {
@@ -239,15 +239,15 @@
 	memcpy(shm, logo, size);
 	/* Send area */
-	rc = sync_send_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);
+	rc = async_req_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);
 	if (rc)
 		goto exit;
-	rc = sync_send_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);
+	rc = async_req_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);
 	if (rc)
 		goto drop;
 	/* Draw logo */
-	nsend_call_2(fbphone, FB_DRAW_PPM, x, y);
+	async_msg_2(fbphone, FB_DRAW_PPM, x, y);
 drop:
 	/* Drop area */
-	nsend_call(fbphone, FB_DROP_SHM, 0);
+	async_msg(fbphone, FB_DROP_SHM, 0);
 exit:       
 	/* Remove area */
@@ -298,13 +298,13 @@
 	memcpy(shm, data, size);
 	/* Send area */
-	rc = sync_send_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);
+	rc = async_req_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);
 	if (rc)
 		goto exit;
-	rc = sync_send_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);
+	rc = async_req_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);
 	if (rc)
 		goto drop;
 
 	/* Obtain pixmap */
-	rc = sync_send(fbphone, FB_SHM2PIXMAP, 0, NULL);
+	rc = async_req(fbphone, FB_SHM2PIXMAP, 0, NULL);
 	if (rc < 0)
 		goto drop;
@@ -312,5 +312,5 @@
 drop:
 	/* Drop area */
-	nsend_call(fbphone, FB_DROP_SHM, 0);
+	async_msg(fbphone, FB_DROP_SHM, 0);
 exit:       
 	/* Remove area */
Index: fb/fb.c
===================================================================
--- fb/fb.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ fb/fb.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -43,5 +43,4 @@
 
 #include "font-8x16.h"
-#include "helenos.xbm"
 #include "fb.h"
 #include "main.h"
Index: helenos.xbm
===================================================================
--- fb/helenos.xbm	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ 	(revision )
@@ -1,163 +1,0 @@
-#define helenos_width 127
-#define helenos_height 120
-static unsigned char helenos_bits[] = {
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x80, 0x0f, 0x78, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x80, 0x81,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
-   0x0f, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x06,
-   0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07,
-   0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x0c,
-   0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
-   0x00, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-   0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
-   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
-   0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x80, 0xc1, 0x00, 0x00, 0x00,
-   0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x80,
-   0xc1, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0xfe, 0x01, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00,
-   0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00,
-   0x03, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0xff, 0x07, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00,
-   0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
-   0x0c, 0x02, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0xff, 0x0f, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00,
-   0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00,
-   0x18, 0x0c, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
-   0xfc, 0x1f, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00,
-   0x80, 0x1f, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00,
-   0x18, 0x02, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00,
-   0x30, 0x18, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00,
-   0xf8, 0x3f, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00,
-   0xe0, 0x7f, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00,
-   0x38, 0x0c, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00,
-   0xe0, 0x20, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00,
-   0xf0, 0x7f, 0x00, 0x00, 0xc0, 0x78, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00,
-   0xe0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xc0, 0x7c, 0x00, 0x00,
-   0x70, 0x18, 0x00, 0x00, 0xe0, 0xff, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x00,
-   0x80, 0xfd, 0x00, 0x00, 0x60, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00,
-   0xfc, 0xff, 0x01, 0x00, 0x80, 0xf9, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00,
-   0xc0, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x00, 0x80, 0xfb, 0x00, 0x00,
-   0xc0, 0x7f, 0x00, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x03, 0x00,
-   0x00, 0xf3, 0x01, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x03, 0xfc,
-   0xff, 0xff, 0x03, 0x00, 0x00, 0xf3, 0x01, 0x00, 0xc0, 0x7f, 0x00, 0x00,
-   0x80, 0xff, 0x07, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xf6, 0x03, 0x00,
-   0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0xe7, 0xff, 0xff, 0xff, 0x07, 0x00,
-   0x00, 0xe6, 0x03, 0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
-   0xff, 0xff, 0x07, 0x00, 0x00, 0xec, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00,
-   0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xcc, 0x07, 0x00,
-   0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0x0f, 0x00,
-   0x00, 0xdc, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xff,
-   0x1f, 0xfe, 0x0f, 0x00, 0x00, 0xd8, 0x0f, 0x00, 0x00, 0xfe, 0x03, 0x00,
-   0x00, 0xfc, 0xff, 0xff, 0x03, 0xfe, 0x1f, 0x00, 0x00, 0x98, 0x0f, 0x00,
-   0x00, 0xfe, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0xfc, 0x1f, 0x00,
-   0x00, 0xb0, 0x1f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x1f,
-   0x00, 0xfc, 0x3f, 0x00, 0x00, 0x30, 0x1f, 0x00, 0x00, 0xfc, 0x07, 0x00,
-   0x00, 0xf8, 0xff, 0x07, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x70, 0x1f, 0x00,
-   0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00,
-   0x00, 0x60, 0x3e, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0x00,
-   0x00, 0xf8, 0x7f, 0x00, 0x00, 0xe0, 0x3e, 0x00, 0x00, 0xf8, 0x0f, 0x00,
-   0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf8, 0x7e, 0x00,
-   0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00,
-   0x00, 0xfc, 0x7c, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xe0, 0xff, 0x00,
-   0x00, 0xf0, 0xff, 0x00, 0x00, 0xfe, 0xfd, 0x00, 0x00, 0xf0, 0x1f, 0x00,
-   0x00, 0xe0, 0xff, 0x01, 0x00, 0xe0, 0xff, 0x00, 0x80, 0xff, 0xf9, 0x00,
-   0x00, 0xe0, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0xe0, 0xff, 0x00,
-   0xc0, 0xff, 0xfb, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x03,
-   0x00, 0xc0, 0x7f, 0x00, 0xe0, 0xff, 0xfb, 0x01, 0x00, 0xc0, 0x7f, 0x00,
-   0x00, 0x80, 0xff, 0x03, 0x00, 0xc0, 0x7f, 0x00, 0xf8, 0xff, 0xf7, 0x01,
-   0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00, 0x80, 0x3f, 0x00,
-   0xfc, 0xff, 0xf7, 0x03, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x07,
-   0x00, 0x00, 0x00, 0x00, 0xfe, 0xef, 0xe7, 0x03, 0x00, 0x80, 0xff, 0x00,
-   0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdf, 0xef, 0x07,
-   0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xc0,
-   0xff, 0xdf, 0xef, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0x0f,
-   0x00, 0x00, 0x00, 0xe0, 0xff, 0xcf, 0xcf, 0x07, 0x00, 0x00, 0xff, 0x01,
-   0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0xc3, 0xcf, 0x0f,
-   0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0xfc,
-   0xff, 0xe0, 0xcf, 0x0f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xfc, 0x1f,
-   0x00, 0x00, 0x00, 0xfe, 0xff, 0xf9, 0xc7, 0x0f, 0x00, 0x00, 0xfe, 0x03,
-   0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe7, 0x0f,
-   0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0xff,
-   0xff, 0xff, 0xe7, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0x07,
-   0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xe3, 0x0f, 0x00, 0x00, 0xfc, 0x0f,
-   0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xf1, 0x0f,
-   0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
-   0xff, 0xff, 0xf8, 0x0f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0xfe, 0xff, 0xff, 0x3f, 0xfc, 0x0f, 0x00, 0x00, 0xf0, 0x1f,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0xfe, 0x0f,
-   0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff,
-   0xff, 0x81, 0xff, 0x07, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0xe0, 0xff, 0xff, 0x3f, 0xe0, 0xff, 0x07, 0x00, 0x00, 0xe0, 0x3f,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0xfc, 0xff, 0x07,
-   0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff,
-   0x80, 0xff, 0xff, 0x03, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0xfe, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0x7f,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x00,
-   0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xc0,
-   0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00,
-   0xe0, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xdf,
-   0x00, 0x3c, 0x00, 0x00, 0xf0, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x0f, 0x00,
-   0x00, 0x00, 0x00, 0xcf, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x7f, 0xc0, 0xff,
-   0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x01, 0x7e, 0x00, 0x00,
-   0xfe, 0x0f, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97,
-   0x01, 0x3e, 0x00, 0x00, 0xff, 0x03, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x9e, 0x03, 0x00, 0x00, 0xc0, 0x7f, 0xc0, 0xff, 0xff,
-   0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0xe0,
-   0x0f, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
-   0x03, 0x00, 0x00, 0xf8, 0x01, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x7c, 0x06, 0x00, 0x00, 0x3f, 0xe0, 0xff, 0xff, 0xff,
-   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0xe0, 0x0f,
-   0xfc, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
-   0x3c, 0x00, 0xfc, 0x01, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0xf8, 0x78, 0x80, 0x3f, 0xe0, 0xff, 0xff, 0xff, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe1, 0xff, 0x07, 0xfc,
-   0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
-   0x81, 0xff, 0x80, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0xff,
-   0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
-   0x0f, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0xc0, 0x3f, 0xc0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff,
-   0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
-   0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
Index: kbd/generic/kbd.c
===================================================================
--- kbd/generic/kbd.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ kbd/generic/kbd.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -39,6 +39,64 @@
 #include <libadt/fifo.h>
 #include <key_buffer.h>
+#include <async.h>
 
 #define NAME "KBD"
+
+int cons_connected = 0;
+int phone2cons = -1;
+keybuffer_t keybuffer;	
+
+static void irq_handler(ipc_callid_t iid, ipc_call_t *call)
+{
+	int chr;
+	
+	if (cons_connected && phone2cons != -1) {
+		/* recode to ASCII - one interrupt can produce more than one code so result is stored in fifo */
+		kbd_arch_process(&keybuffer, IPC_GET_ARG2(*call));
+		
+		while (!keybuffer_empty(&keybuffer)) {
+			if (!keybuffer_pop(&keybuffer, (int *)&chr))
+				break;
+
+			async_msg(phone2cons, KBD_PUSHCHAR, chr);
+		}
+	}
+}
+
+static void console_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	int retval;
+
+	if (cons_connected) {
+		ipc_answer_fast(iid, ELIMIT, 0, 0);
+		return;
+	}
+	cons_connected = 1;
+	ipc_answer_fast(iid, 0, 0, 0);
+
+	while (1) {
+		callid = async_get_call(&call);
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			cons_connected = 0;
+			ipc_hangup(phone2cons);
+			phone2cons = -1;
+			ipc_answer_fast(callid, 0,0,0);
+			return;
+		case IPC_M_CONNECT_TO_ME:
+			if (phone2cons != -1) {
+				retval = ELIMIT;
+				break;
+			}
+			phone2cons = IPC_GET_ARG3(call);
+			retval = 0;
+			break;
+		}
+		ipc_answer_fast(callid, retval, 0, 0);
+	}	
+}
+
 
 int main(int argc, char **argv)
@@ -50,9 +108,5 @@
 	ipcarg_t phoneid;
 	char connected = 0;
-	keybuffer_t keybuffer;	
 	ipcarg_t retval, arg1, arg2;
-	
-	//open("null",0);
-	//open("stdout",0);
 	
 	/* Initialize arch dependent parts */
@@ -68,56 +122,9 @@
 	if ((res = ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, &phonead)) != 0) {
 		return -1;
-	};
-	while (1) {
-		callid = ipc_wait_for_call(&call);
-		switch (IPC_GET_METHOD(call)) {
-			case IPC_M_PHONE_HUNGUP:
-				connected = 0;
-				retval = 0;
-				break;
-			case IPC_M_CONNECT_ME_TO:
-				/* Only one connected client allowed */
-				if (connected) {
-					retval = ELIMIT;
-				} else {
-					retval = 0;
-					connected = 1;
-				}
-				break;
-			case IPC_M_CONNECT_TO_ME:
-				phoneid = IPC_GET_ARG3(call);
-				retval = 0;
-				break;
+	}
 
-			case IPC_M_INTERRUPT:
-				if (connected) {
-					int chr;
-					/* recode to ASCII - one interrupt can produce more than one code so result is stored in fifo */
-					kbd_arch_process(&keybuffer, IPC_GET_ARG2(call));
+	async_set_client_connection(console_connection);
+	async_set_interrupt_received(irq_handler);
+	async_manager();
 
-					retval = 0;
-					
-
-					while (!keybuffer_empty(&keybuffer)) {
-						if (!keybuffer_pop(&keybuffer, (int *)&chr)) {
-							break;
-						}
-						{
-							arg1=chr;
-							send_call(phoneid, KBD_PUSHCHAR, arg1);
-						}    
-					}
-
-				}
-				break;
-			default:
-				retval = ENOENT;
-				break;
-		}
-
-		if (! (callid & IPC_CALLID_NOTIFICATION)) {
-			ipc_answer_fast(callid, retval, arg1, arg2);
-		}
-	}
 }
-
Index: klog/klog.c
===================================================================
--- klog/klog.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ klog/klog.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -41,10 +41,10 @@
 	int i;
 	
-//	psthread_serialize_start();
+	async_serialize_start();
 	/* TODO: remove workaround around non-functional vsnprintf */
 	for (i=0; klog[i + IPC_GET_ARG2(*call)] && i < IPC_GET_ARG3(*call); i++)
 		putchar(klog[i + IPC_GET_ARG2(*call)]);
 	putchar('\n');
-//	psthread_serialize_done();
+	async_serialize_end();
 }
 
Index: libc/generic/async.c
===================================================================
--- libc/generic/async.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ libc/generic/async.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -135,6 +135,9 @@
 } connection_t;
 
-
+/** Identifier of incoming connection handled by current thread */
 __thread connection_t *PS_connection;
+/** If true, it is forbidden to use async_req functions and
+ *  all preemption is disabled */
+__thread int in_interrupt_handler;
 
 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
@@ -226,4 +229,5 @@
 
 	wd->timedout = 0;
+	wd->inlist = 1;
 
 	tmp = timeout_list.next;
@@ -295,7 +299,4 @@
 	conn = PS_connection; 
 
-	if (usecs < 0) /* TODO: let it get through the ipc_call once */
-		return 0;
-
 	futex_down(&async_futex);
 
@@ -308,8 +309,7 @@
 	/* If nothing in queue, wait until something appears */
 	while (list_empty(&conn->msg_queue)) {
-		if (usecs) {
-			conn->wdata.inlist = 1;
+		if (usecs)
 			insert_timeout(&conn->wdata);
-		}
+
 		conn->wdata.active = 0;
 		psthread_schedule_next_adv(PS_TO_MANAGER);
@@ -363,5 +363,4 @@
 	PS_connection = (connection_t *)arg;
 	PS_connection->cthread(PS_connection->callid, &PS_connection->call);
-
 	/* Remove myself from connection hash table */
 	futex_down(&async_futex);
@@ -436,5 +435,7 @@
 	switch (IPC_GET_METHOD(*call)) {
 	case IPC_M_INTERRUPT:
+		in_interrupt_handler = 1;
 		(*interrupt_received)(callid,call);
+		in_interrupt_handler = 0;
 		return;
 	case IPC_M_CONNECT_ME_TO:
@@ -486,5 +487,5 @@
 
 /** Endless loop dispatching incoming calls and answers */
-int async_manager(void)
+static int async_manager_worker(void)
 {
 	ipc_call_t call;
@@ -522,6 +523,7 @@
 		}
 
-		if (callid & IPC_CALLID_ANSWERED)
+		if (callid & IPC_CALLID_ANSWERED) {
 			continue;
+		}
 
 		handle_call(callid, &call);
@@ -538,7 +540,8 @@
 static int async_manager_thread(void *arg)
 {
+	in_interrupt_handler = 0; // TODO: Handle TLS better
 	futex_up(&async_futex); /* async_futex is always locked when entering
 				* manager */
-	async_manager();
+	async_manager_worker();
 }
 
@@ -608,4 +611,9 @@
 	amsg_t *msg;
 
+	if (in_interrupt_handler) {
+		printf("Cannot send asynchronou request in interrupt handler.\n");
+		_exit(1);
+	}
+
 	msg = malloc(sizeof(*msg));
 	msg->done = 0;
@@ -628,4 +636,9 @@
 {
 	amsg_t *msg;
+
+	if (in_interrupt_handler) {
+		printf("Cannot send asynchronou request in interrupt handler.\n");
+		_exit(1);
+	}
 
 	msg = malloc(sizeof(*msg));
@@ -699,6 +712,4 @@
 	msg->wdata.ptid = psthread_get_id();
 	msg->wdata.active = 0;
-	msg->wdata.inlist = 1;
-
 	insert_timeout(&msg->wdata);
 
@@ -726,4 +737,9 @@
 	amsg_t *msg;
 	
+	if (in_interrupt_handler) {
+		printf("Cannot call async_usleep in interrupt handler.\n");
+		_exit(1);
+	}
+
 	msg = malloc(sizeof(*msg));
 	if (!msg)
@@ -731,5 +747,4 @@
 
 	msg->wdata.ptid = psthread_get_id();
-	msg->wdata.inlist = 1;
 	msg->wdata.active = 0;
 
@@ -757,2 +772,14 @@
 	interrupt_received = conn;
 }
+
+/* Primitive functions for simple communication */
+void async_msg_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
+		 ipcarg_t arg2, ipcarg_t arg3)
+{
+	ipc_call_async_3(phoneid, method, arg1, arg2, arg3, NULL, NULL, !in_interrupt_handler);
+}
+
+void async_msg_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2)
+{
+	ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, !in_interrupt_handler);
+}
Index: libc/generic/io/stream.c
===================================================================
--- libc/generic/io/stream.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ libc/generic/io/stream.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -65,5 +65,5 @@
 
 	while (i < count) {
-		if (sync_send_2(streams[0].phone, CONSOLE_GETCHAR, 0, 0, &r0, &r1) < 0) {
+		if (async_req_2(streams[0].phone, CONSOLE_GETCHAR, 0, 0, &r0, &r1) < 0) {
 			return -1;
 		}
@@ -79,5 +79,5 @@
 
 	for (i = 0; i < count; i++)
-		send_call(streams[1].phone, CONSOLE_PUTCHAR, ((const char *)buf)[i]);
+		async_msg(streams[1].phone, CONSOLE_PUTCHAR, ((const char *)buf)[i]);
 	
 	return count;
@@ -131,5 +131,5 @@
 {
 	int c = 0;
-	
+
 	while (((streams[c].w) || (streams[c].r)) && (c < FDS))
 		c++;
@@ -160,4 +160,6 @@
 ssize_t write(int fd, const void *buf, size_t count)
 {
+//	__SYSCALL3(SYS_IO, 1, (sysarg_t)buf, (sysarg_t) count);
+//	return count;
 	if (fd < FDS)
 		return streams[fd].w(streams[fd].param, buf, count);
Index: libc/generic/ipc.c
===================================================================
--- libc/generic/ipc.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ libc/generic/ipc.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -438,25 +438,2 @@
 }
 
-/* Primitive functions for simple communication */
-void send_call_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
-		 ipcarg_t arg2, ipcarg_t arg3)
-{
-	ipc_call_async_3(phoneid, method, arg1, arg2, arg3, NULL, NULL, 1);
-}
-
-void send_call_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2)
-{
-	ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, 1);
-}
-
-void nsend_call_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
-		  ipcarg_t arg2, ipcarg_t arg3)
-{
-	ipc_call_async_3(phoneid, method, arg1, arg2, arg3, NULL, NULL, 0);
-}
-
-void nsend_call_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2)
-{
-	ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, 0);
-}
-
Index: libc/generic/psthread.c
===================================================================
--- libc/generic/psthread.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ libc/generic/psthread.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -43,4 +43,5 @@
 
 static LIST_INITIALIZE(ready_list);
+static LIST_INITIALIZE(serialized_list);
 static LIST_INITIALIZE(manager_list);
 
@@ -49,4 +50,10 @@
 
 static atomic_t psthread_futex = FUTEX_INITIALIZER;
+/** Count of real threads that are in async_serialized mode */
+static int serialized_threads; /* Protected by async_futex */
+/** Thread-local count of serialization. If >0, we must not preempt */
+static __thread serialization_count;
+/** Counter of threads residing in async_manager */
+static int threads_in_manager;
 
 /** Setup PSthread information into TCB structure */
@@ -78,28 +85,4 @@
 }
 
-/** Function to preempt to other pseudo thread without adding
- * currently running pseudo thread to ready_list.
- */
-void psthread_exit(void)
-{
-	psthread_data_t *pt;
-
-	futex_down(&psthread_futex);
-
-	if (!list_empty(&ready_list))
-		pt = list_get_instance(ready_list.next, psthread_data_t, link);
-	else if (!list_empty(&manager_list)) 
-		pt = list_get_instance(manager_list.next, psthread_data_t, link);
-	else {
-		printf("Cannot find suitable psthread to run.\n");
-		_exit(0);
-	}
-	list_remove(&pt->link);
-	futex_up(&psthread_futex);
-
-	context_restore(&pt->ctx);
-	/* Never reached */
-}
-
 /** Function that is called on entry to new uspace thread */
 void psthread_main(void)
@@ -107,4 +90,5 @@
 	psthread_data_t *pt = __tcb_get()->pst_data;
 
+	serialization_count = 0; // TODO: WHY HERE?
 	pt->retval = pt->func(pt->arg);
 
@@ -113,5 +97,5 @@
 		list_append(&pt->waiter->link, &ready_list);
 
-	psthread_exit();
+	psthread_schedule_next_adv(PS_FROM_DEAD);
 }
 
@@ -128,5 +112,5 @@
 int psthread_schedule_next_adv(pschange_type ctype)
 {
-	psthread_data_t *pt;
+	psthread_data_t *srcpt, *dstpt;
 	int retval = 0;
 	
@@ -136,31 +120,59 @@
 		goto ret_0;
 
-	if (ctype == PS_FROM_MANAGER && list_empty(&ready_list)) {
-		goto ret_0;
+	if (ctype == PS_FROM_MANAGER) {
+		if (list_empty(&ready_list) && list_empty(&serialized_list))
+			goto ret_0;
+		/* Do not preempt if there is not sufficient count of thread managers */
+		if (list_empty(&serialized_list) && threads_in_manager <= serialized_threads) {
+			goto ret_0;
+		}
 	}
 	/* If we are going to manager and none exists, create it */
-	while (ctype == PS_TO_MANAGER && list_empty(&manager_list)) {
-		futex_up(&psthread_futex);
-		async_create_manager();
-		futex_down(&psthread_futex);
-	}
-
-	pt = __tcb_get()->pst_data;
-	if (!context_save(&pt->ctx)) 
-		return 1; // futex_up already done here
-
-	if (ctype == PS_PREEMPT)
-		list_append(&pt->link, &ready_list);
-	else if (ctype == PS_FROM_MANAGER)
-		list_append(&pt->link, &manager_list);
+	if (ctype == PS_TO_MANAGER || ctype == PS_FROM_DEAD) {
+		while (list_empty(&manager_list)) {
+			futex_up(&psthread_futex);
+			async_create_manager();
+			futex_down(&psthread_futex);
+		}
+	}
 	
-	if (ctype == PS_TO_MANAGER)
-		pt = list_get_instance(manager_list.next,psthread_data_t, link);
-	else
-		pt = list_get_instance(ready_list.next, psthread_data_t, link);
-	list_remove(&pt->link);
-
-	futex_up(&psthread_futex);
-	context_restore(&pt->ctx);
+	if (ctype != PS_FROM_DEAD) {
+		/* Save current state */
+		srcpt = __tcb_get()->pst_data;
+		if (!context_save(&srcpt->ctx)) {
+			if (serialization_count)
+				srcpt->flags &= ~PSTHREAD_SERIALIZED;
+			return 1; // futex_up already done here
+		}
+
+		/* Save myself to correct run list */
+		if (ctype == PS_PREEMPT)
+			list_append(&srcpt->link, &ready_list);
+		else if (ctype == PS_FROM_MANAGER) {
+			list_append(&srcpt->link, &manager_list);
+			threads_in_manager--;
+		} /* If ctype == PS_TO_MANAGER, don't save ourselves to any list, we should
+		   * already be somewhere, or we will be lost */
+	}
+
+	/* Choose new thread to run */
+	if (ctype == PS_TO_MANAGER || ctype == PS_FROM_DEAD) {
+		dstpt = list_get_instance(manager_list.next,psthread_data_t, link);
+		if (serialization_count && ctype == PS_TO_MANAGER) {
+			serialized_threads++;
+			srcpt->flags |= PSTHREAD_SERIALIZED;
+		}
+		threads_in_manager++;
+	} else {
+		if (!list_empty(&serialized_list)) {
+			dstpt = list_get_instance(serialized_list.next, psthread_data_t, link);
+			serialized_threads--;
+		} else
+			dstpt = list_get_instance(ready_list.next, psthread_data_t, link);
+	}
+	list_remove(&dstpt->link);
+
+	futex_up(&psthread_futex);
+	context_restore(&dstpt->ctx);
 
 ret_0:
@@ -183,11 +195,8 @@
 	pt = (psthread_data_t *) psthrid;
 
-	if (!pt->finished) {
-		mypt = __tcb_get()->pst_data;
-		if (context_save(&((psthread_data_t *) mypt)->ctx)) {
-			pt->waiter = (psthread_data_t *) mypt;
-			psthread_exit();
-		}
-	}
+	/* TODO */
+	printf("join unsupported\n");
+	_exit(1);
+
 	retval = pt->retval;
 
@@ -224,4 +233,5 @@
 	pt->finished = 0;
 	pt->waiter = NULL;
+	pt->flags = 0;
 
 	context_save(&pt->ctx);
@@ -239,5 +249,8 @@
 	pt = (psthread_data_t *) psthrid;
 	futex_down(&psthread_futex);
-	list_append(&pt->link, &ready_list);
+	if ((pt->flags & PSTHREAD_SERIALIZED))
+		list_append(&pt->link, &serialized_list);
+	else
+		list_append(&pt->link, &ready_list);
 	futex_up(&psthread_futex);
 }
@@ -272,2 +285,20 @@
 	return (pstid_t)__tcb_get()->pst_data;
 }
+
+/** Disable preemption 
+ *
+ * If the thread wants to send several message in row and does not want
+ * to be preempted, it should start async_serialize_start() in the beginning
+ * of communication and async_serialize_end() in the end. If it is a
+ * true multithreaded application, it should protect the communication channel
+ * by a futex as well. Interrupt messages will can still be preempted.
+ */
+void psthread_inc_sercount(void)
+{
+	serialization_count++;
+}
+
+void psthread_dec_sercount(void)
+{
+	serialization_count--;
+}
Index: libc/include/async.h
===================================================================
--- libc/include/async.h	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ libc/include/async.h	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -38,5 +38,9 @@
 typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
 
-int async_manager(void);
+static inline void async_manager(void)
+{
+	psthread_schedule_next_adv(PS_TO_MANAGER);
+}
+
 ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
 static inline ipc_callid_t async_get_call(ipc_call_t *data)
@@ -58,5 +62,5 @@
  * @return Return code of message
  */
-static inline ipcarg_t sync_send_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t *r1, ipcarg_t *r2)
+static inline ipcarg_t async_req_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t *r1, ipcarg_t *r2)
 {
 	ipc_call_t result;
@@ -71,7 +75,7 @@
 	return rc;
 }
-#define sync_send(phoneid, method, arg1, r1) sync_send_2(phoneid, method, arg1, 0, r1, 0)
+#define async_req(phoneid, method, arg1, r1) async_req_2(phoneid, method, arg1, 0, r1, 0)
 
-static inline ipcarg_t sync_send_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
+static inline ipcarg_t async_req_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
 				   ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *r1, 
 				   ipcarg_t *r2, ipcarg_t *r3)
@@ -103,5 +107,19 @@
 
 
+/* Primitve functions for IPC communication */
+void async_msg_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, 
+		 ipcarg_t arg3);
+void async_msg_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2);
+#define async_msg(ph,m,a1) async_msg_2(ph,m,a1,0)
+
+static inline void async_serialize_start(void)
+{
+	psthread_inc_sercount();
+}
+static inline void async_serialize_end(void)
+{
+	psthread_dec_sercount();
+}
+
 extern atomic_t async_futex;
-
 #endif
Index: libc/include/ipc/ipc.h
===================================================================
--- libc/include/ipc/ipc.h	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ libc/include/ipc/ipc.h	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -82,15 +82,3 @@
 extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method, ipcarg_t arg1);
 
-
-/* Primitve functions for IPC communication */
-void send_call_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, 
-		 ipcarg_t arg3);
-void send_call_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2);
-#define send_call(ph,m,a1) send_call_2(ph,m,a1,0)
-/* These functions never preempt */
-void nsend_call_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
-		  ipcarg_t arg2, ipcarg_t arg3);
-void nsend_call_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2);
-#define nsend_call(ph,m,a1) nsend_call_2(ph,m,a1,0)
-
 #endif
Index: libc/include/psthread.h
===================================================================
--- libc/include/psthread.h	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ libc/include/psthread.h	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -41,8 +41,11 @@
 #endif /* context_set */
 
+#define PSTHREAD_SERIALIZED   1
+
 typedef enum {
 	PS_TO_MANAGER,
 	PS_FROM_MANAGER,
-	PS_PREEMPT
+	PS_PREEMPT,
+	PS_FROM_DEAD
 } pschange_type;
 
@@ -76,4 +79,6 @@
 void psthread_remove_manager(void);
 pstid_t psthread_get_id(void);
+void psthread_inc_sercount(void);
+void psthread_dec_sercount(void);
 
 static inline int psthread_schedule_next() {
Index: tetris/screen.c
===================================================================
--- tetris/screen.c	(revision d7eafd83ba96f175df79926c5ba49ba3181ebb5a)
+++ tetris/screen.c	(revision 085bd54731b26cc239e79bff42bde24e87ebf930)
@@ -81,5 +81,5 @@
 static void set_style(int fgcolor, int bgcolor)
 {
-	send_call_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);
+	async_msg_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);
 }
 
@@ -97,5 +97,5 @@
 void clear_screen(void)
 {
-	send_call(con_phone, CONSOLE_CLEAR, 0);
+	async_msg(con_phone, CONSOLE_CLEAR, 0);
 	moveto(0,0);
 }
@@ -109,5 +109,5 @@
 
 	resume_normal();
-	send_call(con_phone, CONSOLE_CLEAR, 0);
+	async_msg(con_phone, CONSOLE_CLEAR, 0);
 	curscore = -1;
 	memset((char *)curscreen, 0, sizeof(curscreen));
@@ -121,5 +121,5 @@
 {
 	con_phone = get_fd_phone(1);
-	send_call(con_phone, CONSOLE_CURSOR_VISIBILITY, 0);
+	async_msg(con_phone, CONSOLE_CURSOR_VISIBILITY, 0);
 	resume_normal();
 	scr_clear();
@@ -128,10 +128,10 @@
 void moveto(int r, int c)
 {
-	send_call_2(con_phone, CONSOLE_GOTO, r, c);
+	async_msg_2(con_phone, CONSOLE_GOTO, r, c);
 }
 
 static void fflush(void)
 {
-	send_call(con_phone, CONSOLE_FLUSH, 0);
+	async_msg(con_phone, CONSOLE_FLUSH, 0);
 }
 
@@ -140,5 +140,5 @@
 static int get_display_size(winsize_t *ws)
 {
-	return sync_send_2(con_phone, CONSOLE_GETSIZE, 0, 0, &ws->ws_row, &ws->ws_col);
+	return async_req_2(con_phone, CONSOLE_GETSIZE, 0, 0, &ws->ws_row, &ws->ws_col);
 }
 
