Index: automake/cfa.m4
===================================================================
--- automake/cfa.m4	(revision d97c3a4b9cfd1040061ab2ac4708294336c5404b)
+++ automake/cfa.m4	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
@@ -73,4 +73,5 @@
 		"arm"        ) cannon_arch_name="arm";;
 		"ARM"        ) cannon_arch_name="arm";;
+		"armv7l"     ) cannon_arch_name="arm";;
 		*)
 		>&2 echo "Unkown architecture " $arch_name;
Index: configure
===================================================================
--- configure	(revision d97c3a4b9cfd1040061ab2ac4708294336c5404b)
+++ configure	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
@@ -3550,4 +3550,5 @@
 		"arm"        ) cannon_arch_name="arm";;
 		"ARM"        ) cannon_arch_name="arm";;
+		"armv7l"     ) cannon_arch_name="arm";;
 		*)
 		>&2 echo "Unkown architecture " $arch_name;
@@ -3590,4 +3591,5 @@
 		"arm"        ) cannon_arch_name="arm";;
 		"ARM"        ) cannon_arch_name="arm";;
+		"armv7l"     ) cannon_arch_name="arm";;
 		*)
 		>&2 echo "Unkown architecture " $arch_name;
Index: libcfa/src/concurrency/CtxSwitch-arm.S
===================================================================
--- libcfa/src/concurrency/CtxSwitch-arm.S	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
+++ libcfa/src/concurrency/CtxSwitch-arm.S	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
@@ -0,0 +1,62 @@
+	@ 32 bit ARM context switch
+	@ This function assumes that r9 has no special meaning on the platform it's
+	@ being built on.
+	@ If r9 is special, uncomment the following line and it will be left alone
+
+	@ #define R9_SPECIAL
+
+	#define PTR_BYTE        4
+	#define SP_OFFSET       ( 0 * PTR_BYTE )
+	#define FP_OFFSET       ( 1 * PTR_BYTE )
+	#define PC_OFFSET       ( 2 * PTR_BYTE )
+
+	.text
+	.align  2
+	.global CtxSwitch
+	.type   CtxSwitch, %function
+
+CtxSwitch:
+	@ save callee-saved registers: r4-r8, r10, r11, r13(sp) (plus r9 depending on platform specification)
+	@ I've seen reference to 31 registers on 64-bit, if this is the case, more need to be saved
+	@ save thread state registers: r14(lr)
+	@ r12(ip) is intra-procedure-call scratch register, does not need saving between function calls
+
+	#ifdef R9_SPECIAL
+	stmfd r13!, {r4-r8,r10,r11,r14}
+	#else
+	stmfd r13!, {r4-r11,r14}
+	#endif // R9_SPECIAL
+
+	@ save floating point registers: s16-s31
+	vstmdb r13!, {s16-s31}
+
+	@ save frame pointer and stack pointer to outgoing datastructure
+	str sp, [r0, #SP_OFFSET]
+	str fp, [r0, #FP_OFFSET]
+
+	@ restore frame pointer and stack pointer from incoming datastructure
+	ldr fp, [r1, #FP_OFFSET]
+	ldr sp, [r1, #SP_OFFSET]
+
+	@ restore floating point registers: s16-s31
+	vldm r13!, {s16-s31}
+	@ restore r14(lr)
+	@ restore 64-bit extra registers?
+	@ restore callee-saved registers: r4-r8, r10, r11, r13
+
+	#ifdef R9_SPECIAL
+	ldmfd r13!, {r4-r8,r10,r11,r15}
+	#else
+	ldmfd r13!, {r4-r11,r14}    @ loading r14 back into r15 returns
+
+	mov r15, r14
+	#endif // R9_SPECIAL
+	
+	.text
+	.align  2
+	.global CtxInvokeStub
+	.type   CtxInvokeStub, %function
+
+CtxInvokeStub:
+        ldmfd r13!, {r0-r1}
+	mov r15, r1
Index: bcfa/src/concurrency/CtxSwitch-armv7l.S
===================================================================
--- libcfa/src/concurrency/CtxSwitch-armv7l.S	(revision d97c3a4b9cfd1040061ab2ac4708294336c5404b)
+++ 	(revision )
@@ -1,62 +1,0 @@
-	@ 32 bit ARM context switch
-	@ This function assumes that r9 has no special meaning on the platform it's
-	@ being built on.
-	@ If r9 is special, uncomment the following line and it will be left alone
-
-	@ #define R9_SPECIAL
-
-	#define PTR_BYTE        4
-	#define SP_OFFSET       ( 0 * PTR_BYTE )
-	#define FP_OFFSET       ( 1 * PTR_BYTE )
-	#define PC_OFFSET       ( 2 * PTR_BYTE )
-
-	.text
-	.align  2
-	.global CtxSwitch
-	.type   CtxSwitch, %function
-
-CtxSwitch:
-	@ save callee-saved registers: r4-r8, r10, r11, r13(sp) (plus r9 depending on platform specification)
-	@ I've seen reference to 31 registers on 64-bit, if this is the case, more need to be saved
-	@ save thread state registers: r14(lr)
-	@ r12(ip) is intra-procedure-call scratch register, does not need saving between function calls
-
-	#ifdef R9_SPECIAL
-	stmfd r13!, {r4-r8,r10,r11,r14}
-	#else
-	stmfd r13!, {r4-r11,r14}
-	#endif // R9_SPECIAL
-
-	@ save floating point registers: s16-s31
-	vstmdb r13!, {s16-s31}
-
-	@ save frame pointer and stack pointer to outgoing datastructure
-	str sp, [r0, #SP_OFFSET]
-	str fp, [r0, #FP_OFFSET]
-
-	@ restore frame pointer and stack pointer from incoming datastructure
-	ldr fp, [r1, #FP_OFFSET]
-	ldr sp, [r1, #SP_OFFSET]
-
-	@ restore floating point registers: s16-s31
-	vldm r13!, {s16-s31}
-	@ restore r14(lr)
-	@ restore 64-bit extra registers?
-	@ restore callee-saved registers: r4-r8, r10, r11, r13
-
-	#ifdef R9_SPECIAL
-	ldmfd r13!, {r4-r8,r10,r11,r15}
-	#else
-	ldmfd r13!, {r4-r11,r14}    @ loading r14 back into r15 returns
-
-	mov r15, r14
-	#endif // R9_SPECIAL
-	
-	.text
-	.align  2
-	.global CtxInvokeStub
-	.type   CtxInvokeStub, %function
-
-CtxInvokeStub:
-        ldmfd r13!, {r0-r1}
-	mov r15, r1
Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision d97c3a4b9cfd1040061ab2ac4708294336c5404b)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
@@ -22,4 +22,8 @@
 #include <string.h>
 #include <unistd.h>
+// use this define to make unwind.h play nice, definetely a hack
+#define HIDE_EXPORTS
+#include <unwind.h>
+#undef HIDE_EXPORTS
 #include <sys/mman.h>
 }
@@ -29,4 +33,12 @@
 #define __CFA_INVOKE_PRIVATE__
 #include "invoke.h"
+
+extern "C" {
+      void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) __attribute__ ((__noreturn__));
+      static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) __attribute__ ((__noreturn__));
+      static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) {
+            abort();
+      }
+}
 
 //-----------------------------------------------------------------------------
@@ -67,7 +79,26 @@
       starter = NULL;
       last = NULL;
-}
-
-void ^?{}(coroutine_desc& this) {}
+      cancellation = NULL;
+}
+
+void ^?{}(coroutine_desc& this) {
+      if(this.state != Halted) {
+            coroutine_desc * src = TL_GET( this_coroutine );
+            coroutine_desc * dst = &this;
+
+            struct _Unwind_Exception storage;
+            storage.exception_class = -1;
+            storage.exception_cleanup = _CtxCoroutine_UnwindCleanup;
+            this.cancellation = &storage;
+            this.last = src;
+
+	      // not resuming self ?
+	      if ( src == dst ) {
+		      abort( "Attempt by coroutine %.256s (%p) to terminate itself.\n", src->name, src );
+            }
+
+	      CoroutineCtxSwitch( src, dst );
+      }
+}
 
 // Part of the Public API
@@ -105,4 +136,8 @@
       // 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);
+      }
 } //ctxSwitchDirect
 
@@ -162,17 +197,20 @@
       }
 
-      void __leave_coroutine(void) {
+      void __leave_coroutine() {
             coroutine_desc * src = TL_GET( this_coroutine ); // optimization
-
-            assertf( src->starter != 0,
+            coroutine_desc * starter = src->cancellation != 0 ? src->last : src->starter;
+
+            src->state = Halted;
+
+            assertf( starter != 0,
                   "Attempt to suspend/leave 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->starter->state != Halted,
+            assertf( starter->state != Halted,
                   "Attempt by coroutine \"%.256s\" (%p) to suspend/leave back to terminated coroutine \"%.256s\" (%p).\n"
                   "Possible cause is terminated coroutine's main routine has already returned.",
-                  src->name, src, src->starter->name, src->starter );
-
-            CoroutineCtxSwitch( src, src->starter );
+                  src->name, src, starter->name, starter );
+
+            CoroutineCtxSwitch( src, starter );
       }
 }
Index: libcfa/src/concurrency/invoke.c
===================================================================
--- libcfa/src/concurrency/invoke.c	(revision d97c3a4b9cfd1040061ab2ac4708294336c5404b)
+++ libcfa/src/concurrency/invoke.c	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
@@ -17,4 +17,5 @@
 #include <stdlib.h>
 #include <stdio.h>
+#include <unwind.h>
 
 #include "invoke.h"
@@ -50,9 +51,33 @@
 	main( this );
 
-	cor->state = Halted;
-
 	//Final suspend, should never return
 	__leave_coroutine();
 	__cabi_abort( "Resumed dead coroutine" );
+}
+
+static _Unwind_Reason_Code _CtxCoroutine_UnwindStop(
+	__attribute((__unused__)) int version,
+	_Unwind_Action actions,
+	__attribute((__unused__)) _Unwind_Exception_Class exceptionClass,
+	__attribute((__unused__)) struct _Unwind_Exception * unwind_exception,
+	__attribute((__unused__)) struct _Unwind_Context * context,
+	__attribute((__unused__)) void * param
+) {
+	if( actions & _UA_END_OF_STACK  ) {
+		// We finished unwinding the coroutine,
+		// leave it
+		__leave_coroutine();
+		__cabi_abort( "Resumed dead coroutine" );
+	}
+	if( actions & _UA_CLEANUP_PHASE ) return _URC_NO_REASON;
+
+	return _URC_FATAL_PHASE2_ERROR;
+}
+
+void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) __attribute__ ((__noreturn__));
+void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) {
+	_Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, NULL );
+	printf("UNWIND ERROR %d after force unwind\n", ret);
+	abort();
 }
 
Index: libcfa/src/concurrency/invoke.h
===================================================================
--- libcfa/src/concurrency/invoke.h	(revision d97c3a4b9cfd1040061ab2ac4708294336c5404b)
+++ libcfa/src/concurrency/invoke.h	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
@@ -80,12 +80,27 @@
 
 	struct coroutine_desc {
-		struct coStack_t stack;							// stack information of the coroutine
-		const char * name;								// textual name for coroutine/task, initialized by uC++ generated code
-		int errno_;										// copy of global UNIX variable errno
-		enum coroutine_state state;						// current execution status for coroutine
-		struct coroutine_desc * starter;				// first coroutine to resume this one
-		struct coroutine_desc * last;					// last coroutine to resume this one
-	};
-
+		// stack information of the coroutine
+		struct coStack_t stack;
+
+		// textual name for coroutine/task, initialized by uC++ generated code
+		const char * name;
+
+		// copy of global UNIX variable errno
+		int errno_;
+
+		// current execution status for coroutine
+		enum coroutine_state state;
+		// first coroutine to resume this one
+		struct coroutine_desc * starter;
+
+		// last coroutine to resume this one
+		struct coroutine_desc * last;
+
+		// If non-null stack must be unwound with this exception
+		struct _Unwind_Exception * cancellation;
+
+	};
+
+	// struct which calls the monitor is accepting
 	struct __waitfor_mask_t {
 		// the index of the accepted function, -1 if none
Index: tests/coroutine/pingpong.cfa
===================================================================
--- tests/coroutine/pingpong.cfa	(revision d97c3a4b9cfd1040061ab2ac4708294336c5404b)
+++ tests/coroutine/pingpong.cfa	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
@@ -24,4 +24,5 @@
 
 void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) {
+	(this.__cor){name};
 	this.name = name;
 	this.N = N;
Index: tests/test.py
===================================================================
--- tests/test.py	(revision d97c3a4b9cfd1040061ab2ac4708294336c5404b)
+++ tests/test.py	(revision 52ffa30aa99274381f3378ddebbe6301748191ef)
@@ -19,5 +19,5 @@
 
 	def matchTest(path):
-		match = re.search("%s\/([\w\/\-_]*).expect\/([\w\-_]+)(\.[\w\-_]+)?\.txt" % settings.SRCDIR, path)
+		match = re.search("^%s\/([\w\/\-_]*).expect\/([\w\-_]+)(\.[\w\-_]+)?\.txt$" % settings.SRCDIR, path)
 		if match :
 			test = Test()
