Index: src/libcfa/concurrency/kernel
===================================================================
--- src/libcfa/concurrency/kernel	(revision b877fa86a922c3a230e0f056e345fad6ee045b3c)
+++ src/libcfa/concurrency/kernel	(revision bdeba0b46cbdd4fb2e60e402dfee5a5543d02905)
@@ -33,15 +33,15 @@
 void unlock    ( spinlock * );
 
-struct signal_once {
-	volatile bool cond;
-	struct spinlock lock;
-	struct __thread_queue_t blocked;
+struct semaphore {
+	spinlock lock;
+	int count;
+	__thread_queue_t waiting;
 };
 
-void ?{}(signal_once * this);
-void ^?{}(signal_once * this);
+void  ?{}(semaphore * this, int count = 1);
+void ^?{}(semaphore * this);
+void P(semaphore * this);
+void V(semaphore * this);
 
-void wait( signal_once * );
-void signal( signal_once * );
 
 //-----------------------------------------------------------------------------
@@ -81,5 +81,5 @@
 	pthread_t kernel_thread;
 
-	signal_once terminated;
+	semaphore terminated;
 	volatile bool is_terminated;
 
Index: src/libcfa/concurrency/kernel.c
===================================================================
--- src/libcfa/concurrency/kernel.c	(revision b877fa86a922c3a230e0f056e345fad6ee045b3c)
+++ src/libcfa/concurrency/kernel.c	(revision bdeba0b46cbdd4fb2e60e402dfee5a5543d02905)
@@ -129,5 +129,5 @@
 void ?{}(processor * this, cluster * cltr) {
 	this->cltr = cltr;
-	(&this->terminated){};
+	(&this->terminated){ 0 };
 	this->is_terminated = false;
 	this->preemption_alarm = NULL;
@@ -140,5 +140,5 @@
 void ?{}(processor * this, cluster * cltr, processorCtx_t * runner) {
 	this->cltr = cltr;
-	(&this->terminated){};
+	(&this->terminated){ 0 };
 	this->is_terminated = false;
 	this->preemption_alarm = NULL;
@@ -168,5 +168,6 @@
 		LIB_DEBUG_PRINT_SAFE("Kernel : core %p signaling termination\n", this);
 		this->is_terminated = true;
-		wait( &this->terminated );
+		P( &this->terminated );
+		pthread_join( this->kernel_thread, NULL );
 	}
 }
@@ -223,5 +224,6 @@
 	}
 
-	signal( &this->terminated );
+	V( &this->terminated );
+
 	LIB_DEBUG_PRINT_SAFE("Kernel : core %p terminated\n", this);
 }
@@ -607,35 +609,39 @@
 }
 
-void ?{}( signal_once * this ) {
-	this->cond = false;
-}
-void ^?{}( signal_once * this ) {
-
-}
-
-void wait( signal_once * this ) {
+void  ?{}( semaphore * this, int count = 1 ) {
+	(&this->lock){};
+	this->count = count;
+	(&this->waiting){};
+}
+void ^?{}(semaphore * this) {}
+
+void P(semaphore * this) {
 	lock( &this->lock DEBUG_CTX2 );
-	if( !this->cond ) {
-		append( &this->blocked, (thread_desc*)this_thread );
+	this->count -= 1;
+	if ( this->count < 0 ) {
+		// queue current task
+		append( &this->waiting, (thread_desc *)this_thread );
+
+		// atomically release spin lock and block
 		BlockInternal( &this->lock );
 	}
 	else {
-		unlock( &this->lock );
-	}
-}
-
-void signal( signal_once * this ) {
+	    unlock( &this->lock );
+	}
+}
+
+void V(semaphore * this) {
+	thread_desc * thrd = NULL;
 	lock( &this->lock DEBUG_CTX2 );
-	{
-		this->cond = true;
-
-		disable_interrupts();
-		thread_desc * it;
-		while( it = pop_head( &this->blocked) ) {
-			ScheduleThread( it );
-		}
-		enable_interrupts( DEBUG_CTX );
-	}
+	this->count += 1;
+	if ( this->count <= 0 ) {
+		// remove task at head of waiting list
+		thrd = pop_head( &this->waiting );
+	}
+
 	unlock( &this->lock );
+
+	// make new owner
+	WakeThread( thrd );
 }
 
