Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision b4b63e8f7b73b2f77b154650ba47a2df216a9713)
+++ libcfa/src/concurrency/kernel.cfa	(revision 0190480ad9dd1345c67a816a96d7e00dbe611252)
@@ -237,4 +237,7 @@
 	$coroutine * proc_cor = get_coroutine(this->runner);
 
+	// Update global state
+	kernelTLS.this_thread = thrd_dst;
+
 	// set state of processor coroutine to inactive
 	verify(proc_cor->state == Active);
@@ -246,29 +249,24 @@
 		thrd_dst->state = Active;
 
-		// Update global state
-		kernelTLS.this_thread = thrd_dst;
+		__cfaabi_dbg_debug_do(
+			thrd_dst->park_stale   = true;
+			thrd_dst->unpark_stale = true;
+		)
 
 		/* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
 		/* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
-		/* paranoid */ verify( thrd_dst->context.SP );
 		/* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor
 		/* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor
-		/* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_dst->canary );
-
-
 
 		// set context switch to the thread that the processor is executing
+		verify( thrd_dst->context.SP );
 		__cfactx_switch( &proc_cor->context, &thrd_dst->context );
 		// when __cfactx_switch returns we are back in the processor coroutine
 
-		/* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_dst->canary );
 		/* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst );
 		/* 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( kernelTLS.this_thread == thrd_dst );
 		/* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
 
-		// Reset global state
-		kernelTLS.this_thread = 0p;
 
 		// We just finished running a thread, there are a few things that could have happened.
@@ -288,5 +286,5 @@
 			// The thread has halted, it should never be scheduled/run again
 			// We may need to wake someone up here since
-			unpark( this->destroyer );
+			unpark( this->destroyer __cfaabi_dbg_ctx2 );
 			this->destroyer = 0p;
 			break RUNNING;
@@ -298,4 +296,5 @@
 		// set state of processor coroutine to active and the thread to inactive
 		int old_ticket = __atomic_fetch_sub(&thrd_dst->ticket, 1, __ATOMIC_SEQ_CST);
+		__cfaabi_dbg_debug_do( thrd_dst->park_result = old_ticket; )
 		switch(old_ticket) {
 			case 1:
@@ -314,4 +313,5 @@
 	// Just before returning to the processor, set the processor coroutine to active
 	proc_cor->state = Active;
+	kernelTLS.this_thread = 0p;
 
 	/* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
@@ -334,8 +334,6 @@
 			__x87_store;
 		#endif
-		/* paranoid */ verify( proc_cor->context.SP );
-		/* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_src->canary );
+		verify( proc_cor->context.SP );
 		__cfactx_switch( &thrd_src->context, &proc_cor->context );
-		/* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_src->canary );
 		#if defined( __i386 ) || defined( __x86_64 )
 			__x87_load;
@@ -369,6 +367,4 @@
 	/* paranoid */ #endif
 	/* paranoid */ verifyf( thrd->link.next == 0p, "Expected null got %p", thrd->link.next );
-	/* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd->canary );
-
 
 	if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready;
@@ -407,6 +403,10 @@
 
 // KERNEL ONLY unpark with out disabling interrupts
-void __unpark(  struct __processor_id_t * id, $thread * thrd ) {
+void __unpark(  struct __processor_id_t * id, $thread * thrd __cfaabi_dbg_ctx_param2 ) {
+	// record activity
+	__cfaabi_dbg_record_thrd( *thrd, false, caller );
+
 	int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
+	__cfaabi_dbg_debug_do( thrd->unpark_result = old_ticket; thrd->unpark_state = thrd->state; )
 	switch(old_ticket) {
 		case 1:
@@ -426,17 +426,20 @@
 }
 
-void unpark( $thread * thrd ) {
+void unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) {
 	if( !thrd ) return;
 
 	disable_interrupts();
-	__unpark( (__processor_id_t*)kernelTLS.this_processor, thrd );
+	__unpark( (__processor_id_t*)kernelTLS.this_processor, thrd __cfaabi_dbg_ctx_fwd2 );
 	enable_interrupts( __cfaabi_dbg_ctx );
 }
 
-void park( void ) {
+void park( __cfaabi_dbg_ctx_param ) {
 	/* paranoid */ verify( kernelTLS.preemption_state.enabled );
 	disable_interrupts();
 	/* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
 	/* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION );
+
+	// record activity
+	__cfaabi_dbg_record_thrd( *kernelTLS.this_thread, true, caller );
 
 	returnToKernel();
@@ -518,5 +521,5 @@
 	disable_interrupts();
 		/* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
-		post( this->idle );
+		bool ret = post( this->idle );
 	enable_interrupts( __cfaabi_dbg_ctx );
 }
@@ -646,5 +649,5 @@
 		// atomically release spin lock and block
 		unlock( lock );
-		park();
+		park( __cfaabi_dbg_ctx );
 		return true;
 	}
@@ -667,5 +670,5 @@
 
 	// make new owner
-	unpark( thrd );
+	unpark( thrd __cfaabi_dbg_ctx2 );
 
 	return thrd != 0p;
@@ -678,5 +681,5 @@
 	count += diff;
 	for(release) {
-		unpark( pop_head( waiting ) );
+		unpark( pop_head( waiting ) __cfaabi_dbg_ctx2 );
 	}
 
@@ -694,4 +697,15 @@
 			this.prev_thrd = kernelTLS.this_thread;
 		}
+
+		void __cfaabi_dbg_record_thrd($thread & this, bool park, const char prev_name[]) {
+			if(park) {
+				this.park_caller   = prev_name;
+				this.park_stale    = false;
+			}
+			else {
+				this.unpark_caller = prev_name;
+				this.unpark_stale  = false;
+			}
+		}
 	}
 )
