Index: libcfa/src/concurrency/CtxSwitch-x86_64.S
===================================================================
--- libcfa/src/concurrency/CtxSwitch-x86_64.S	(revision 673cd637ca3377db61b5ca17aa0ec910e12ae819)
+++ libcfa/src/concurrency/CtxSwitch-x86_64.S	(revision 5b11c25668bf48e43c6bf9f0e7c460acb2ca76f5)
@@ -40,4 +40,6 @@
 #define FP_OFFSET	( 1 * PTR_BYTE )
 
+//-----------------------------------------------------------------------------
+// Regular context switch routine which enables switching from one context to anouther
 	.text
 	.align 2
@@ -77,10 +79,66 @@
 	.size  CtxSwitch, .-CtxSwitch
 
-.text
+//-----------------------------------------------------------------------------
+// Part of a 2 part context switch routine, use with CtxRet, stores the current context and then makes a function call
+	.text
 	.align 2
-.globl	CtxInvokeStub
+	.globl CtxStore
+	.type  CtxStore, @function
+CtxStore:
+
+	// Save volatile registers on the stack.
+
+	pushq %r15
+	pushq %r14
+	pushq %r13
+	pushq %r12
+	pushq %rbx
+
+	// Save old context in the "from" area.
+
+	movq %rsp,SP_OFFSET(%rdi)
+	movq %rbp,FP_OFFSET(%rdi)
+
+	// Don't load a new context, directly jump to the desired function
+
+	jmp *%rsi
+	.size  CtxStore, .-CtxStore
+
+//-----------------------------------------------------------------------------
+// Part of a 2 part context switch routine, use with CtxStore, context switches to the desired target without saving the current context
+	.text
+	.align 2
+	.globl CtxRet
+	.type  CtxRet, @function
+CtxRet:
+	// Load new context from the "to" area.
+
+	movq SP_OFFSET(%rdi),%rsp
+	movq FP_OFFSET(%rdi),%rbp
+
+	// Load volatile registers from the stack.
+
+	popq %rbx
+	popq %r12
+	popq %r13
+	popq %r14
+	popq %r15
+
+	// Return to thread.
+
+	ret
+	.size  CtxRet, .-CtxRet
+
+
+//-----------------------------------------------------------------------------
+// Stub used to create new stacks which are ready to be context switched to
+	.text
+	.align 2
+	.globl CtxInvokeStub
+	.type	 CtxInvokeStub, @function
 CtxInvokeStub:
 	movq %rbx, %rdi
 	jmp *%r12
+	.size  CtxInvokeStub, .-CtxInvokeStub
 
 // Local Variables: //
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision 673cd637ca3377db61b5ca17aa0ec910e12ae819)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 5b11c25668bf48e43c6bf9f0e7c460acb2ca76f5)
@@ -68,6 +68,6 @@
 
 	extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch");
-	// void CtxStore ( void * this ) asm ("CtxStore");
-	// void CtxRet   ( void * dst  ) asm ("CtxRet");
+	extern void CtxStore ( struct __stack_context_t * from, __attribute__((noreturn)) void (*__callback)(void) ) asm ("CtxStore");
+	extern void CtxRet   ( struct __stack_context_t * to ) asm ("CtxRet") __attribute__ ((__noreturn__));
 }
 
@@ -172,35 +172,52 @@
 }
 
-
-
-// static inline bool suspend_checkpoint(void) {
-// 	// optimization : read TLS once and reuse it
-// 	// Safety note: this is preemption safe since if
-// 	// preemption occurs after this line, the pointer
-// 	// will also migrate which means this value will
-// 	// stay in syn with the TLS
-// 	// set state of current coroutine to inactive
-//       this->state = Checkpoint;
-
-//       // context switch to specified coroutine
-//       assert( src->stack.context );
-
-//       CtxStore(src->stack.context);
-
-// 	bool ret = this->state == Checkpoint;
-
-//       // set state of new coroutine to active
-//       src->state = Active;
-
-//       enable_interrupts( __cfaabi_dbg_ctx );
-//       // Safety note : This could cause some false positives due to preemption
-//       verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
-
-//       if( unlikely(src->cancellation != NULL) ) {
-//             _CtxCoroutine_Unwind(src->cancellation);
-//       }
-
-// 	return ret;
-// }
+static inline void suspend_then(fptr_t call) {
+	// optimization : read TLS once and reuse it
+	// Safety note: this is preemption safe since if
+	// preemption occurs after this line, the pointer
+	// will also migrate which means this value will
+	// stay in syn with the TLS
+	coroutine_desc * src = TL_GET( this_thread )->curr_cor;
+
+	assertf( src->last != 0,
+		"Attempt to suspend coroutine \"%.256s\" (%p) that has never been resumed.\n"
+		"Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
+		src->name, src );
+	assertf( src->last->state != Halted,
+		"Attempt by coroutine \"%.256s\" (%p) to suspend back to terminated coroutine \"%.256s\" (%p).\n"
+		"Possible cause is terminated coroutine's main routine has already returned.",
+		src->name, src, src->last->name, src->last );
+
+	src->state = PreInactive;
+
+      // context switch to specified coroutine
+      assert( src->context.SP );
+
+	__attribute__((noreturn)) void __suspend_callback(void) {
+		call();
+
+		// set state of current coroutine to inactive
+		src->state = src->state == Halted ? Halted : Inactive;
+
+		TL_GET( this_thread )->curr_cor = src->last;
+
+		// context switch to specified coroutine
+		assert( src->last->context.SP );
+		CtxRet( &src->last->context );
+
+		abort();
+	}
+      CtxStore( &src->context, __suspend_callback );
+	// when CtxStore returns we are back in the src coroutine
+
+	// set state of new coroutine to active
+	src->state = Active;
+
+	if( unlikely(src->cancellation != NULL) ) {
+		_CtxCoroutine_Unwind(src->cancellation, src);
+	}
+
+	return;
+}
 
 // static inline void suspend_return(void) {
Index: libcfa/src/concurrency/invoke.h
===================================================================
--- libcfa/src/concurrency/invoke.h	(revision 673cd637ca3377db61b5ca17aa0ec910e12ae819)
+++ libcfa/src/concurrency/invoke.h	(revision 5b11c25668bf48e43c6bf9f0e7c460acb2ca76f5)
@@ -93,5 +93,5 @@
 	};
 
-	enum coroutine_state { Halted, Start, Inactive, Active, Primed };
+	enum coroutine_state { Halted, Start, Inactive, Active, Primed, PreInactive };
 
 	struct coroutine_desc {
