Index: src/libcfa/concurrency/monitor
===================================================================
--- src/libcfa/concurrency/monitor	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/libcfa/concurrency/monitor	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -87,3 +87,4 @@
 void wait( condition * this );
 void signal( condition * this );
+void signal_block( condition * this );
 #endif //MONITOR_H
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/libcfa/concurrency/monitor.c	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -62,4 +62,5 @@
 			//Some one else has the monitor, wait in line for it
 			append( &this->entry_queue, thrd );
+			LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
 			ScheduleInternal( &this->lock );
 
@@ -97,4 +98,6 @@
 		unlock( &this->lock );
 
+		LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
+
 		//We need to wake-up the thread
 		ScheduleThread( new_owner );
@@ -149,4 +152,5 @@
 	assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
 	assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
+	assertf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
 
 	unsigned short count = this->monitor_count;
@@ -184,6 +188,4 @@
 	}
 
-	debug_break();
-
 	for( int i = 0; i < count; i++) {
 		thread_desc * new_owner = next_thread( this->monitors[i] );
@@ -191,6 +193,4 @@
 	}
 
-	debug_break();
-
 	LIB_DEBUG_PRINT_SAFE("Will unblock: ");
 	for(int i = 0; i < thread_count; i++) {
@@ -202,5 +202,5 @@
 	ScheduleInternal( locks, count, threads, thread_count );
 
-
+	debug_break();
 	//WE WOKE UP
 
@@ -224,4 +224,5 @@
 	unsigned short count = this->monitor_count;
 	
+	//Some more checking in debug
 	LIB_DEBUG_DO(
 		thread_desc * this_thrd = this_thread();
@@ -237,8 +238,12 @@
 	);
 
+	//Lock all the monitors
 	lock_all( this->monitors, NULL, count );
 	LIB_DEBUG_PRINT_SAFE("Signalling");
 
+	//Pop the head of the waiting queue
 	__condition_node_t * node = pop_head( &this->blocked );
+
+	//Add the thread to the proper AS stack
 	for(int i = 0; i < count; i++) {
 		__condition_criterion_t * crit = &node->criteria[i];
@@ -250,5 +255,64 @@
 	LIB_DEBUG_PRINT_SAFE("\n");
 
+	//Release
 	unlock_all( this->monitors, count );
+}
+
+void signal_block( condition * this ) {
+	if( !this->blocked.head ) {
+		LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
+		return;
+	}
+
+	//Check that everything is as expected
+	assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
+	assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
+
+	unsigned short count = this->monitor_count;
+	unsigned int recursions[ count ];		//Save the current recursion levels to restore them later
+	spinlock *   locks     [ count ];		//We need to pass-in an array of locks to ScheduleInternal
+
+	lock_all( this->monitors, locks, count );
+
+	//create creteria
+	__condition_node_t waiter;
+	waiter.waiting_thread = this_thread();
+	waiter.count = count;
+	waiter.next = NULL;
+
+	__condition_criterion_t criteria[count];
+	for(int i = 0; i < count; i++) {
+		LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
+		criteria[i].ready  = false;
+		criteria[i].owner  = &waiter;
+		criteria[i].next   = NULL;
+		criteria[i].target = this->monitors[i];
+		push( &criteria[i].target->signal_stack, &criteria[i] );
+	}
+
+	waiter.criteria = criteria;
+
+	//save contexts
+	save_recursion( this->monitors, recursions, count );
+
+	//Find the thread to run
+	thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
+	for(int i = 0; i < count; i++) {
+		set_owner( this->monitors[i], signallee );
+	}
+
+	LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" );
+	debug_break();
+
+	//Everything is ready to go to sleep
+	ScheduleInternal( locks, count, &signallee, 1 );
+
+	debug_break();
+	LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" );
+
+	//We are back, restore the owners and recursions
+	lock_all( locks, count );
+	restore_recursion( this->monitors, recursions, count );
+	unlock_all( locks, count );
 }
 
@@ -335,4 +399,5 @@
 
 	for(	int i = 0; i < count; i++ ) {
+
 		LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
 		if( &criteria[i] == target ) {
Index: src/libcfa/concurrency/thread
===================================================================
--- src/libcfa/concurrency/thread	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/libcfa/concurrency/thread	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -82,4 +82,5 @@
 
 void yield();
+void yield( unsigned times );
 
 #endif //THREADS_H
Index: src/libcfa/concurrency/thread.c
===================================================================
--- src/libcfa/concurrency/thread.c	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/libcfa/concurrency/thread.c	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -87,4 +87,10 @@
 }
 
+void yield( unsigned times ) {
+	for( unsigned i = 0; i < times; i++ ) {
+		yield();
+	}
+}
+
 void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
 	// set state of current coroutine to inactive
Index: src/libcfa/gmp
===================================================================
--- src/libcfa/gmp	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/libcfa/gmp	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -10,6 +10,6 @@
 // Created On       : Tue Apr 19 08:43:43 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun May 14 23:47:36 2017
-// Update Count     : 9
+// Last Modified On : Mon May 22 08:32:39 2017
+// Update Count     : 13
 // 
 
@@ -35,5 +35,5 @@
 Int ?=?( Int * lhs, long int rhs ) { mpz_set_si( lhs->mpz, rhs ); return *lhs; }
 Int ?=?( Int * lhs, unsigned long int rhs ) { mpz_set_ui( lhs->mpz, rhs ); return *lhs; }
-//Int ?=?( Int * lhs, const char * rhs ) { if ( mpq_set_str( lhs->mpz, rhs, 0 ) ) abort(); return *lhs; }
+Int ?=?( Int * lhs, const char * rhs ) { if ( mpz_set_str( lhs->mpz, rhs, 0 ) ) { printf( "invalid string conversion\n" ); abort(); } return *lhs; }
 
 char ?=?( char * lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); *lhs = val; return val; }
Index: src/tests/.expect/64/gmp.txt
===================================================================
--- src/tests/.expect/64/gmp.txt	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/tests/.expect/64/gmp.txt	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -4,4 +4,5 @@
 conversions
 y:97
+y:12345678901234567890123456789
 y:3
 y:-3
@@ -24,4 +25,5 @@
 z:150000000000000000000
 z:16666666666666666666
+16666666666666666666, 2 16666666666666666666, 2
 x:16666666666666666666 y:2
 
Index: src/tests/.expect/concurrent/sched-int-block.txt
===================================================================
--- src/tests/.expect/concurrent/sched-int-block.txt	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
+++ src/tests/.expect/concurrent/sched-int-block.txt	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -0,0 +1,2 @@
+Starting waiters
+Waiters done
Index: src/tests/Makefile.am
===================================================================
--- src/tests/Makefile.am	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/tests/Makefile.am	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -22,5 +22,5 @@
 concurrent=yes
 quick_test+= coroutine thread monitor
-concurrent_test=coroutine thread monitor multi-monitor sched-int-disjoint sched-int-barge sched-int-wait sched-ext sched-ext-multi preempt
+concurrent_test=coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt
 else
 concurrent=no
Index: src/tests/Makefile.in
===================================================================
--- src/tests/Makefile.in	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/tests/Makefile.in	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -230,5 +230,5 @@
 @BUILD_CONCURRENCY_TRUE@concurrent = yes
 @BUILD_CONCURRENCY_FALSE@concurrent_test = 
-@BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-disjoint sched-int-barge sched-int-wait sched-ext sched-ext-multi preempt
+@BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-barge sched-int-block sched-int-disjoint sched-int-wait sched-ext sched-ext-multi preempt
 
 # applies to both programs
Index: src/tests/gmp.c
===================================================================
--- src/tests/gmp.c	(revision 7f623d6fc2334cda8b26a77d059a48637fb5a398)
+++ src/tests/gmp.c	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -10,11 +10,11 @@
 // Created On       : Tue Apr 19 08:55:51 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun May 14 14:46:50 2017
-// Update Count     : 530
+// Last Modified On : Mon May 22 09:05:09 2017
+// Update Count     : 538
 // 
 
 #include <gmp>
 
-int main() {
+int main( void ) {
 	sout | "constructors" | endl;
 	short int si = 3;
@@ -25,4 +25,6 @@
 	sout | "conversions" | endl;
 	y = 'a';
+	sout | "y:" | y | endl;
+	y = "12345678901234567890123456789";
 	sout | "y:" | y | endl;
 	y = si;
@@ -62,7 +64,7 @@
 	z = x / 3;
 	sout | "z:" | z | endl;
+	sout | div( x, 3 ) | x / 3 | "," | x % 3 | endl;
 	[ x, y ] = div( x, 3 );
 	sout | "x:" | x | "y:" | y | endl;
-//	sout | div( x, 3 ) | x / 3 | "," | x % 3 | endl;
 
 	sout | endl;
@@ -72,7 +74,7 @@
 	fn = (Int){0}; fn1 = fn;							// 1st case
 	sout | (int)0 | fn | endl;
-	fn = (Int){1}; fn2 = fn1; fn1 = fn;					// 2nd case
+	fn = 1; fn2 = fn1; fn1 = fn;						// 2nd case
 	sout | 1 | fn | endl;
-	for ( int i = 2; i <= 200; i += 1 ) {
+	for ( unsigned int i = 2; i <= 200; i += 1 ) {
 		fn = fn1 + fn2; fn2 = fn1; fn1 = fn;			// general case
 		sout | i | fn | endl;
@@ -83,7 +85,7 @@
 	sout | "Factorial Numbers" | endl;
 	Int fact;
-	fact = (Int){1};									// 1st case
+	fact = 1;											// 1st case
 	sout | (int)0 | fact | endl;
-	for ( int i = 1; i <= 40; i += 1 ) {
+	for ( unsigned int i = 1; i <= 40; i += 1 ) {
 		fact = fact * i;								// general case
 		sout | i | fact | endl;
Index: src/tests/sched-int-block.c
===================================================================
--- src/tests/sched-int-block.c	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
+++ src/tests/sched-int-block.c	(revision cf0b8923b19d710edf28a43fe16a09eb76ce9ae2)
@@ -0,0 +1,113 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+static const unsigned N = 100_000;
+
+enum state_t { WAITED, SIGNAL, BARGE };
+
+monitor global_t {};
+
+monitor global_data_t {
+	state_t state;
+	bool ran;
+};
+
+void ?{} ( global_data_t * this ) {
+	this->state = BARGE;
+}
+
+void ^?{} ( global_data_t * this ) {}
+
+global_data_t globalA, globalB;
+
+condition cond;
+
+volatile bool done;
+
+//------------------------------------------------------------------------------
+void wait_op( global_data_t * mutex a, global_data_t * mutex b, unsigned i ) {
+	wait( &cond );
+	a->ran = b->ran = true;
+
+	yield( ((unsigned)rand48()) % 10 );
+
+	if(a->state != SIGNAL || b->state != SIGNAL) {
+		sout | "ERROR Barging detected" | a->state | b->state | endl;
+		abort();
+	}
+
+	a->state = b->state = WAITED;
+
+	yield( ((unsigned)rand48()) % 10 );
+}
+
+thread Waiter {};
+void main( Waiter* this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait_op( &globalA, &globalB, i );
+	}
+}
+
+//------------------------------------------------------------------------------
+void signal_op( global_data_t * mutex a, global_data_t * mutex b ) {
+	yield( ((unsigned)rand48()) % 10 );
+
+	a->ran = b->ran = false;
+	a->state = b->state = SIGNAL;
+
+	signal_block( &cond );
+
+	yield( ((unsigned)rand48()) % 10 );
+
+	assert(a->ran == b->ran);
+	if(a->ran)
+	{
+		if(a->state != WAITED || b->state != WAITED) {
+			sout | "ERROR Barging detected" | a->state | b->state | endl;
+			abort();
+		}
+	}
+
+}
+
+thread Signaller {};
+void main( Signaller* this ) {
+	while( !done ) {
+		signal_op( &globalA, &globalB );
+	}
+}
+
+//------------------------------------------------------------------------------
+void barge_op( global_data_t * mutex a ) {
+	a->state = BARGE;
+}
+
+thread Barger {};
+void main( Barger* this ) {
+	for( unsigned i = 0; !done; i++ ) {
+		//Choose some monitor to barge into with some irregular pattern
+		bool choose_a = (i % 13) > (i % 17);
+		barge_op( choose_a ? &globalA : &globalB );
+	}
+}
+
+//------------------------------------------------------------------------------
+
+int main(int argc, char* argv[]) {
+	rand48seed(0);
+	done = false;
+	processor p;
+	{
+		Signaller s[4];
+		Barger b[13];
+		sout | "Starting waiters" | endl;
+		{
+			Waiter w[3];
+		}
+		sout | "Waiters done" | endl;
+		done = true;
+	}
+}
