Index: tests/concurrent/coroutineYield.c
===================================================================
--- tests/concurrent/coroutineYield.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,53 +1,0 @@
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#define __kick_rate 150000ul
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-#ifdef TEST_LONG
-static const unsigned long N = 600_000ul;
-#else
-static const unsigned long N = 1_000ul;
-#endif
-
-coroutine Coroutine {};
-
-void main(Coroutine& this) {
-	while(true) {
-		#if !defined(TEST_FOREVER)
-			sout | "Coroutine 1";
-		#endif
-		yield();
-		#if !defined(TEST_FOREVER)
-			sout | "Coroutine 2";
-		#endif
-		suspend();
-	}
-}
-
-
-int main(int argc, char* argv[]) {
-	Coroutine c;
-	for(int i = 0; TEST(i < N); i++) {
-		#if !defined(TEST_FOREVER)
-			sout | "Thread 1";
-		#endif
-		resume(c);
-		#if !defined(TEST_FOREVER)
-			sout | "Thread 2";
-		#endif
-		yield();
-		KICK_WATCHDOG;
-	}
-}
Index: tests/concurrent/coroutineYield.cfa
===================================================================
--- tests/concurrent/coroutineYield.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/coroutineYield.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,53 @@
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#define __kick_rate 150000ul
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10`ms
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+#ifdef TEST_LONG
+static const unsigned long N = 600_000ul;
+#else
+static const unsigned long N = 1_000ul;
+#endif
+
+coroutine Coroutine {};
+
+void main(Coroutine& this) {
+	while(true) {
+		#if !defined(TEST_FOREVER)
+			sout | "Coroutine 1";
+		#endif
+		yield();
+		#if !defined(TEST_FOREVER)
+			sout | "Coroutine 2";
+		#endif
+		suspend();
+	}
+}
+
+
+int main(int argc, char* argv[]) {
+	Coroutine c;
+	for(int i = 0; TEST(i < N); i++) {
+		#if !defined(TEST_FOREVER)
+			sout | "Thread 1";
+		#endif
+		resume(c);
+		#if !defined(TEST_FOREVER)
+			sout | "Thread 2";
+		#endif
+		yield();
+		KICK_WATCHDOG;
+	}
+}
Index: tests/concurrent/examples/boundedBufferEXT.c
===================================================================
--- tests/concurrent/examples/boundedBufferEXT.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,123 +1,0 @@
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// boundedBufferEXT.c --
-//
-// Author           : Peter A. Buhr
-// Created On       : Wed Apr 18 22:52:12 2018
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 11 21:55:02 2018
-// Update Count     : 9
-//
-
-#include <stdlib.hfa>										// random
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <thread.hfa>
-#include <unistd.h>										// getpid
-
-//Duration default_preemption() { return 0; }
-
-enum { BufferSize = 50 };
-
-forall( otype T ) {
-	monitor Buffer {
-		int front, back, count;
-		T elements[BufferSize];
-	}; // Buffer
-
-	void ?{}( Buffer(T) & buffer ) with( buffer ) { [front, back, count] = 0; }
-
-	int query( Buffer(T) & buffer ) { return buffer.count; } // read-only, no mutual exclusion
-
-	T remove( Buffer(T) & mutex buffer );				// forward
-
-	void insert( Buffer(T) & mutex buffer, T elem ) with( buffer ) {
-		if ( count == BufferSize ) waitfor( remove, buffer );
-		elements[back] = elem;
-		back = ( back + 1 ) % BufferSize;
-		count += 1;
-	} // insert
-
-	T remove( Buffer(T) & mutex buffer ) with( buffer ) {
-		if ( count == 0 ) waitfor( insert, buffer );
-		T elem = elements[front];
-		front = ( front + 1 ) % BufferSize;
-		count -= 1;
-		return elem;
-	} // remove
-}
-
-const int Sentinel = -1;
-
-thread Producer {
-	Buffer(int) & buffer;
-	unsigned int N;
-};
-void main( Producer & prod ) with( prod ) {
-	for ( int i = 1; i <= N; i += 1 ) {
-		yield( random( 5 ) );
-		insert( buffer, 1 );
-	} // for
-}
-void ?{}( Producer & prod, Buffer(int) * buffer, int N ) {
-	&prod.buffer = buffer;
-	prod.N = N;
-}
-
-thread Consumer {
-	Buffer(int) & buffer;
-	int & sum;											// summation of producer values
-};
-void main( Consumer & cons ) with( cons ) {
-	sum = 0;
-	for () {
-		yield( random( 5 ) );
-		int item = remove( buffer );
-	  if ( item == Sentinel ) break;					// sentinel ?
-		sum += item;
-	} // for
-}
-void ?{}( Consumer & cons, Buffer(int) * buffer, int & sum ) {
-	&cons.buffer = buffer;
-	&cons.sum = &sum;
-}
-
-int main() {
-	Buffer(int) buffer;
-	enum { Prods = 4, Cons = 5 };
-	Producer * prods[Prods];
-	Consumer * cons[Cons];
-	int sums[Cons];
-	int i;
-	processor p;
-
-	//srandom( getpid() );
-	srandom( 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, 100000 );
-	} // 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;
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// compile-command: "cfa boundedBufferEXT.c" //
-// End: //
Index: tests/concurrent/examples/boundedBufferEXT.cfa
===================================================================
--- tests/concurrent/examples/boundedBufferEXT.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/examples/boundedBufferEXT.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,123 @@
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// boundedBufferEXT.c --
+//
+// Author           : Peter A. Buhr
+// Created On       : Wed Apr 18 22:52:12 2018
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec 11 21:55:02 2018
+// Update Count     : 9
+//
+
+#include <stdlib.hfa>										// random
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <unistd.h>										// getpid
+
+//Duration default_preemption() { return 0; }
+
+enum { BufferSize = 50 };
+
+forall( otype T ) {
+	monitor Buffer {
+		int front, back, count;
+		T elements[BufferSize];
+	}; // Buffer
+
+	void ?{}( Buffer(T) & buffer ) with( buffer ) { [front, back, count] = 0; }
+
+	int query( Buffer(T) & buffer ) { return buffer.count; } // read-only, no mutual exclusion
+
+	T remove( Buffer(T) & mutex buffer );				// forward
+
+	void insert( Buffer(T) & mutex buffer, T elem ) with( buffer ) {
+		if ( count == BufferSize ) waitfor( remove, buffer );
+		elements[back] = elem;
+		back = ( back + 1 ) % BufferSize;
+		count += 1;
+	} // insert
+
+	T remove( Buffer(T) & mutex buffer ) with( buffer ) {
+		if ( count == 0 ) waitfor( insert, buffer );
+		T elem = elements[front];
+		front = ( front + 1 ) % BufferSize;
+		count -= 1;
+		return elem;
+	} // remove
+}
+
+const int Sentinel = -1;
+
+thread Producer {
+	Buffer(int) & buffer;
+	unsigned int N;
+};
+void main( Producer & prod ) with( prod ) {
+	for ( int i = 1; i <= N; i += 1 ) {
+		yield( random( 5 ) );
+		insert( buffer, 1 );
+	} // for
+}
+void ?{}( Producer & prod, Buffer(int) * buffer, int N ) {
+	&prod.buffer = buffer;
+	prod.N = N;
+}
+
+thread Consumer {
+	Buffer(int) & buffer;
+	int & sum;											// summation of producer values
+};
+void main( Consumer & cons ) with( cons ) {
+	sum = 0;
+	for () {
+		yield( random( 5 ) );
+		int item = remove( buffer );
+	  if ( item == Sentinel ) break;					// sentinel ?
+		sum += item;
+	} // for
+}
+void ?{}( Consumer & cons, Buffer(int) * buffer, int & sum ) {
+	&cons.buffer = buffer;
+	&cons.sum = &sum;
+}
+
+int main() {
+	Buffer(int) buffer;
+	enum { Prods = 4, Cons = 5 };
+	Producer * prods[Prods];
+	Consumer * cons[Cons];
+	int sums[Cons];
+	int i;
+	processor p;
+
+	//srandom( getpid() );
+	srandom( 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, 100000 );
+	} // 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;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa boundedBufferEXT.c" //
+// End: //
Index: tests/concurrent/examples/boundedBufferINT.c
===================================================================
--- tests/concurrent/examples/boundedBufferINT.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,124 +1,0 @@
-//
-// 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 : Tue Dec 11 21:55:45 2018
-// Update Count     : 84
-//
-
-#include <stdlib.hfa>										// random
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <thread.hfa>
-#include <unistd.h>										// getpid
-
-//Duration default_preemption() { return 0; }
-
-enum { BufferSize = 50 };
-
-forall( otype T ) {
-	monitor Buffer {
-		condition full, empty;
-		int front, back, count;
-		T elements[BufferSize];
-	}; // Buffer
-
-	void ?{}( Buffer(T) & buffer ) with( buffer ) { [front, back, count] = 0; }
-
-	int query( Buffer(T) & buffer ) { return buffer.count; } // read-only, no mutual exclusion
-
-	void insert( Buffer(T) & mutex buffer, T elem ) with( buffer ) {
-		if ( count == BufferSize ) wait( empty );
-		elements[back] = elem;
-		back = ( back + 1 ) % BufferSize;
-		count += 1;
-		signal( full );
-	} // insert
-
-	T remove( Buffer(T) & mutex buffer ) with( buffer ) {
-		if ( count == 0 ) wait( full );
-		T elem = elements[front];
-		front = ( front + 1 ) % BufferSize;
-		count -= 1;
-		signal( empty );
-		return elem;
-	} // remove
-}
-
-const int Sentinel = -1;
-
-thread Producer {
-	Buffer(int) & buffer;
-	unsigned int N;
-};
-void main( Producer & prod ) with( prod ) {
-	for ( int i = 1; i <= N; i += 1 ) {
-		yield( random( 5 ) );
-		insert( buffer, 1 );
-	} // for
-}
-void ?{}( Producer & prod, Buffer(int) * buffer, int N ) {
-	&prod.buffer = buffer;
-	prod.N = N;
-}
-
-thread Consumer {
-	Buffer(int) & buffer;
-	int & sum;											// summation of producer values
-};
-void main( Consumer & cons ) with( cons ) {
-	sum = 0;
-	for () {
-		yield( random( 5 ) );
-		int item = remove( buffer );
-	  if ( item == Sentinel ) break;					// sentinel ?
-		sum += item;
-	} // for
-}
-void ?{}( Consumer & cons, Buffer(int) * buffer, int & sum ) {
-	&cons.buffer = buffer;
-	&cons.sum = &sum;
-}
-
-int main() {
-	Buffer(int) buffer;
-	enum { Prods = 4, Cons = 5 };
-	Producer * prods[Prods];
-	Consumer * cons[Cons];
-	int sums[Cons];
-	int i;
-	processor p;
-
-	//srandom( getpid() );
-	srandom( 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, 100000 );
-	} // 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;
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// compile-command: "cfa boundedBufferINT.c" //
-// End: //
Index: tests/concurrent/examples/boundedBufferINT.cfa
===================================================================
--- tests/concurrent/examples/boundedBufferINT.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/examples/boundedBufferINT.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,124 @@
+//
+// 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 : Tue Dec 11 21:55:45 2018
+// Update Count     : 84
+//
+
+#include <stdlib.hfa>										// random
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <unistd.h>										// getpid
+
+//Duration default_preemption() { return 0; }
+
+enum { BufferSize = 50 };
+
+forall( otype T ) {
+	monitor Buffer {
+		condition full, empty;
+		int front, back, count;
+		T elements[BufferSize];
+	}; // Buffer
+
+	void ?{}( Buffer(T) & buffer ) with( buffer ) { [front, back, count] = 0; }
+
+	int query( Buffer(T) & buffer ) { return buffer.count; } // read-only, no mutual exclusion
+
+	void insert( Buffer(T) & mutex buffer, T elem ) with( buffer ) {
+		if ( count == BufferSize ) wait( empty );
+		elements[back] = elem;
+		back = ( back + 1 ) % BufferSize;
+		count += 1;
+		signal( full );
+	} // insert
+
+	T remove( Buffer(T) & mutex buffer ) with( buffer ) {
+		if ( count == 0 ) wait( full );
+		T elem = elements[front];
+		front = ( front + 1 ) % BufferSize;
+		count -= 1;
+		signal( empty );
+		return elem;
+	} // remove
+}
+
+const int Sentinel = -1;
+
+thread Producer {
+	Buffer(int) & buffer;
+	unsigned int N;
+};
+void main( Producer & prod ) with( prod ) {
+	for ( int i = 1; i <= N; i += 1 ) {
+		yield( random( 5 ) );
+		insert( buffer, 1 );
+	} // for
+}
+void ?{}( Producer & prod, Buffer(int) * buffer, int N ) {
+	&prod.buffer = buffer;
+	prod.N = N;
+}
+
+thread Consumer {
+	Buffer(int) & buffer;
+	int & sum;											// summation of producer values
+};
+void main( Consumer & cons ) with( cons ) {
+	sum = 0;
+	for () {
+		yield( random( 5 ) );
+		int item = remove( buffer );
+	  if ( item == Sentinel ) break;					// sentinel ?
+		sum += item;
+	} // for
+}
+void ?{}( Consumer & cons, Buffer(int) * buffer, int & sum ) {
+	&cons.buffer = buffer;
+	&cons.sum = &sum;
+}
+
+int main() {
+	Buffer(int) buffer;
+	enum { Prods = 4, Cons = 5 };
+	Producer * prods[Prods];
+	Consumer * cons[Cons];
+	int sums[Cons];
+	int i;
+	processor p;
+
+	//srandom( getpid() );
+	srandom( 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, 100000 );
+	} // 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;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa boundedBufferINT.c" //
+// End: //
Index: tests/concurrent/examples/datingService.c
===================================================================
--- tests/concurrent/examples/datingService.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,113 +1,0 @@
-//
-// 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 : Tue Dec 11 21:55:34 2018
-// Update Count     : 28
-//
-
-#include <stdlib.hfa>										// random
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <thread.hfa>
-#include <unistd.h>										// getpid
-
-enum { CompCodes = 20 };								// number of compatibility codes
-
-monitor DatingService {
-	condition Girls[CompCodes], Boys[CompCodes];
-	unsigned int GirlPhoneNo, BoyPhoneNo;
-}; // DatingService
-
-unsigned int girl( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) with( ds ) {
-	if ( is_empty( Boys[ccode] ) ) {					// no compatible boy ?
-		wait( Girls[ccode] );							// wait for boy
-		GirlPhoneNo = PhoneNo;							// make phone number available
-	} else {
-		GirlPhoneNo = PhoneNo;							// make phone number available
-		signal_block( Boys[ccode] );					// restart boy to set phone number
-	} // if
-	return BoyPhoneNo;
-} // DatingService girl
-
-unsigned int boy( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) with( ds ) {
-	if ( is_empty( Girls[ccode] ) ) {					// no compatible girl ?
-		wait( Boys[ccode] );							// wait for girl
-		BoyPhoneNo = PhoneNo;							// make phone number available
-	} else {
-		BoyPhoneNo = PhoneNo;							// make phone number available
-		signal_block( Girls[ccode] );					// restart girl to set phone number
-	} // if
-	return GirlPhoneNo;
-} // DatingService boy
-
-unsigned int girlck[CompCodes];
-unsigned int boyck[CompCodes];
-
-thread Girl {
-	DatingService & TheExchange;
-	unsigned int id, ccode;
-}; // Girl
-
-void main( Girl & g ) with( g ) {
-	yield( random( 100 ) );								// don't all start at the same time
-	unsigned int partner = girl( TheExchange, id, ccode );
-	sout | "Girl:" | id | "is dating Boy at" | partner | "with ccode" | ccode;
-	girlck[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 ) with( b ) {
-	yield( random( 100 ) );								// don't all start at the same time
-	unsigned int partner = boy( TheExchange, id, ccode );
-	sout | " Boy:" | id | "is dating Girl" | partner | "with ccode" | ccode;
-	boyck[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[CompCodes];
-	Boy  * boys[CompCodes];
-
-	srandom( /*getpid()*/ 103 );
-
-	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
-		girls[i] = new( &TheExchange, i, i );
-		boys[i]  = new( &TheExchange, i, CompCodes - ( i + 1 ) );
-	} // for
-
-	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
-		delete( boys[i] );
-		delete( girls[i] );
-	} // for
-
-	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
-		if ( girlck[ boyck[i] ] != boyck[ girlck[i] ] ) abort();
-	} // for
-} // main
-
-// Local Variables: //
-// tab-width: 4 //
-// compile-command: "cfa datingService.c" //
-// End: //
Index: tests/concurrent/examples/datingService.cfa
===================================================================
--- tests/concurrent/examples/datingService.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/examples/datingService.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,113 @@
+//
+// 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 : Tue Dec 11 21:55:34 2018
+// Update Count     : 28
+//
+
+#include <stdlib.hfa>										// random
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <unistd.h>										// getpid
+
+enum { CompCodes = 20 };								// number of compatibility codes
+
+monitor DatingService {
+	condition Girls[CompCodes], Boys[CompCodes];
+	unsigned int GirlPhoneNo, BoyPhoneNo;
+}; // DatingService
+
+unsigned int girl( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) with( ds ) {
+	if ( is_empty( Boys[ccode] ) ) {					// no compatible boy ?
+		wait( Girls[ccode] );							// wait for boy
+		GirlPhoneNo = PhoneNo;							// make phone number available
+	} else {
+		GirlPhoneNo = PhoneNo;							// make phone number available
+		signal_block( Boys[ccode] );					// restart boy to set phone number
+	} // if
+	return BoyPhoneNo;
+} // DatingService girl
+
+unsigned int boy( DatingService & mutex ds, unsigned int PhoneNo, unsigned int ccode ) with( ds ) {
+	if ( is_empty( Girls[ccode] ) ) {					// no compatible girl ?
+		wait( Boys[ccode] );							// wait for girl
+		BoyPhoneNo = PhoneNo;							// make phone number available
+	} else {
+		BoyPhoneNo = PhoneNo;							// make phone number available
+		signal_block( Girls[ccode] );					// restart girl to set phone number
+	} // if
+	return GirlPhoneNo;
+} // DatingService boy
+
+unsigned int girlck[CompCodes];
+unsigned int boyck[CompCodes];
+
+thread Girl {
+	DatingService & TheExchange;
+	unsigned int id, ccode;
+}; // Girl
+
+void main( Girl & g ) with( g ) {
+	yield( random( 100 ) );								// don't all start at the same time
+	unsigned int partner = girl( TheExchange, id, ccode );
+	sout | "Girl:" | id | "is dating Boy at" | partner | "with ccode" | ccode;
+	girlck[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 ) with( b ) {
+	yield( random( 100 ) );								// don't all start at the same time
+	unsigned int partner = boy( TheExchange, id, ccode );
+	sout | " Boy:" | id | "is dating Girl" | partner | "with ccode" | ccode;
+	boyck[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[CompCodes];
+	Boy  * boys[CompCodes];
+
+	srandom( /*getpid()*/ 103 );
+
+	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
+		girls[i] = new( &TheExchange, i, i );
+		boys[i]  = new( &TheExchange, i, CompCodes - ( i + 1 ) );
+	} // for
+
+	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
+		delete( boys[i] );
+		delete( girls[i] );
+	} // for
+
+	for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
+		if ( girlck[ boyck[i] ] != boyck[ girlck[i] ] ) abort();
+	} // for
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa datingService.c" //
+// End: //
Index: tests/concurrent/examples/matrixSum.c
===================================================================
--- tests/concurrent/examples/matrixSum.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,62 +1,0 @@
-//                               -*- 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.cfa --
-//
-// Author           : Peter A. Buhr
-// Created On       : Mon Oct  9 08:29:28 2017
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 11 21:54:55 2018
-// Update Count     : 15
-//
-
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <thread.hfa>
-
-thread Adder {
-	int * row, cols, & subtotal;						// communication
-};
-
-void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
-	adder.[ row, cols ] = [ row, cols ];				// expression disallowed in multi-member access
-	&adder.subtotal = &subtotal;
-}
-
-void main( Adder & adder ) with( adder ) {				// thread starts here
-	subtotal = 0;
-	for ( c; cols ) {
-		subtotal += row[c];
-	} // for
-}
-
-int main() {
-	/* const */ int rows = 10, cols = 1000;
-	int matrix[rows][cols], subtotals[rows], total = 0;
-	processor p;										// add kernel thread
-
-	for ( r; rows ) {
-		for ( c; cols ) {
-			matrix[r][c] = 1;
-		} // for
-	} // for
-	Adder * adders[rows];
-	for ( r; rows ) {									// start threads to sum rows
-		adders[r] = &(*malloc()){ matrix[r], cols, subtotals[r] };
-//		adders[r] = new( matrix[r], cols, &subtotals[r] );
-	} // for
-	for ( r; rows ) {									// wait for threads to finish
-		delete( adders[r] );
-		total += subtotals[r];							// total subtotals
-	} // for
-	sout | total;
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// compile-command: "cfa matrixSum.cfa" //
-// End: //
Index: tests/concurrent/examples/matrixSum.cfa
===================================================================
--- tests/concurrent/examples/matrixSum.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/examples/matrixSum.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,62 @@
+//                               -*- 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.cfa --
+//
+// Author           : Peter A. Buhr
+// Created On       : Mon Oct  9 08:29:28 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec 11 21:54:55 2018
+// Update Count     : 15
+//
+
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <thread.hfa>
+
+thread Adder {
+	int * row, cols, & subtotal;						// communication
+};
+
+void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
+	adder.[ row, cols ] = [ row, cols ];				// expression disallowed in multi-member access
+	&adder.subtotal = &subtotal;
+}
+
+void main( Adder & adder ) with( adder ) {				// thread starts here
+	subtotal = 0;
+	for ( c; cols ) {
+		subtotal += row[c];
+	} // for
+}
+
+int main() {
+	/* const */ int rows = 10, cols = 1000;
+	int matrix[rows][cols], subtotals[rows], total = 0;
+	processor p;										// add kernel thread
+
+	for ( r; rows ) {
+		for ( c; cols ) {
+			matrix[r][c] = 1;
+		} // for
+	} // for
+	Adder * adders[rows];
+	for ( r; rows ) {									// start threads to sum rows
+		adders[r] = &(*malloc()){ matrix[r], cols, subtotals[r] };
+//		adders[r] = new( matrix[r], cols, &subtotals[r] );
+	} // for
+	for ( r; rows ) {									// wait for threads to finish
+		delete( adders[r] );
+		total += subtotals[r];							// total subtotals
+	} // for
+	sout | total;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa matrixSum.cfa" //
+// End: //
Index: tests/concurrent/examples/quickSort.c
===================================================================
--- tests/concurrent/examples/quickSort.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,181 +1,0 @@
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// quickSort.c -- In-place concurrent quick-sort: threads are created to partition to a specific depth, then sequential
-//		recursive-calls are use to sort each partition.
-//
-// Author           : Peter A. Buhr
-// Created On       : Wed Dec  6 12:15:52 2017
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Dec 22 08:44:27 2018
-// Update Count     : 168
-//
-
-#include <fstream.hfa>
-#include <stdlib.hfa>
-#include <kernel.hfa>
-#include <thread.hfa>
-#include <string.h>										// strcmp
-
-thread Quicksort {
-	int * values;										// communication variables
-	int low, high, depth;
-};
-
-void ?{}( Quicksort & qs, int values[], int size, int depth ) {
-	qs.values = values;  qs.low = 0;  qs.high = size;  qs.depth = depth;
-} // Quicksort
-
-void main( Quicksort & qs ) {							// thread starts here
-	// nested routines: information hiding
-
-	void ?{}( Quicksort & qs, int values[], int low, int high, int depth ) {
-		qs.values = values;  qs.low = low;  qs.high = high;  qs.depth = depth;
-	} // Quicksort
-
-	void sort( int values[], int low, int high, int depth ) {
-		int left, right;								// index to left/right-hand side of the values
-		int pivot;										// pivot value of values
-		int swap;										// temporary
-
-		//verify();										// check for stack overflow due to recursion
-
-		// partition while 2 or more elements in the array
-		if ( low < high ) {
-			pivot = values[low + ( high - low ) / 2];
-			left  = low;
-			right = high;
-
-			// partition: move values less < pivot before the pivot and values > pivot after the pivot
-			do {
-				while ( values[left] < pivot ) left += 1; // changed values[left] < pivot
-				while ( pivot < values[right] ) right -= 1;
-				if ( left <= right ) {
-					swap = values[left];				// interchange values
-					values[left]  = values[right];
-					values[right] = swap;
-					left += 1;
-					right -= 1;
-				} // if
-			} while ( left <= right );
-
-			// restrict number of tasks to slightly greater than number of processors
-			if ( depth > 0 ) {
-				depth -= 1;
-				Quicksort rqs = { values, low, right, depth }; // concurrently sort upper half
-				//Quicksort lqs( values, left, high, depth ); // concurrently sort lower half
-				sort( values, left, high, depth );		// concurrently sort lower half
-			} else {
-				sort( values, low, right, 0 );			// sequentially sort lower half
-				sort( values, left, high, 0 );			// sequentially sort upper half
-			} // if
-		} // if
-	} // sort
-
-	with( qs ) {
-		sort( values, low, high, depth );
-	} // with
-} // main
-
-
-bool convert( int & val, const char * nptr ) {			// convert C string to integer
-	char * eptr;
-	int temp = strto( nptr, &eptr, 10 );				// do not change val on false
-	// true => entire string valid with no extra characters
-	return *nptr != '\0' && *eptr == '\0' ? val = temp, true : false;
-} // convert
-
-void usage( char * argv[] ) {
-	sout | "Usage:" | argv[0] | "( -s unsorted-file [ sorted-file ] | -t size (>= 0) [ depth (>= 0) ] )";
-	exit( EXIT_FAILURE );								// TERMINATE!
-} // usage
-
-
-int main( int argc, char * argv[] ) {
-	ifstream & unsortedfile = sin;
-	ofstream & sortedfile = sout;						// default value
-	int depth = 0, size;
-
-	if ( argc != 1 ) {									// do not use defaults
-		if ( argc < 2 || argc > 4 ) usage( argv );		// wrong number of options
-		if ( strcmp( argv[1], "-t" ) == 0 ) {			// timing ?
-			&unsortedfile = (ifstream *)0;				// no input
-			choose ( argc ) {
-			  case 4:
-				if ( ! convert( depth, argv[3] ) || depth < 0 ) usage( argv );
-				fallthrough;
-			  case 3:
-				if ( ! convert( size, argv[2] ) || size < 0 ) usage( argv );
-			} // choose
-		} else {										// sort file
-			choose ( argc ) {
-			  case 3:
-				&sortedfile = new( (const char *)argv[2] ); // open the output file
-				if ( fail( sortedfile ) ) {
-					serr | "Error! Could not open sorted output file \"" | argv[2] | "\"";
-					usage( argv );
-				} // if
-				fallthrough;
-			  case 2:
-				&unsortedfile = new( (const char *)argv[1] ); // open the input file
-				if ( fail( unsortedfile ) ) {
-					serr | "Error! Could not open unsorted input file \"" | argv[1] | "\"";
-					usage( argv );
-				} // if
-			} // choose
-		} // if
-	} // if
-	sortedfile | nlOff;									// turn off auto newline
-
-	enum { ValuesPerLine = 22 };						// number of values printed per line
-
-	if ( &unsortedfile ) {								// generate output ?
-		for () {
-			unsortedfile | size;						// read number of elements in the list
-		  if ( eof( unsortedfile ) ) break;
-			int * values = alloc( size );				// values to be sorted, too large to put on stack
-			for ( int counter = 0; counter < size; counter += 1 ) { // read unsorted numbers
-				unsortedfile | values[counter];
-				if ( counter != 0 && counter % ValuesPerLine == 0 ) sortedfile | nl | "  ";
-				sortedfile | values[counter];
-				if ( counter < size - 1 && (counter + 1) % ValuesPerLine != 0 ) sortedfile | ' ';
-			} // for
-			sortedfile | nl;
-			if ( size > 0 ) {							// values to sort ?
-				Quicksort QS = { values, size - 1, 0 }; // sort values
-			} // wait until sort tasks terminate
-			for ( int counter = 0; counter < size; counter += 1 ) { // print sorted list
-				if ( counter != 0 && counter % ValuesPerLine == 0 ) sortedfile | nl | "  ";
-				sortedfile | values[counter];
-				if ( counter < size - 1 && (counter + 1) % ValuesPerLine != 0 ) sortedfile | ' ';
-			} // for
-			sortedfile | nl | nl;
-
-			delete( values );
-		} // for
-		if ( &unsortedfile != &sin ) delete( &unsortedfile ); // close input/output files
-		if ( &sortedfile != &sout ) delete( &sortedfile );
-	} else {
-		processor processors[ (1 << depth) - 1 ] __attribute__(( unused )); // create 2^depth-1 kernel threads
-
-		int * values = alloc( size );				// values to be sorted, too large to put on stack
-		for ( int counter = 0; counter < size; counter += 1 ) { // generate unsorted numbers
-			values[counter] = size - counter;			// descending values
-		} // for
-		{
-			Quicksort QS = { values, size - 1, depth }; // sort values
-		} // wait until sort tasks terminate
-
-		// for ( int counter = 0; counter < size - 1; counter += 1 ) { // check sorting
-		// 	if ( values[counter] > values[counter + 1] ) abort();
-		// } // for
-
-		delete( values );
-	} // if
-} // main
-
-// Local Variables: //
-// tab-width: 4 //
-// compile-command: "cfa quickSort.c" //
-// End: //
Index: tests/concurrent/examples/quickSort.cfa
===================================================================
--- tests/concurrent/examples/quickSort.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/examples/quickSort.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,181 @@
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// quickSort.c -- In-place concurrent quick-sort: threads are created to partition to a specific depth, then sequential
+//		recursive-calls are use to sort each partition.
+//
+// Author           : Peter A. Buhr
+// Created On       : Wed Dec  6 12:15:52 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Dec 22 08:44:27 2018
+// Update Count     : 168
+//
+
+#include <fstream.hfa>
+#include <stdlib.hfa>
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <string.h>										// strcmp
+
+thread Quicksort {
+	int * values;										// communication variables
+	int low, high, depth;
+};
+
+void ?{}( Quicksort & qs, int values[], int size, int depth ) {
+	qs.values = values;  qs.low = 0;  qs.high = size;  qs.depth = depth;
+} // Quicksort
+
+void main( Quicksort & qs ) {							// thread starts here
+	// nested routines: information hiding
+
+	void ?{}( Quicksort & qs, int values[], int low, int high, int depth ) {
+		qs.values = values;  qs.low = low;  qs.high = high;  qs.depth = depth;
+	} // Quicksort
+
+	void sort( int values[], int low, int high, int depth ) {
+		int left, right;								// index to left/right-hand side of the values
+		int pivot;										// pivot value of values
+		int swap;										// temporary
+
+		//verify();										// check for stack overflow due to recursion
+
+		// partition while 2 or more elements in the array
+		if ( low < high ) {
+			pivot = values[low + ( high - low ) / 2];
+			left  = low;
+			right = high;
+
+			// partition: move values less < pivot before the pivot and values > pivot after the pivot
+			do {
+				while ( values[left] < pivot ) left += 1; // changed values[left] < pivot
+				while ( pivot < values[right] ) right -= 1;
+				if ( left <= right ) {
+					swap = values[left];				// interchange values
+					values[left]  = values[right];
+					values[right] = swap;
+					left += 1;
+					right -= 1;
+				} // if
+			} while ( left <= right );
+
+			// restrict number of tasks to slightly greater than number of processors
+			if ( depth > 0 ) {
+				depth -= 1;
+				Quicksort rqs = { values, low, right, depth }; // concurrently sort upper half
+				//Quicksort lqs( values, left, high, depth ); // concurrently sort lower half
+				sort( values, left, high, depth );		// concurrently sort lower half
+			} else {
+				sort( values, low, right, 0 );			// sequentially sort lower half
+				sort( values, left, high, 0 );			// sequentially sort upper half
+			} // if
+		} // if
+	} // sort
+
+	with( qs ) {
+		sort( values, low, high, depth );
+	} // with
+} // main
+
+
+bool convert( int & val, const char * nptr ) {			// convert C string to integer
+	char * eptr;
+	int temp = strto( nptr, &eptr, 10 );				// do not change val on false
+	// true => entire string valid with no extra characters
+	return *nptr != '\0' && *eptr == '\0' ? val = temp, true : false;
+} // convert
+
+void usage( char * argv[] ) {
+	sout | "Usage:" | argv[0] | "( -s unsorted-file [ sorted-file ] | -t size (>= 0) [ depth (>= 0) ] )";
+	exit( EXIT_FAILURE );								// TERMINATE!
+} // usage
+
+
+int main( int argc, char * argv[] ) {
+	ifstream & unsortedfile = sin;
+	ofstream & sortedfile = sout;						// default value
+	int depth = 0, size;
+
+	if ( argc != 1 ) {									// do not use defaults
+		if ( argc < 2 || argc > 4 ) usage( argv );		// wrong number of options
+		if ( strcmp( argv[1], "-t" ) == 0 ) {			// timing ?
+			&unsortedfile = (ifstream *)0;				// no input
+			choose ( argc ) {
+			  case 4:
+				if ( ! convert( depth, argv[3] ) || depth < 0 ) usage( argv );
+				fallthrough;
+			  case 3:
+				if ( ! convert( size, argv[2] ) || size < 0 ) usage( argv );
+			} // choose
+		} else {										// sort file
+			choose ( argc ) {
+			  case 3:
+				&sortedfile = new( (const char *)argv[2] ); // open the output file
+				if ( fail( sortedfile ) ) {
+					serr | "Error! Could not open sorted output file \"" | argv[2] | "\"";
+					usage( argv );
+				} // if
+				fallthrough;
+			  case 2:
+				&unsortedfile = new( (const char *)argv[1] ); // open the input file
+				if ( fail( unsortedfile ) ) {
+					serr | "Error! Could not open unsorted input file \"" | argv[1] | "\"";
+					usage( argv );
+				} // if
+			} // choose
+		} // if
+	} // if
+	sortedfile | nlOff;									// turn off auto newline
+
+	enum { ValuesPerLine = 22 };						// number of values printed per line
+
+	if ( &unsortedfile ) {								// generate output ?
+		for () {
+			unsortedfile | size;						// read number of elements in the list
+		  if ( eof( unsortedfile ) ) break;
+			int * values = alloc( size );				// values to be sorted, too large to put on stack
+			for ( int counter = 0; counter < size; counter += 1 ) { // read unsorted numbers
+				unsortedfile | values[counter];
+				if ( counter != 0 && counter % ValuesPerLine == 0 ) sortedfile | nl | "  ";
+				sortedfile | values[counter];
+				if ( counter < size - 1 && (counter + 1) % ValuesPerLine != 0 ) sortedfile | ' ';
+			} // for
+			sortedfile | nl;
+			if ( size > 0 ) {							// values to sort ?
+				Quicksort QS = { values, size - 1, 0 }; // sort values
+			} // wait until sort tasks terminate
+			for ( int counter = 0; counter < size; counter += 1 ) { // print sorted list
+				if ( counter != 0 && counter % ValuesPerLine == 0 ) sortedfile | nl | "  ";
+				sortedfile | values[counter];
+				if ( counter < size - 1 && (counter + 1) % ValuesPerLine != 0 ) sortedfile | ' ';
+			} // for
+			sortedfile | nl | nl;
+
+			delete( values );
+		} // for
+		if ( &unsortedfile != &sin ) delete( &unsortedfile ); // close input/output files
+		if ( &sortedfile != &sout ) delete( &sortedfile );
+	} else {
+		processor processors[ (1 << depth) - 1 ] __attribute__(( unused )); // create 2^depth-1 kernel threads
+
+		int * values = alloc( size );				// values to be sorted, too large to put on stack
+		for ( int counter = 0; counter < size; counter += 1 ) { // generate unsorted numbers
+			values[counter] = size - counter;			// descending values
+		} // for
+		{
+			Quicksort QS = { values, size - 1, depth }; // sort values
+		} // wait until sort tasks terminate
+
+		// for ( int counter = 0; counter < size - 1; counter += 1 ) { // check sorting
+		// 	if ( values[counter] > values[counter + 1] ) abort();
+		// } // for
+
+		delete( values );
+	} // if
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa quickSort.c" //
+// End: //
Index: tests/concurrent/monitor.c
===================================================================
--- tests/concurrent/monitor.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,43 +1,0 @@
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <thread.hfa>
-
-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;
-}
Index: tests/concurrent/monitor.cfa
===================================================================
--- tests/concurrent/monitor.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/monitor.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,43 @@
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <thread.hfa>
+
+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;
+}
Index: tests/concurrent/multi-monitor.c
===================================================================
--- tests/concurrent/multi-monitor.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,55 +1,0 @@
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <thread.hfa>
-
-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;
-}
Index: tests/concurrent/multi-monitor.cfa
===================================================================
--- tests/concurrent/multi-monitor.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/multi-monitor.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,55 @@
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <thread.hfa>
+
+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;
+}
Index: tests/concurrent/preempt.c
===================================================================
--- tests/concurrent/preempt.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,59 +1,0 @@
-#include <kernel.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-#ifdef TEST_LONG
-static const unsigned long N = 30_000ul;
-#else
-static const unsigned long N = 500ul;
-#endif
-
-extern void __cfaabi_check_preemption();
-
-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(TEST(counter < N)) {
-		__cfaabi_check_preemption();
-		if( (counter % 7) == this.value ) {
-			__cfaabi_check_preemption();
-			int next = __atomic_add_fetch_4(&counter, 1, __ATOMIC_SEQ_CST);
-			__cfaabi_check_preemption();
-			if( (next % 100) == 0 ) printf("%d\n", (int)next);
-			__cfaabi_check_preemption();
-		}
-		__cfaabi_check_preemption();
-		KICK_WATCHDOG;
-	}
-}
-
-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: tests/concurrent/preempt.cfa
===================================================================
--- tests/concurrent/preempt.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/preempt.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,59 @@
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10`ms
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+#ifdef TEST_LONG
+static const unsigned long N = 30_000ul;
+#else
+static const unsigned long N = 500ul;
+#endif
+
+extern void __cfaabi_check_preemption();
+
+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(TEST(counter < N)) {
+		__cfaabi_check_preemption();
+		if( (counter % 7) == this.value ) {
+			__cfaabi_check_preemption();
+			int next = __atomic_add_fetch_4(&counter, 1, __ATOMIC_SEQ_CST);
+			__cfaabi_check_preemption();
+			if( (next % 100) == 0 ) printf("%d\n", (int)next);
+			__cfaabi_check_preemption();
+		}
+		__cfaabi_check_preemption();
+		KICK_WATCHDOG;
+	}
+}
+
+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: tests/concurrent/signal/block.c
===================================================================
--- tests/concurrent/signal/block.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,139 +1,0 @@
-//---------------------------------------------------------
-// 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.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-#ifdef TEST_LONG
-static const unsigned long N = 150_000ul;
-#else
-static const unsigned long N = 5_000ul;
-#endif
-
-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 & mutex 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)active_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;
-		abort();
-	}
-
-	a.last_thread = b.last_thread = active_thread();
-
-	yield( random( 10 ) );
-}
-
-thread Waiter {};
-void main( Waiter & this ) {
-	for( int i = 0; TEST(i < N); i++ ) {
-		wait_op( globalA, globalB, i );
-		KICK_WATCHDOG;
-	}
-}
-
-//------------------------------------------------------------------------------
-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] = active_thread();
-
-	if( !is_empty( cond ) ) {
-
-		thread_desc * next = front( cond );
-
-		if( ! signal_block( cond ) ) {
-			sout | "ERROR expected to be able to signal";
-			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;
-			abort();
-		}
-	}
-
-}
-
-thread Signaller {};
-void main( Signaller & this ) {
-	while( !done ) {
-		signal_op( globalA, globalB );
-	}
-}
-
-//------------------------------------------------------------------------------
-void barge_op( global_data_t & mutex a ) {
-	a.last_thread = active_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[]) {
-	srandom( time( NULL ) );
-	done = false;
-	processor p;
-	{
-		Signaller s[4];
-		Barger b[13];
-		sout | "Starting waiters";
-		{
-			Waiter w[3];
-		}
-		sout | "Waiters done";
-		done = true;
-	}
-}
Index: tests/concurrent/signal/block.cfa
===================================================================
--- tests/concurrent/signal/block.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/signal/block.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,139 @@
+//---------------------------------------------------------
+// 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.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10`ms
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+#ifdef TEST_LONG
+static const unsigned long N = 150_000ul;
+#else
+static const unsigned long N = 5_000ul;
+#endif
+
+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 & mutex 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)active_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;
+		abort();
+	}
+
+	a.last_thread = b.last_thread = active_thread();
+
+	yield( random( 10 ) );
+}
+
+thread Waiter {};
+void main( Waiter & this ) {
+	for( int i = 0; TEST(i < N); i++ ) {
+		wait_op( globalA, globalB, i );
+		KICK_WATCHDOG;
+	}
+}
+
+//------------------------------------------------------------------------------
+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] = active_thread();
+
+	if( !is_empty( cond ) ) {
+
+		thread_desc * next = front( cond );
+
+		if( ! signal_block( cond ) ) {
+			sout | "ERROR expected to be able to signal";
+			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;
+			abort();
+		}
+	}
+
+}
+
+thread Signaller {};
+void main( Signaller & this ) {
+	while( !done ) {
+		signal_op( globalA, globalB );
+	}
+}
+
+//------------------------------------------------------------------------------
+void barge_op( global_data_t & mutex a ) {
+	a.last_thread = active_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[]) {
+	srandom( time( NULL ) );
+	done = false;
+	processor p;
+	{
+		Signaller s[4];
+		Barger b[13];
+		sout | "Starting waiters";
+		{
+			Waiter w[3];
+		}
+		sout | "Waiters done";
+		done = true;
+	}
+}
Index: tests/concurrent/signal/disjoint.c
===================================================================
--- tests/concurrent/signal/disjoint.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,129 +1,0 @@
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-#ifdef TEST_LONG
-static const unsigned long N = 300_000ul;
-#else
-static const unsigned long N = 10_000ul;
-#endif
-
-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 & mutex 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 & mutex 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!";
-	}
-
-	#if !defined(TEST_FOREVER)
-		d.counter++;
-		if( (d.counter % 1000) == 0 ) sout | d.counter;
-	#endif
-
-	return TEST(d.counter < N);
-}
-
-thread Waiter {};
-
-void main( Waiter & this ) {
-	while( wait( mut, data ) ) { KICK_WATCHDOG; 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 = TEST(data.counter < N) && data.counter > 0;
-	if( data.state != SIGNAL && running ) {
-		sout | "ERROR Eager signal" | data.state;
-	}
-}
-
-thread Signaller {};
-
-void main( Signaller & this ) {
-	while( !all_done ) {
-		logic( mut );
-		yield();
-	}
-}
-
-//------------------------------------------------------------------------------
-// Main loop
-int main(int argc, char* argv[]) {
-	srandom( time( NULL ) );
-	all_done = false;
-	processor p;
-	{
-		Signaller s;
-		Barger b[17];
-		{
-			Waiter w[4];
-		}
-		sout | "All waiter done";
-		all_done = true;
-	}
-}
Index: tests/concurrent/signal/disjoint.cfa
===================================================================
--- tests/concurrent/signal/disjoint.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/signal/disjoint.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,129 @@
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10`ms
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+#ifdef TEST_LONG
+static const unsigned long N = 300_000ul;
+#else
+static const unsigned long N = 10_000ul;
+#endif
+
+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 & mutex 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 & mutex 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!";
+	}
+
+	#if !defined(TEST_FOREVER)
+		d.counter++;
+		if( (d.counter % 1000) == 0 ) sout | d.counter;
+	#endif
+
+	return TEST(d.counter < N);
+}
+
+thread Waiter {};
+
+void main( Waiter & this ) {
+	while( wait( mut, data ) ) { KICK_WATCHDOG; 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 = TEST(data.counter < N) && data.counter > 0;
+	if( data.state != SIGNAL && running ) {
+		sout | "ERROR Eager signal" | data.state;
+	}
+}
+
+thread Signaller {};
+
+void main( Signaller & this ) {
+	while( !all_done ) {
+		logic( mut );
+		yield();
+	}
+}
+
+//------------------------------------------------------------------------------
+// Main loop
+int main(int argc, char* argv[]) {
+	srandom( time( NULL ) );
+	all_done = false;
+	processor p;
+	{
+		Signaller s;
+		Barger b[17];
+		{
+			Waiter w[4];
+		}
+		sout | "All waiter done";
+		all_done = true;
+	}
+}
Index: tests/concurrent/signal/wait.c
===================================================================
--- tests/concurrent/signal/wait.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,153 +1,0 @@
-//---------------------------------------------------------
-// Multi wait test
-// Ensures that no deadlock from waiting/signalling conditions
-//---------------------------------------------------------
-
-
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#define __kick_rate 12000ul
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-#ifdef TEST_LONG
-static const unsigned long N = 375_000ul;
-#else
-static const unsigned long N = 2_500ul;
-#endif
-
-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";
-				abort();
-		}
-		yield();
-	}
-}
-
-//----------------------------------------------------------------------------------------------------
-// Waiter ABC
-void main( WaiterABC & this ) {
-	for( int i = 0; TEST(i < N); i++ ) {
-		wait( condABC, globalA, globalB, globalC );
-		KICK_WATCHDOG;
-	}
-
-	__sync_fetch_and_sub_4( &waiter_left, 1);
-}
-
-//----------------------------------------------------------------------------------------------------
-// Waiter AB
-void main( WaiterAB & this ) {
-	for( int i = 0; TEST(i < N); i++ ) {
-		wait( condAB , globalA, globalB );
-		KICK_WATCHDOG;
-	}
-
-	__sync_fetch_and_sub_4( &waiter_left, 1);
-}
-
-//----------------------------------------------------------------------------------------------------
-// Waiter AC
-void main( WaiterAC & this ) {
-	for( int i = 0; TEST(i < N); i++ ) {
-		wait( condAC , globalA, globalC );
-		KICK_WATCHDOG;
-	}
-
-	__sync_fetch_and_sub_4( &waiter_left, 1);
-}
-
-//----------------------------------------------------------------------------------------------------
-// Waiter BC
-void main( WaiterBC & this ) {
-	for( int i = 0; TEST(i < N); i++ ) {
-		wait( condBC , globalB, globalC );
-		KICK_WATCHDOG;
-	}
-
-	__sync_fetch_and_sub_4( &waiter_left, 1);
-}
-
-//----------------------------------------------------------------------------------------------------
-// Main
-int main(int argc, char* argv[]) {
-	srandom( time( NULL ) );
-	waiter_left = 4;
-	processor p[2];
-	sout | "Starting";
-	{
-		Signaler  e;
-		{
-			WaiterABC a;
-			WaiterAB  b;
-			WaiterBC  c;
-			WaiterAC  d;
-		}
-	}
-	sout | "Done";
-}
Index: tests/concurrent/signal/wait.cfa
===================================================================
--- tests/concurrent/signal/wait.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/signal/wait.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,153 @@
+//---------------------------------------------------------
+// Multi wait test
+// Ensures that no deadlock from waiting/signalling conditions
+//---------------------------------------------------------
+
+
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#define __kick_rate 12000ul
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10`ms
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+#ifdef TEST_LONG
+static const unsigned long N = 375_000ul;
+#else
+static const unsigned long N = 2_500ul;
+#endif
+
+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";
+				abort();
+		}
+		yield();
+	}
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter ABC
+void main( WaiterABC & this ) {
+	for( int i = 0; TEST(i < N); i++ ) {
+		wait( condABC, globalA, globalB, globalC );
+		KICK_WATCHDOG;
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter AB
+void main( WaiterAB & this ) {
+	for( int i = 0; TEST(i < N); i++ ) {
+		wait( condAB , globalA, globalB );
+		KICK_WATCHDOG;
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter AC
+void main( WaiterAC & this ) {
+	for( int i = 0; TEST(i < N); i++ ) {
+		wait( condAC , globalA, globalC );
+		KICK_WATCHDOG;
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Waiter BC
+void main( WaiterBC & this ) {
+	for( int i = 0; TEST(i < N); i++ ) {
+		wait( condBC , globalB, globalC );
+		KICK_WATCHDOG;
+	}
+
+	__sync_fetch_and_sub_4( &waiter_left, 1);
+}
+
+//----------------------------------------------------------------------------------------------------
+// Main
+int main(int argc, char* argv[]) {
+	srandom( time( NULL ) );
+	waiter_left = 4;
+	processor p[2];
+	sout | "Starting";
+	{
+		Signaler  e;
+		{
+			WaiterABC a;
+			WaiterAB  b;
+			WaiterBC  c;
+			WaiterAC  d;
+		}
+	}
+	sout | "Done";
+}
Index: tests/concurrent/thread.c
===================================================================
--- tests/concurrent/thread.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-thread First  { semaphore* lock; };
-thread Second { semaphore* lock; };
-
-void ?{}( First  & this, semaphore & lock ) { ((thread&)this){"Thread 1"}; this.lock = &lock; }
-void ?{}( Second & this, semaphore & lock ) { ((thread&)this){"Thread 2"}; this.lock = &lock; }
-
-void main(First& this) {
-	for(int i = 0; i < 10; i++) {
-		sout | "First : Suspend No." | i + 1;
-		yield();
-	}
-	V(*this.lock);
-}
-
-void main(Second& this) {
-	P(*this.lock);
-	for(int i = 0; i < 10; i++) {
-		sout | "Second : Suspend No." | i + 1;
-		yield();
-	}
-}
-
-
-int main(int argc, char* argv[]) {
-	semaphore lock = { 0 };
-	sout | "User main begin";
-	{
-		processor p;
-		{
-			First  f = { lock };
-			Second s = { lock };
-		}
-	}
-	sout | "User main end";
-}
Index: tests/concurrent/thread.cfa
===================================================================
--- tests/concurrent/thread.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/thread.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,40 @@
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+
+thread First  { semaphore* lock; };
+thread Second { semaphore* lock; };
+
+void ?{}( First  & this, semaphore & lock ) { ((thread&)this){"Thread 1"}; this.lock = &lock; }
+void ?{}( Second & this, semaphore & lock ) { ((thread&)this){"Thread 2"}; this.lock = &lock; }
+
+void main(First& this) {
+	for(int i = 0; i < 10; i++) {
+		sout | "First : Suspend No." | i + 1;
+		yield();
+	}
+	V(*this.lock);
+}
+
+void main(Second& this) {
+	P(*this.lock);
+	for(int i = 0; i < 10; i++) {
+		sout | "Second : Suspend No." | i + 1;
+		yield();
+	}
+}
+
+
+int main(int argc, char* argv[]) {
+	semaphore lock = { 0 };
+	sout | "User main begin";
+	{
+		processor p;
+		{
+			First  f = { lock };
+			Second s = { lock };
+		}
+	}
+	sout | "User main end";
+}
Index: tests/concurrent/waitfor/barge.c
===================================================================
--- tests/concurrent/waitfor/barge.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,92 +1,0 @@
-//---------------------------------------------------------
-// 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.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-#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";
-	}
-
-	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;
-		}
-
-		if( this.state != CALL ) {
-			serr | "Barging after caller detected";
-		}
-	}
-
-	this.done = true;
-}
-
-thread waiter_t{};
-void main( waiter_t & this ) {
-	do_wait(global);
-}
-
-int main() {
-	sout | "Starting";
-	{
-		barger_t bargers[17];
-		caller_t callers[7];
-		waiter_t waiters;
-	}
-	sout | "Stopping";
-}
Index: tests/concurrent/waitfor/barge.cfa
===================================================================
--- tests/concurrent/waitfor/barge.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/barge.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -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.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+
+#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";
+	}
+
+	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;
+		}
+
+		if( this.state != CALL ) {
+			serr | "Barging after caller detected";
+		}
+	}
+
+	this.done = true;
+}
+
+thread waiter_t{};
+void main( waiter_t & this ) {
+	do_wait(global);
+}
+
+int main() {
+	sout | "Starting";
+	{
+		barger_t bargers[17];
+		caller_t callers[7];
+		waiter_t waiters;
+	}
+	sout | "Stopping";
+}
Index: tests/concurrent/waitfor/dtor.c
===================================================================
--- tests/concurrent/waitfor/dtor.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,63 +1,0 @@
-//---------------------------------------------------------
-// Barging test
-// Ensures the statement order is reverse when using waitfor ^?{}
-//---------------------------------------------------------
-
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-#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" ; abort(); } this.state = state; break;
-		case AFTER : if( this.state != MAIN  ) { serr | "ERROR Expected state to be MAIN" ; abort(); } this.state = state; break;
-		case END   : if( this.state != AFTER ) { serr | "ERROR Expected state to be AFTER"; abort(); } this.state = state; break;
-		case DTOR  : if( this.state != END   ) { serr | "ERROR Expected state to be END"  ; 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";
-	processor p;
-	for( int i = 0; i < N; i++ ){
-		dummy_t dummy[4];
-		yield( random( 100 ) );
-	}
-	sout | "Stopping";
-}
Index: tests/concurrent/waitfor/dtor.cfa
===================================================================
--- tests/concurrent/waitfor/dtor.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/dtor.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,63 @@
+//---------------------------------------------------------
+// Barging test
+// Ensures the statement order is reverse when using waitfor ^?{}
+//---------------------------------------------------------
+
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+
+#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" ; abort(); } this.state = state; break;
+		case AFTER : if( this.state != MAIN  ) { serr | "ERROR Expected state to be MAIN" ; abort(); } this.state = state; break;
+		case END   : if( this.state != AFTER ) { serr | "ERROR Expected state to be AFTER"; abort(); } this.state = state; break;
+		case DTOR  : if( this.state != END   ) { serr | "ERROR Expected state to be END"  ; 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";
+	processor p;
+	for( int i = 0; i < N; i++ ){
+		dummy_t dummy[4];
+		yield( random( 100 ) );
+	}
+	sout | "Stopping";
+}
Index: tests/concurrent/waitfor/else.c
===================================================================
--- tests/concurrent/waitfor/else.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,48 +1,0 @@
-#include <fstream.hfa>
-#include <monitor.hfa>
-
-#include <stdbool.h>
-
-monitor M {};
-
-void notcalled( M & mutex m ) {
-	abort();
-}
-
-void test( M & mutex m ) {
-	int i = 0;
-	sout | "Starting";
-
-	when( false ) waitfor( notcalled, m );
-
-	sout | "Step" | i++;
-
-	waitfor( notcalled, m ); or else {
-		sout | "else called";
-	}
-
-	sout | "Step" | i++;
-
-	when( true ) waitfor( notcalled, m ); or when( true ) else {
-		sout | "else called";
-	}
-
-	sout | "Step" | i++;
-
-	when( false ) waitfor( notcalled, m ); or when( true ) else {
-		sout | "else called";
-	}
-
-	sout | "Step" | i++;
-
-	when( false ) waitfor( notcalled, m ); or when( false ) else {
-		sout | "else called";
-	}
-
-	sout | "Done";
-}
-
-int main() {
-	M m;
-	test(m);
-}
Index: tests/concurrent/waitfor/else.cfa
===================================================================
--- tests/concurrent/waitfor/else.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/else.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,48 @@
+#include <fstream.hfa>
+#include <monitor.hfa>
+
+#include <stdbool.h>
+
+monitor M {};
+
+void notcalled( M & mutex m ) {
+	abort();
+}
+
+void test( M & mutex m ) {
+	int i = 0;
+	sout | "Starting";
+
+	when( false ) waitfor( notcalled, m );
+
+	sout | "Step" | i++;
+
+	waitfor( notcalled, m ); or else {
+		sout | "else called";
+	}
+
+	sout | "Step" | i++;
+
+	when( true ) waitfor( notcalled, m ); or when( true ) else {
+		sout | "else called";
+	}
+
+	sout | "Step" | i++;
+
+	when( false ) waitfor( notcalled, m ); or when( true ) else {
+		sout | "else called";
+	}
+
+	sout | "Step" | i++;
+
+	when( false ) waitfor( notcalled, m ); or when( false ) else {
+		sout | "else called";
+	}
+
+	sout | "Done";
+}
+
+int main() {
+	M m;
+	test(m);
+}
Index: tests/concurrent/waitfor/parse.c
===================================================================
--- tests/concurrent/waitfor/parse.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,104 +1,0 @@
-//----------------------------------------------------------------------------------------
-//----------------------------------------------------------------------------------------
-//
-//		DEPRECATED TEST
-//		DIFFERS BETWEEN DEBUG AND RELEASE
-//
-//----------------------------------------------------------------------------------------
-//----------------------------------------------------------------------------------------
-
-#include <monitor.hfa>
-
-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: tests/concurrent/waitfor/parse.cfa
===================================================================
--- tests/concurrent/waitfor/parse.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/parse.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,104 @@
+//----------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------
+//
+//		DEPRECATED TEST
+//		DIFFERS BETWEEN DEBUG AND RELEASE
+//
+//----------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------
+
+#include <monitor.hfa>
+
+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: tests/concurrent/waitfor/parse2.c
===================================================================
--- tests/concurrent/waitfor/parse2.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,249 +1,0 @@
-// 
-// 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: //
Index: tests/concurrent/waitfor/parse2.cfa
===================================================================
--- tests/concurrent/waitfor/parse2.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/parse2.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -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: //
Index: tests/concurrent/waitfor/recurse.c
===================================================================
--- tests/concurrent/waitfor/recurse.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,146 +1,0 @@
-//----------------------------------------------------------------
-// Recursion test
-// Ensures that proper ordering occurs between the nested waitfors
-//-----------------------------------------------------------------
-
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-#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" | nl;
-
-	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" | nl;
-		}
-	}
-}
-
-static waiter_t * volatile the_threads;
-
-int main() {
-	srandom( time(NULL) );
-	sout | nlOff;					// turn off auto newline
-	sout | "Starting" | nl;
-	{
-		waiter_t waiters[4] = {
-			{ 0, FIRST  },
-			{ 1, SECOND },
-			{ 2, THIRD  },
-			{ 3, LAST   }
-		};
-		the_threads = waiters;
-	}
-	sout | "Stopping" | nl;
-}
Index: tests/concurrent/waitfor/recurse.cfa
===================================================================
--- tests/concurrent/waitfor/recurse.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/recurse.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,146 @@
+//----------------------------------------------------------------
+// Recursion test
+// Ensures that proper ordering occurs between the nested waitfors
+//-----------------------------------------------------------------
+
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+
+#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" | nl;
+
+	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" | nl;
+		}
+	}
+}
+
+static waiter_t * volatile the_threads;
+
+int main() {
+	srandom( time(NULL) );
+	sout | nlOff;					// turn off auto newline
+	sout | "Starting" | nl;
+	{
+		waiter_t waiters[4] = {
+			{ 0, FIRST  },
+			{ 1, SECOND },
+			{ 2, THIRD  },
+			{ 3, LAST   }
+		};
+		the_threads = waiters;
+	}
+	sout | "Stopping" | nl;
+}
Index: tests/concurrent/waitfor/simple.c
===================================================================
--- tests/concurrent/waitfor/simple.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,85 +1,0 @@
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-#include <time.h>
-
-static const unsigned long N = 500ul;
-
-#ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
-#endif
-
-Duration 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";
-	yield( random( 10 ) );
-
-	sout | "Accepting";
-
-	__acceptable_t acceptable;
-	acceptable.func          = (fptr_t)do_notify;
-	acceptable.count         = 1;
-	acceptable.monitors      = &a;
-
-	__waitfor_internal( 1, &acceptable );
-
-	sout | "Accepted";
-	yield( random( 10 ) );
-}
-
-void main( Acceptor* this ) {
-	for( int i = 0; i < N; i++ ) {
-		do_wait( &globalA );
-		sout | i;
-	}
-
-	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;
-	srandom( time( NULL ) );
-	printf("%p\n", &globalA);
-	sout | "Starting";
-	{
-		Acceptor r;
-		Acceptee e[13];
-
-	}
-	sout | "Done";
-}
Index: tests/concurrent/waitfor/simple.cfa
===================================================================
--- tests/concurrent/waitfor/simple.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/simple.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,85 @@
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+
+#include <time.h>
+
+static const unsigned long N = 500ul;
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10`ms
+#endif
+
+Duration 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";
+	yield( random( 10 ) );
+
+	sout | "Accepting";
+
+	__acceptable_t acceptable;
+	acceptable.func          = (fptr_t)do_notify;
+	acceptable.count         = 1;
+	acceptable.monitors      = &a;
+
+	__waitfor_internal( 1, &acceptable );
+
+	sout | "Accepted";
+	yield( random( 10 ) );
+}
+
+void main( Acceptor* this ) {
+	for( int i = 0; i < N; i++ ) {
+		do_wait( &globalA );
+		sout | i;
+	}
+
+	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;
+	srandom( time( NULL ) );
+	printf("%p\n", &globalA);
+	sout | "Starting";
+	{
+		Acceptor r;
+		Acceptee e[13];
+
+	}
+	sout | "Done";
+}
Index: tests/concurrent/waitfor/statment.c
===================================================================
--- tests/concurrent/waitfor/statment.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,136 +1,0 @@
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <thread.hfa>
-
-#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;
-			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"; if( this.last_val != 1 ) { serr | "Incorrect index: expected" | 1 | "got" | this.last_val; } }
-		or waitfor( call2, this ) { sout | "Statement"; if( this.last_val != 2 ) { serr | "Incorrect index: expected" | 2 | "got" | this.last_val; } }
-		or waitfor( call3, this ) { sout | "Statement"; if( this.last_val != 3 ) { serr | "Incorrect index: expected" | 3 | "got" | this.last_val; } }
-		or waitfor( call4, this ) { sout | "Statement"; if( this.last_val != 4 ) { serr | "Incorrect index: expected" | 4 | "got" | this.last_val; } }
-		or waitfor( call5, this ) { sout | "Statement"; if( this.last_val != 5 ) { serr | "Incorrect index: expected" | 5 | "got" | this.last_val; } }
-		or waitfor( call6, this ) { sout | "Statement"; if( this.last_val != 6 ) { serr | "Incorrect index: expected" | 6 | "got" | this.last_val; } }
-		or waitfor( call7, this ) { sout | "Statement"; if( this.last_val != 7 ) { serr | "Incorrect index: expected" | 7 | "got" | this.last_val; } }
-
-		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";
-	{
-		caller c[7];
-		waiter w;
-	}
-	sout | "Stopping";
-}
Index: tests/concurrent/waitfor/statment.cfa
===================================================================
--- tests/concurrent/waitfor/statment.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/statment.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,136 @@
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <thread.hfa>
+
+#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;
+			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"; if( this.last_val != 1 ) { serr | "Incorrect index: expected" | 1 | "got" | this.last_val; } }
+		or waitfor( call2, this ) { sout | "Statement"; if( this.last_val != 2 ) { serr | "Incorrect index: expected" | 2 | "got" | this.last_val; } }
+		or waitfor( call3, this ) { sout | "Statement"; if( this.last_val != 3 ) { serr | "Incorrect index: expected" | 3 | "got" | this.last_val; } }
+		or waitfor( call4, this ) { sout | "Statement"; if( this.last_val != 4 ) { serr | "Incorrect index: expected" | 4 | "got" | this.last_val; } }
+		or waitfor( call5, this ) { sout | "Statement"; if( this.last_val != 5 ) { serr | "Incorrect index: expected" | 5 | "got" | this.last_val; } }
+		or waitfor( call6, this ) { sout | "Statement"; if( this.last_val != 6 ) { serr | "Incorrect index: expected" | 6 | "got" | this.last_val; } }
+		or waitfor( call7, this ) { sout | "Statement"; if( this.last_val != 7 ) { serr | "Incorrect index: expected" | 7 | "got" | this.last_val; } }
+
+		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";
+	{
+		caller c[7];
+		waiter w;
+	}
+	sout | "Stopping";
+}
Index: tests/concurrent/waitfor/when.c
===================================================================
--- tests/concurrent/waitfor/when.c	(revision 5ea5b28f99a21543ee16545ccb212eddbb550eff)
+++ 	(revision )
@@ -1,87 +1,0 @@
-//----------------------------------------------------------------
-// When test
-// Ensures that when clauses on waitfor are respected
-//-----------------------------------------------------------------
-
-#include <fstream.hfa>
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-#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; } }
-		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; } }
-		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; } }
-		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; } }
-		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; } }
-		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; } }
-
-		sout | this.last_call;
-	}
-
-	this.done = true;
-}
-
-thread arbiter_t{};
-void main( arbiter_t & this ) {
-	arbiter( global );
-}
-
-int main() {
-	srandom( time(NULL) );
-	sout | "Starting";
-	{
-		arbiter_t arbiter;
-		caller_t callers[7];
-
-	}
-	sout | "Stopping";
-}
Index: tests/concurrent/waitfor/when.cfa
===================================================================
--- tests/concurrent/waitfor/when.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
+++ tests/concurrent/waitfor/when.cfa	(revision 1cc4390a9eac2ad86029fdf9cdced2a90cceb75b)
@@ -0,0 +1,87 @@
+//----------------------------------------------------------------
+// When test
+// Ensures that when clauses on waitfor are respected
+//-----------------------------------------------------------------
+
+#include <fstream.hfa>
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+
+#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; } }
+		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; } }
+		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; } }
+		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; } }
+		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; } }
+		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; } }
+
+		sout | this.last_call;
+	}
+
+	this.done = true;
+}
+
+thread arbiter_t{};
+void main( arbiter_t & this ) {
+	arbiter( global );
+}
+
+int main() {
+	srandom( time(NULL) );
+	sout | "Starting";
+	{
+		arbiter_t arbiter;
+		caller_t callers[7];
+
+	}
+	sout | "Stopping";
+}
