Index: benchmark/io/http/protocol.cfa
===================================================================
--- benchmark/io/http/protocol.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ benchmark/io/http/protocol.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -5,4 +5,7 @@
 	#include <fcntl.h>
 }
+
+#define xstr(s) str(s)
+#define str(s) #s
 
 #include <fstream.hfa>
@@ -21,4 +24,5 @@
 
 #define PLAINTEXT_1WRITE
+#define PLAINTEXT_MEMCPY
 #define PLAINTEXT_NOCOPY
 
@@ -85,9 +89,26 @@
 #if defined(PLAINTEXT_NOCOPY)
 int answer_plaintext( int fd ) {
-	return answer(fd, http_msgs[OK200_PlainText]->msg, http_msgs[OK200_PlainText]->len + 1); // +1 cause snprintf doesn't count nullterminator
+	return answer(fd, http_msgs[OK200_PlainText]->msg, http_msgs[OK200_PlainText]->len); // +1 cause snprintf doesn't count nullterminator
+}
+#elif defined(PLAINTEXT_MEMCPY)
+#define TEXTSIZE 15
+int answer_plaintext( int fd ) {
+	char text[] = "Hello, World!\n\n";
+	char ts[] = xstr(TEXTSIZE) " \n\n";
+	_Static_assert(sizeof(text) - 1 == TEXTSIZE);
+	char buffer[512 + TEXTSIZE];
+	char * it = buffer;
+	memcpy(it, http_msgs[OK200]->msg, http_msgs[OK200]->len);
+	it += http_msgs[OK200]->len;
+	int len = http_msgs[OK200]->len;
+	memcpy(it, ts, sizeof(ts) - 1);
+	it += sizeof(ts) - 1;
+	len += sizeof(ts) - 1;
+	memcpy(it, text, TEXTSIZE);
+	return answer(fd, buffer, len + TEXTSIZE);
 }
 #elif defined(PLAINTEXT_1WRITE)
 int answer_plaintext( int fd ) {
-	char text[] = "Hello, World!\n";
+	char text[] = "Hello, World!\n\n";
 	char buffer[512 + sizeof(text)];
 	char * it = buffer;
@@ -103,5 +124,5 @@
 #else
 int answer_plaintext( int fd ) {
-	char text[] = "Hello, World!\n";
+	char text[] = "Hello, World!\n\n";
 	int ret = answer_header(fd, sizeof(text));
 	if( ret < 0 ) return ret;
@@ -194,5 +215,5 @@
 const char * original_http_msgs[] = {
 	"HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: ",
-	"HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 15\n\nHello, World!\n",
+	"HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 15\n\nHello, World!\n\n",
 	"HTTP/1.1 400 Bad Request\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
 	"HTTP/1.1 404 Not Found\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
Index: benchmark/io/http/worker.cfa
===================================================================
--- benchmark/io/http/worker.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ benchmark/io/http/worker.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -18,5 +18,5 @@
 void ?{}( Worker & this ) {
 	size_t cli = rand() % options.clopts.cltr_cnt;
-	((thread&)this){ "Server Worker Thread", *options.clopts.instance[cli] };
+	((thread&)this){ "Server Worker Thread", *options.clopts.instance[cli], 512000 };
 	options.clopts.thrd_cnt[cli]++;
 	this.pipe[0] = -1;
Index: benchmark/readyQ/cycle.cpp
===================================================================
--- benchmark/readyQ/cycle.cpp	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ benchmark/readyQ/cycle.cpp	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -3,46 +3,4 @@
 #include <libfibre/fibre.h>
 
-class __attribute__((aligned(128))) bench_sem {
-	Fibre * volatile ptr = nullptr;
-public:
-	inline bool wait() {
-		static Fibre * const ready  = reinterpret_cast<Fibre * const>(1ull);
-		for(;;) {
-			Fibre * expected = this->ptr;
-			if(expected == ready) {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					return false;
-				}
-			}
-			else {
-				/* paranoid */ assert( expected == nullptr );
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, fibre_self(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					fibre_park();
-					return true;
-				}
-			}
-
-		}
-	}
-
-	inline bool post() {
-		static Fibre * const ready  = reinterpret_cast<Fibre * const>(1ull);
-		for(;;) {
-			Fibre * expected = this->ptr;
-			if(expected == ready) return false;
-			if(expected == nullptr) {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, ready, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					return false;
-				}
-			}
-			else {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					fibre_unpark( expected );
-					return true;
-				}
-			}
-		}
-	}
-};
 struct Partner {
 	unsigned long long count  = 0;
Index: benchmark/readyQ/locality.cpp
===================================================================
--- benchmark/readyQ/locality.cpp	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ benchmark/readyQ/locality.cpp	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -9,47 +9,4 @@
 	uint64_t dmigs = 0;
 	uint64_t gmigs = 0;
-};
-
-class __attribute__((aligned(128))) bench_sem {
-	Fibre * volatile ptr = nullptr;
-public:
-	inline bool wait() {
-		static Fibre * const ready  = reinterpret_cast<Fibre * const>(1ull);
-		for(;;) {
-			Fibre * expected = this->ptr;
-			if(expected == ready) {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					return false;
-				}
-			}
-			else {
-				/* paranoid */ assert( expected == nullptr );
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, fibre_self(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					fibre_park();
-					return true;
-				}
-			}
-
-		}
-	}
-
-	inline bool post() {
-		static Fibre * const ready  = reinterpret_cast<Fibre * const>(1ull);
-		for(;;) {
-			Fibre * expected = this->ptr;
-			if(expected == ready) return false;
-			if(expected == nullptr) {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, ready, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					return false;
-				}
-			}
-			else {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					fibre_unpark( expected );
-					return true;
-				}
-			}
-		}
-	}
 };
 
Index: benchmark/readyQ/rq_bench.hfa
===================================================================
--- benchmark/readyQ/rq_bench.hfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ benchmark/readyQ/rq_bench.hfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -4,4 +4,5 @@
 #include <stdio.h>
 #include <stdlib.hfa>
+#include <stats.hfa>
 #include <thread.hfa>
 #include <time.hfa>
@@ -63,4 +64,7 @@
 		(*p){ "Benchmark Processor", this.cl };
 	}
+	#if !defined(__CFA_NO_STATISTICS__)
+		print_stats_at_exit( this.cl, CFA_STATS_READY_Q );
+	#endif
 }
 
Index: benchmark/readyQ/rq_bench.hpp
===================================================================
--- benchmark/readyQ/rq_bench.hpp	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ benchmark/readyQ/rq_bench.hpp	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -6,4 +6,10 @@
 #include <time.h>										// timespec
 #include <sys/time.h>									// timeval
+
+typedef __uint128_t __lehmer64_state_t;
+static inline uint64_t __lehmer64( __lehmer64_state_t & state ) {
+	state *= 0xda942042e4dd58b5;
+	return state >> 64;
+}
 
 enum { TIMEGRAN = 1000000000LL };					// nanosecond granularity, except for timeval
@@ -75,4 +81,52 @@
 }
 
+class Fibre;
+int fibre_park();
+int fibre_unpark( Fibre * );
+Fibre * fibre_self();
+
+class __attribute__((aligned(128))) bench_sem {
+	Fibre * volatile ptr = nullptr;
+public:
+	inline bool wait() {
+		static Fibre * const ready  = reinterpret_cast<Fibre *>(1ull);
+		for(;;) {
+			Fibre * expected = this->ptr;
+			if(expected == ready) {
+				if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
+					return false;
+				}
+			}
+			else {
+				/* paranoid */ assert( expected == nullptr );
+				if(__atomic_compare_exchange_n(&this->ptr, &expected, fibre_self(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
+					fibre_park();
+					return true;
+				}
+			}
+
+		}
+	}
+
+	inline bool post() {
+		static Fibre * const ready  = reinterpret_cast<Fibre *>(1ull);
+		for(;;) {
+			Fibre * expected = this->ptr;
+			if(expected == ready) return false;
+			if(expected == nullptr) {
+				if(__atomic_compare_exchange_n(&this->ptr, &expected, ready, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
+					return false;
+				}
+			}
+			else {
+				if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
+					fibre_unpark( expected );
+					return true;
+				}
+			}
+		}
+	}
+};
+
 // ==========================================================================================
 #include <cstdlib>
@@ -188,5 +242,8 @@
 		this->help       = help;
 		this->variable   = reinterpret_cast<void*>(&variable);
-		this->parse_fun  = reinterpret_cast<bool (*)(const char *, void * )>(static_cast<bool (*)(const char *, T & )>(parse));
+		#pragma GCC diagnostic push
+		#pragma GCC diagnostic ignored "-Wcast-function-type"
+				this->parse_fun  = reinterpret_cast<bool (*)(const char *, void * )>(static_cast<bool (*)(const char *, T & )>(parse));
+		#pragma GCC diagnostic pop
 	}
 
@@ -197,5 +254,8 @@
 		this->help       = help;
 		this->variable   = reinterpret_cast<void*>(&variable);
-		this->parse_fun  = reinterpret_cast<bool (*)(const char *, void * )>(parse);
+		#pragma GCC diagnostic push
+		#pragma GCC diagnostic ignored "-Wcast-function-type"
+			this->parse_fun  = reinterpret_cast<bool (*)(const char *, void * )>(parse);
+		#pragma GCC diagnostic pop
 	}
 };
Index: benchmark/readyQ/transfer.cfa
===================================================================
--- benchmark/readyQ/transfer.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
+++ benchmark/readyQ/transfer.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -0,0 +1,176 @@
+#include "rq_bench.hfa"
+#include <fstream.hfa>
+
+Duration default_preemption() {
+	return 0;
+}
+
+#define PRINT(...)
+
+__lehmer64_state_t lead_seed;
+volatile unsigned leader;
+volatile size_t lead_idx;
+
+bool exhaust = false;
+
+$thread * the_main;
+
+thread __attribute__((aligned(128))) MyThread {
+	unsigned id;
+	volatile size_t idx;
+	bench_sem sem;
+	size_t rechecks;
+};
+
+void ?{}( MyThread & this, unsigned id ) {
+	((thread&)this){ bench_cluster };
+	this.id = id;
+	this.idx = 0;
+	this.rechecks = 0;
+}
+
+MyThread ** threads;
+
+static void waitgroup() {
+	Time start = timeHiRes();
+	for(i; nthreads) {
+		PRINT( sout | "Waiting for :" | i | "(" | threads[i]->idx | ")"; )
+		while( threads[i]->idx != lead_idx ) {
+			Pause();
+			if( (timeHiRes() - start) > 5`s ) {
+				serr | "Programs has been blocked for more than 5 secs";
+				exit(1);
+			}
+		}
+	}
+	PRINT( sout | "Waiting done"; )
+}
+
+static void wakegroup(unsigned me) {
+	if(!exhaust) return;
+
+	for(i; nthreads) {
+		if(i!= me) post( threads[i]->sem );
+	}
+}
+
+static void lead(MyThread & this) {
+	this.idx = ++lead_idx;
+	if(lead_idx > stop_count) {
+		PRINT( sout | "Leader" | this.id | "done"; )
+		unpark( the_main );
+		return;
+	}
+
+	PRINT( sout | "Leader no" | this.idx| ":" | this.id; )
+
+	waitgroup();
+
+	unsigned nleader = __lehmer64( lead_seed ) % nthreads;
+	__atomic_store_n( &leader, nleader, __ATOMIC_SEQ_CST );
+
+	wakegroup(this.id);
+}
+
+static void wait(MyThread & this) {
+	yield();
+	if(lead_idx == this.idx) {
+		this.rechecks++;
+		return;
+	}
+
+	assert( (lead_idx - 1) == this.idx );
+	__atomic_add_fetch( &this.idx, 1, __ATOMIC_SEQ_CST );
+	if(exhaust) wait( this.sem );
+	else yield();
+}
+
+void main(MyThread & this) {
+	park();
+
+	unsigned me = this.id;
+
+	for() {
+		if(leader == me) {
+			lead( this );
+		}
+		else {
+			wait( this );
+		}
+		if(lead_idx > stop_count) break;
+	}
+}
+
+// ==================================================
+int main(int argc, char * argv[]) {
+	__lehmer64_state_t lead_seed = getpid();
+	for(10) __lehmer64( lead_seed );
+	unsigned nprocs = 2;
+
+	cfa_option opt[] = {
+		BENCH_OPT,
+		{ 'e', "exhaust", "Whether or not threads that have seen the new epoch should yield or park.", exhaust, parse_yesno}
+	};
+	BENCH_OPT_PARSE("cforall transition benchmark");
+
+	if(clock_mode) {
+		serr | "This benchmark doesn't support duration mode";
+		return 1;
+	}
+
+	if(nprocs < 2) {
+		serr | "Must have at least 2 processors";
+		return 1;
+	}
+
+	lead_idx = 0;
+	leader = __lehmer64( lead_seed ) % nthreads;
+
+	size_t rechecks = 0;
+	the_main = active_thread();
+
+	Time start, end;
+	{
+		BenchCluster bc = { nprocs };
+		{
+			threads = alloc(nthreads);
+			for(i; nthreads) {
+				threads[i] = malloc();
+				(*threads[i]){
+					i
+				};
+			}
+
+			start = timeHiRes();
+			for(i; nthreads) {
+				unpark(*threads[i]);
+			}
+
+			park();
+			end = timeHiRes();
+
+			for(i; nthreads) {
+				post(threads[i]->sem);
+			}
+
+			for(i; nthreads) {
+				MyThread & thrd = join(*threads[i]);
+				PRINT( sout | i | "joined"; )
+				rechecks += thrd.rechecks;
+				^( *threads[i] ){};
+				free(threads[i]);
+			}
+
+			free(threads);
+		}
+	}
+
+	sout | "Duration                : " | ws(3, 3, unit(eng((end - start)`ds))) | 's';
+	sout | "Number of processors    : " | nprocs;
+	sout | "Number of threads       : " | nthreads;
+	sout | "Total Operations(ops)   : " | stop_count;
+	sout | "Threads parking on wait : " | (exhaust ? "yes" : "no");
+	sout | "Rechecking              : " | rechecks;
+
+
+}
Index: benchmark/readyQ/transfer.cpp
===================================================================
--- benchmark/readyQ/transfer.cpp	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
+++ benchmark/readyQ/transfer.cpp	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -0,0 +1,183 @@
+#include "rq_bench.hpp"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+	#include <libfibre/fibre.h>
+#pragma GCC diagnostic pop
+
+#define PRINT(...)
+
+__lehmer64_state_t lead_seed;
+volatile unsigned leader;
+volatile size_t lead_idx;
+
+bool exhaust = false;
+
+bench_sem the_main;
+
+class __attribute__((aligned(128))) MyThread;
+
+MyThread ** threads;
+
+class __attribute__((aligned(128))) MyThread {
+	unsigned id;
+	volatile size_t idx;
+	bench_sem sem;
+
+public:
+	size_t rechecks;
+
+	MyThread(unsigned _id)
+		: id(_id), idx(0), rechecks(0)
+	{}
+
+	void unpark() { sem.post(); }
+	void park  () { sem.wait(); }
+
+	void waitgroup() {
+		uint64_t start = timeHiRes();
+		for(size_t i = 0; i < nthreads; i++) {
+			PRINT( std::cout << "Waiting for : " << i << " (" << threads[i]->idx << ")" << std::endl; )
+			while( threads[i]->idx != lead_idx ) {
+				Pause();
+				if( to_miliseconds(timeHiRes() - start) > 5'000 ) {
+					std::cerr << "Programs has been blocked for more than 5 secs" << std::endl;
+					std::exit(1);
+				}
+			}
+		}
+		PRINT( std::cout | "Waiting done"; )
+	}
+
+	void wakegroup(unsigned me) {
+		if(!exhaust) return;
+
+		for(size_t i = 0; i < nthreads; i++) {
+			if(i!= me) threads[i]->sem.post();
+		}
+	}
+
+	void lead() {
+		this->idx = ++lead_idx;
+		if(lead_idx > stop_count) {
+			PRINT( std::cout << "Leader " << this->id << " done" << std::endl; )
+			the_main.post();
+			return;
+		}
+
+		PRINT( sout << "Leader no " << this->idx << ": " << this->id << std::endl; )
+
+		waitgroup();
+
+		unsigned nleader = __lehmer64( lead_seed ) % nthreads;
+		__atomic_store_n( &leader, nleader, __ATOMIC_SEQ_CST );
+
+		wakegroup(this->id);
+	}
+
+	void wait() {
+		fibre_yield();
+		if(lead_idx == this->idx) {
+			this->rechecks++;
+			return;
+		}
+
+		assert( (lead_idx - 1) == this->idx );
+		__atomic_add_fetch( &this->idx, 1, __ATOMIC_SEQ_CST );
+		if(exhaust) this->sem.wait();
+		else fibre_yield();
+	}
+
+	static void main(void * arg) {
+		MyThread & self = *reinterpret_cast<MyThread*>(arg);
+		self.park();
+
+		unsigned me = self.id;
+
+		for(;;) {
+			if(leader == me) {
+				self.lead();
+			}
+			else {
+				self.wait();
+			}
+			if(lead_idx > stop_count) break;
+		}
+	}
+};
+
+// ==================================================
+int main(int argc, char * argv[]) {
+	__lehmer64_state_t lead_seed = getpid();
+	for(int i = 0; i < 10; i++) __lehmer64( lead_seed );
+	unsigned nprocs = 2;
+
+	option_t opt[] = {
+		BENCH_OPT,
+		{ 'e', "exhaust", "Whether or not threads that have seen the new epoch should yield or park.", exhaust, parse_yesno}
+	};
+	BENCH_OPT_PARSE("cforall transition benchmark");
+
+	std::cout.imbue(std::locale(""));
+	setlocale(LC_ALL, "");
+
+	if(clock_mode) {
+		std::cerr << "This benchmark doesn't support duration mode" << std::endl;
+		return 1;
+	}
+
+	if(nprocs < 2) {
+		std::cerr << "Must have at least 2 processors" << std::endl;
+		return 1;
+	}
+
+	lead_idx = 0;
+	leader = __lehmer64( lead_seed ) % nthreads;
+
+	size_t rechecks = 0;
+
+	uint64_t start, end;
+	{
+		FibreInit(1, nprocs);
+		{
+			Fibre ** handles = new Fibre*[nthreads];
+			threads = new MyThread*[nthreads];
+			for(size_t i = 0; i < nthreads; i++) {
+				threads[i] = new MyThread( i );
+				handles[i] = new Fibre( MyThread::main, threads[i] );
+			}
+
+			start = timeHiRes();
+			for(size_t i = 0; i < nthreads; i++) {
+				threads[i]->unpark();
+			}
+
+			the_main.wait();
+			end = timeHiRes();
+
+			for(size_t i = 0; i < nthreads; i++) {
+				threads[i]->unpark();
+			}
+
+			for(size_t i = 0; i < nthreads; i++) {
+				MyThread & thrd = *threads[i];
+				fibre_join( handles[i], nullptr );
+				PRINT( std::cout << i << " joined" << std::endl; )
+				rechecks += thrd.rechecks;
+				// delete( handles[i] );
+				delete( threads[i] );
+			}
+
+			delete[] (threads);
+			delete[] (handles);
+		}
+	}
+
+	std::cout << "Duration                : " << to_miliseconds(end - start) << "ms" << std::endl;
+	std::cout << "Number of processors    : " << nprocs << std::endl;
+	std::cout << "Number of threads       : " << nthreads << std::endl;
+	std::cout << "Total Operations(ops)   : " << stop_count << std::endl;
+	std::cout << "Threads parking on wait : " << (exhaust ? "yes" : "no") << std::endl;
+	std::cout << "Rechecking              : " << rechecks << std::endl;
+
+
+}
Index: libcfa/src/concurrency/clib/cfathread.cfa
===================================================================
--- libcfa/src/concurrency/clib/cfathread.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/concurrency/clib/cfathread.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -50,4 +50,6 @@
 
 cfathread_vtable _cfathread_vtable_instance;
+
+cfathread_vtable & const _default_vtable = _cfathread_vtable_instance;
 
 cfathread_vtable const & get_exception_vtable(cfathread_exception *) {
Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -46,6 +46,4 @@
 
 //-----------------------------------------------------------------------------
-EHM_VIRTUAL_TABLE(SomeCoroutineCancelled, std_coroutine_cancelled);
-
 forall(T &)
 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) {
@@ -62,5 +60,6 @@
 // This code should not be inlined. It is the error path on resume.
 forall(T & | is_coroutine(T))
-void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ) {
+void __cfaehm_cancelled_coroutine(
+		T & cor, $coroutine * desc, _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable ) {
 	verify( desc->cancellation );
 	desc->state = Cancelled;
@@ -68,10 +67,10 @@
 
 	// TODO: Remove explitate vtable set once trac#186 is fixed.
-	SomeCoroutineCancelled except;
-	except.virtual_table = &std_coroutine_cancelled;
+	CoroutineCancelled(T) except;
+	except.virtual_table = &_default_vtable;
 	except.the_coroutine = &cor;
 	except.the_exception = except;
 	// Why does this need a cast?
-	throwResume (SomeCoroutineCancelled &)except;
+	throwResume (CoroutineCancelled(T) &)except;
 
 	except->virtual_table->free( except );
@@ -146,5 +145,5 @@
 // Part of the Public API
 // Not inline since only ever called once per coroutine
-forall(T & | is_coroutine(T))
+forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
 void prime(T& cor) {
 	$coroutine* this = get_coroutine(cor);
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -22,11 +22,4 @@
 //-----------------------------------------------------------------------------
 // Exception thrown from resume when a coroutine stack is cancelled.
-EHM_EXCEPTION(SomeCoroutineCancelled)(
-	void * the_coroutine;
-	exception_t * the_exception;
-);
-
-EHM_EXTERN_VTABLE(SomeCoroutineCancelled, std_coroutine_cancelled);
-
 EHM_FORALL_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) (
 	coroutine_t * the_coroutine;
@@ -44,5 +37,5 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(SomeCoroutineCancelled)) {
+trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) {
 	void main(T & this);
 	$coroutine * get_coroutine(T & this);
@@ -67,5 +60,5 @@
 //-----------------------------------------------------------------------------
 // Public coroutine API
-forall(T & | is_coroutine(T))
+forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
 void prime(T & cor);
 
@@ -137,8 +130,9 @@
 
 forall(T & | is_coroutine(T))
-void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc );
+void __cfaehm_cancelled_coroutine(
+	T & cor, $coroutine * desc, _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable );
 
 // Resume implementation inlined for performance
-forall(T & | is_coroutine(T))
+forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
 static inline T & resume(T & cor) {
 	// optimization : read TLS once and reuse it
@@ -170,5 +164,5 @@
 	$ctx_switch( src, dst );
 	if ( unlikely(dst->cancellation) ) {
-		__cfaehm_cancelled_coroutine( cor, dst );
+		__cfaehm_cancelled_coroutine( cor, dst, _default_vtable );
 	}
 
Index: libcfa/src/concurrency/locks.hfa
===================================================================
--- libcfa/src/concurrency/locks.hfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/concurrency/locks.hfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -197,6 +197,5 @@
 static inline $thread * unlock( fast_lock & this ) __attribute__((artificial));
 static inline $thread * unlock( fast_lock & this ) {
-	$thread * thrd = active_thread();
-	/* paranoid */ verify(thrd == this.owner);
+	/* paranoid */ verify(active_thread() == this.owner);
 
 	// open 'owner' before unlocking anyone
Index: libcfa/src/concurrency/ready_queue.cfa
===================================================================
--- libcfa/src/concurrency/ready_queue.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/concurrency/ready_queue.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -413,13 +413,17 @@
 			unsigned it2  = proc->rdq.itr + 1;
 			unsigned idx1 = proc->rdq.id + (it1 % READYQ_SHARD_FACTOR);
-			unsigned idx2 = proc->rdq.id + (it1 % READYQ_SHARD_FACTOR);
+			unsigned idx2 = proc->rdq.id + (it2 % READYQ_SHARD_FACTOR);
 			unsigned long long tsc1 = ts(lanes.data[idx1]);
 			unsigned long long tsc2 = ts(lanes.data[idx2]);
 			proc->rdq.cutoff = min(tsc1, tsc2);
-		}
-		else if(lanes.tscs[proc->rdq.target].tv < proc->rdq.cutoff) {
-			$thread * t = try_pop(cltr, proc->rdq.target __STATS(, __tls_stats()->ready.pop.help));
+			if(proc->rdq.cutoff == 0) proc->rdq.cutoff = -1ull;
+		}
+		else {
+			unsigned target = proc->rdq.target;
 			proc->rdq.target = -1u;
-			if(t) return t;
+			if(lanes.tscs[target].tv < proc->rdq.cutoff) {
+				$thread * t = try_pop(cltr, target __STATS(, __tls_stats()->ready.pop.help));
+				if(t) return t;
+			}
 		}
 
Index: libcfa/src/concurrency/stats.cfa
===================================================================
--- libcfa/src/concurrency/stats.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/concurrency/stats.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -126,28 +126,29 @@
 			double sExt_len = ready.push.extrn.success ? ((double)ready.push.extrn.attempt) / ready.push.extrn.success : 0;
 
-			double rLcl_len  = ready.pop.local .success ? ((double)ready.pop.local .attempt) / ready.pop.local .success : 0;
-			double rHlp_len  = ready.pop.help  .success ? ((double)ready.pop.help  .attempt) / ready.pop.help  .success : 0;
-			double rStl_len  = ready.pop.steal .success ? ((double)ready.pop.steal .attempt) / ready.pop.steal .success : 0;
-			double rSch_len  = ready.pop.search.success ? ((double)ready.pop.search.attempt) / ready.pop.search.success : 0;
+			uint64_t total = ready.pop.local.success + ready.pop.help.success + ready.pop.steal.success + ready.pop.search.success;
+			double rLcl_pc = (100.0 * (double)ready.pop.local .success) / total;
+			double rHlp_pc = (100.0 * (double)ready.pop.help  .success) / total;
+			double rStl_pc = (100.0 * (double)ready.pop.steal .success) / total;
+			double rSch_pc = (100.0 * (double)ready.pop.search.success) / total;
 
 			__cfaabi_bits_print_safe( STDOUT_FILENO,
 				"----- %s \"%s\" (%p) - Ready Q Stats -----\n"
 				"- totals   : %'3" PRIu64 " run, %'3" PRIu64 " schd (%'" PRIu64 "ext, %'" PRIu64 "mig, %'" PRId64 " )\n"
-				"- push avg : %'3.2lf (l: %'3.2lf/%'" PRIu64 ", s: %'3.2lf/%'" PRIu64 ", e: %'3.2lf : %'" PRIu64 "e)\n"
-				"- local    : %'3.2lf (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
-				"- help     : %'3.2lf (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
-				"- steal    : %'3.2lf (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
-				"- search   : %'3.2lf (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
+				"- push avg : %'3.0lf (l: %'3.2lf/%'" PRIu64 ", s: %'3.2lf/%'" PRIu64 ", e: %'3.2lf : %'" PRIu64 "e)\n"
+				"- local    : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
+				"- help     : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
+				"- steal    : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
+				"- search   : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"
 				"- Idle Slp : %'3" PRIu64 "h, %'3" PRIu64 "c, %'3" PRIu64 "w, %'3" PRIu64 "e\n"
 				"\n"
 				, type, name, id
-				, ready.pop.local.success + ready.pop.help.success + ready.pop.steal.success + ready.pop.search.success
+				, total
 				, ready.push.local.success + ready.push.share.success + ready.push.extrn.success
 				, ready.push.extrn.success, ready.threads.migration, ready.threads.threads
 				, push_len, sLcl_len, ready.push.local.attempt, sOth_len, ready.push.share.attempt, sExt_len, ready.push.extrn.attempt
-				, rLcl_len, ready.pop.local .attempt, ready.pop.local .espec, ready.pop.local .elock, ready.pop.local .eempty
-				, rHlp_len, ready.pop.help  .attempt, ready.pop.help  .espec, ready.pop.help  .elock, ready.pop.help  .eempty
-				, rStl_len, ready.pop.steal .attempt, ready.pop.steal .espec, ready.pop.steal .elock, ready.pop.steal .eempty
-				, rSch_len, ready.pop.search.attempt, ready.pop.search.espec, ready.pop.search.elock, ready.pop.search.eempty
+				, rLcl_pc, ready.pop.local .success, ready.pop.local .attempt, ready.pop.local .espec, ready.pop.local .elock, ready.pop.local .eempty
+				, rHlp_pc, ready.pop.help  .success, ready.pop.help  .attempt, ready.pop.help  .espec, ready.pop.help  .elock, ready.pop.help  .eempty
+				, rStl_pc, ready.pop.steal .success, ready.pop.steal .attempt, ready.pop.steal .espec, ready.pop.steal .elock, ready.pop.steal .eempty
+				, rSch_pc, ready.pop.search.success, ready.pop.search.attempt, ready.pop.search.espec, ready.pop.search.elock, ready.pop.search.eempty
 				, ready.sleep.halts, ready.sleep.cancels, ready.sleep.wakes, ready.sleep.exits
 			);
Index: libcfa/src/concurrency/thread.cfa
===================================================================
--- libcfa/src/concurrency/thread.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/concurrency/thread.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -61,6 +61,4 @@
 }
 
-EHM_VIRTUAL_TABLE(SomeThreadCancelled, std_thread_cancelled);
-
 forall(T &)
 void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src) {
@@ -81,12 +79,8 @@
 }
 
-static void default_thread_cancel_handler(SomeThreadCancelled & ) {
-	// Improve this error message, can I do formatting?
-	abort( "Unhandled thread cancellation.\n" );
-}
-
-forall(T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled))
+forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))
+    | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; })
 void ?{}( thread_dtor_guard_t & this,
-		T & thrd, void(*cancelHandler)(SomeThreadCancelled &)) {
+		T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) {
 	$monitor * m = get_monitor(thrd);
 	$thread * desc = get_thread(thrd);
@@ -94,5 +88,5 @@
 	// Setup the monitor guard
 	void (*dtor)(T& mutex this) = ^?{};
-	bool join = cancelHandler != (void(*)(SomeThreadCancelled&))0;
+	bool join = cancelHandler != (void(*)(ThreadCancelled(T)&))0;
 	(this.mg){&m, (void(*)())dtor, join};
 
@@ -108,14 +102,14 @@
 	}
 	desc->state = Cancelled;
-	void(*defaultResumptionHandler)(SomeThreadCancelled &) =
+	void(*defaultResumptionHandler)(ThreadCancelled(T) &) =
 		join ? cancelHandler : default_thread_cancel_handler;
 
 	// TODO: Remove explitate vtable set once trac#186 is fixed.
-	SomeThreadCancelled except;
-	except.virtual_table = &std_thread_cancelled;
+	ThreadCancelled(T) except;
+	except.virtual_table = &_default_vtable;
 	except.the_thread = &thrd;
 	except.the_exception = __cfaehm_cancellation_exception( cancellation );
 	// Why is this cast required?
-	throwResume (SomeThreadCancelled &)except;
+	throwResume (ThreadCancelled(T) &)except;
 
 	except.the_exception->virtual_table->free( except.the_exception );
@@ -164,5 +158,6 @@
 
 //-----------------------------------------------------------------------------
-forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled))
+forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))
+    | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; })
 T & join( T & this ) {
 	thread_dtor_guard_t guard = { this, defaultResumptionHandler };
Index: libcfa/src/concurrency/thread.hfa
===================================================================
--- libcfa/src/concurrency/thread.hfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/concurrency/thread.hfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -31,11 +31,4 @@
 	$thread* get_thread(T& this);
 };
-
-EHM_EXCEPTION(SomeThreadCancelled) (
-	void * the_thread;
-	exception_t * the_exception;
-);
-
-EHM_EXTERN_VTABLE(SomeThreadCancelled, std_thread_cancelled);
 
 EHM_FORALL_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) (
@@ -86,6 +79,7 @@
 };
 
-forall( T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled) )
-void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(SomeThreadCancelled &) );
+forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))
+    | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; } )
+void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) );
 void ^?{}( thread_dtor_guard_t & this );
 
@@ -132,5 +126,6 @@
 //----------
 // join
-forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled) )
+forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))
+    | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; } )
 T & join( T & this );
 
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ libcfa/src/exception.hfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -142,8 +142,4 @@
 		_EHM_VTABLE_TYPE(exception_name) parameters const &) {} \
 
-#define _EHM_TRAIT_FUNCTION2(exception_name, forall_clause, parameters) \
-	forall_clause _EHM_VTABLE_TYPE(exception_name) parameters const & \
-			get_exception_vtable(exception_name parameters const & this)
-
 #define __EHM_TRAIT_FUNCTION(exception_name, forall_clause, parameters) \
 	forall_clause inline _EHM_VTABLE_TYPE(exception_name) parameters const & \
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ src/Concurrency/Keywords.cc	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -414,7 +414,5 @@
 		if ( type_decl && isDestructorFor( decl, type_decl ) )
 			dtor_decl = decl;
-		else if ( vtable_name.empty() )
-			;
-		else if( !decl->has_body() )
+		else if ( vtable_name.empty() || !decl->has_body() )
 			;
 		else if ( auto param = isMainFor( decl, cast_target ) ) {
@@ -428,6 +426,17 @@
 			std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) };
 			ObjectDecl * vtable_object = Virtual::makeVtableInstance(
+				"_default_vtable_object_declaration",
 				vtable_decl->makeInst( poly_args ), struct_type, nullptr );
 			declsToAddAfter.push_back( vtable_object );
+			declsToAddAfter.push_back(
+				new ObjectDecl(
+					Virtual::concurrentDefaultVTableName(),
+					Type::Const,
+					LinkageSpec::Cforall,
+					/* bitfieldWidth */ nullptr,
+					new ReferenceType( Type::Const, vtable_object->type->clone() ),
+					new SingleInit( new VariableExpr( vtable_object ) )
+				)
+			);
 			declsToAddAfter.push_back( Virtual::makeGetExceptionFunction(
 				vtable_object, except_decl->makeInst( std::move( poly_args ) )
@@ -488,6 +497,18 @@
 			except_decl->makeInst( poly_args )
 		) );
-		declsToAddBefore.push_back( Virtual::makeVtableForward(
-			vtable_decl->makeInst( move( poly_args ) ) ) );
+		ObjectDecl * vtable_object = Virtual::makeVtableForward(
+			"_default_vtable_object_declaration",
+			vtable_decl->makeInst( move( poly_args ) ) );
+		declsToAddBefore.push_back( vtable_object );
+		declsToAddBefore.push_back(
+			new ObjectDecl(
+				Virtual::concurrentDefaultVTableName(),
+				Type::Const,
+				LinkageSpec::Cforall,
+				/* bitfieldWidth */ nullptr,
+				new ReferenceType( Type::Const, vtable_object->type->clone() ),
+				/* init */ nullptr
+			)
+		);
 	}
 
Index: src/Virtual/Tables.cc
===================================================================
--- src/Virtual/Tables.cc	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ src/Virtual/Tables.cc	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -10,6 +10,6 @@
 // Created On       : Mon Aug 31 11:11:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Apr  8 15:51:00 2021
-// Update Count     : 1
+// Last Modified On : Wed Apr 21 15:36:00 2021
+// Update Count     : 2
 //
 
@@ -50,4 +50,8 @@
 }
 
+std::string concurrentDefaultVTableName() {
+	return "_default_vtable";
+}
+
 bool isVTableInstanceName( std::string const & name ) {
 	// There are some delicate length calculations here.
@@ -57,6 +61,6 @@
 
 static ObjectDecl * makeVtableDeclaration(
+		std::string const & name,
 		StructInstType * type, Initializer * init ) {
-	std::string const & name = instanceName( type->name );
 	Type::StorageClasses storage = noStorageClasses;
 	if ( nullptr == init ) {
@@ -73,11 +77,12 @@
 }
 
-ObjectDecl * makeVtableForward( StructInstType * type ) {
+ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) {
 	assert( type );
-	return makeVtableDeclaration( type, nullptr );
+	return makeVtableDeclaration( name, type, nullptr );
 }
 
 ObjectDecl * makeVtableInstance(
-		StructInstType * vtableType, Type * objectType, Initializer * init ) {
+		std::string const & name, StructInstType * vtableType,
+		Type * objectType, Initializer * init ) {
 	assert( vtableType );
 	assert( objectType );
@@ -115,5 +120,5 @@
 		assert(false);
 	}
-	return makeVtableDeclaration( vtableType, init );
+	return makeVtableDeclaration( name, vtableType, init );
 }
 
@@ -167,8 +172,4 @@
 }
 
-ObjectDecl * makeTypeIdForward() {
-	return nullptr;
-}
-
 Attribute * linkonce( const std::string & subsection ) {
 	const std::string section = ".gnu.linkonce." + subsection;
Index: src/Virtual/Tables.h
===================================================================
--- src/Virtual/Tables.h	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ src/Virtual/Tables.h	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -10,6 +10,6 @@
 // Created On       : Mon Aug 31 11:07:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Apr  8 15:55:00 2021
-// Update Count     : 1
+// Last Modified On : Wed Apr 21 10:30:00 2021
+// Update Count     : 2
 //
 
@@ -27,12 +27,16 @@
 std::string instanceName( std::string const & vtable_name );
 std::string vtableInstanceName( std::string const & type_name );
+std::string concurrentDefaultVTableName();
 bool isVTableInstanceName( std::string const & name );
 
-ObjectDecl * makeVtableForward( StructInstType * vtableType );
+ObjectDecl * makeVtableForward(
+	std::string const & name, StructInstType * vtableType );
 /* Create a forward declaration of a vtable of the given type.
  * vtableType node is consumed.
  */
 
-ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType,
+ObjectDecl * makeVtableInstance(
+	std::string const & name,
+	StructInstType * vtableType, Type * objectType,
 	Initializer * init = nullptr );
 /* Create an initialized definition of a vtable.
Index: tests/concurrent/coroutineYield.cfa
===================================================================
--- tests/concurrent/coroutineYield.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ tests/concurrent/coroutineYield.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -38,6 +38,6 @@
 
 
+Coroutine c;
 int main(int argc, char* argv[]) {
-	Coroutine c;
 	for(int i = 0; TEST(i < N); i++) {
 		#if !defined(TEST_FOREVER)
Index: tests/exceptions/cancel/coroutine.cfa
===================================================================
--- tests/exceptions/cancel/coroutine.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ tests/exceptions/cancel/coroutine.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -25,5 +25,5 @@
 		resume(cancel);
 		printf("4");
-	} catchResume (SomeCoroutineCancelled * error) {
+	} catchResume (CoroutineCancelled(WillCancel) * error) {
 		printf("2");
 		if ((virtual internal_error *)error->the_exception) {
Index: tests/exceptions/cancel/thread.cfa
===================================================================
--- tests/exceptions/cancel/thread.cfa	(revision fec63b21f5efc819f13b798d37a05390d81a66ee)
+++ tests/exceptions/cancel/thread.cfa	(revision 50f6afb777a2a99adaa5c5a1c12c05fea3ddc2c4)
@@ -26,5 +26,5 @@
 		join(cancel);
 		printf("4");
-	} catchResume (SomeThreadCancelled * error) {
+	} catchResume (ThreadCancelled(WillCancel) * error) {
 		printf("2");
 		if ((virtual internal_error *)error->the_exception) {
@@ -43,5 +43,5 @@
 		}
 		printf("4");
-	} catchResume (SomeThreadCancelled * error) {
+	} catchResume (ThreadCancelled(WillCancel) * error) {
 		printf("2");
 		if ((virtual internal_error *)error->the_exception) {
