Index: benchmark/readyQ/cycle.cc
===================================================================
--- benchmark/readyQ/cycle.cc	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
+++ benchmark/readyQ/cycle.cc	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
@@ -0,0 +1,132 @@
+#include "rq_bench.hpp"
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <unistd.h>
+
+struct Pthread {
+	static int usleep(useconds_t usec) {
+		return ::usleep(usec);
+	}
+};
+
+struct Partner {
+	unsigned long long count  = 0;
+	unsigned long long blocks = 0;
+	sem_t self;
+	sem_t * next;
+};
+
+void partner_main( Partner * self ) {
+	self->count = 0;
+	for(;;) {
+		sem_wait(&self->self);
+		sem_post(self->next);
+		self->count ++;
+		if( clock_mode && stop) break;
+		if(!clock_mode && self->count >= stop_count) break;
+
+		int sval;
+		sem_getvalue(&self->self, &sval);
+		if(sval > 1) std::abort();
+		if(sval < 0) std::abort();
+	}
+
+	__atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST);
+}
+
+int main(int argc, char * argv[]) {
+	unsigned ring_size = 2;
+	option_t opt[] = {
+		BENCH_OPT,
+		{ 'r', "ringsize", "Number of threads in a cycle", ring_size }
+	};
+	BENCH_OPT_PARSE("cforall cycle benchmark");
+
+	{
+		unsigned long long global_counter = 0;
+		unsigned long long global_blocks  = 0;
+		unsigned tthreads = nthreads * ring_size;
+		uint64_t start, end;
+
+		{
+			cpu_set_t cpuset;
+			int ret = pthread_getaffinity_np( pthread_self(), sizeof(cpuset), &cpuset );
+			if(ret != 0) std::abort();
+
+			unsigned cnt = CPU_COUNT_S(sizeof(cpuset), &cpuset);
+			if(cnt > nprocs) {
+				unsigned extras = cnt - nprocs;
+				for(int i = 0; i < CPU_SETSIZE && extras > 0; i++) {
+					if(CPU_ISSET_S(i, sizeof(cpuset), &cpuset)) {
+						CPU_CLR_S(i, sizeof(cpuset), &cpuset);
+						extras--;
+					}
+				}
+
+				ret = pthread_setaffinity_np( pthread_self(), sizeof(cpuset), &cpuset );
+				if(ret != 0) std::abort();
+			}
+		}
+
+		{
+			threads_left = tthreads;
+			pthread_t threads[tthreads];
+			Partner thddata[tthreads];
+			for(int i = 0; i < tthreads; i++) {
+				int ret = sem_init( &thddata[i].self, false, 0 );
+				if(ret != 0) std::abort();
+
+				unsigned pi = (i + nthreads) % tthreads;
+				thddata[i].next = &thddata[pi].self;
+			}
+			for(int i = 0; i < tthreads; i++) {
+				int ret = pthread_create( &threads[i], nullptr, reinterpret_cast<void * (*)(void *)>(partner_main), &thddata[i] );
+				if(ret != 0) std::abort();
+			}
+			printf("Starting\n");
+
+			bool is_tty = isatty(STDOUT_FILENO);
+			start = getTimeNsec();
+
+			for(int i = 0; i < nthreads; i++) {
+				sem_post(&thddata[i].self);
+			}
+			wait<Pthread>(start, is_tty);
+
+			stop = true;
+			end = getTimeNsec();
+			printf("\nDone\n");
+
+			for(int i = 0; i < tthreads; i++) {
+				sem_post(&thddata[i].self);
+				int ret = pthread_join( threads[i], nullptr );
+				if(ret != 0) std::abort();
+				global_counter += thddata[i].count;
+				global_blocks  += thddata[i].blocks;
+			}
+
+			for(int i = 0; i < tthreads; i++) {
+				int ret = sem_destroy( &thddata[i].self );
+				if(ret != 0) std::abort();
+			}
+		}
+
+		printf("Duration (ms)        : %'ld\n", to_miliseconds(end - start));
+		printf("Number of processors : %'d\n", nprocs);
+		printf("Number of threads    : %'d\n", tthreads);
+		printf("Cycle size (# thrds) : %'d\n", ring_size);
+		printf("Total Operations(ops): %'15llu\n", global_counter);
+		printf("Total blocks         : %'15llu\n", global_blocks);
+		printf("Ops per second       : %'18.2lf\n", ((double)global_counter) / to_fseconds(end - start));
+		printf("ns per ops           : %'18.2lf\n", ((double)(end - start)) / global_counter);
+		printf("Ops per threads      : %'15llu\n", global_counter / tthreads);
+		printf("Ops per procs        : %'15llu\n", global_counter / nprocs);
+		printf("Ops/sec/procs        : %'18.2lf\n", (((double)global_counter) / nprocs) / to_fseconds(end - start));
+		printf("ns per ops/procs     : %'18.2lf\n", ((double)(end - start)) / (global_counter / nprocs));
+		fflush(stdout);
+	}
+
+	return 0;
+}
Index: benchmark/readyQ/cycle.cfa
===================================================================
--- benchmark/readyQ/cycle.cfa	(revision b4130f981945eac8c1a3502df50beed667506743)
+++ benchmark/readyQ/cycle.cfa	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
@@ -77,4 +77,5 @@
 
 			for(i; tthreads) {
+				post( thddata[i].self );
 				Partner & partner = join( *threads[i] ).partner;
 				global_counter += partner.count;
Index: benchmark/readyQ/cycle.cpp
===================================================================
--- benchmark/readyQ/cycle.cpp	(revision b4130f981945eac8c1a3502df50beed667506743)
+++ benchmark/readyQ/cycle.cpp	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
@@ -1,5 +1,48 @@
 
 #include "rq_bench.hpp"
+#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;
@@ -55,5 +98,5 @@
 				thddata[i].self.post();
 			}
-			wait(start, is_tty);
+			wait<Fibre>(start, is_tty);
 
 			stop = true;
@@ -62,4 +105,5 @@
 
 			for(int i = 0; i < tthreads; i++) {
+				thddata[i].self.post();
 				fibre_join( threads[i], nullptr );
 				global_counter += thddata[i].count;
Index: benchmark/readyQ/cycle.go
===================================================================
--- benchmark/readyQ/cycle.go	(revision b4130f981945eac8c1a3502df50beed667506743)
+++ benchmark/readyQ/cycle.go	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
@@ -63,4 +63,8 @@
 	global_counter := uint64(0)
 	for i := 0; i < tthreads; i++ {
+		select {
+		case channels[i] <- 0:
+		default:
+		}
 		global_counter += <- result
 	}
Index: libcfa/src/concurrency/invoke.h
===================================================================
--- libcfa/src/concurrency/invoke.h	(revision b4130f981945eac8c1a3502df50beed667506743)
+++ libcfa/src/concurrency/invoke.h	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
@@ -68,5 +68,5 @@
 	};
 
-	enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active, Cancelled };
+	enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active, Cancelled, Halting };
 
 	struct $coroutine {
Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision b4130f981945eac8c1a3502df50beed667506743)
+++ libcfa/src/concurrency/kernel.cfa	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
@@ -251,4 +251,5 @@
 		/* paranoid */ verify( ! __preemption_enabled() );
 		/* paranoid */ verify( kernelTLS().this_thread == thrd_dst );
+		/* paranoid */ verify( thrd_dst->curr_cluster == this->cltr );
 		/* paranoid */ verify( thrd_dst->context.SP );
 		/* paranoid */ verify( thrd_dst->state != Halted );
@@ -267,4 +268,5 @@
 		/* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst );
 		/* paranoid */ verify( thrd_dst->context.SP );
+		/* paranoid */ verify( thrd_dst->curr_cluster == this->cltr );
 		/* paranoid */ verify( kernelTLS().this_thread == thrd_dst );
 		/* paranoid */ verify( ! __preemption_enabled() );
@@ -286,5 +288,5 @@
 		}
 
-		if(unlikely(thrd_dst->state == Halted)) {
+		if(unlikely(thrd_dst->state == Halting)) {
 			// The thread has halted, it should never be scheduled/run again
 			// finish the thread
@@ -360,7 +362,8 @@
 void __schedule_thread( $thread * thrd ) {
 	/* paranoid */ verify( ! __preemption_enabled() );
+	/* paranoid */ verify( kernelTLS().this_proc_id );
 	/* paranoid */ verify( thrd );
 	/* paranoid */ verify( thrd->state != Halted );
-	/* paranoid */ verify( kernelTLS().this_proc_id );
+	/* paranoid */ verify( thrd->curr_cluster );
 	/* paranoid */ #if defined( __CFA_WITH_VERIFY__ )
 	/* paranoid */ 	if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
@@ -473,14 +476,22 @@
 		disable_interrupts();
 
-		thrd->state = Halted;
+		/* paranoid */ verify( ! __preemption_enabled() );
+		/* paranoid */ verify( thrd->state == Active );
+		/* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd->canary );
+		/* paranoid */ verify( kernelTLS().this_thread == thrd );
+		/* paranoid */ verify( thrd->context.SP );
+		/* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) > ((uintptr_t)__get_stack(thrd->curr_cor)->limit), "ERROR : $thread %p has been corrupted.\n StackPointer too large.\n", thrd );
+		/* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) < ((uintptr_t)__get_stack(thrd->curr_cor)->base ), "ERROR : $thread %p has been corrupted.\n StackPointer too small.\n", thrd );
+
+		thrd->state = Halting;
 		if( TICKET_RUNNING != thrd->ticket ) { abort( "Thread terminated with pending unpark" ); }
-		if( thrd != this->owner || this->recursion != 1) { abort( "Thread internal monitor has unbalanced recursion" ); }
+		if( thrd != this->owner ) { abort( "Thread internal monitor has incorrect owner" ); }
+		if( this->recursion != 1) { abort( "Thread internal monitor has unbalanced recursion" ); }
 
 		// Leave the thread
-		/* paranoid */ verify( ! __preemption_enabled() );
 		returnToKernel();
+
+		// Control flow should never reach here!
 		abort();
-
-		// Control flow should never reach here!
 	}
 }
Index: libcfa/src/concurrency/monitor.cfa
===================================================================
--- libcfa/src/concurrency/monitor.cfa	(revision b4130f981945eac8c1a3502df50beed667506743)
+++ libcfa/src/concurrency/monitor.cfa	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
@@ -142,4 +142,7 @@
 static void __dtor_enter( $monitor * this, fptr_t func, bool join ) {
 	$thread * thrd = active_thread();
+	#if defined( __CFA_WITH_VERIFY__ )
+		bool is_thrd = this == &thrd->self_mon;
+	#endif
 
 	// Lock the monitor spinlock
@@ -155,5 +158,6 @@
 		__set_owner( this, thrd );
 
-		verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
+		/* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
+		/* paranoid */ verify( !is_thrd || thrd->state == Halted || thrd->state == Cancelled );
 
 		unlock( this->lock );
@@ -166,4 +170,5 @@
 	}
 	// SKULLDUGGERY: join will act as a dtor so it would normally trigger to above check
+	// because join will not release the monitor after it executed.
 	// to avoid that it sets the owner to the special value thrd | 1p before exiting
 	else if( this->owner == ($thread*)(1 | (uintptr_t)thrd) ) {
@@ -172,11 +177,15 @@
 
 		// No one has the monitor, just take it
-		this->owner = thrd;
-
-		verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
+		__set_owner( this, thrd );
+
+		/* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
+		/* paranoid */ verify( !is_thrd || thrd->state == Halted || thrd->state == Cancelled );
 
 		unlock( this->lock );
 		return;
 	}
+
+	// The monitor is busy, if this is a thread and the thread owns itself, it better be active
+	/* paranoid */ verify( !is_thrd || this->owner != thrd || (thrd->state != Halted && thrd->state != Cancelled) );
 
 	__lock_size_t count = 1;
@@ -208,4 +217,7 @@
 		// Some one was waiting for us, enter
 		/* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
+
+		__cfaabi_dbg_print_safe( "Kernel : Destroying %p\n", this);
+		return;
 	}
 	else {
@@ -227,7 +239,4 @@
 		return;
 	}
-
-	__cfaabi_dbg_print_safe( "Kernel : Destroying %p\n", this);
-
 }
 
@@ -285,8 +294,13 @@
 
 	// Lock the monitor now
+	/* paranoid */ verify( 0x0D15EA5E0D15EA5Ep == thrd->canary );
 	/* paranoid */ verify( this->lock.lock );
+	/* paranoid */ verify( thrd->context.SP );
+	/* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) > ((uintptr_t)__get_stack(thrd->curr_cor)->limit), "ERROR : $thread %p has been corrupted.\n StackPointer too large.\n", thrd );
+	/* paranoid */ verifyf( ((uintptr_t)thrd->context.SP) < ((uintptr_t)__get_stack(thrd->curr_cor)->base ), "ERROR : $thread %p has been corrupted.\n StackPointer too small.\n", thrd );
+	/* paranoid */ verify( ! __preemption_enabled() );
+
 	/* paranoid */ verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", thrd, this->owner, this->recursion, this );
-	/* paranoid */ verify( ! __preemption_enabled() );
-	/* paranoid */ verify( thrd->state == Halted );
+	/* paranoid */ verify( thrd->state == Halting );
 	/* paranoid */ verify( this->recursion == 1 );
 
@@ -297,4 +311,7 @@
 	// Fetch the next thread, can be null
 	$thread * new_owner = next_thread( this );
+
+	// Mark the state as fully halted
+	thrd->state = Halted;
 
 	// Release the monitor lock
Index: libcfa/src/concurrency/thread.cfa
===================================================================
--- libcfa/src/concurrency/thread.cfa	(revision b4130f981945eac8c1a3502df50beed667506743)
+++ libcfa/src/concurrency/thread.cfa	(revision 7c9ac4af78fda11cf4e9558899fd4764524f22f5)
@@ -82,10 +82,15 @@
 		T & thrd, void(*defaultResumptionHandler)(ThreadCancelled(T) &)) {
 	$monitor * m = get_monitor(thrd);
+	$thread * desc = get_thread(thrd);
+
+	// Setup the monitor guard
 	void (*dtor)(T& mutex this) = ^?{};
 	bool join = defaultResumptionHandler != (void(*)(ThreadCancelled(T)&))0;
 	(this.mg){&m, (void(*)())dtor, join};
 
+
+	/* paranoid */ verifyf( Halted == desc->state || Cancelled == desc->state, "Expected thread to be Halted or Cancelled, was %d\n", (int)desc->state );
+
 	// After the guard set-up and any wait, check for cancellation.
-	$thread * desc = get_thread(thrd);
 	struct _Unwind_Exception * cancellation = desc->self_cor.cancellation;
 	if ( likely( 0p == cancellation ) ) {
