Index: src/tests/concurrent/boundedBuffer.c
===================================================================
--- src/tests/concurrent/boundedBuffer.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/boundedBuffer.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,119 @@
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// boundedBuffer.c --
+//
+// Author           : Peter A. Buhr
+// Created On       : Mon Oct 30 12:45:13 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Oct 30 23:02:46 2017
+// Update Count     : 9
+//
+
+#include <stdlib>
+#include <fstream>										// random
+#include <kernel>
+#include <thread>
+#include <unistd.h>										// getpid
+
+monitor Buffer {
+	condition full, empty;
+	int front, back, count;
+	int elements[20];
+};
+
+void ?{}( Buffer & buffer ) {
+	buffer.front = buffer.back = buffer.count = 0;
+}
+
+int query( Buffer & buffer ) { return buffer.count; }
+
+void insert( Buffer & mutex buffer, int elem ) {
+	if ( buffer.count == 20 ) wait( buffer.empty );
+	buffer.elements[buffer.back] = elem;
+	buffer.back = ( buffer.back + 1 ) % 20;
+	buffer.count += 1;
+	signal( buffer.full );
+}
+int remove( Buffer & mutex buffer ) {
+	if ( buffer.count == 0 ) wait( buffer.full );
+	int elem = buffer.elements[buffer.front];
+	buffer.front = ( buffer.front + 1 ) % 20;
+	buffer.count -= 1;
+	signal( buffer.empty );
+	return elem;
+}
+
+thread Producer {
+	Buffer & buffer;
+	unsigned int N;
+};
+void main( Producer & prod ) {
+	for ( int i = 1; i <= prod.N; i += 1 ) {
+		yield( random( 5 ) );
+		insert( prod.buffer, 1 );
+	} // for
+	insert( prod.buffer, -1 );
+}
+void ?{}( Producer & prod, Buffer * buffer, unsigned int N ) {
+	&prod.buffer = buffer;
+	prod.N = N;
+		}
+
+thread Consumer {
+	Buffer & buffer;
+	int & sum;						// summation of producer values
+};
+void main( Consumer & cons ) {
+	cons.sum = 0;
+	for ( ;; ) {
+		yield( random( 5 ) );
+		int item = remove( cons.buffer );
+		if ( item == -1 ) break;				// sentinel ?
+		cons.sum += item;
+	} // for
+}
+void ?{}( Consumer & cons, Buffer * buffer, int * sum ) {
+	&cons.buffer = buffer;
+	&cons.sum = sum;
+}
+
+int main() {
+	Buffer buffer;
+	enum { Prods = 5, Cons = 5 };
+	Producer * prods[Prods];
+	Consumer * cons[Cons];
+	const int Sentinel = -1;
+	int sums[Cons];
+	int i;
+	processor p;
+
+	//random_seed( getpid() );
+	random_seed( 1003 );
+
+	for ( i = 0; i < Cons; i += 1 ) {			// create consumers
+		cons[i] = new( &buffer, &sums[i] );
+	} // for
+	for ( i = 0; i < Prods; i += 1 ) {			// create producers
+		prods[i] = new( &buffer, 100000u );
+	} // for
+
+	for ( i = 0; i < Prods; i += 1 ) {			// wait for producers to finish
+		delete( prods[i] );
+	} // for
+	for ( i = 0; i < Cons; i += 1 ) {			// generate sentinal values to stop consumers
+		insert( buffer, Sentinel );
+	} // for
+	int sum = 0;
+	for ( i = 0; i < Cons; i += 1 ) {			// wait for consumers to finish
+		delete( cons[i] );
+		sum += sums[i];
+	} // for
+	sout | "total:" | sum | endl;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa boundedBuffer.c" //
+// End: //
Index: src/tests/concurrent/datingService.c
===================================================================
--- src/tests/concurrent/datingService.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/datingService.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,114 @@
+//                               -*- Mode: C -*-
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// datingService.c --
+//
+// Author           : Peter A. Buhr
+// Created On       : Mon Oct 30 12:56:20 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Oct 30 23:02:11 2017
+// Update Count     : 15
+//
+
+#include <stdlib>										// random
+#include <fstream>
+#include <kernel>
+#include <thread>
+#include <unistd.h>										// getpid
+
+enum { NoOfPairs = 20 };
+
+monitor DatingService {
+	condition Girls[NoOfPairs], Boys[NoOfPairs];
+	unsigned int GirlPhoneNo, BoyPhoneNo;
+}; // DatingService
+
+unsigned int girl( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) {
+	if ( is_empty( ds.Boys[ccode] ) ) {
+		wait( ds.Girls[ccode] );
+		ds.GirlPhoneNo = PhoneNo;
+	} else {
+		ds.GirlPhoneNo = PhoneNo;
+		signal_block( ds.Boys[ccode] );
+	} // if
+	return ds.BoyPhoneNo;
+} // DatingService girl
+
+unsigned int boy( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) {
+	if ( is_empty( ds.Girls[ccode] ) ) {
+		wait( ds.Boys[ccode] );
+		ds.BoyPhoneNo = PhoneNo;
+	} else {
+		ds.BoyPhoneNo = PhoneNo;
+		signal_block( ds.Girls[ccode] );
+	} // if
+	return ds.GirlPhoneNo;
+} // DatingService boy
+
+unsigned int girlck[NoOfPairs];
+unsigned int boyck[NoOfPairs];
+
+thread Girl {
+	DatingService & TheExchange;
+	unsigned int id, ccode;
+}; // Girl
+
+void main( Girl & g ) {
+	yield( random( 100 ) );								// don't all start at the same time
+	unsigned int partner = girl( g.TheExchange, g.id, g.ccode );
+	//sout | "Girl:" | g.id | "is dating Boy at" | partner | "with ccode" | g.ccode | endl;
+	girlck[g.id] = partner;
+} // Girl main
+
+void ?{}( Girl & g, DatingService * TheExchange, unsigned int id, unsigned int ccode ) {
+	&g.TheExchange = TheExchange;
+	g.id = id;
+	g.ccode = ccode;
+} // Girl ?{}
+
+thread Boy {
+	DatingService &TheExchange;
+	unsigned int id, ccode;
+}; // Boy
+
+void main( Boy & b ) {
+	yield( random( 100 ) );								// don't all start at the same time
+	unsigned int partner = boy( b.TheExchange, b.id, b.ccode );
+	//sout | " Boy:" | b.id | "is dating Girl" | partner | "with ccode" | b.ccode | endl;
+	boyck[b.id] = partner;
+} // Boy main
+
+void ?{}( Boy & b, DatingService * TheExchange, unsigned int id, unsigned int ccode ) {
+	&b.TheExchange = TheExchange;
+	b.id = id;
+	b.ccode = ccode;
+} // Boy ?{}
+
+int main() {
+	DatingService TheExchange;
+	Girl *girls[NoOfPairs];
+	Boy  *boys[NoOfPairs];
+
+	random_seed( getpid() );
+
+	for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
+		girls[i] = new( &TheExchange, i, i );
+		boys[i]  = new( &TheExchange, i, NoOfPairs - ( i + 1 ) );
+	} // for
+
+	for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
+		delete( boys[i] );
+		delete( girls[i] );
+	} // for
+
+	for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
+		if ( girlck[ boyck[i] ] != boyck[ girlck[i] ] ) abort();
+	} // for
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa datingService.c" //
+// End: //
Index: src/tests/concurrent/matrixSum.c
===================================================================
--- src/tests/concurrent/matrixSum.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/matrixSum.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,63 @@
+//                               -*- Mode: C -*- 
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// matrixSum.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Mon Oct  9 08:29:28 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sun Oct 29 21:08:48 2017
+// Update Count     : 2
+// 
+
+#include <fstream>
+#include <kernel>
+#include <thread>
+
+thread Adder {
+    int * row, cols, * subtotal;						// communication
+};
+
+void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
+    adder.row = row;
+    adder.cols = cols;
+    adder.subtotal = &subtotal;
+}
+
+void main( Adder & adder ) {
+    *adder.subtotal = 0;
+    for ( int c = 0; c < adder.cols; c += 1 ) {
+		*adder.subtotal += adder.row[c];
+    } // for
+}
+
+int main() {
+    const int rows = 10, cols = 1000;
+    int matrix[rows][cols], subtotals[rows], total = 0;
+    processor p;										// extra kernel thread
+
+    for ( int r = 0; r < rows; r += 1 ) {
+		for ( int c = 0; c < cols; c += 1 ) {
+			matrix[r][c] = 1;
+		} // for
+    } // for
+    Adder * adders[rows];
+    for ( int r = 0; r < rows; r += 1 ) {				// start threads to sum rows
+		adders[r] = &(*malloc()){ matrix[r], cols, subtotals[r] };
+//		adders[r] = new( matrix[r], cols, &subtotals[r] );
+    } // for
+    for ( int r = 0; r < rows; r += 1 ) {				// wait for threads to finish
+		delete( adders[r] );
+		total += subtotals[r];							// total subtotals
+    } // for
+    sout | total | endl;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa matrixSum.c" //
+// End: //
Index: src/tests/concurrent/monitor.c
===================================================================
--- src/tests/concurrent/monitor.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/monitor.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,43 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <thread>
+
+monitor global_t {
+	int value;
+};
+
+void ?{}(global_t & this) {
+	this.value = 0;
+}
+
+static global_t global;
+
+void increment3( global_t & mutex this ) {
+	this.value += 1;
+}
+
+void increment2( global_t & mutex this ) {
+	increment3( this );
+}
+
+void increment( global_t & mutex this ) {
+	increment2( this );
+}
+
+thread MyThread {};
+
+void main( MyThread & this ) {
+	for(int i = 0; i < 1_000_000; i++) {
+		increment( global );
+	}
+}
+
+int main(int argc, char* argv[]) {
+	assert( global.__mon.entry_queue.tail != NULL );
+	processor p;
+	{
+		MyThread f[4];
+	}
+	sout | global.value | endl;
+}
Index: src/tests/concurrent/multi-monitor.c
===================================================================
--- src/tests/concurrent/multi-monitor.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/multi-monitor.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,55 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <thread>
+
+static int global12, global23, global13;
+
+monitor monitor_t {};
+
+static monitor_t m1, m2, m3;
+
+void increment( monitor_t & mutex p1, monitor_t & mutex p2, int & value ) {
+	value += 1;
+}
+
+thread MyThread {
+	int target;
+};
+
+void ?{}( MyThread & this, int target ) {
+	this.target = target;
+}
+
+void ^?{}( MyThread & mutex this ) {}
+
+void main( MyThread & this ) {
+	for(int i = 0; i < 1000000; i++) {
+		choose(this.target) {
+			case 0: increment( m1, m2, global12 );
+			case 1: increment( m2, m3, global23 );
+			case 2: increment( m1, m3, global13 );
+		}
+	}
+}
+
+forall(dtype T | sized(T) | { void ^?{}(T & mutex); })
+void delete_mutex(T * x) {
+	^(*x){};
+	free(x);
+}
+
+int main(int argc, char* argv[]) {
+	processor p;
+	{
+		MyThread * f[6];
+		for(int i = 0; i < 6; i++) {
+			f[i] = new(i % 3);
+		}
+
+		for(int i = 0; i < 6; i++) {
+			delete_mutex( f[i] );
+		}
+	}
+	sout | global12 | global23 | global13 | endl;
+}
Index: src/tests/concurrent/preempt.c
===================================================================
--- src/tests/concurrent/preempt.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/preempt.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,42 @@
+#include <kernel>
+#include <thread>
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10_000ul
+#endif
+
+unsigned int default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+static volatile int counter = 0;
+
+thread worker_t {
+	int value;
+};
+
+void ?{}( worker_t & this, int value ) {
+	this.value = value;
+}
+
+void main(worker_t & this) {
+	while(counter < 1000) {
+		if( (counter % 7) == this.value ) {
+			int next = __atomic_add_fetch_4(&counter, 1, __ATOMIC_SEQ_CST);
+			if( (next % 100) == 0 ) printf("%d\n", next);
+		}
+	}
+}
+
+int main(int argc, char* argv[]) {
+	processor p;
+	{
+		worker_t w0 = 0;
+		worker_t w1 = 1;
+		worker_t w2 = 2;
+		worker_t w3 = 3;
+		worker_t w4 = 4;
+		worker_t w5 = 5;
+		worker_t w6 = 6;
+	}
+}
Index: src/tests/concurrent/sched-ext-barge.c
===================================================================
--- src/tests/concurrent/sched-ext-barge.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-ext-barge.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,92 @@
+//---------------------------------------------------------
+// Barging test
+// Ensures that no barging can occur between :
+//   - the frontend of the waitfor and the waited call
+//   - the waited call and the backend of the waitfor
+//---------------------------------------------------------
+
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+#include <stdbool.h>
+
+static const unsigned long N = 5_000ul;
+
+enum state_t { WAITFOR, CALL, BARGE };
+
+monitor global_t {
+	bool done;
+	bool started;
+	state_t state;
+};
+
+void ?{} ( global_t & this ) {
+	this.done = false;
+	this.started = false;
+	this.state = BARGE;
+}
+
+void ^?{} ( global_t & mutex this ) {}
+
+global_t global;
+
+bool barge( global_t & mutex this ) {
+	this.state = BARGE;
+	return !this.done;
+}
+
+thread barger_t {};
+void main( barger_t & this ) {
+	yield();
+	while( barge( global ) ) { yield(random( 10 )); }
+}
+
+bool do_call( global_t & mutex this ) {
+	yield(random( 10 ));
+	if( this.state != WAITFOR && !this.done && this.started ) {
+		serr | "Barging before caller detected" | endl;
+	}
+
+	this.state = CALL;
+	return !this.done;
+}
+
+thread caller_t {};
+void main( caller_t & this ) {
+	while( do_call(global) ) { yield(random( 10 )); }
+}
+
+void do_wait( global_t & mutex this ) {
+	this.started = true;
+	for( int i = 0; i < N; i++) {
+		yield(random( 10 ));
+		this.state = WAITFOR;
+		waitfor(do_call, this) {
+			sout | i | endl;
+		}
+
+		if( this.state != CALL ) {
+			serr | "Barging after caller detected" | endl;
+		}
+	}
+
+	this.done = true;
+}
+
+thread waiter_t{};
+void main( waiter_t & this ) {
+	do_wait(global);
+}
+
+int main() {
+	sout | "Starting" | endl;
+	{
+		barger_t bargers[17];
+		caller_t callers[7];
+		waiter_t waiters;
+	}
+	sout | "Stopping" | endl;
+}
Index: src/tests/concurrent/sched-ext-dtor.c
===================================================================
--- src/tests/concurrent/sched-ext-dtor.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-ext-dtor.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,63 @@
+//---------------------------------------------------------
+// Barging test
+// Ensures the statement order is reverse when using waitfor ^?{}
+//---------------------------------------------------------
+
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+#include <stdbool.h>
+
+static const unsigned long N = 5_000ul;
+
+enum state_t {
+	CTOR,
+	MAIN,
+	AFTER,
+	END,
+	DTOR
+};
+
+thread dummy_t {
+	state_t state;
+};
+
+static inline void set_state( dummy_t & this, state_t state) {
+	switch(state) {
+		case CTOR  : break;
+		case MAIN  : if( this.state != CTOR  ) { serr | "ERROR Expected state to be CTOR"  | endl; abort(); } this.state = state; break;
+		case AFTER : if( this.state != MAIN  ) { serr | "ERROR Expected state to be MAIN"  | endl; abort(); } this.state = state; break;
+		case END   : if( this.state != AFTER ) { serr | "ERROR Expected state to be AFTER" | endl; abort(); } this.state = state; break;
+		case DTOR  : if( this.state != END   ) { serr | "ERROR Expected state to be END"   | endl; abort(); } this.state = state; break;
+	}
+}
+
+void ^?{}( dummy_t & mutex this ) {
+	set_state( this, DTOR );
+}
+
+void ?{}( dummy_t & this ) {
+	this.state = CTOR;
+}
+
+void main( dummy_t & this ) {
+	yield(random( 10 ));
+	set_state( this, MAIN );
+	waitfor( ^?{}, this ) {
+		set_state( this, AFTER );
+	}
+	set_state( this, END );
+}
+
+int main() {
+	sout | "Starting" | endl;
+	processor p;
+	for( int i = 0; i < N; i++ ){
+		dummy_t dummy[4];
+		yield( random( 100 ) );
+	}
+	sout | "Stopping" | endl;
+}
Index: src/tests/concurrent/sched-ext-else.c
===================================================================
--- src/tests/concurrent/sched-ext-else.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-ext-else.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,48 @@
+#include <fstream>
+#include <monitor>
+
+#include <stdbool.h>
+
+monitor M {};
+
+void notcalled( M & mutex m ) {
+	abort();
+}
+
+void test( M & mutex m ) {
+	int i = 0;
+	sout | "Starting" | endl;
+
+	when( false ) waitfor( notcalled, m );
+
+	sout | "Step" | i++ | endl;
+
+	waitfor( notcalled, m ); or else {
+		sout | "else called" | endl;
+	}
+
+	sout | "Step" | i++ | endl;
+
+	when( true ) waitfor( notcalled, m ); or when( true ) else {
+		sout | "else called" | endl;
+	}
+
+	sout | "Step" | i++ | endl;
+
+	when( false ) waitfor( notcalled, m ); or when( true ) else {
+		sout | "else called" | endl;
+	}
+
+	sout | "Step" | i++ | endl;
+
+	when( false ) waitfor( notcalled, m ); or when( false ) else {
+		sout | "else called" | endl;
+	}
+
+	sout | "Done" | endl;
+}
+
+int main() {
+	M m;
+	test(m);
+}
Index: src/tests/concurrent/sched-ext-parse.c
===================================================================
--- src/tests/concurrent/sched-ext-parse.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-ext-parse.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,104 @@
+//----------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------
+//
+//		DEPRECATED TEST
+//		DIFFERS BETWEEN DEBUG AND RELEASE
+//
+//----------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------
+
+#include <monitor>
+
+monitor M {};
+
+M a;
+
+void f1( M & mutex a );
+void f2( M & mutex a );
+void f2( M & mutex a, M & mutex b );
+void f3( M & mutex a );
+void f3( M & mutex a, M & mutex b );
+void f3( M & mutex a, M & mutex b, M & mutex c );
+
+void foo() {
+
+	//---------------------------------------
+	waitfor( f1, a ) {
+		1;
+	}
+
+	//---------------------------------------
+	waitfor( f1, a ) {
+		2;
+	}
+	waitfor( f2, a ) {
+		3;
+	}
+
+	//---------------------------------------
+	when( 1 < 3 ) waitfor( f2, a, a ) {
+		4;
+	}
+	or timeout( 100 ) {
+		5;
+	}
+
+	//---------------------------------------
+	when( 2 < 3 ) waitfor( f3, a ) {
+		5;
+	}
+	or else {
+		6;
+	}
+
+	//---------------------------------------
+	when( 3 < 3 ) waitfor( f3, a, a ) {
+		7;
+	}
+	or when( 4 < 3 ) timeout( 101 ) {
+		8;
+	}
+	or when( 5 < 3 ) else {
+		9;
+	}
+
+	//---------------------------------------
+	when( 6 < 3 ) waitfor( f3, a, a, a ) {
+		10;
+	}
+ 	or when( 7 < 3 ) waitfor( f1, a  ) {
+		11;
+	}
+	or else {
+		12;
+	}
+
+	//---------------------------------------
+	when( 8 < 3 ) waitfor( f3, a, a ) {
+		13;
+	}
+ 	or waitfor( f1, a  ) {
+		14;
+	}
+	or when( 9 < 3 ) timeout( 102 ) {
+		15;
+	}
+
+	//---------------------------------------
+	when( 10 < 3 ) waitfor( f1, a ) {
+		16;
+	}
+ 	or waitfor( f2, a, a ) {
+		17;
+	}
+	or timeout( 103 ) {
+		18;
+	}
+	or when( 11 < 3 ) else {
+		19;
+	}
+}
+
+int main() {
+
+}
Index: src/tests/concurrent/sched-ext-recurse.c
===================================================================
--- src/tests/concurrent/sched-ext-recurse.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-ext-recurse.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,145 @@
+//----------------------------------------------------------------
+// Recursion test
+// Ensures that proper ordering occurs between the nested waitfors
+//-----------------------------------------------------------------
+
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+#include <stdbool.h>
+#include <time.h>
+
+static const unsigned long N = 5_000ul;
+
+static inline void rand_yield() { yield(random( 10 )); }
+
+enum state_t { FIRST, SECOND, THIRD, LAST, STOP };
+void shuffle(enum state_t * array)
+{
+	int i;
+	for (i = 0; i < 4; i++)
+	{
+		int j = random( 4 );
+		enum state_t t = array[j];
+		array[j] = array[i];
+		array[i] = t;
+	}
+}
+
+
+monitor global_t {
+	int counter;
+	volatile bool ready;
+	state_t actions[4];
+};
+
+void ?{} ( global_t & this ) {
+	this.counter = 0;
+	this.ready = false;
+	this.actions[0] = FIRST;
+	this.actions[1] = SECOND;
+	this.actions[2] = THIRD;
+	this.actions[3] = LAST;
+	shuffle( this.actions );
+}
+
+void ^?{} ( global_t & mutex this ) {}
+
+global_t global;
+
+state_t call4( global_t & mutex this, int idx ) {
+	sout | "Last";
+
+	rand_yield();
+	this.counter++;
+	this.ready = false;
+	shuffle( this.actions );
+
+	return this.counter < N ? (state_t)this.actions[idx] : (state_t)STOP;
+}
+
+state_t call3( global_t & mutex this, int idx ) {
+	sout | "3rd";
+
+	rand_yield();
+	waitfor( call4, this );
+	rand_yield();
+
+	sout | "3rd";
+
+	return this.counter < N ? (state_t)this.actions[idx] : (state_t)STOP;
+}
+
+state_t call2( global_t & mutex this, int idx ) {
+	sout | "2nd";
+
+	rand_yield();
+	waitfor( call3, this );
+	rand_yield();
+
+	sout | "2nd";
+
+	return this.counter < N ? (state_t)this.actions[idx] : (state_t)STOP;
+}
+
+state_t call1( global_t & mutex this, int idx ) {
+	this.ready = true;
+
+	sout | this.counter | "1st";
+
+	rand_yield();
+	waitfor( call2, this );
+	rand_yield();
+
+	sout | "1st" | endl;
+
+	return this.counter < N ? (state_t)this.actions[idx] : (state_t)STOP;
+}
+
+thread waiter_t{
+	int     idx;
+	state_t state;
+};
+
+void ^?{} ( waiter_t & mutex this ) {}
+void ?{} ( waiter_t & this ) {}
+
+void ?{}( waiter_t & this, int idx, state_t state ) {
+	this.idx   = idx;
+	this.state = state;
+}
+
+
+void main( waiter_t & this ) {
+	while( this.state != STOP ) {
+		rand_yield();
+
+		switch( this.state ) {
+			case FIRST  :                                     this.state = call1( global, this.idx ); break;
+			case SECOND : while( !global.ready ) { yield(); } this.state = call2( global, this.idx ); break;
+			case THIRD  : while( !global.ready ) { yield(); } this.state = call3( global, this.idx ); break;
+			case LAST   : while( !global.ready ) { yield(); } this.state = call4( global, this.idx ); break;
+			case STOP   : serr | "This should not happen" | endl;
+		}
+	}
+}
+
+static waiter_t * volatile the_threads;
+
+int main() {
+	random_seed( time(NULL) );
+	sout | "Starting" | endl;
+	{
+		waiter_t waiters[4] = {
+			{ 0, FIRST  },
+			{ 1, SECOND },
+			{ 2, THIRD  },
+			{ 3, LAST   }
+		};
+		the_threads = waiters;
+	}
+	sout | "Stopping" | endl;
+}
Index: src/tests/concurrent/sched-ext-statment.c
===================================================================
--- src/tests/concurrent/sched-ext-statment.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-ext-statment.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,136 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <thread>
+
+#include <stdbool.h>
+
+monitor M {
+	int index;
+	int last_val;
+	int calls[7];
+};
+
+volatile bool start = false;
+
+void ?{}( M & this ) {
+	this.index = 0;
+	this.last_val = 0;
+	for( int i = 0; i < 7; i++ ) {
+		this.calls[i] = 100; //10_000;
+	}
+}
+
+void ^?{} ( M &  mutex this ) {}
+
+int get_index( M & mutex this ) {
+	this.index += 1;
+	return this.index;
+}
+
+bool call1( M & mutex this ) {
+	this.last_val = 1;
+	this.calls[0] -= 1;
+	return this.calls[0] > 0;
+}
+
+bool call2( M & mutex this ) {
+	this.last_val = 2;
+	this.calls[1] -= 1;
+	return this.calls[1] > 0;
+}
+
+bool call3( M & mutex this ) {
+	this.last_val = 3;
+	this.calls[2] -= 1;
+	return this.calls[2] > 0;
+}
+
+bool call4( M & mutex this ) {
+	this.last_val = 4;
+	this.calls[3] -= 1;
+	return this.calls[3] > 0;
+}
+
+bool call5( M & mutex this ) {
+	this.last_val = 5;
+	this.calls[4] -= 1;
+	return this.calls[4] > 0;
+}
+
+bool call6( M & mutex this ) {
+	this.last_val = 6;
+	this.calls[5] -= 1;
+	return this.calls[5] > 0;
+}
+
+bool call7( M & mutex this ) {
+	this.last_val = 7;
+	this.calls[6] -= 1;
+	return this.calls[6] > 0;
+}
+
+M m;
+thread caller{};
+
+bool call( int index ) {
+	switch( index ) {
+		case 1: return call1( m );
+		case 2: return call2( m );
+		case 3: return call3( m );
+		case 4: return call4( m );
+		case 5: return call5( m );
+		case 6: return call6( m );
+		case 7: return call7( m );
+		default :
+			serr | "Incorrect index" | index | endl;
+			abort();
+	}
+}
+
+void main( caller & this ) {
+	int index = get_index( m );
+	while( !start ) yield();
+	while( call( index ) );
+}
+
+void do_wait( M & mutex this ) {
+	bool done = false;
+
+	start = true;
+
+	while( !done ) {
+		   waitfor( get_index, this );
+		or waitfor( call1, this ) { sout | "Statement" | endl; if( this.last_val != 1 ) { serr | "Incorrect index: expected" | 1 | "got" | this.last_val | endl; } }
+		or waitfor( call2, this ) { sout | "Statement" | endl; if( this.last_val != 2 ) { serr | "Incorrect index: expected" | 2 | "got" | this.last_val | endl; } }
+		or waitfor( call3, this ) { sout | "Statement" | endl; if( this.last_val != 3 ) { serr | "Incorrect index: expected" | 3 | "got" | this.last_val | endl; } }
+		or waitfor( call4, this ) { sout | "Statement" | endl; if( this.last_val != 4 ) { serr | "Incorrect index: expected" | 4 | "got" | this.last_val | endl; } }
+		or waitfor( call5, this ) { sout | "Statement" | endl; if( this.last_val != 5 ) { serr | "Incorrect index: expected" | 5 | "got" | this.last_val | endl; } }
+		or waitfor( call6, this ) { sout | "Statement" | endl; if( this.last_val != 6 ) { serr | "Incorrect index: expected" | 6 | "got" | this.last_val | endl; } }
+		or waitfor( call7, this ) { sout | "Statement" | endl; if( this.last_val != 7 ) { serr | "Incorrect index: expected" | 7 | "got" | this.last_val | endl; } }
+
+		done = true;
+		for( int i = 0; i < 7; i++ ) {
+			if( this.calls[i] > 0 ) {
+				done = false;
+				break;
+			}
+		}
+	}
+}
+
+thread waiter{};
+
+void main( waiter & this ) {
+	do_wait( m );
+}
+
+int main() {
+	processor p[2];
+	sout | "Starting" | endl;
+	{
+		caller c[7];
+		waiter w;
+	}
+	sout | "Stopping" | endl;
+}
Index: src/tests/concurrent/sched-ext-when.c
===================================================================
--- src/tests/concurrent/sched-ext-when.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-ext-when.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,87 @@
+//----------------------------------------------------------------
+// When test
+// Ensures that when clauses on waitfor are respected
+//-----------------------------------------------------------------
+
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+#include <stdbool.h>
+#include <time.h>
+
+static const unsigned long N = 4_998ul;
+
+static inline void rand_yield() { yield(random( 10 )); }
+
+monitor global_t {
+	int last_call;
+	bool done;
+};
+
+void ?{} ( global_t & this ) {
+	this.last_call = 6;
+	this.done = false;
+}
+
+void ^?{} ( global_t & mutex this ) {}
+
+global_t global;
+
+bool call1( global_t & mutex this ) { this.last_call = 1; return this.done; }
+bool call2( global_t & mutex this ) { this.last_call = 2; return this.done; }
+bool call3( global_t & mutex this ) { this.last_call = 3; return this.done; }
+bool call4( global_t & mutex this ) { this.last_call = 4; return this.done; }
+bool call5( global_t & mutex this ) { this.last_call = 5; return this.done; }
+bool call6( global_t & mutex this ) { this.last_call = 6; return this.done; }
+
+thread caller_t{};
+void main( caller_t & this ) {
+	while( true ) {
+		rand_yield();
+		if( call1( global ) ) return;
+		rand_yield();
+		if( call2( global ) ) return;
+		rand_yield();
+		if( call3( global ) ) return;
+		rand_yield();
+		if( call4( global ) ) return;
+		rand_yield();
+		if( call5( global ) ) return;
+		rand_yield();
+		if( call6( global ) ) return;
+	}
+}
+
+void arbiter( global_t & mutex this ) {
+	for( int i = 0; i < N; i++ ) {
+		   when( this.last_call == 6 ) waitfor( call1, this ) { if( this.last_call != 1) { serr | "Expected last_call to be 1 got" | this.last_call | endl; } }
+		or when( this.last_call == 1 ) waitfor( call2, this ) { if( this.last_call != 2) { serr | "Expected last_call to be 2 got" | this.last_call | endl; } }
+		or when( this.last_call == 2 ) waitfor( call3, this ) { if( this.last_call != 3) { serr | "Expected last_call to be 3 got" | this.last_call | endl; } }
+		or when( this.last_call == 3 ) waitfor( call4, this ) { if( this.last_call != 4) { serr | "Expected last_call to be 4 got" | this.last_call | endl; } }
+		or when( this.last_call == 4 ) waitfor( call5, this ) { if( this.last_call != 5) { serr | "Expected last_call to be 5 got" | this.last_call | endl; } }
+		or when( this.last_call == 5 ) waitfor( call6, this ) { if( this.last_call != 6) { serr | "Expected last_call to be 6 got" | this.last_call | endl; } }
+
+		sout | this.last_call | endl;
+	}
+
+	this.done = true;
+}
+
+thread arbiter_t{};
+void main( arbiter_t & this ) {
+	arbiter( global );
+}
+
+int main() {
+	random_seed( time(NULL) );
+	sout | "Starting" | endl;
+	{
+		arbiter_t arbiter;
+		caller_t callers[7];
+
+	}
+	sout | "Stopping" | endl;
+}
Index: src/tests/concurrent/sched-ext.c
===================================================================
--- src/tests/concurrent/sched-ext.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-ext.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,85 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+#include <time.h>
+
+static const unsigned long N = 500ul;
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10_000ul
+#endif
+
+unsigned int default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+monitor global_t {};
+
+global_t globalA;
+
+thread Acceptor {};
+thread Acceptee {};
+
+volatile bool done;
+
+//----------------------------------------------------------------------------------------------------
+// Acceptor
+void do_notify( global_t * mutex a );
+
+void do_wait( global_t * mutex a ) {
+	sout | "Waiting to accept" | endl;
+	yield( random( 10 ) );
+
+	sout | "Accepting" | endl;
+
+	__acceptable_t acceptable;
+	acceptable.func          = (fptr_t)do_notify;
+	acceptable.count         = 1;
+	acceptable.monitors      = &a;
+
+	__waitfor_internal( 1, &acceptable );
+
+	sout | "Accepted" | endl;
+	yield( random( 10 ) );
+}
+
+void main( Acceptor* this ) {
+	for( int i = 0; i < N; i++ ) {
+		do_wait( &globalA );
+		sout | i | endl;
+	}
+
+	done = true;
+}
+
+//----------------------------------------------------------------------------------------------------
+// Acceptee
+void do_notify( global_t * mutex a ) {
+
+}
+
+void main( Acceptee* this ) {
+	while( !done ) {
+		yield( random( 10 ) );
+		do_notify( &globalA );
+		yield( random( 10 ) );
+	}
+}
+
+//----------------------------------------------------------------------------------------------------
+// Main
+int main(int argc, char* argv[]) {
+	done = false;
+	random_seed( time( NULL ) );
+	printf("%p\n", &globalA);
+	sout | "Starting" | endl;
+	{
+		Acceptor r;
+		Acceptee e[13];
+
+	}
+	sout | "Done" | endl;
+}
Index: src/tests/concurrent/sched-int-barge.c
===================================================================
--- src/tests/concurrent/sched-int-barge.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-int-barge.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,117 @@
+//----------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------
+//
+//		DEPRECATED TEST
+//
+//----------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------
+
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+static const unsigned long N = 50_000ul;
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10_000ul
+#endif
+
+unsigned int default_preemption() {
+	return 0;
+}
+enum state_t { WAIT, SIGNAL, BARGE };
+
+monitor global_t {};
+
+monitor global_data_t {
+	volatile bool done;
+	int counter;
+	state_t state;
+
+	unsigned short do_signal;
+	unsigned short do_wait2;
+	unsigned short do_wait1;
+};
+
+void ?{} ( global_data_t & this ) {
+	this.done = false;
+	this.counter = 0;
+	this.state = BARGE;
+
+	this.do_signal = 6;
+	this.do_wait1  = 1;
+	this.do_wait2  = 3;
+}
+
+void ^?{} ( global_data_t & this ) {}
+
+global_t globalA;
+global_t globalB;
+global_data_t globalC;
+
+condition cond;
+
+thread Threads {};
+
+bool logicC( global_t & mutex a, global_t & mutex b, global_data_t & mutex c ) {
+	c.counter++;
+
+	if( (c.counter % 1000) == 0 ) sout | c.counter | endl;
+
+	int action = c.counter % 10;
+
+	if( action == 0 ) {
+		c.do_signal = max( random( 10 ), 1);
+		c.do_wait1 = random( c.do_signal );
+		c.do_wait2 = random( c.do_signal );
+
+		if(c.do_wait1 == c.do_wait2) sout | "Same" | endl;
+	}
+
+	if( action == c.do_wait1 || action == c.do_wait2 ) {
+		c.state = WAIT;
+		wait( cond );
+
+		if(c.state != SIGNAL) {
+			sout | "ERROR Barging detected" | c.counter | endl;
+			abort();
+		}
+	}
+	else if( action == c.do_signal ) {
+		c.state = SIGNAL;
+
+		signal( cond );
+		signal( cond );
+	}
+	else {
+		c.state = BARGE;
+	}
+
+	if( c.counter >= N ) c.done = true;
+	return !c.done;
+}
+
+bool logicB( global_t & mutex a, global_t & mutex b ) {
+	return logicC(a, b, globalC);
+}
+
+bool logicA( global_t & mutex a ) {
+	return logicB(a, globalB);
+}
+
+void main( Threads & this ) {
+	while( logicA(globalA) ) { yield(); };
+}
+
+static thread_desc * volatile the_threads;
+
+int main(int argc, char* argv[]) {
+	random_seed(0);
+	processor p;
+	{
+		Threads t[17];
+		the_threads = (thread_desc*)t;
+	}
+}
Index: src/tests/concurrent/sched-int-block.c
===================================================================
--- src/tests/concurrent/sched-int-block.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-int-block.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,133 @@
+//---------------------------------------------------------
+// Barging test
+// Ensures that no barging can occur between :
+//   - the frontend of the signal_block and the signaled thread
+//   - the signaled  threadand the backend of the signal_block
+//---------------------------------------------------------
+
+
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+#include <time.h>
+
+static const unsigned long N = 5_000ul;
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10_000ul
+#endif
+
+unsigned int default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+enum state_t { WAITED, SIGNAL, BARGE };
+
+monitor global_data_t {
+	thread_desc * last_thread;
+	thread_desc * last_signaller;
+};
+
+void ?{} ( global_data_t & this ) {
+	this.last_thread = NULL;
+	this.last_signaller = NULL;
+}
+
+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, (uintptr_t)this_thread );
+
+	yield( random( 10 ) );
+
+	if(a.last_thread != a.last_signaller || b.last_thread != b.last_signaller ) {
+		sout | "ERROR Barging detected, expected" | a.last_signaller | b.last_signaller | "got" | a.last_thread | b.last_thread | endl;
+		abort();
+	}
+
+	a.last_thread = b.last_thread = this_thread;
+
+	yield( random( 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( random( 10 ) );
+
+	[a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = this_thread;
+
+	if( !is_empty( cond ) ) {
+
+		thread_desc * next = front( cond );
+
+		if( ! signal_block( cond ) ) {
+			sout | "ERROR expected to be able to signal" | endl;
+			abort();
+		}
+
+		yield( random( 10 ) );
+
+		if(a.last_thread != next || b.last_thread != next) {
+			sout | "ERROR Barging detected, expected" | next | "got" | a.last_thread | b.last_thread | endl;
+			abort();
+		}
+	}
+
+}
+
+thread Signaller {};
+void main( Signaller & this ) {
+	while( !done ) {
+		signal_op( globalA, globalB );
+	}
+}
+
+//------------------------------------------------------------------------------
+void barge_op( global_data_t & mutex a ) {
+	a.last_thread = this_thread;
+}
+
+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);
+		if ( choose_a ) barge_op( globalA );
+		else barge_op( globalB );
+	}
+}
+
+//------------------------------------------------------------------------------
+
+int main(int argc, char* argv[]) {
+	random_seed( time( NULL ) );
+	done = false;
+	processor p;
+	{
+		Signaller s[4];
+		Barger b[13];
+		sout | "Starting waiters" | endl;
+		{
+			Waiter w[3];
+		}
+		sout | "Waiters done" | endl;
+		done = true;
+	}
+}
Index: src/tests/concurrent/sched-int-disjoint.c
===================================================================
--- src/tests/concurrent/sched-int-disjoint.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-int-disjoint.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,123 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <thread>
+
+#include <time.h>
+
+static const unsigned long N = 10_000ul;
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10_000ul
+#endif
+
+unsigned int default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+enum state_t { WAIT, SIGNAL, BARGE };
+
+monitor global_t {};
+global_t mut;
+
+monitor global_data_t;
+void ?{}( global_data_t & this );
+void ^?{} ( global_data_t & this );
+
+monitor global_data_t {
+	int counter;
+	state_t state;
+} data;
+
+condition cond;
+
+volatile bool all_done;
+
+void ?{}( global_data_t & this ) {
+	this.counter == 0;
+	this.state = BARGE;
+}
+
+void ^?{} ( global_data_t & this ) {}
+
+//------------------------------------------------------------------------------
+// Barging logic
+void barge( global_data_t & mutex d ) {
+	d.state = BARGE;
+}
+
+thread Barger {};
+
+void main( Barger & this ) {
+	while( !all_done ) {
+		barge( data );
+		yield();
+	}
+}
+
+//------------------------------------------------------------------------------
+// Waiting logic
+bool wait( global_t & mutex m, global_data_t & mutex d ) {
+	wait( cond );
+	if( d.state != SIGNAL ) {
+		sout | "ERROR barging!" | endl;
+	}
+
+	d.counter++;
+
+	if( (d.counter % 1000) == 0 ) sout | d.counter | endl;
+
+	return d.counter < N;
+}
+
+thread Waiter {};
+
+void main( Waiter & this ) {
+	while( wait( mut, data ) ) { yield(); }
+}
+
+
+//------------------------------------------------------------------------------
+// Signalling logic
+void signal( condition & cond, global_t & mutex a, global_data_t & mutex b ) {
+	b.state = SIGNAL;
+	signal( cond );
+}
+
+void logic( global_t & mutex a ) {
+	signal( cond, a, data );
+
+	yield( random( 10 ) );
+
+	//This is technically a mutual exclusion violation but the mutex monitor protects us
+	bool running = data.counter < N && data.counter > 0;
+	if( data.state != SIGNAL && running ) {
+		sout | "ERROR Eager signal" | data.state | endl;
+	}
+}
+
+thread Signaller {};
+
+void main( Signaller & this ) {
+	while( !all_done ) {
+		logic( mut );
+		yield();
+	}
+}
+
+//------------------------------------------------------------------------------
+// Main loop
+int main(int argc, char* argv[]) {
+	random_seed( time( NULL ) );
+	all_done = false;
+	processor p;
+	{
+		Signaller s;
+		Barger b[17];
+		{
+			Waiter w[4];
+		}
+		sout | "All waiter done" | endl;
+		all_done = true;
+	}
+}
Index: src/tests/concurrent/sched-int-wait.c
===================================================================
--- src/tests/concurrent/sched-int-wait.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/sched-int-wait.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,143 @@
+//---------------------------------------------------------
+// Multi wait test
+// Ensures that no deadlock from waiting/signalling conditions
+//---------------------------------------------------------
+
+
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+#include <time.h>
+
+static const unsigned long N = 2_500ul;
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10_000ul
+#endif
+
+unsigned int default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+monitor global_t {};
+
+global_t globalA;
+global_t globalB;
+global_t globalC;
+
+condition condAB, condAC, condBC, condABC;
+
+thread Signaler {};
+thread WaiterAB {};
+thread WaiterAC {};
+thread WaiterBC {};
+thread WaiterABC{};
+
+volatile int waiter_left;
+
+//----------------------------------------------------------------------------------------------------
+// Tools
+void signal( condition & cond, global_t & mutex a, global_t & mutex b ) {
+	signal( cond );
+}
+
+void signal( condition & cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {
+	signal( cond );
+}
+
+void wait( condition & cond, global_t & mutex a, global_t & mutex b ) {
+	wait( cond );
+}
+
+void wait( condition & cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {
+	wait( cond );
+}
+
+//----------------------------------------------------------------------------------------------------
+// Signaler
+void main( Signaler & this ) {
+
+	while( waiter_left != 0 ) {
+		unsigned action = random( 4 );
+		switch( action ) {
+			case 0:
+				signal( condABC, globalA, globalB, globalC );
+				break;
+			case 1:
+				signal( condAB , globalA, globalB );
+				break;
+			case 2:
+				signal( condBC , globalB, globalC );
+				break;
+			case 3:
+				signal( condAC , globalA, globalC );
+				break;
+			default:
+				sout | "Something went wrong" | endl;
+				abort();
+		}
+		yield();
+	}
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter ABC
+void main( WaiterABC & this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait( condABC, globalA, globalB, globalC );
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter AB
+void main( WaiterAB & this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait( condAB , globalA, globalB );
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter AC
+void main( WaiterAC & this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait( condAC , globalA, globalC );
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter BC
+void main( WaiterBC & this ) {
+	for( int i = 0; i < N; i++ ) {
+		wait( condBC , globalB, globalC );
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Main
+int main(int argc, char* argv[]) {
+	random_seed( time( NULL ) );
+	waiter_left = 4;
+	processor p[2];
+	sout | "Starting" | endl;
+	{
+		Signaler  e;
+		{
+			WaiterABC a;
+			WaiterAB  b;
+			WaiterBC  c;
+			WaiterAC  d;
+		}
+	}
+	sout | "Done" | endl;
+}
Index: src/tests/concurrent/thread.c
===================================================================
--- src/tests/concurrent/thread.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/thread.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,40 @@
+#include <fstream>
+#include <kernel>
+#include <stdlib>
+#include <thread>
+
+thread First  { semaphore* lock; };
+thread Second { semaphore* lock; };
+
+void ?{}( First & this, semaphore & lock ) { this.lock = &lock; }
+void ?{}( Second & this, semaphore & lock ) { this.lock = &lock; }
+
+void main(First& this) {
+	for(int i = 0; i < 10; i++) {
+		sout | "First : Suspend No." | i + 1 | endl;
+		yield();
+	}
+	V(*this.lock);
+}
+
+void main(Second& this) {
+	P(*this.lock);
+	for(int i = 0; i < 10; i++) {
+		sout | "Second : Suspend No." | i + 1 | endl;
+		yield();
+	}
+}
+
+
+int main(int argc, char* argv[]) {
+	semaphore lock = { 0 };
+	sout | "User main begin" | endl;
+	{
+		processor p;
+		{
+			First  f = { lock };
+			Second s = { lock };
+		}
+	}
+	sout | "User main end" | endl;
+}
Index: src/tests/concurrent/waitfor.c
===================================================================
--- src/tests/concurrent/waitfor.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
+++ src/tests/concurrent/waitfor.c	(revision 557435e22bc33d5b46d38478863149e4bb72817e)
@@ -0,0 +1,249 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// waitfor.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed Aug 30 17:53:29 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Aug 30 17:55:17 2017
+// Update Count     : 2
+// 
+
+#include <stdbool.h>
+
+int fred() {
+	int x, z;
+
+	// test waitfor and when
+
+	waitfor( x );
+
+	waitfor( x ) {
+	}
+
+	waitfor( x, z ) {
+	}
+
+	when( true ) waitfor( x );
+
+	when( true ) waitfor( x ) {
+	}
+
+	waitfor( x );
+	or waitfor( y );
+
+	waitfor( x, z );
+	or waitfor( y );
+
+	when( true ) waitfor( x );
+	or when( true ) waitfor( y );
+
+	when( true ) waitfor( x, z );
+	or when( true ) waitfor( y );
+
+	waitfor( x ) {
+	} or waitfor( y ) {
+	}
+
+	waitfor( x, z ) {
+	} or waitfor( y ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) waitfor( y ) {
+	}
+
+	waitfor( x );
+	or waitfor( y ) {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) waitfor( y ) {
+	}
+
+	waitfor( x ) {
+	} or waitfor( y );
+
+	when( true ) waitfor( x ) {
+	} or when( true ) waitfor( y );
+
+	// test when, waitfor and else
+
+	waitfor( x );
+	or else;
+
+	when( true ) waitfor( x );
+	or else;
+
+	when( true ) waitfor( x, z );
+	or else;
+
+	waitfor( x ) {
+	} or else {
+	}
+
+	when( true ) waitfor( x ) {
+	} or else {
+	}
+
+	waitfor( x );
+	or else {
+	}
+
+	when( true ) waitfor( x );
+	or else {
+	}
+
+	when( true ) waitfor( x, z );
+	or else {
+	}
+
+	waitfor( x ) {
+	} or else;
+
+	when( true ) waitfor( x ) {
+	} or else;
+
+	waitfor( x );
+	or when( true ) else;
+
+	when( true ) waitfor( x );
+	or when( true ) else;
+
+	when( true ) waitfor( x, z );
+	or when( true ) else;
+
+	waitfor( x ) {
+	} or when( true ) else {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) else {
+	}
+
+	waitfor( x );
+	or when( true ) else {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) else {
+	}
+
+	when( true ) waitfor( x, z );
+	or when( true ) else {
+	}
+
+	waitfor( x ) {
+	} or when( true ) else;
+
+	when( true ) waitfor( x ) {
+	} or when( true ) else;
+
+	// test when, waitfor and timeout
+
+	waitfor( x );
+	or timeout( 3 );
+
+	waitfor( x, z );
+	or timeout( 3 );
+
+	when( true ) waitfor( x );
+	or timeout( 3 );
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x, z ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when ( true ) timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x, z ) {
+	} or when ( true ) timeout( 3 ) {
+	}
+
+	waitfor( x );
+	or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x );
+	or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) timeout( 3 ) {
+	}
+
+	waitfor( x ) {
+	} or timeout( 3 );
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 );
+
+	when( true ) waitfor( x ) {
+	} or when( true ) timeout( 3 );
+
+	// test when, waitfor, timeout and else
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	// test quasi-keywords "or" and "timeout"
+
+	int or, timeout;
+	waitfor( timeout, 7 ) 3;
+	waitfor( timeout, 7 ) 3; or waitfor( timeout, 7 ) 3;
+	when( or ) waitfor( or, ) { 4; } or timeout( 1 ) 3;
+	when( 3 ) waitfor( or, 2 ) 4; or else 4;
+	when( 3 ) waitfor( or, 3 ) 4; or when( or ) timeout( or ) 4; or when( or ) else timeout;
+	when( 3 ) waitfor( or, or ) 3; or when( or ) waitfor( or, timeout ) 4; or else 4;
+	when( 3 ) waitfor( or, or ) 3; or waitfor( or, 9 ) 4; or when( or ) timeout( timeout ) 4;
+	when( 3 ) waitfor( or, 3 ) 3; or waitfor( or, 7 ) or; or timeout( 1 ) or; or when( 3 ) else or;
+
+	// test else selection
+
+	if ( or > timeout ) waitfor( or ) 3;
+	else waitfor( timeout ) 4;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa waitfor.c" //
+// End: //
