Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision 8e1dc006010967a74ddd6d508a3d813402117e3a)
+++ uspace/app/trace/trace.c	(revision 84683fdcff89e57c1a5b8126534bdef325411961)
@@ -73,6 +73,9 @@
 uintptr_t thash;
 volatile int paused;
-fibril_condvar_t paused_cv;
-fibril_mutex_t paused_lock;
+fibril_condvar_t state_cv;
+fibril_mutex_t state_lock;
+
+int cev_valid;
+console_event_t cev;
 
 void thread_trace_start(uintptr_t thread_hash);
@@ -86,4 +89,5 @@
 
 static int program_run_fibril(void *arg);
+static int cev_fibril(void *arg);
 
 static void program_run(void)
@@ -92,4 +96,17 @@
 
 	fid = fibril_create(program_run_fibril, NULL);
+	if (fid == 0) {
+		printf("Error creating fibril\n");
+		exit(1);
+	}
+
+	fibril_add_ready(fid);
+}
+
+static void cev_fibril_start(void)
+{
+	fid_t fid;
+
+	fid = fibril_create(cev_fibril, NULL);
 	if (fid == 0) {
 		printf("Error creating fibril\n");
@@ -457,5 +474,5 @@
 	while (!abort_trace) {
 
-		fibril_mutex_lock(&paused_lock);
+		fibril_mutex_lock(&state_lock);
 		if (paused) {
 			printf("Thread [%d] paused. Press R to resume.\n",
@@ -463,9 +480,9 @@
 
 			while (paused)
-				fibril_condvar_wait(&paused_cv, &paused_lock);
+				fibril_condvar_wait(&state_cv, &state_lock);
 
 			printf("Thread [%d] resumed.\n", thread_id);
 		}
-		fibril_mutex_unlock(&paused_lock);
+		fibril_mutex_unlock(&state_lock);
 
 		/* Run thread until an event occurs */
@@ -489,7 +506,7 @@
 			case UDEBUG_EVENT_STOP:
 				printf("Stop event\n");
-				fibril_mutex_lock(&paused_lock);
+				fibril_mutex_lock(&state_lock);
 				paused = 1;
-				fibril_mutex_unlock(&paused_lock);
+				fibril_mutex_unlock(&state_lock);
 				break;
 			case UDEBUG_EVENT_THREAD_B:
@@ -498,5 +515,8 @@
 			case UDEBUG_EVENT_THREAD_E:
 				printf("Thread 0x%lx exited.\n", val0);
+				fibril_mutex_lock(&state_lock);
 				abort_trace = 1;
+				fibril_condvar_broadcast(&state_cv);
+				fibril_mutex_unlock(&state_lock);
 				break;
 			default:
@@ -593,4 +613,30 @@
 }
 
+static int cev_fibril(void *arg)
+{
+	(void) arg;
+
+	printf("cev_fibril()\n");
+	while (true) {
+		printf("cev_fibril: wait for cev_valid == 0\n");
+		fibril_mutex_lock(&state_lock);
+		while (cev_valid)
+			fibril_condvar_wait(&state_cv, &state_lock);
+		fibril_mutex_unlock(&state_lock);
+
+		printf("cev_fibril: wait for key\n");
+
+		if (!console_get_event(fphone(stdin), &cev))
+			return -1;
+
+		printf("cev_fibril: broadcast cev_valid = 1\n");
+
+		fibril_mutex_lock(&state_lock);
+		cev_valid = 1;
+		fibril_condvar_broadcast(&state_cv);
+		fibril_mutex_unlock(&state_lock);		
+	}
+}
+
 static void trace_task(task_id_t task_id)
 {
@@ -623,6 +669,21 @@
 
 	while (!done) {
-		if (!console_get_event(fphone(stdin), &ev))
-			return;
+		printf("trace_task: wait for cev_valid || abort_trace\n");
+		fibril_mutex_lock(&state_lock);
+		while (!cev_valid && !abort_trace)
+			fibril_condvar_wait(&state_cv, &state_lock);
+		fibril_mutex_unlock(&state_lock);
+
+		printf("trace_task: got something\n");
+
+		ev = cev;
+
+		fibril_mutex_lock(&state_lock);
+		cev_valid = false;
+		fibril_condvar_broadcast(&state_cv);
+		fibril_mutex_unlock(&state_lock);
+
+		if (abort_trace)
+			break;
 
 		if (ev.type != KEY_PRESS)
@@ -640,8 +701,8 @@
 			break;
 		case KC_R:
-			fibril_mutex_lock(&paused_lock);
+			fibril_mutex_lock(&state_lock);
 			paused = 0;
-			fibril_condvar_broadcast(&paused_cv);
-			fibril_mutex_unlock(&paused_lock);
+			fibril_condvar_broadcast(&state_cv);
+			fibril_mutex_unlock(&state_lock);
 			printf("Resume...\n");
 			break;
@@ -683,6 +744,8 @@
 	next_thread_id = 1;
 	paused = 0;
-	fibril_mutex_initialize(&paused_lock);
-	fibril_condvar_initialize(&paused_cv);
+	cev_valid = 0;
+
+	fibril_mutex_initialize(&state_lock);
+	fibril_condvar_initialize(&state_cv);
 
 	proto_init();
@@ -874,4 +937,5 @@
 	}
 
+	cev_fibril_start();
 	trace_task(task_id);
 
