Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/Makefile.am	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -186,5 +186,5 @@
 if ENABLE_DISTCC
 
-../prelude/distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ ../prelude/gcc-builtins.cf ../prelude/builtins.cf ../prelude/extras.cf ../prelude/prelude.cfa ../prelude/bootloader.c $(srcdir)/../../tools/build/push2dist.sh
+../prelude/distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ ../prelude/defines.hfa ../prelude/gcc-builtins.cf ../prelude/builtins.cf ../prelude/extras.cf ../prelude/prelude.cfa ../prelude/bootloader.c $(srcdir)/../../tools/build/push2dist.sh
 	@+make -C ../prelude distribution
 
Index: libcfa/src/bits/defs.hfa
===================================================================
--- libcfa/src/bits/defs.hfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/bits/defs.hfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -24,5 +24,4 @@
 #define likely(x)   __builtin_expect(!!(x), 1)
 #define unlikely(x) __builtin_expect(!!(x), 0)
-#define thread_local _Thread_local
 
 typedef void (*fptr_t)();
@@ -37,5 +36,21 @@
 #endif
 
+
+#if defined(__has_attribute)
+#if !__has_attribute(__noclone__)
+#define ATTRIBUTE_NOCLONE
+#endif
+#endif
+#ifndef ATTRIBUTE_NOCLONE
+#define ATTRIBUTE_NOCLONE __attribute__((__noclone__))
+#endif
+
 #define libcfa_public __attribute__((visibility("default")))
+#define libcfa_nopreempt __attribute__((section("cfatext_nopreempt"))) __attribute__((__noinline__)) ATTRIBUTE_NOCLONE
+
+struct __cfa_nopreempt_region {
+	void * start;
+	void * stop;
+};
 
 #ifdef __cforall
Index: libcfa/src/bits/locks.hfa
===================================================================
--- libcfa/src/bits/locks.hfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/bits/locks.hfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -13,6 +13,6 @@
 // Created On       : Tue Oct 31 15:14:38 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Aug 27 15:06:39 2022
-// Update Count     : 15
+// Last Modified On : Mon Sep 19 18:39:45 2022
+// Update Count     : 16
 //
 
Index: libcfa/src/concurrency/io/call.cfa.in
===================================================================
--- libcfa/src/concurrency/io/call.cfa.in	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/concurrency/io/call.cfa.in	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -202,16 +202,9 @@
 		struct io_context$ * ctx = cfa_io_allocate( &sqe, &idx, 1 );
 
+		memset(sqe, 0, sizeof(*sqe));
 		sqe->opcode = IORING_OP_{op};
+		sqe->flags = sflags;
 		sqe->user_data = (uintptr_t)&future;
-		sqe->flags = sflags;
-		sqe->ioprio = 0;
-		sqe->fd = 0;
-		sqe->off = 0;
-		sqe->addr = 0;
-		sqe->len = 0;
-		sqe->fsync_flags = 0;
-		sqe->__pad2[0] = 0;
-		sqe->__pad2[1] = 0;
-		sqe->__pad2[2] = 0;{body}
+		{body}
 
 		asm volatile("": : :"memory");
Index: libcfa/src/concurrency/io/setup.cfa
===================================================================
--- libcfa/src/concurrency/io/setup.cfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/concurrency/io/setup.cfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -228,4 +228,5 @@
 
 		#if !defined(CFA_WITH_IO_URING_IDLE)
+		{
 			// Step 4 : eventfd
 			__cfadbg_print_safe(io_core, "Kernel I/O : registering %d for completion with ring %d\n", procfd, fd);
@@ -237,7 +238,12 @@
 
 			__cfadbg_print_safe(io_core, "Kernel I/O : registered %d for completion with ring %d\n", procfd, fd);
-		#endif
-
+		}
+		#endif
+
+		// TODO: implement a proper version of this.
+		// I have not found a better maximum that works in general but users should be able to configure it
+		// the same way they configure other I/O options
 		// #if defined(CFA_HAVE_IORING_REGISTER_IOWQ_MAX_WORKERS)
+		// {
 		// 	// Step 5 : max worker count
 		// 	__cfadbg_print_safe(io_core, "Kernel I/O : lmiting max workers for ring %d\n", fd);
@@ -252,4 +258,5 @@
 
 		// 	__cfadbg_print_safe(io_core, "Kernel I/O : lmited max workers for ring %d\n", fd);
+		// }
 		// #endif
 
Index: libcfa/src/concurrency/kernel/cluster.hfa
===================================================================
--- libcfa/src/concurrency/kernel/cluster.hfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/concurrency/kernel/cluster.hfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -63,5 +63,5 @@
 		}
 	}
-	return (max + 2 * max) / 2;
+	return 8 * max;
 }
 
Index: libcfa/src/concurrency/kernel/fwd.hfa
===================================================================
--- libcfa/src/concurrency/kernel/fwd.hfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/concurrency/kernel/fwd.hfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -35,5 +35,5 @@
 extern "C" {
 	extern "Cforall" {
-		extern __attribute__((aligned(64))) thread_local struct KernelThreadData {
+		extern __attribute__((aligned(64))) __thread struct KernelThreadData {
 			struct thread$          * volatile this_thread;
 			struct processor        * volatile this_processor;
@@ -179,8 +179,9 @@
 		// Similar to a binary semaphore with a 'one shot' semantic
 		// is expected to be discarded after each party call their side
+		enum(struct thread$ *) { oneshot_ARMED = 0p, oneshot_FULFILLED = 1p };
 		struct oneshot {
 			// Internal state :
-			//     0p     : is initial state (wait will block)
-			//     1p     : fulfilled (wait won't block)
+			// armed      : initial state, wait will block
+			// fulfilled  : wait won't block
 			// any thread : a thread is currently waiting
 			struct thread$ * volatile ptr;
@@ -189,5 +190,5 @@
 		static inline {
 			void  ?{}(oneshot & this) {
-				this.ptr = 0p;
+				this.ptr = oneshot_ARMED;
 			}
 
@@ -199,8 +200,8 @@
 				for() {
 					struct thread$ * expected = this.ptr;
-					if(expected == 1p) return false;
+					if(expected == oneshot_FULFILLED) return false;
 					if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
 						park();
-						/* paranoid */ verify( this.ptr == 1p );
+						/* paranoid */ verify( this.ptr == oneshot_FULFILLED );
 						return true;
 					}
@@ -211,6 +212,6 @@
 			// return true if a thread was unparked
 			thread$ * post(oneshot & this, bool do_unpark = true) {
-				struct thread$ * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
-				if( got == 0p || got == 1p ) return 0p;
+				struct thread$ * got = __atomic_exchange_n( &this.ptr, oneshot_FULFILLED, __ATOMIC_SEQ_CST);
+				if( got == oneshot_ARMED || got == oneshot_FULFILLED ) return 0p;
 				if(do_unpark) unpark( got );
 				return got;
@@ -223,10 +224,11 @@
 		// thread on "any of" [a given set of] futures.
 		// does not support multiple threads waiting on the same future
+		enum(struct oneshot *) { future_ARMED = 0p, future_FULFILLED = 1p, future_PROGRESS = 2p, future_ABANDONED = 3p };
 		struct future_t {
 			// Internal state :
-			//     0p      : is initial state (wait will block)
-			//     1p      : fulfilled (wait won't block)
-			//     2p      : in progress ()
-			//     3p      : abandoned, server should delete
+			// armed       : initial state, wait will block
+			// fulfilled   : result is ready, wait won't block
+			// progress    : someone else is in the process of fulfilling this
+			// abandoned   : client no longer cares, server should delete
 			// any oneshot : a context has been setup to wait, a thread could wait on it
 			struct oneshot * volatile ptr;
@@ -235,5 +237,5 @@
 		static inline {
 			void  ?{}(future_t & this) {
-				this.ptr = 0p;
+				this.ptr = future_ARMED;
 			}
 
@@ -242,11 +244,11 @@
 			void reset(future_t & this) {
 				// needs to be in 0p or 1p
-				__atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);
+				__atomic_exchange_n( &this.ptr, future_ARMED, __ATOMIC_SEQ_CST);
 			}
 
 			// check if the future is available
 			bool available( future_t & this ) {
-				while( this.ptr == 2p ) Pause();
-				return this.ptr == 1p;
+				while( this.ptr == future_PROGRESS ) Pause();
+				return this.ptr == future_FULFILLED;
 			}
 
@@ -254,10 +256,10 @@
 			// intented to be use by wait, wait_any, waitfor, etc. rather than used directly
 			bool setup( future_t & this, oneshot & wait_ctx ) {
-				/* paranoid */ verify( wait_ctx.ptr == 0p || wait_ctx.ptr == 1p );
+				/* paranoid */ verify( wait_ctx.ptr == oneshot_ARMED || wait_ctx.ptr == oneshot_FULFILLED );
 				// The future needs to set the wait context
 				for() {
 					struct oneshot * expected = this.ptr;
 					// Is the future already fulfilled?
-					if(expected == 1p) return false; // Yes, just return false (didn't block)
+					if(expected == future_FULFILLED) return false; // Yes, just return false (didn't block)
 
 					// The future is not fulfilled, try to setup the wait context
@@ -277,22 +279,22 @@
 
 				// attempt to remove the context so it doesn't get consumed.
-				if(__atomic_compare_exchange_n( &this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
+				if(__atomic_compare_exchange_n( &this.ptr, &expected, future_ARMED, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
 					// we still have the original context, then no one else saw it
 					return false;
 				}
 
-				// expected == 0p: future was never actually setup, just return
-				if( expected == 0p ) return false;
-
-				// expected == 1p: the future is ready and the context was fully consumed
+				// expected == ARMED: future was never actually setup, just return
+				if( expected == future_ARMED ) return false;
+
+				// expected == FULFILLED: the future is ready and the context was fully consumed
 				// the server won't use the pointer again
 				// It is safe to delete (which could happen after the return)
-				if( expected == 1p ) return true;
-
-				// expected == 2p: the future is ready but the context hasn't fully been consumed
+				if( expected == future_FULFILLED ) return true;
+
+				// expected == PROGRESS: the future is ready but the context hasn't fully been consumed
 				// spin until it is safe to move on
-				if( expected == 2p ) {
-					while( this.ptr != 1p ) Pause();
-					/* paranoid */ verify( this.ptr == 1p );
+				if( expected == future_PROGRESS ) {
+					while( this.ptr != future_FULFILLED ) Pause();
+					/* paranoid */ verify( this.ptr == future_FULFILLED );
 					return true;
 				}
@@ -305,21 +307,21 @@
 			// Mark the future as abandoned, meaning it will be deleted by the server
 			bool abandon( future_t & this ) {
-				/* paranoid */ verify( this.ptr != 3p );
+				/* paranoid */ verify( this.ptr != future_ABANDONED );
 
 				// Mark the future as abandonned
-				struct oneshot * got = __atomic_exchange_n( &this.ptr, 3p, __ATOMIC_SEQ_CST);
+				struct oneshot * got = __atomic_exchange_n( &this.ptr, future_ABANDONED, __ATOMIC_SEQ_CST);
 
 				// If the future isn't already fulfilled, let the server delete it
-				if( got == 0p ) return false;
-
-				// got == 2p: the future is ready but the context hasn't fully been consumed
+				if( got == future_ARMED ) return false;
+
+				// got == PROGRESS: the future is ready but the context hasn't fully been consumed
 				// spin until it is safe to move on
-				if( got == 2p ) {
-					while( this.ptr != 1p ) Pause();
-					got = 1p;
+				if( got == future_PROGRESS ) {
+					while( this.ptr != future_FULFILLED ) Pause();
+					got = future_FULFILLED;
 				}
 
 				// The future is completed delete it now
-				/* paranoid */ verify( this.ptr != 1p );
+				/* paranoid */ verify( this.ptr != future_FULFILLED );
 				free( &this );
 				return true;
@@ -336,19 +338,19 @@
 						#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
 					#endif
-						if( expected == 3p ) { free( &this ); return 0p; }
+						if( expected == future_ABANDONED ) { free( &this ); return 0p; }
 					#if defined(__GNUC__) && __GNUC__ >= 7
 						#pragma GCC diagnostic pop
 					#endif
 
-					/* paranoid */ verify( expected != 1p ); // Future is already fulfilled, should not happen
-					/* paranoid */ verify( expected != 2p ); // Future is bein fulfilled by someone else, this is even less supported then the previous case.
+					/* paranoid */ verify( expected != future_FULFILLED ); // Future is already fulfilled, should not happen
+					/* paranoid */ verify( expected != future_PROGRESS ); // Future is bein fulfilled by someone else, this is even less supported then the previous case.
 
 					// If there is a wait context, we need to consume it and mark it as consumed after
 					// If there is no context then we can skip the in progress phase
-					struct oneshot * want = expected == 0p ? 1p : 2p;
+					struct oneshot * want = expected == future_ARMED ? future_FULFILLED : future_PROGRESS;
 					if(__atomic_compare_exchange_n(&this.ptr, &expected, want, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-						if( expected == 0p ) { return 0p; }
+						if( expected == future_ARMED ) { return 0p; }
 						thread$ * ret = post( *expected, do_unpark );
-						__atomic_store_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
+						__atomic_store_n( &this.ptr, future_FULFILLED, __ATOMIC_SEQ_CST);
 						return ret;
 					}
@@ -366,5 +368,5 @@
 
 				// Wait for the future to tru
-				while( this.ptr == 2p ) Pause();
+				while( this.ptr == future_PROGRESS ) Pause();
 				// Make sure the state makes sense
 				// Should be fulfilled, could be in progress but it's out of date if so
@@ -372,5 +374,5 @@
 				// and the oneshot should not be needed any more
 				__attribute__((unused)) struct oneshot * was = this.ptr;
-				/* paranoid */ verifyf( was == 1p, "Expected this.ptr to be 1p, was %p\n", was );
+				/* paranoid */ verifyf( was == future_FULFILLED, "Expected this.ptr to be 1p, was %p\n", was );
 
 				// Mark the future as fulfilled, to be consistent
Index: libcfa/src/concurrency/kernel/private.hfa
===================================================================
--- libcfa/src/concurrency/kernel/private.hfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/concurrency/kernel/private.hfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -88,5 +88,5 @@
 #elif defined(CFA_HAVE_LINUX_RSEQ_H)
 	extern "Cforall" {
-		extern __attribute__((aligned(64))) thread_local volatile struct rseq __cfaabi_rseq;
+		extern __attribute__((aligned(64))) __thread volatile struct rseq __cfaabi_rseq;
 	}
 #else
@@ -161,4 +161,7 @@
 // Blocking acquire
 static inline void __atomic_acquire(volatile bool * ll) {
+	/* paranoid */ verify( ! __preemption_enabled() );
+	/* paranoid */ verify(ll);
+
 	while( __builtin_expect(__atomic_exchange_n(ll, (bool)true, __ATOMIC_SEQ_CST), false) ) {
 		while(__atomic_load_n(ll, (int)__ATOMIC_RELAXED))
@@ -166,8 +169,12 @@
 	}
 	/* paranoid */ verify(*ll);
+	/* paranoid */ verify( ! __preemption_enabled() );
 }
 
 // Non-Blocking acquire
 static inline bool __atomic_try_acquire(volatile bool * ll) {
+	/* paranoid */ verify( ! __preemption_enabled() );
+	/* paranoid */ verify(ll);
+
 	return !__atomic_exchange_n(ll, (bool)true, __ATOMIC_SEQ_CST);
 }
@@ -175,4 +182,6 @@
 // Release
 static inline void __atomic_unlock(volatile bool * ll) {
+	/* paranoid */ verify( ! __preemption_enabled() );
+	/* paranoid */ verify(ll);
 	/* paranoid */ verify(*ll);
 	__atomic_store_n(ll, (bool)false, __ATOMIC_RELEASE);
Index: libcfa/src/concurrency/kernel/startup.cfa
===================================================================
--- libcfa/src/concurrency/kernel/startup.cfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/concurrency/kernel/startup.cfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -133,5 +133,5 @@
 //-----------------------------------------------------------------------------
 // Global state
-thread_local struct KernelThreadData __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" ))) @= {
+__thread struct KernelThreadData __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" ))) @= {
 	NULL,												// cannot use 0p
 	NULL,
@@ -153,5 +153,5 @@
 #elif defined(CFA_HAVE_LINUX_RSEQ_H)
 	extern "Cforall" {
-		__attribute__((aligned(64))) thread_local volatile struct rseq __cfaabi_rseq @= {
+		__attribute__((aligned(64))) __thread volatile struct rseq __cfaabi_rseq @= {
 			.cpu_id : RSEQ_CPU_ID_UNINITIALIZED,
 		};
Index: libcfa/src/concurrency/preemption.cfa
===================================================================
--- libcfa/src/concurrency/preemption.cfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/concurrency/preemption.cfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -238,5 +238,5 @@
 //----------
 // special case for preemption since used often
-__attribute__((optimize("no-reorder-blocks"))) bool __preemption_enabled() libcfa_public {
+__attribute__((optimize("no-reorder-blocks"))) bool __preemption_enabled() libcfa_nopreempt libcfa_public {
 	// create a assembler label before
 	// marked as clobber all to avoid movement
@@ -272,9 +272,24 @@
 }
 
+extern "C" {
+	__attribute__((visibility("hidden"))) extern void * const __start_cfatext_nopreempt;
+	__attribute__((visibility("hidden"))) extern void * const __stop_cfatext_nopreempt;
+
+	extern const __cfa_nopreempt_region __libcfa_nopreempt;
+	__attribute__((visibility("protected"))) const __cfa_nopreempt_region __libcfathrd_nopreempt @= {
+		(void * const)&__start_cfatext_nopreempt,
+		(void * const)&__stop_cfatext_nopreempt
+	};
+}
+
+static inline bool __cfaabi_in( void * const ip, const struct __cfa_nopreempt_region & const region ) {
+	return ip >= region.start && ip <= region.stop;
+}
+
 
 //----------
 // Get data from the TLS block
 // struct asm_region __cfaasm_get;
-uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__, visibility("default"))); //no inline to avoid problems
+uintptr_t __cfatls_get( unsigned long int offset ) libcfa_nopreempt libcfa_public; //no inline to avoid problems
 uintptr_t __cfatls_get( unsigned long int offset ) {
 	// create a assembler label before
@@ -295,5 +310,5 @@
 extern "C" {
 	// Disable interrupts by incrementing the counter
-	__attribute__((__noinline__, visibility("default"))) void disable_interrupts() libcfa_public {
+	void disable_interrupts() libcfa_nopreempt libcfa_public {
 		// create a assembler label before
 		// marked as clobber all to avoid movement
@@ -326,5 +341,5 @@
 	// Enable interrupts by decrementing the counter
 	// If counter reaches 0, execute any pending __cfactx_switch
-	void enable_interrupts( bool poll ) libcfa_public {
+	void enable_interrupts( bool poll ) libcfa_nopreempt libcfa_public {
 		// Cache the processor now since interrupts can start happening after the atomic store
 		processor   * proc = __cfaabi_tls.this_processor;
@@ -358,4 +373,27 @@
 		}
 	}
+
+	// Check whether or not there is pending preemption
+	// force_yield( __POLL_PREEMPTION ) if appropriate
+	// return true if the thread was in an interruptable state
+	// i.e. on a real processor and not in the kernel
+	// (can return true even if no preemption was pending)
+	bool poll_interrupts() libcfa_public {
+		// Cache the processor now since interrupts can start happening after the atomic store
+		processor   * proc = publicTLS_get( this_processor );
+		if ( ! proc ) return false;
+		if ( ! __preemption_enabled() ) return false;
+
+		with( __cfaabi_tls.preemption_state ){
+			// Signal the compiler that a fence is needed but only for signal handlers
+			__atomic_signal_fence(__ATOMIC_RELEASE);
+			if( proc->pending_preemption ) {
+				proc->pending_preemption = false;
+				force_yield( __POLL_PREEMPTION );
+			}
+		}
+
+		return true;
+	}
 }
 
@@ -463,84 +501,4 @@
 
 //-----------------------------------------------------------------------------
-// Some assembly required
-#if defined( __i386 )
-	#ifdef __PIC__
-		#define RELOC_PRELUDE( label ) \
-			"calll   .Lcfaasm_prelude_" #label "$pb\n\t" \
-			".Lcfaasm_prelude_" #label "$pb:\n\t" \
-			"popl    %%eax\n\t" \
-			".Lcfaasm_prelude_" #label "_end:\n\t" \
-			"addl    $_GLOBAL_OFFSET_TABLE_+(.Lcfaasm_prelude_" #label "_end-.Lcfaasm_prelude_" #label "$pb), %%eax\n\t"
-		#define RELOC_PREFIX ""
-		#define RELOC_SUFFIX "@GOT(%%eax)"
-	#else
-		#define RELOC_PREFIX "$"
-		#define RELOC_SUFFIX ""
-	#endif
-	#define __cfaasm_label( label ) struct asm_region label = \
-		({ \
-			struct asm_region region; \
-			asm( \
-				RELOC_PRELUDE( label ) \
-				"movl " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \
-				"movl " RELOC_PREFIX "__cfaasm_" #label "_after"  RELOC_SUFFIX ", %[va]\n\t" \
-				 : [vb]"=r"(region.before), [va]"=r"(region.after) \
-			); \
-			region; \
-		});
-#elif defined( __x86_64 )
-	#ifdef __PIC__
-		#define RELOC_PREFIX ""
-		#define RELOC_SUFFIX "@GOTPCREL(%%rip)"
-	#else
-		#define RELOC_PREFIX "$"
-		#define RELOC_SUFFIX ""
-	#endif
-	#define __cfaasm_label( label ) struct asm_region label = \
-		({ \
-			struct asm_region region; \
-			asm( \
-				"movq " RELOC_PREFIX "__cfaasm_" #label "_before" RELOC_SUFFIX ", %[vb]\n\t" \
-				"movq " RELOC_PREFIX "__cfaasm_" #label "_after"  RELOC_SUFFIX ", %[va]\n\t" \
-				 : [vb]"=r"(region.before), [va]"=r"(region.after) \
-			); \
-			region; \
-		});
-#elif defined( __aarch64__ )
-	#ifdef __PIC__
-		// Note that this works only for gcc
-		#define __cfaasm_label( label ) struct asm_region label = \
-		({ \
-			struct asm_region region; \
-			asm( \
-				"adrp %[vb], _GLOBAL_OFFSET_TABLE_"                              "\n\t" \
-        			"ldr  %[vb], [%[vb], #:gotpage_lo15:__cfaasm_" #label "_before]" "\n\t" \
-				"adrp %[va], _GLOBAL_OFFSET_TABLE_"                              "\n\t" \
-        			"ldr  %[va], [%[va], #:gotpage_lo15:__cfaasm_" #label "_after]"  "\n\t" \
-				 : [vb]"=r"(region.before), [va]"=r"(region.after) \
-			); \
-			region; \
-		});
-	#else
-		#error this is not the right thing to do
-		/*
-		#define __cfaasm_label( label ) struct asm_region label = \
-		({ \
-			struct asm_region region; \
-			asm( \
-				"adrp %[vb], __cfaasm_" #label "_before"              "\n\t" \
-        			"add  %[vb], %[vb], :lo12:__cfaasm_" #label "_before" "\n\t" \
-				"adrp %[va], :got:__cfaasm_" #label "_after"          "\n\t" \
-        			"add  %[va], %[va], :lo12:__cfaasm_" #label "_after"  "\n\t" \
-				 : [vb]"=r"(region.before), [va]"=r"(region.after) \
-			); \
-			region; \
-		});
-		*/
-	#endif
-#else
-	#error unknown hardware architecture
-#endif
-
 // KERNEL ONLY
 // Check if a __cfactx_switch signal handler shoud defer
@@ -548,16 +506,9 @@
 // If false : preemption is unsafe and marked as pending
 static inline bool preemption_ready( void * ip ) {
-	// Get all the region for which it is not safe to preempt
-	__cfaasm_label( get    );
-	__cfaasm_label( check  );
-	__cfaasm_label( dsable );
-	// __cfaasm_label( debug  );
-
 	// Check if preemption is safe
 	bool ready = true;
-	if( __cfaasm_in( ip, get    ) ) { ready = false; goto EXIT; };
-	if( __cfaasm_in( ip, check  ) ) { ready = false; goto EXIT; };
-	if( __cfaasm_in( ip, dsable ) ) { ready = false; goto EXIT; };
-	// if( __cfaasm_in( ip, debug  ) ) { ready = false; goto EXIT; };
+	if( __cfaabi_in( ip, __libcfa_nopreempt ) ) { ready = false; goto EXIT; };
+	if( __cfaabi_in( ip, __libcfathrd_nopreempt ) ) { ready = false; goto EXIT; };
+
 	if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
 	if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
@@ -643,5 +594,5 @@
 // Kernel Signal Handlers
 //=============================================================================================
-__cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; )
+__cfaabi_dbg_debug_do( static __thread void * last_interrupt = 0; )
 
 // Context switch signal handler
Index: libcfa/src/startup.cfa
===================================================================
--- libcfa/src/startup.cfa	(revision ebf8ca5fd2d4a1e12022556c0cc689ccac0d0414)
+++ libcfa/src/startup.cfa	(revision 23a08aa0632e10eefd0b98b0e8dbba78191b5702)
@@ -41,6 +41,15 @@
 	} // __cfaabi_appready_shutdown
 
-	void disable_interrupts() __attribute__(( weak )) libcfa_public {}
-	void enable_interrupts() __attribute__(( weak )) libcfa_public {}
+	void disable_interrupts() __attribute__(( weak )) libcfa_nopreempt libcfa_public {}
+	void enable_interrupts() __attribute__(( weak )) libcfa_nopreempt libcfa_public {}
+	bool poll_interrupts() __attribute__(( weak )) libcfa_nopreempt libcfa_public { return false; }
+
+	__attribute__((visibility("hidden"))) extern void * const __start_cfatext_nopreempt;
+	__attribute__((visibility("hidden"))) extern void * const __stop_cfatext_nopreempt;
+
+	__attribute__((visibility("protected"))) const __cfa_nopreempt_region __libcfa_nopreempt @= {
+		(void * const)&__start_cfatext_nopreempt,
+		(void * const)&__stop_cfatext_nopreempt
+	};
 
 
