Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision d25b2d6b1b89b6a396a1fa4fbb2697d6f7e3ce3c)
+++ libcfa/src/concurrency/coroutine.cfa	(revision a00a2c125ed6c98b9dd8952920e10c8e5c2a5846)
@@ -10,6 +10,6 @@
 // Created On       : Mon Nov 28 12:27:26 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Oct 23 23:05:24 2020
-// Update Count     : 22
+// Last Modified On : Tue Dec 15 12:06:04 2020
+// Update Count     : 23
 //
 
@@ -28,4 +28,7 @@
 #include "kernel_private.hfa"
 #include "exception.hfa"
+#include "math.hfa"
+
+#define CFA_COROUTINE_USE_MMAP 0
 
 #define __CFA_INVOKE_PRIVATE__
@@ -85,6 +88,8 @@
 static const size_t MinStackSize = 1000;
 extern size_t __page_size;				// architecture pagesize HACK, should go in proper runtime singleton
+extern int __map_prot;
 
 void __stack_prepare( __stack_info_t * this, size_t create_size );
+void __stack_clean  ( __stack_info_t * this );
 
 //-----------------------------------------------------------------------------
@@ -107,16 +112,5 @@
 	bool userStack = ((intptr_t)this.storage & 0x1) != 0;
 	if ( ! userStack && this.storage ) {
-		__attribute__((may_alias)) intptr_t * istorage = (intptr_t *)&this.storage;
-		*istorage &= (intptr_t)-1;
-
-		void * storage = this.storage->limit;
-		__cfaabi_dbg_debug_do(
-			storage = (char*)(storage) - __page_size;
-			if ( mprotect( storage, __page_size, PROT_READ | PROT_WRITE ) == -1 ) {
-				abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
-			}
-		);
-		__cfaabi_dbg_print_safe("Kernel : Deleting stack %p\n", storage);
-		free( storage );
+		__stack_clean( &this );
 	}
 }
@@ -167,24 +161,58 @@
 	assert(__page_size != 0l);
 	size_t size = libCeiling( storageSize, 16 ) + stack_data_size;
+	size = ceiling(size, __page_size);
 
 	// If we are running debug, we also need to allocate a guardpage to catch stack overflows.
 	void * storage;
-	__cfaabi_dbg_debug_do(
-		storage = memalign( __page_size, size + __page_size );
-	);
-	__cfaabi_dbg_no_debug_do(
-		storage = (void*)malloc(size);
-	);
-
+	#if CFA_COROUTINE_USE_MMAP
+		storage = mmap(0p, size + __page_size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+		if(storage == ((void*)-1)) {
+			abort( "coroutine stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
+		}
+		if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
+			abort( "coroutine stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
+		} // if
+		storage = (void *)(((intptr_t)storage) + __page_size);
+	#else
+		__cfaabi_dbg_debug_do(
+			storage = memalign( __page_size, size + __page_size );
+		);
+		__cfaabi_dbg_no_debug_do(
+			storage = (void*)malloc(size);
+		);
+
+		__cfaabi_dbg_debug_do(
+			if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
+				abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) );
+			}
+			storage = (void *)(((intptr_t)storage) + __page_size);
+		);
+	#endif
 	__cfaabi_dbg_print_safe("Kernel : Created stack %p of size %zu\n", storage, size);
-	__cfaabi_dbg_debug_do(
-		if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
-			abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) );
-		}
-		storage = (void *)(((intptr_t)storage) + __page_size);
-	);
 
 	verify( ((intptr_t)storage & (libAlign() - 1)) == 0ul );
 	return [storage, size];
+}
+
+void __stack_clean  ( __stack_info_t * this ) {
+	size_t size = ((intptr_t)this->storage->base) - ((intptr_t)this->storage->limit) + sizeof(__stack_t);
+	void * storage = this->storage->limit;
+
+	#if CFA_COROUTINE_USE_MMAP
+		storage = (void *)(((intptr_t)storage) - __page_size);
+		if(munmap(storage, size + __page_size) == -1) {
+			abort( "coroutine stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );
+		}
+	#else
+		__cfaabi_dbg_debug_do(
+			storage = (char*)(storage) - __page_size;
+			if ( mprotect( storage, __page_size, __map_prot ) == -1 ) {
+				abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
+			}
+		);
+
+		free( storage );
+	#endif
+	__cfaabi_dbg_print_safe("Kernel : Deleting stack %p\n", storage);
 }
 
@@ -210,7 +238,7 @@
 	assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %zd bytes for a stack.", size, MinStackSize );
 
-	this->storage = (__stack_t *)((intptr_t)storage + size);
+	this->storage = (__stack_t *)((intptr_t)storage + size - sizeof(__stack_t));
 	this->storage->limit = storage;
-	this->storage->base  = (void*)((intptr_t)storage + size);
+	this->storage->base  = (void*)((intptr_t)storage + size - sizeof(__stack_t));
 	this->storage->exception_context.top_resume = 0p;
 	this->storage->exception_context.current_exception = 0p;
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision d25b2d6b1b89b6a396a1fa4fbb2697d6f7e3ce3c)
+++ libcfa/src/concurrency/coroutine.hfa	(revision a00a2c125ed6c98b9dd8952920e10c8e5c2a5846)
@@ -102,5 +102,7 @@
 }
 
-extern void __stack_prepare   ( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
+extern void __stack_prepare( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
+extern void __stack_clean  ( __stack_info_t * this );
+
 
 // Suspend implementation inlined for performance
@@ -142,8 +144,6 @@
 
 	if( unlikely(dst->context.SP == 0p) ) {
-		active_thread()->curr_cor = dst;
 		__stack_prepare(&dst->stack, 65000);
 		__cfactx_start(main, dst, cor, __cfactx_invoke_coroutine);
-		active_thread()->curr_cor = src;
 	}
 
Index: libcfa/src/concurrency/io/setup.cfa
===================================================================
--- libcfa/src/concurrency/io/setup.cfa	(revision d25b2d6b1b89b6a396a1fa4fbb2697d6f7e3ce3c)
+++ libcfa/src/concurrency/io/setup.cfa	(revision a00a2c125ed6c98b9dd8952920e10c8e5c2a5846)
@@ -17,4 +17,9 @@
 #define _GNU_SOURCE         /* See feature_test_macros(7) */
 
+#if defined(__CFA_DEBUG__)
+	// #define __CFA_DEBUG_PRINT_IO__
+	// #define __CFA_DEBUG_PRINT_IO_CORE__
+#endif
+
 #include "io/types.hfa"
 #include "kernel.hfa"
@@ -111,5 +116,5 @@
 
 	void __kernel_io_startup(void) {
-		__cfaabi_dbg_print_safe( "Kernel : Creating EPOLL instance\n" );
+		__cfadbg_print_safe(io_core, "Kernel : Creating EPOLL instance\n" );
 
 		iopoll.epollfd = epoll_create1(0);
@@ -118,5 +123,5 @@
 		}
 
-		__cfaabi_dbg_print_safe( "Kernel : Starting io poller thread\n" );
+		__cfadbg_print_safe(io_core, "Kernel : Starting io poller thread\n" );
 
 		iopoll.run = true;
@@ -132,6 +137,5 @@
 		// Wait for the io poller thread to finish
 
-		pthread_join( iopoll.thrd, 0p );
-		free( iopoll.stack );
+		__destroy_pthread( iopoll.thrd, iopoll.stack, 0p );
 
 		int ret = close(iopoll.epollfd);
@@ -142,5 +146,5 @@
 		// Io polling is now fully stopped
 
-		__cfaabi_dbg_print_safe( "Kernel : IO poller stopped\n" );
+		__cfadbg_print_safe(io_core, "Kernel : IO poller stopped\n" );
 	}
 
@@ -150,5 +154,5 @@
 		id.id = doregister(&id);
 		__cfaabi_tls.this_proc_id = &id;
-		__cfaabi_dbg_print_safe( "Kernel : IO poller thread starting\n" );
+		__cfadbg_print_safe(io_core, "Kernel : IO poller thread starting\n" );
 
 		// Block signals to control when they arrive
@@ -185,5 +189,5 @@
 		}
 
-		__cfaabi_dbg_print_safe( "Kernel : IO poller thread stopping\n" );
+		__cfadbg_print_safe(io_core, "Kernel : IO poller thread stopping\n" );
 		unregister(&id);
 		return 0p;
Index: libcfa/src/concurrency/kernel/startup.cfa
===================================================================
--- libcfa/src/concurrency/kernel/startup.cfa	(revision d25b2d6b1b89b6a396a1fa4fbb2697d6f7e3ce3c)
+++ libcfa/src/concurrency/kernel/startup.cfa	(revision a00a2c125ed6c98b9dd8952920e10c8e5c2a5846)
@@ -29,4 +29,7 @@
 #include "kernel_private.hfa"
 #include "startup.hfa"          // STARTUP_PRIORITY_XXX
+#include "math.hfa"
+
+#define CFA_PROCESSOR_USE_MMAP 0
 
 //-----------------------------------------------------------------------------
@@ -114,5 +117,5 @@
 }
 
-size_t __page_size = 0;
+extern size_t __page_size;
 
 //-----------------------------------------------------------------------------
@@ -158,6 +161,4 @@
 	/* paranoid */ verify( ! __preemption_enabled() );
 	__cfadbg_print_safe(runtime_core, "Kernel : Starting\n");
-
-	__page_size = sysconf( _SC_PAGESIZE );
 
 	__cfa_dbg_global_clusters.list{ __get };
@@ -539,4 +540,5 @@
 }
 
+extern size_t __page_size;
 void ^?{}(processor & this) with( this ){
 	if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
@@ -550,8 +552,5 @@
 	}
 
-	int err = pthread_join( kernel_thread, 0p );
-	if( err != 0 ) abort("KERNEL ERROR: joining processor %p caused error %s\n", &this, strerror(err));
-
-	free( this.stack );
+	__destroy_pthread( kernel_thread, this.stack, 0p );
 
 	disable_interrupts();
@@ -678,14 +677,26 @@
 
 	void * stack;
-	__cfaabi_dbg_debug_do(
-		stack = memalign( __page_size, stacksize + __page_size );
-		// pthread has no mechanism to create the guard page in user supplied stack.
+	#if CFA_PROCESSOR_USE_MMAP
+		stacksize = ceiling( stacksize, __page_size ) + __page_size;
+		stack = mmap(0p, stacksize, __map_prot, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+		if(stack == ((void*)-1)) {
+			abort( "pthread stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
+		}
 		if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
-			abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
+			abort( "pthread stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
 		} // if
-	);
-	__cfaabi_dbg_no_debug_do(
-		stack = malloc( stacksize );
-	);
+	#else
+		__cfaabi_dbg_debug_do(
+			stack = memalign( __page_size, stacksize + __page_size );
+			// pthread has no mechanism to create the guard page in user supplied stack.
+			if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
+				abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
+			} // if
+		);
+		__cfaabi_dbg_no_debug_do(
+			stack = malloc( stacksize );
+		);
+	#endif
+
 
 	check( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );
@@ -694,4 +705,28 @@
 	return stack;
 }
+
+void __destroy_pthread( pthread_t pthread, void * stack, void ** retval ) {
+	int err = pthread_join( pthread, retval );
+	if( err != 0 ) abort("KERNEL ERROR: joining pthread %p caused error %s\n", (void*)pthread, strerror(err));
+
+	#if CFA_PROCESSOR_USE_MMAP
+		pthread_attr_t attr;
+
+		check( pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute
+
+		size_t stacksize;
+		// default stack size, normally defined by shell limit
+		check( pthread_attr_getstacksize( &attr, &stacksize ), "pthread_attr_getstacksize" );
+		assert( stacksize >= PTHREAD_STACK_MIN );
+		stacksize += __page_size;
+
+		if(munmap(stack, stacksize) == -1) {
+			abort( "pthread stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );
+		}
+	#else
+		free( stack );
+	#endif
+}
+
 
 #if defined(__CFA_WITH_VERIFY__)
Index: libcfa/src/concurrency/kernel_private.hfa
===================================================================
--- libcfa/src/concurrency/kernel_private.hfa	(revision d25b2d6b1b89b6a396a1fa4fbb2697d6f7e3ce3c)
+++ libcfa/src/concurrency/kernel_private.hfa	(revision a00a2c125ed6c98b9dd8952920e10c8e5c2a5846)
@@ -49,4 +49,5 @@
 
 void * __create_pthread( pthread_t *, void * (*)(void *), void * );
+void __destroy_pthread( pthread_t pthread, void * stack, void ** retval );
 
 
Index: libcfa/src/concurrency/preemption.cfa
===================================================================
--- libcfa/src/concurrency/preemption.cfa	(revision d25b2d6b1b89b6a396a1fa4fbb2697d6f7e3ce3c)
+++ libcfa/src/concurrency/preemption.cfa	(revision a00a2c125ed6c98b9dd8952920e10c8e5c2a5846)
@@ -575,6 +575,5 @@
 	// Wait for the preemption thread to finish
 
-	pthread_join( alarm_thread, 0p );
-	free( alarm_stack );
+	__destroy_pthread( alarm_thread, alarm_stack, 0p );
 
 	// Preemption is now fully stopped
