Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/Makefile.am	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -33,5 +33,5 @@
 # The built sources must not depend on the installed inst_headers_src
 AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr -I$(srcdir)/concurrency $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
-AM_CFLAGS = -g -Wall -Werror=return-type -Wno-unused-function -fPIC -fexceptions -pthread @ARCH_FLAGS@ @CONFIG_CFLAGS@
+AM_CFLAGS = -g -Wall -Werror=return-type -Wno-unused-function -fPIC -fexceptions -fvisibility=hidden -pthread @ARCH_FLAGS@ @CONFIG_CFLAGS@
 AM_CCASFLAGS = -g -Wall -Werror=return-type -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@
 CFACC = @CFACC@
@@ -194,9 +194,9 @@
 
 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
-	${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA,-l ${<} -c -o ${@}
+	${AM_V_GEN}$(CFACOMPILE) -quiet -XCFA,-l ${<} -c -fvisibility=default -o ${@}
 
 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @LOCAL_CFACC@ @CFACPP@
 	${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
-	$(CFACOMPILE) -quiet -XCFA,-l ${<} -c -o ${@}
+	$(CFACOMPILE) -quiet -XCFA,-l ${<} -c -fvisibility=default -o ${@}
 
 concurrency/io/call.cfa: $(srcdir)/concurrency/io/call.cfa.in
Index: libcfa/src/algorithms/range_iterator.cfa
===================================================================
--- libcfa/src/algorithms/range_iterator.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/algorithms/range_iterator.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -20,5 +20,7 @@
 #include <fstream.hfa>
 
-void main(RangeIter & this) {
+#include "bits/defs.hfa"
+
+void main(RangeIter & this) libcfa_public {
 	for() {
 		this._start = -1;
Index: libcfa/src/assert.cfa
===================================================================
--- libcfa/src/assert.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/assert.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -19,4 +19,5 @@
 #include <unistd.h>								// STDERR_FILENO
 #include "bits/debug.hfa"
+#include "bits/defs.hfa"
 
 extern "C" {
@@ -26,5 +27,6 @@
 
 	// called by macro assert in assert.h
-	void __assert_fail( const char assertion[], const char file[], unsigned int line, const char function[] ) {
+	// would be cool to remove libcfa_public but it's needed for libcfathread
+	void __assert_fail( const char assertion[], const char file[], unsigned int line, const char function[] ) libcfa_public {
 		__cfaabi_bits_print_safe( STDERR_FILENO, CFA_ASSERT_FMT ".\n", assertion, __progname, function, line, file );
 		abort();
@@ -32,5 +34,6 @@
 
 	// called by macro assertf
-	void __assert_fail_f( const char assertion[], const char file[], unsigned int line, const char function[], const char fmt[], ... ) {
+	// would be cool to remove libcfa_public but it's needed for libcfathread
+	void __assert_fail_f( const char assertion[], const char file[], unsigned int line, const char function[], const char fmt[], ... ) libcfa_public {
 		__cfaabi_bits_acquire();
 		__cfaabi_bits_print_nolock( STDERR_FILENO, CFA_ASSERT_FMT ": ", assertion, __progname, function, line, file );
Index: libcfa/src/bits/debug.cfa
===================================================================
--- libcfa/src/bits/debug.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/bits/debug.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -21,9 +21,12 @@
 #include <unistd.h>
 
+#include "bits/defs.hfa"
+
 enum { buffer_size = 4096 };
 static char buffer[ buffer_size ];
 
 extern "C" {
-	void __cfaabi_bits_write( int fd, const char in_buffer[], int len ) {
+	// would be cool to remove libcfa_public but it's needed for libcfathread
+	void __cfaabi_bits_write( int fd, const char in_buffer[], int len ) libcfa_public {
 		// ensure all data is written
 		for ( int count = 0, retcode; count < len; count += retcode ) {
@@ -44,5 +47,6 @@
 	void __cfaabi_bits_release() __attribute__((__weak__)) {}
 
-	int __cfaabi_bits_print_safe  ( int fd, const char fmt[], ... ) __attribute__(( format(printf, 2, 3) )) {
+	// would be cool to remove libcfa_public but it's needed for libcfathread
+	int __cfaabi_bits_print_safe  ( int fd, const char fmt[], ... ) __attribute__(( format(printf, 2, 3) )) libcfa_public {
 		va_list args;
 
Index: libcfa/src/bits/defs.hfa
===================================================================
--- libcfa/src/bits/defs.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/bits/defs.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -36,4 +36,6 @@
 #define __cfa_dlink(x) struct { struct x * next; struct x * back; } __dlink_substitute
 #endif
+
+#define libcfa_public __attribute__((visibility("default")))
 
 #ifdef __cforall
Index: libcfa/src/bits/weakso_locks.cfa
===================================================================
--- libcfa/src/bits/weakso_locks.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/bits/weakso_locks.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -18,4 +18,6 @@
 #include "bits/weakso_locks.hfa"
 
+#pragma GCC visibility push(default)
+
 void  ?{}( blocking_lock &, bool, bool ) {}
 void ^?{}( blocking_lock & ) {}
Index: libcfa/src/common.cfa
===================================================================
--- libcfa/src/common.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/common.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -18,4 +18,6 @@
 #include <stdlib.h>					// div_t, *div
 
+#pragma GCC visibility push(default)
+
 //---------------------------------------
 
Index: libcfa/src/concurrency/alarm.cfa
===================================================================
--- libcfa/src/concurrency/alarm.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/alarm.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -141,5 +141,5 @@
 //=============================================================================================
 
-void sleep( Duration duration ) {
+void sleep( Duration duration ) libcfa_public {
 	alarm_node_t node = { active_thread(), duration, 0`s };
 
Index: libcfa/src/concurrency/clib/cfathread.cfa
===================================================================
--- libcfa/src/concurrency/clib/cfathread.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/clib/cfathread.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -237,5 +237,5 @@
 
 typedef ThreadCancelled(cfathread_object) cfathread_exception;
-typedef ThreadCancelled_vtable(cfathread_object) cfathread_vtable;
+typedef vtable(ThreadCancelled(cfathread_object)) cfathread_vtable;
 
 void defaultResumptionHandler(ThreadCancelled(cfathread_object) & except) {
@@ -283,5 +283,5 @@
 
 typedef ThreadCancelled(__cfainit) __cfainit_exception;
-typedef ThreadCancelled_vtable(__cfainit) __cfainit_vtable;
+typedef vtable(ThreadCancelled(__cfainit)) __cfainit_vtable;
 
 void defaultResumptionHandler(ThreadCancelled(__cfainit) & except) {
@@ -326,17 +326,19 @@
 }
 
+#pragma GCC visibility push(default)
+
 //================================================================================
 // Main Api
 extern "C" {
-	int cfathread_cluster_create(cfathread_cluster_t * cl) __attribute__((nonnull(1))) {
+	int cfathread_cluster_create(cfathread_cluster_t * cl) __attribute__((nonnull(1))) libcfa_public {
 		*cl = new();
 		return 0;
 	}
 
-	cfathread_cluster_t cfathread_cluster_self(void) {
+	cfathread_cluster_t cfathread_cluster_self(void) libcfa_public {
 		return active_cluster();
 	}
 
-	int cfathread_cluster_print_stats( cfathread_cluster_t cl ) {
+	int cfathread_cluster_print_stats( cfathread_cluster_t cl ) libcfa_public {
 		#if !defined(__CFA_NO_STATISTICS__)
 			print_stats_at_exit( *cl, CFA_STATS_READY_Q | CFA_STATS_IO );
Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -48,5 +48,5 @@
 //-----------------------------------------------------------------------------
 forall(T &)
-void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) {
+void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) libcfa_public {
 	dst->virtual_table = src->virtual_table;
 	dst->the_coroutine = src->the_coroutine;
@@ -55,5 +55,5 @@
 
 forall(T &)
-const char * msg(CoroutineCancelled(T) *) {
+const char * msg(CoroutineCancelled(T) *) libcfa_public {
 	return "CoroutineCancelled(...)";
 }
@@ -62,5 +62,5 @@
 forall(T & | is_coroutine(T))
 void __cfaehm_cancelled_coroutine(
-		T & cor, coroutine$ * desc, EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)) ) {
+		T & cor, coroutine$ * desc, EHM_DEFAULT_VTABLE(CoroutineCancelled(T)) ) libcfa_public {
 	verify( desc->cancellation );
 	desc->state = Cancelled;
@@ -89,5 +89,5 @@
 
 void __stack_prepare( __stack_info_t * this, size_t create_size );
-void __stack_clean  ( __stack_info_t * this );
+static void __stack_clean  ( __stack_info_t * this );
 
 //-----------------------------------------------------------------------------
@@ -114,5 +114,5 @@
 }
 
-void ?{}( coroutine$ & this, const char name[], void * storage, size_t storageSize ) with( this ) {
+void ?{}( coroutine$ & this, const char name[], void * storage, size_t storageSize ) libcfa_public with( this ) {
 	(this.context){0p, 0p};
 	(this.stack){storage, storageSize};
@@ -124,5 +124,5 @@
 }
 
-void ^?{}(coroutine$& this) {
+void ^?{}(coroutine$& this) libcfa_public {
 	if(this.state != Halted && this.state != Start && this.state != Primed) {
 		coroutine$ * src = active_coroutine();
@@ -146,6 +146,6 @@
 // Part of the Public API
 // Not inline since only ever called once per coroutine
-forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)); })
-void prime(T& cor) {
+forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled(T)); })
+void prime(T& cor) libcfa_public {
 	coroutine$* this = get_coroutine(cor);
 	assert(this->state == Start);
@@ -155,5 +155,5 @@
 }
 
-[void *, size_t] __stack_alloc( size_t storageSize ) {
+static [void *, size_t] __stack_alloc( size_t storageSize ) {
 	const size_t stack_data_size = libCeiling( sizeof(__stack_t), 16 ); // minimum alignment
 	assert(__page_size != 0l);
@@ -193,5 +193,5 @@
 }
 
-void __stack_clean  ( __stack_info_t * this ) {
+static void __stack_clean  ( __stack_info_t * this ) {
 	void * storage = this->storage->limit;
 
@@ -215,5 +215,5 @@
 }
 
-void __stack_prepare( __stack_info_t * this, size_t create_size ) {
+void __stack_prepare( __stack_info_t * this, size_t create_size ) libcfa_public {
 	const size_t stack_data_size = libCeiling( sizeof(__stack_t), 16 ); // minimum alignment
 	bool userStack;
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -22,8 +22,9 @@
 //-----------------------------------------------------------------------------
 // Exception thrown from resume when a coroutine stack is cancelled.
-EHM_FORALL_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) (
+forall(coroutine_t &)
+exception CoroutineCancelled {
 	coroutine_t * the_coroutine;
 	exception_t * the_exception;
-);
+};
 
 forall(T &)
@@ -37,5 +38,5 @@
 // Anything that implements this trait can be resumed.
 // Anything that is resumed is a coroutine.
-trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) {
+trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T))) {
 	void main(T & this);
 	coroutine$ * get_coroutine(T & this);
@@ -60,5 +61,5 @@
 //-----------------------------------------------------------------------------
 // Public coroutine API
-forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)); })
+forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled(T)); })
 void prime(T & cor);
 
@@ -113,6 +114,4 @@
 
 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
@@ -141,8 +140,8 @@
 forall(T & | is_coroutine(T))
 void __cfaehm_cancelled_coroutine(
-	T & cor, coroutine$ * desc, EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)) );
+	T & cor, coroutine$ * desc, EHM_DEFAULT_VTABLE(CoroutineCancelled(T)) );
 
 // Resume implementation inlined for performance
-forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)); })
+forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled(T)); })
 static inline T & resume(T & cor) {
 	// optimization : read TLS once and reuse it
Index: libcfa/src/concurrency/exception.cfa
===================================================================
--- libcfa/src/concurrency/exception.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/exception.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -64,9 +64,9 @@
 extern "C" {
 
-struct exception_context_t * this_exception_context(void) {
+struct exception_context_t * this_exception_context(void) libcfa_public {
 	return &__get_stack( active_coroutine() )->exception_context;
 }
 
-_Unwind_Reason_Code __cfaehm_cancellation_unwind( struct _Unwind_Exception * unwind_exception ) {
+_Unwind_Reason_Code __cfaehm_cancellation_unwind( struct _Unwind_Exception * unwind_exception ) libcfa_public {
 	_Unwind_Stop_Fn stop_func;
 	void * stop_param;
Index: libcfa/src/concurrency/invoke.c
===================================================================
--- libcfa/src/concurrency/invoke.c	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/invoke.c	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -36,5 +36,5 @@
 extern void enable_interrupts( _Bool poll );
 
-void __cfactx_invoke_coroutine(
+libcfa_public void __cfactx_invoke_coroutine(
 	void (*main)(void *),
 	void *this
@@ -70,5 +70,5 @@
 }
 
-void __cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct coroutine$ * cor) __attribute__ ((__noreturn__));
+libcfa_public void __cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct coroutine$ * cor) __attribute__ ((__noreturn__));
 void __cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct coroutine$ * cor) {
 	_Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, __cfactx_coroutine_unwindstop, cor );
@@ -77,5 +77,5 @@
 }
 
-void __cfactx_invoke_thread(
+libcfa_public void __cfactx_invoke_thread(
 	void (*main)(void *),
 	void *this
@@ -98,5 +98,5 @@
 }
 
-void __cfactx_start(
+libcfa_public void __cfactx_start(
 	void (*main)(void *),
 	struct coroutine$ * cor,
Index: libcfa/src/concurrency/io.cfa
===================================================================
--- libcfa/src/concurrency/io.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/io.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -221,5 +221,5 @@
 			const unsigned long long ctsc = rdtscl();
 
-			if(proc->io.target == MAX) {
+			if(proc->io.target == UINT_MAX) {
 				uint64_t chaos = __tls_rand();
 				unsigned ext = chaos & 0xff;
@@ -232,5 +232,5 @@
 			else {
 				const unsigned target = proc->io.target;
-				/* paranoid */ verify( io.tscs[target].tv != MAX );
+				/* paranoid */ verify( io.tscs[target].tv != ULLONG_MAX );
 				HELP: if(target < ctxs_count) {
 					const unsigned long long cutoff = calc_cutoff(ctsc, ctx->cq.id, ctxs_count, io.data, io.tscs, __shard_factor.io);
@@ -246,5 +246,5 @@
 					__STATS__( true, io.calls.helped++; )
 				}
-				proc->io.target = MAX;
+				proc->io.target = UINT_MAX;
 			}
 		}
@@ -340,5 +340,5 @@
 	// for convenience, return both the index and the pointer to the sqe
 	// sqe == &sqes[idx]
-	struct $io_context * cfa_io_allocate(struct io_uring_sqe * sqes[], __u32 idxs[], __u32 want) {
+	struct $io_context * cfa_io_allocate(struct io_uring_sqe * sqes[], __u32 idxs[], __u32 want) libcfa_public {
 		// __cfadbg_print_safe(io, "Kernel I/O : attempting to allocate %u\n", want);
 
@@ -419,5 +419,5 @@
 	}
 
-	void cfa_io_submit( struct $io_context * inctx, __u32 idxs[], __u32 have, bool lazy ) __attribute__((nonnull (1))) {
+	void cfa_io_submit( struct $io_context * inctx, __u32 idxs[], __u32 have, bool lazy ) __attribute__((nonnull (1))) libcfa_public {
 		// __cfadbg_print_safe(io, "Kernel I/O : attempting to submit %u (%s)\n", have, lazy ? "lazy" : "eager");
 
Index: libcfa/src/concurrency/io/call.cfa.in
===================================================================
--- libcfa/src/concurrency/io/call.cfa.in	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/io/call.cfa.in	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -139,4 +139,5 @@
 // I/O Interface
 //=============================================================================================
+#pragma GCC visibility push(default)
 """
 
Index: libcfa/src/concurrency/io/setup.cfa
===================================================================
--- libcfa/src/concurrency/io/setup.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/io/setup.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -26,5 +26,5 @@
 
 #if !defined(CFA_HAVE_LINUX_IO_URING_H)
-	void ?{}(io_context_params & this) {}
+	void ?{}(io_context_params & this) libcfa_public {}
 
 	void  ?{}($io_context & this, struct cluster & cl) {}
@@ -66,5 +66,5 @@
 #pragma GCC diagnostic pop
 
-	void ?{}(io_context_params & this) {
+	void ?{}(io_context_params & this) libcfa_public {
 		this.num_entries = 256;
 	}
Index: libcfa/src/concurrency/io/types.hfa
===================================================================
--- libcfa/src/concurrency/io/types.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/io/types.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -17,4 +17,6 @@
 #pragma once
 
+#include <limits.h>
+
 extern "C" {
 	#include <linux/types.h>
@@ -25,5 +27,4 @@
 #include "iofwd.hfa"
 #include "kernel/fwd.hfa"
-#include "limits.hfa"
 
 #if defined(CFA_HAVE_LINUX_IO_URING_H)
@@ -140,5 +141,5 @@
 		const __u32 tail = *this->cq.tail;
 
-		if(head == tail) return MAX;
+		if(head == tail) return ULLONG_MAX;
 
 		return this->cq.ts;
Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/kernel.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -389,5 +389,5 @@
 
 // KERNEL_ONLY
-void returnToKernel() {
+static void returnToKernel() {
 	/* paranoid */ verify( ! __preemption_enabled() );
 	coroutine$ * proc_cor = get_coroutine(kernelTLS().this_processor->runner);
@@ -547,5 +547,5 @@
 }
 
-void unpark( thread$ * thrd, unpark_hint hint ) {
+void unpark( thread$ * thrd, unpark_hint hint ) libcfa_public {
 	if( !thrd ) return;
 
@@ -558,5 +558,5 @@
 }
 
-void park( void ) {
+void park( void ) libcfa_public {
 	__disable_interrupts_checked();
 		/* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION );
@@ -601,5 +601,5 @@
 
 // KERNEL ONLY
-bool force_yield( __Preemption_Reason reason ) {
+bool force_yield( __Preemption_Reason reason ) libcfa_public {
 	__disable_interrupts_checked();
 		thread$ * thrd = kernelTLS().this_thread;
@@ -849,5 +849,5 @@
 //-----------------------------------------------------------------------------
 // Debug
-bool threading_enabled(void) __attribute__((const)) {
+bool threading_enabled(void) __attribute__((const)) libcfa_public {
 	return true;
 }
@@ -856,5 +856,5 @@
 // Statistics
 #if !defined(__CFA_NO_STATISTICS__)
-	void print_halts( processor & this ) {
+	void print_halts( processor & this ) libcfa_public {
 		this.print_halts = true;
 	}
@@ -873,5 +873,5 @@
 	}
 
-	void crawl_cluster_stats( cluster & this ) {
+	static void crawl_cluster_stats( cluster & this ) {
 		// Stop the world, otherwise stats could get really messed-up
 		// this doesn't solve all problems but does solve many
@@ -889,5 +889,5 @@
 
 
-	void print_stats_now( cluster & this, int flags ) {
+	void print_stats_now( cluster & this, int flags ) libcfa_public {
 		crawl_cluster_stats( this );
 		__print_stats( this.stats, flags, "Cluster", this.name, (void*)&this );
Index: libcfa/src/concurrency/kernel.hfa
===================================================================
--- libcfa/src/concurrency/kernel.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/kernel.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -49,5 +49,7 @@
 
 // Coroutine used py processors for the 2-step context switch
-coroutine processorCtx_t {
+
+struct processorCtx_t {
+	struct coroutine$ self;
 	struct processor * proc;
 };
Index: libcfa/src/concurrency/kernel/cluster.cfa
===================================================================
--- libcfa/src/concurrency/kernel/cluster.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/kernel/cluster.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -49,5 +49,5 @@
 
 // returns the maximum number of processors the RWLock support
-__attribute__((weak)) unsigned __max_processors() {
+__attribute__((weak)) unsigned __max_processors() libcfa_public {
 	const char * max_cores_s = getenv("CFA_MAX_PROCESSORS");
 	if(!max_cores_s) {
@@ -233,9 +233,9 @@
 					if(is_empty(sl)) {
 						assert( sl.anchor.next == 0p );
-						assert( sl.anchor.ts   == -1llu );
+						assert( sl.anchor.ts   == MAX );
 						assert( mock_head(sl)  == sl.prev );
 					} else {
 						assert( sl.anchor.next != 0p );
-						assert( sl.anchor.ts   != -1llu );
+						assert( sl.anchor.ts   != MAX );
 						assert( mock_head(sl)  != sl.prev );
 					}
@@ -259,9 +259,9 @@
 		/* paranoid */ verifyf( it, "Unexpected null iterator, at index %u of %u\n", i, count);
 		it->rdq.id = valrq;
-		it->rdq.target = MAX;
+		it->rdq.target = UINT_MAX;
 		valrq += __shard_factor.readyq;
 		#if defined(CFA_HAVE_LINUX_IO_URING_H)
 			it->io.ctx->cq.id = valio;
-			it->io.target = MAX;
+			it->io.target = UINT_MAX;
 			valio += __shard_factor.io;
 		#endif
@@ -472,5 +472,5 @@
 	this.prev = mock_head(this);
 	this.anchor.next = 0p;
-	this.anchor.ts   = -1llu;
+	this.anchor.ts   = MAX;
 	#if !defined(__CFA_NO_STATISTICS__)
 		this.cnt  = 0;
@@ -484,5 +484,5 @@
 	/* paranoid */ verify( &mock_head(this)->link.ts   == &this.anchor.ts   );
 	/* paranoid */ verify( mock_head(this)->link.next == 0p );
-	/* paranoid */ verify( mock_head(this)->link.ts   == -1llu  );
+	/* paranoid */ verify( mock_head(this)->link.ts   == MAX );
 	/* paranoid */ verify( mock_head(this) == this.prev );
 	/* paranoid */ verify( __alignof__(__intrusive_lane_t) == 128 );
@@ -495,5 +495,5 @@
 	// Make sure the list is empty
 	/* paranoid */ verify( this.anchor.next == 0p );
-	/* paranoid */ verify( this.anchor.ts   == -1llu );
+	/* paranoid */ verify( this.anchor.ts   == MAX );
 	/* paranoid */ verify( mock_head(this)  == this.prev );
 }
Index: libcfa/src/concurrency/kernel/cluster.hfa
===================================================================
--- libcfa/src/concurrency/kernel/cluster.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/kernel/cluster.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -19,5 +19,5 @@
 #include "kernel/private.hfa"
 
-#include "limits.hfa"
+#include <limits.h>
 
 //-----------------------------------------------------------------------
@@ -37,5 +37,5 @@
 
 static inline void touch_tsc(__timestamp_t * tscs, size_t idx, unsigned long long ts_prev, unsigned long long ts_next) {
-	if (ts_next == MAX) return;
+	if (ts_next == ULLONG_MAX) return;
 	unsigned long long now = rdtscl();
 	unsigned long long pma = __atomic_load_n(&tscs[ idx ].ma, __ATOMIC_RELAXED);
@@ -59,5 +59,5 @@
 	for(i; shard_factor) {
 		unsigned long long ptsc = ts(data[start + i]);
-		if(ptsc != -1ull) {
+		if(ptsc != ULLONG_MAX) {
 			/* paranoid */ verify( start + i < count );
 			unsigned long long tsc = moving_average(ctsc, ptsc, tscs[start + i].ma);
Index: libcfa/src/concurrency/kernel/private.hfa
===================================================================
--- libcfa/src/concurrency/kernel/private.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/kernel/private.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -109,5 +109,6 @@
 //-----------------------------------------------------------------------------
 // Processor
-void main(processorCtx_t *);
+void main(processorCtx_t &);
+static inline coroutine$* get_coroutine(processorCtx_t & this) { return &this.self; }
 
 void * __create_pthread( pthread_t *, void * (*)(void *), void * );
Index: libcfa/src/concurrency/kernel/startup.cfa
===================================================================
--- libcfa/src/concurrency/kernel/startup.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/kernel/startup.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -120,5 +120,5 @@
 #endif
 
-cluster              * mainCluster;
+cluster              * mainCluster libcfa_public;
 processor            * mainProcessor;
 thread$              * mainThread;
@@ -169,5 +169,5 @@
 };
 
-void ?{}( current_stack_info_t & this ) {
+static void ?{}( current_stack_info_t & this ) {
 	__stack_context_t ctx;
 	CtxGet( ctx );
@@ -209,6 +209,6 @@
 	// Construct the processor context of the main processor
 	void ?{}(processorCtx_t & this, processor * proc) {
-		(this.__cor){ "Processor" };
-		this.__cor.starter = 0p;
+		(this.self){ "Processor" };
+		this.self.starter = 0p;
 		this.proc = proc;
 	}
@@ -507,5 +507,5 @@
 	self_mon_p = &self_mon;
 	link.next = 0p;
-	link.ts   = -1llu;
+	link.ts   = MAX;
 	preferred = ready_queue_new_preferred();
 	last_proc = 0p;
@@ -526,5 +526,5 @@
 // Construct the processor context of non-main processors
 static void ?{}(processorCtx_t & this, processor * proc, current_stack_info_t * info) {
-	(this.__cor){ info };
+	(this.self){ info };
 	this.proc = proc;
 }
@@ -578,5 +578,5 @@
 }
 
-void ?{}(processor & this, const char name[], cluster & _cltr, thread$ * initT) {
+void ?{}(processor & this, const char name[], cluster & _cltr, thread$ * initT) libcfa_public {
 	( this.terminated ){};
 	( this.runner ){};
@@ -591,10 +591,10 @@
 }
 
-void ?{}(processor & this, const char name[], cluster & _cltr) {
+void ?{}(processor & this, const char name[], cluster & _cltr) libcfa_public {
 	(this){name, _cltr, 0p};
 }
 
 extern size_t __page_size;
-void ^?{}(processor & this) with( this ){
+void ^?{}(processor & this) libcfa_public with( this ) {
 	/* paranoid */ verify( !__atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) );
 	__cfadbg_print_safe(runtime_core, "Kernel : core %p signaling termination\n", &this);
@@ -623,5 +623,5 @@
 }
 
-void ?{}(cluster & this, const char name[], Duration preemption_rate, unsigned num_io, const io_context_params & io_params) with( this ) {
+void ?{}(cluster & this, const char name[], Duration preemption_rate, unsigned num_io, const io_context_params & io_params) libcfa_public with( this ) {
 	this.name = name;
 	this.preemption_rate = preemption_rate;
@@ -658,5 +658,5 @@
 }
 
-void ^?{}(cluster & this) {
+void ^?{}(cluster & this) libcfa_public {
 	destroy(this.io.arbiter);
 
Index: libcfa/src/concurrency/locks.cfa
===================================================================
--- libcfa/src/concurrency/locks.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/locks.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -24,4 +24,6 @@
 #include <stdlib.hfa>
 
+#pragma GCC visibility push(default)
+
 //-----------------------------------------------------------------------------
 // info_thread
@@ -116,5 +118,5 @@
 }
 
-void pop_and_set_new_owner( blocking_lock & this ) with( this ) {
+static void pop_and_set_new_owner( blocking_lock & this ) with( this ) {
 	thread$ * t = &try_pop_front( blocked_threads );
 	owner = t;
@@ -192,5 +194,5 @@
 	void ^?{}( alarm_node_wrap(L) & this ) { }
 
-	void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) {
+	static void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) {
 		// This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
 		lock( cond->lock __cfaabi_dbg_ctx2 );
@@ -216,5 +218,5 @@
 
 	// this casts the alarm node to our wrapped type since we used type erasure
-	void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
+	static void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
 }
 
@@ -233,5 +235,5 @@
 	void ^?{}( condition_variable(L) & this ){ }
 
-	void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) {
+	static void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) {
 		if(&popped != 0p) {
 			popped.signalled = true;
@@ -278,5 +280,5 @@
 	int counter( condition_variable(L) & this ) with(this) { return count; }
 
-	size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
+	static size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
 		// add info_thread to waiting queue
 		insert_last( blocked_threads, *i );
@@ -291,5 +293,5 @@
 
 	// helper for wait()'s' with no timeout
-	void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
+	static void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
 		lock( lock __cfaabi_dbg_ctx2 );
 		size_t recursion_count = queue_and_get_recursion(this, &i);
@@ -308,5 +310,5 @@
 
 	// helper for wait()'s' with a timeout
-	void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {
+	static void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Duration t, Alarm_Callback callback ) with(this) {
 		lock( lock __cfaabi_dbg_ctx2 );
 		size_t recursion_count = queue_and_get_recursion(this, &info);
@@ -343,5 +345,5 @@
 	// fast_cond_var
 	void  ?{}( fast_cond_var(L) & this ){
-		this.blocked_threads{}; 
+		this.blocked_threads{};
 		#ifdef __CFA_DEBUG__
 		this.lock_used = 0p;
Index: libcfa/src/concurrency/monitor.cfa
===================================================================
--- libcfa/src/concurrency/monitor.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/monitor.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -44,4 +44,8 @@
 static inline void restore( monitor$ * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );
 
+static inline void ?{}(__condition_node_t & this, thread$ * waiting_thread, __lock_size_t count, uintptr_t user_info );
+static inline void ?{}(__condition_criterion_t & this );
+static inline void ?{}(__condition_criterion_t & this, monitor$ * target, __condition_node_t * owner );
+
 static inline void init     ( __lock_size_t count, monitor$ * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
 static inline void init_push( __lock_size_t count, monitor$ * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] );
@@ -243,5 +247,5 @@
 
 // Leave single monitor
-void __leave( monitor$ * this ) {
+static void __leave( monitor$ * this ) {
 	// Lock the monitor spinlock
 	lock( this->lock __cfaabi_dbg_ctx2 );
@@ -278,5 +282,5 @@
 
 // Leave single monitor for the last time
-void __dtor_leave( monitor$ * this, bool join ) {
+static void __dtor_leave( monitor$ * this, bool join ) {
 	__cfaabi_dbg_debug_do(
 		if( active_thread() != this->owner ) {
@@ -344,5 +348,5 @@
 // Ctor for monitor guard
 // Sorts monitors before entering
-void ?{}( monitor_guard_t & this, monitor$ * m [], __lock_size_t count, fptr_t func ) {
+void ?{}( monitor_guard_t & this, monitor$ * m [], __lock_size_t count, fptr_t func ) libcfa_public {
 	thread$ * thrd = active_thread();
 
@@ -369,5 +373,5 @@
 }
 
-void ?{}( monitor_guard_t & this, monitor$ * m [], __lock_size_t count ) {
+void ?{}( monitor_guard_t & this, monitor$ * m [], __lock_size_t count ) libcfa_public {
 	this{ m, count, 0p };
 }
@@ -375,5 +379,5 @@
 
 // Dtor for monitor guard
-void ^?{}( monitor_guard_t & this ) {
+void ^?{}( monitor_guard_t & this ) libcfa_public {
 	// __cfaabi_dbg_print_safe( "MGUARD : leaving %d\n", this.count);
 
@@ -389,5 +393,5 @@
 // Ctor for monitor guard
 // Sorts monitors before entering
-void ?{}( monitor_dtor_guard_t & this, monitor$ * m [], fptr_t func, bool join ) {
+void ?{}( monitor_dtor_guard_t & this, monitor$ * m [], fptr_t func, bool join ) libcfa_public {
 	// optimization
 	thread$ * thrd = active_thread();
@@ -409,5 +413,5 @@
 
 // Dtor for monitor guard
-void ^?{}( monitor_dtor_guard_t & this ) {
+void ^?{}( monitor_dtor_guard_t & this ) libcfa_public {
 	// Leave the monitors in order
 	__dtor_leave( this.m, this.join );
@@ -419,5 +423,5 @@
 //-----------------------------------------------------------------------------
 // Internal scheduling types
-void ?{}(__condition_node_t & this, thread$ * waiting_thread, __lock_size_t count, uintptr_t user_info ) {
+static void ?{}(__condition_node_t & this, thread$ * waiting_thread, __lock_size_t count, uintptr_t user_info ) {
 	this.waiting_thread = waiting_thread;
 	this.count = count;
@@ -426,5 +430,5 @@
 }
 
-void ?{}(__condition_criterion_t & this ) with( this ) {
+static void ?{}(__condition_criterion_t & this ) with( this ) {
 	ready  = false;
 	target = 0p;
@@ -433,5 +437,5 @@
 }
 
-void ?{}(__condition_criterion_t & this, monitor$ * target, __condition_node_t & owner ) {
+static void ?{}(__condition_criterion_t & this, monitor$ * target, __condition_node_t & owner ) {
 	this.ready  = false;
 	this.target = target;
@@ -442,5 +446,5 @@
 //-----------------------------------------------------------------------------
 // Internal scheduling
-void wait( condition & this, uintptr_t user_info = 0 ) {
+void wait( condition & this, uintptr_t user_info = 0 ) libcfa_public {
 	brand_condition( this );
 
@@ -496,5 +500,5 @@
 }
 
-bool signal( condition & this ) {
+bool signal( condition & this ) libcfa_public {
 	if( is_empty( this ) ) { return false; }
 
@@ -538,5 +542,5 @@
 }
 
-bool signal_block( condition & this ) {
+bool signal_block( condition & this ) libcfa_public {
 	if( !this.blocked.head ) { return false; }
 
@@ -586,5 +590,5 @@
 
 // Access the user_info of the thread waiting at the front of the queue
-uintptr_t front( condition & this ) {
+uintptr_t front( condition & this ) libcfa_public {
 	verifyf( !is_empty(this),
 		"Attempt to access user data on an empty condition.\n"
@@ -608,5 +612,5 @@
 // 		setup mask
 // 		block
-void __waitfor_internal( const __waitfor_mask_t & mask, int duration ) {
+void __waitfor_internal( const __waitfor_mask_t & mask, int duration ) libcfa_public {
 	// This statment doesn't have a contiguous list of monitors...
 	// Create one!
@@ -994,5 +998,5 @@
 // Can't be accepted since a mutex stmt is effectively an anonymous routine
 // Thus we do not need a monitor group
-void lock( monitor$ * this ) {
+void lock( monitor$ * this ) libcfa_public {
 	thread$ * thrd = active_thread();
 
@@ -1046,5 +1050,5 @@
 // Leave routine for mutex stmt
 // Is just a wrapper around __leave for the is_lock trait to see
-void unlock( monitor$ * this ) { __leave( this ); }
+void unlock( monitor$ * this ) libcfa_public { __leave( this ); }
 
 // Local Variables: //
Index: libcfa/src/concurrency/monitor.hfa
===================================================================
--- libcfa/src/concurrency/monitor.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/monitor.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -119,7 +119,7 @@
 }
 
-void ?{}(__condition_node_t & this, thread$ * waiting_thread, __lock_size_t count, uintptr_t user_info );
-void ?{}(__condition_criterion_t & this );
-void ?{}(__condition_criterion_t & this, monitor$ * target, __condition_node_t * owner );
+// void ?{}(__condition_node_t & this, thread$ * waiting_thread, __lock_size_t count, uintptr_t user_info );
+// void ?{}(__condition_criterion_t & this );
+// void ?{}(__condition_criterion_t & this, monitor$ * target, __condition_node_t * owner );
 
 struct condition {
Index: libcfa/src/concurrency/preemption.cfa
===================================================================
--- libcfa/src/concurrency/preemption.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/preemption.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -38,5 +38,5 @@
 #endif
 
-__attribute__((weak)) Duration default_preemption() {
+__attribute__((weak)) Duration default_preemption() libcfa_public {
 	const char * preempt_rate_s = getenv("CFA_DEFAULT_PREEMPTION");
 	if(!preempt_rate_s) {
@@ -238,5 +238,5 @@
 //----------
 // special case for preemption since used often
-__attribute__((optimize("no-reorder-blocks"))) bool __preemption_enabled() {
+__attribute__((optimize("no-reorder-blocks"))) bool __preemption_enabled() libcfa_public {
 	// create a assembler label before
 	// marked as clobber all to avoid movement
@@ -276,5 +276,5 @@
 // Get data from the TLS block
 // struct asm_region __cfaasm_get;
-uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__)); //no inline to avoid problems
+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 ) {
 	// create a assembler label before
@@ -295,5 +295,5 @@
 extern "C" {
 	// Disable interrupts by incrementing the counter
-	void disable_interrupts() {
+	__attribute__((__noinline__, visibility("default"))) void disable_interrupts() libcfa_public {
 		// create a assembler label before
 		// marked as clobber all to avoid movement
@@ -326,5 +326,5 @@
 	// Enable interrupts by decrementing the counter
 	// If counter reaches 0, execute any pending __cfactx_switch
-	void enable_interrupts( bool poll ) {
+	void enable_interrupts( bool poll ) libcfa_public {
 		// Cache the processor now since interrupts can start happening after the atomic store
 		processor   * proc = __cfaabi_tls.this_processor;
@@ -362,5 +362,5 @@
 //-----------------------------------------------------------------------------
 // Kernel Signal Debug
-void __cfaabi_check_preemption() {
+void __cfaabi_check_preemption() libcfa_public {
 	bool ready = __preemption_enabled();
 	if(!ready) { abort("Preemption should be ready"); }
Index: libcfa/src/concurrency/ready_queue.cfa
===================================================================
--- libcfa/src/concurrency/ready_queue.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/ready_queue.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -125,5 +125,5 @@
 	const unsigned long long ctsc = rdtscl();
 
-	if(proc->rdq.target == MAX) {
+	if(proc->rdq.target == UINT_MAX) {
 		uint64_t chaos = __tls_rand();
 		unsigned ext = chaos & 0xff;
@@ -137,5 +137,5 @@
 		const unsigned target = proc->rdq.target;
 		__cfadbg_print_safe(ready_queue, "Kernel : %u considering helping %u, tcsc %llu\n", this, target, readyQ.tscs[target].tv);
-		/* paranoid */ verify( readyQ.tscs[target].tv != MAX );
+		/* paranoid */ verify( readyQ.tscs[target].tv != ULLONG_MAX );
 		if(target < lanes_count) {
 			const unsigned long long cutoff = calc_cutoff(ctsc, proc->rdq.id, lanes_count, cltr->sched.readyQ.data, cltr->sched.readyQ.tscs, __shard_factor.readyq);
@@ -147,5 +147,5 @@
 			}
 		}
-		proc->rdq.target = MAX;
+		proc->rdq.target = UINT_MAX;
 	}
 
@@ -245,5 +245,5 @@
 // get preferred ready for new thread
 unsigned ready_queue_new_preferred() {
-	unsigned pref = MAX;
+	unsigned pref = UINT_MAX;
 	if(struct thread$ * thrd = publicTLS_get( this_thread )) {
 		pref = thrd->preferred;
Index: libcfa/src/concurrency/ready_subqueue.hfa
===================================================================
--- libcfa/src/concurrency/ready_subqueue.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/ready_subqueue.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -32,16 +32,16 @@
 	/* paranoid */ verify( this.lock );
 	/* paranoid */ verify( node->link.next == 0p );
-	/* paranoid */ verify( node->link.ts   == MAX  );
+	/* paranoid */ verify( __atomic_load_n(&node->link.ts, __ATOMIC_RELAXED) == MAX  );
 	/* paranoid */ verify( this.prev->link.next == 0p );
-	/* paranoid */ verify( this.prev->link.ts   == MAX  );
+	/* paranoid */ verify( __atomic_load_n(&this.prev->link.ts, __ATOMIC_RELAXED)   == MAX  );
 	if( this.anchor.next == 0p ) {
 		/* paranoid */ verify( this.anchor.next == 0p );
-		/* paranoid */ verify( this.anchor.ts   == MAX );
-		/* paranoid */ verify( this.anchor.ts   != 0  );
+		/* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) == MAX );
+		/* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != 0  );
 		/* paranoid */ verify( this.prev == mock_head( this ) );
 	} else {
 		/* paranoid */ verify( this.anchor.next != 0p );
-		/* paranoid */ verify( this.anchor.ts   != MAX );
-		/* paranoid */ verify( this.anchor.ts   != 0  );
+		/* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != MAX );
+		/* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != 0  );
 		/* paranoid */ verify( this.prev != mock_head( this ) );
 	}
@@ -62,14 +62,14 @@
 	/* paranoid */ verify( this.lock );
 	/* paranoid */ verify( this.anchor.next != 0p );
-	/* paranoid */ verify( this.anchor.ts   != MAX );
-	/* paranoid */ verify( this.anchor.ts   != 0  );
+	/* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != MAX );
+	/* paranoid */ verify( __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED) != 0   );
 
 	// Get the relevant nodes locally
 	thread$ * node = this.anchor.next;
 	this.anchor.next = node->link.next;
-	this.anchor.ts   = node->link.ts;
+	__atomic_store_n(&this.anchor.ts, __atomic_load_n(&node->link.ts, __ATOMIC_RELAXED), __ATOMIC_RELAXED);
 	bool is_empty = this.anchor.next == 0p;
 	node->link.next = 0p;
-	node->link.ts   = MAX;
+	__atomic_store_n(&node->link.ts, ULLONG_MAX, __ATOMIC_RELAXED);
 	#if !defined(__CFA_NO_STATISTICS__)
 		this.cnt--;
@@ -79,10 +79,11 @@
 	if(is_empty) this.prev = mock_head( this );
 
+	unsigned long long ats = __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED);
 	/* paranoid */ verify( node->link.next == 0p );
-	/* paranoid */ verify( node->link.ts   == MAX  );
-	/* paranoid */ verify( node->link.ts   != 0  );
-	/* paranoid */ verify( this.anchor.ts  != 0  );
-	/* paranoid */ verify( (this.anchor.ts  == MAX) == is_empty );
-	return [node, this.anchor.ts];
+	/* paranoid */ verify( __atomic_load_n(&node->link.ts , __ATOMIC_RELAXED) == MAX );
+	/* paranoid */ verify( __atomic_load_n(&node->link.ts , __ATOMIC_RELAXED) != 0   );
+	/* paranoid */ verify( ats != 0 );
+	/* paranoid */ verify( (ats == MAX) == is_empty );
+	return [node, ats];
 }
 
@@ -96,4 +97,5 @@
 	// Cannot verify 'emptiness' here since it may not be locked
 	/* paranoid */ verify(this.anchor.ts != 0);
-	return this.anchor.ts;
+	/* paranoid */ static_assert(__atomic_always_lock_free(sizeof(this.anchor.ts), &this.anchor.ts));
+	return __atomic_load_n(&this.anchor.ts, __ATOMIC_RELAXED);
 }
Index: libcfa/src/concurrency/thread.cfa
===================================================================
--- libcfa/src/concurrency/thread.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/thread.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -19,6 +19,7 @@
 #include "thread.hfa"
 
+#include "exception.hfa"
 #include "kernel/private.hfa"
-#include "exception.hfa"
+#include "limits.hfa"
 
 #define __CFA_INVOKE_PRIVATE__
@@ -26,4 +27,6 @@
 
 extern uint32_t __global_random_seed, __global_random_prime, __global_random_mask;
+
+#pragma GCC visibility push(default)
 
 //-----------------------------------------------------------------------------
@@ -42,5 +45,5 @@
 	curr_cluster = &cl;
 	link.next = 0p;
-	link.ts   = -1llu;
+	link.ts   = MAX;
 	preferred = ready_queue_new_preferred();
 	last_proc = 0p;
@@ -86,6 +89,6 @@
 }
 
-forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))
-    | { EHM_DEFAULT_VTABLE(ThreadCancelled, (T)); })
+forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled(T))
+    | { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); })
 void ?{}( thread_dtor_guard_t & this,
 		T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) {
@@ -165,6 +168,6 @@
 
 //-----------------------------------------------------------------------------
-forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))
-    | { EHM_DEFAULT_VTABLE(ThreadCancelled, (T)); })
+forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled(T))
+	| { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); })
 T & join( T & this ) {
 	thread_dtor_guard_t guard = { this, defaultResumptionHandler };
Index: libcfa/src/concurrency/thread.hfa
===================================================================
--- libcfa/src/concurrency/thread.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/concurrency/thread.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -32,8 +32,9 @@
 };
 
-EHM_FORALL_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) (
+forall(thread_t &)
+exception ThreadCancelled {
 	thread_t * the_thread;
 	exception_t * the_exception;
-);
+};
 
 forall(T &)
@@ -79,6 +80,6 @@
 };
 
-forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))
-    | { EHM_DEFAULT_VTABLE(ThreadCancelled, (T)); })
+forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled(T))
+	| { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); })
 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) );
 void ^?{}( thread_dtor_guard_t & this );
@@ -126,6 +127,6 @@
 //----------
 // join
-forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))
-    | { EHM_DEFAULT_VTABLE(ThreadCancelled, (T)); })
+forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled(T))
+	| { EHM_DEFAULT_VTABLE(ThreadCancelled(T)); })
 T & join( T & this );
 
Index: libcfa/src/containers/maybe.cfa
===================================================================
--- libcfa/src/containers/maybe.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/containers/maybe.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -17,4 +17,5 @@
 #include <assert.h>
 
+#pragma GCC visibility push(default)
 
 forall(T)
Index: libcfa/src/containers/result.cfa
===================================================================
--- libcfa/src/containers/result.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/containers/result.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -17,4 +17,5 @@
 #include <assert.h>
 
+#pragma GCC visibility push(default)
 
 forall(T, E)
Index: libcfa/src/containers/string.cfa
===================================================================
--- libcfa/src/containers/string.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/containers/string.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -18,4 +18,5 @@
 #include <stdlib.hfa>
 
+#pragma GCC visibility push(default)
 
 /*
Index: libcfa/src/containers/string_sharectx.hfa
===================================================================
--- libcfa/src/containers/string_sharectx.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/containers/string_sharectx.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -16,9 +16,11 @@
 #pragma once
 
+#pragma GCC visibility push(default)
+
 //######################### String Sharing Context #########################
 
 struct VbyteHeap;
 
-// A string_sharectx 
+// A string_sharectx
 //
 // Usage:
Index: libcfa/src/containers/vector.cfa
===================================================================
--- libcfa/src/containers/vector.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/containers/vector.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -18,6 +18,8 @@
 #include <stdlib.hfa>
 
+#pragma GCC visibility push(default)
+
 forall(T, allocator_t | allocator_c(T, allocator_t))
-void copy_internal(vector(T, allocator_t)* this, vector(T, allocator_t)* other);
+static void copy_internal(vector(T, allocator_t)* this, vector(T, allocator_t)* other);
 
 //------------------------------------------------------------------------------
@@ -83,5 +85,5 @@
 
 forall(T, allocator_t | allocator_c(T, allocator_t))
-void copy_internal(vector(T, allocator_t)* this, vector(T, allocator_t)* other)
+static void copy_internal(vector(T, allocator_t)* this, vector(T, allocator_t)* other)
 {
 	this->size = other->size;
Index: libcfa/src/device/cpu.cfa
===================================================================
--- libcfa/src/device/cpu.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/device/cpu.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -31,4 +31,5 @@
 }
 
+#include "bits/defs.hfa"
 #include "algorithms/range_iterator.hfa"
 
@@ -456,3 +457,3 @@
 }
 
-cpu_info_t cpu_info;
+libcfa_public cpu_info_t cpu_info;
Index: libcfa/src/exception.c
===================================================================
--- libcfa/src/exception.c	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/exception.c	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -27,4 +27,7 @@
 #include "stdhdr/assert.h"
 #include "virtual.h"
+
+#pragma GCC visibility push(default)
+
 #include "lsda.h"
 
@@ -261,5 +264,5 @@
 #else // defined( __ARM_ARCH )
 	// The return code from _Unwind_RaiseException seems to be corrupt on ARM at end of stack.
-	// This workaround tries to keep default exception handling working. 
+	// This workaround tries to keep default exception handling working.
 	if ( ret == _URC_FATAL_PHASE1_ERROR || ret == _URC_FATAL_PHASE2_ERROR ) {
 #endif
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/exception.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -10,6 +10,6 @@
 // Created On       : Thu Apr  7 10:25:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr Apr  8 15:16:00 2021
-// Update Count     : 4
+// Last Modified On : Wed May 25 17:20:00 2022
+// Update Count     : 5
 //
 
@@ -18,169 +18,15 @@
 // -----------------------------------------------------------------------------------------------
 
-// EHM_EXCEPTION(exception_name)(fields...);
-// Create an exception (a virtual structure that inherits from exception_t)
-// with the given name and fields.
-#define EHM_EXCEPTION(exception_name) \
-	_EHM_TYPE_ID_STRUCT(exception_name, ); \
-	_EHM_TYPE_ID_VALUE(exception_name, ); \
-	_EHM_VIRTUAL_TABLE_STRUCT(exception_name, , ); \
-	_EHM_EXCEPTION_STRUCT(exception_name, , )
+// EHM_DEFAULT_VTABLE(exception_type)
+// Create a declaration for a (possibly polymorphic) default vtable.
+// Mostly used by and for the currency module.
+#define EHM_DEFAULT_VTABLE(type) vtable(type) & const _default_vtable
 
-// EHM_EXTERN_VTABLE(exception_name, table_name);
-// Forward declare a virtual table called table_name for exception_name type.
-#define EHM_EXTERN_VTABLE(exception_name, table_name) \
-	_EHM_EXTERN_VTABLE(exception_name, , table_name)
-
-// EHM_VIRTUAL_TABLE(exception_name, table_name);
-// Define a virtual table called table_name for exception_name type.
-#define EHM_VIRTUAL_TABLE(exception_name, table_name) \
-	_EHM_DEFINE_COPY(exception_name, ) \
-	_EHM_DEFINE_MSG(exception_name, ) \
-	_EHM_VIRTUAL_TABLE(exception_name, , table_name)
-
-// EHM_FORALL_EXCEPTION(exception_name, (assertions), (parameters))(fields...);
-// As EHM_EXCEPTION but for polymorphic types instead of monomorphic ones.
-// The assertions list should include all polymorphic parameters and
-// assertions inside a parentisized list. Parameters should include all the
-// polymorphic parameter names inside a parentisized list (same order).
-#define EHM_FORALL_EXCEPTION(exception_name, assertions, parameters) \
-	_EHM_TYPE_ID_STRUCT(exception_name, forall assertions); \
-	_EHM_VIRTUAL_TABLE_STRUCT(exception_name, forall assertions, parameters); \
-	_EHM_EXCEPTION_STRUCT(exception_name, forall assertions, parameters)
-
-// EHM_FORALL_EXTERN_VTABLE(exception_name, (arguments), table_name);
-// As EHM_EXTERN_VTABLE but for polymorphic types instead of monomorphic ones.
-// Arguments should be the parentisized list of polymorphic arguments.
-#define EHM_FORALL_EXTERN_VTABLE(exception_name, arguments, table_name) \
-	_EHM_EXTERN_VTABLE(exception_name, arguments, table_name)
-
-// EHM_FORALL_VIRTUAL_TABLE(exception_name, (arguments), table_name);
-// As EHM_VIRTUAL_TABLE but for polymorphic types instead of monomorphic ones.
-// Arguments should be the parentisized list of polymorphic arguments.
-#define EHM_FORALL_VIRTUAL_TABLE(exception_name, arguments, table_name) \
-	_EHM_TYPE_ID_VALUE(exception_name, arguments); \
-	_EHM_DEFINE_COPY(exception_name, arguments) \
-	_EHM_DEFINE_MSG(exception_name, arguments) \
-	_EHM_VIRTUAL_TABLE(exception_name, arguments, table_name)
-
-// EHM_DEFAULT_VTABLE(exception_name, (arguments))
-// Create a declaration for a (possibly polymorphic) default vtable.
-#define EHM_DEFAULT_VTABLE(exception_name, arguments) \
-	_EHM_VTABLE_TYPE(exception_name) arguments & const _default_vtable
-
-// IS_EXCEPTION(exception_name [, (...parameters)])
-// IS_RESUMPTION_EXCEPTION(exception_name [, (parameters...)])
-// IS_TERMINATION_EXCEPTION(exception_name [, (parameters...)])
-// Create an assertion that exception_name, possibly with the qualifing parameters, is the given
-// kind of exception with the standard vtable with the same parameters if applicable.
-#define IS_EXCEPTION(...) _IS_EXCEPTION(is_exception, __VA_ARGS__, , ~)
-#define IS_RESUMPTION_EXCEPTION(...) _IS_EXCEPTION(is_resumption_exception, __VA_ARGS__, , ~)
-#define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~)
-
-// Macros starting with a leading underscore are internal.
-
-// Create an exception type definition. must be tailing, can be polymorphic.
-#define _EHM_EXCEPTION_STRUCT(exception_name, forall_clause, parameters) \
-	forall_clause struct exception_name { \
-		_EHM_VTABLE_TYPE(exception_name) parameters const * virtual_table; \
-		_CLOSE
-
-// Create a (possibly polymorphic) virtual table forward declaration.
-#define _EHM_EXTERN_VTABLE(exception_name, arguments, table_name) \
-	extern const _EHM_VTABLE_TYPE(exception_name) arguments table_name
-
-// Create a (possibly polymorphic) virtual table definition.
-#define _EHM_VIRTUAL_TABLE(exception_type, arguments, table_name) \
-	const _EHM_VTABLE_TYPE(exception_type) arguments table_name @= { \
-		.__cfavir_typeid : &_EHM_TYPE_ID_NAME(exception_type), \
-		.size : sizeof(struct exception_type arguments), \
-		.copy : copy, \
-		.^?{} : ^?{}, \
-		.msg : msg, \
-	}
-
-// Create a (possibly polymorphic) copy function from an assignment operator.
-#define _EHM_DEFINE_FORALL_COPY(exception_name, forall_clause, parameters) \
-	forall_clause void copy(exception_name parameters * this, \
-			exception_name parameters * that) { \
-		*this = *that; \
-	}
-
-#define _EHM_DEFINE_COPY(exception_name, arguments) \
-	void copy(exception_name arguments * this, exception_name arguments * that) { \
-		*this = *that; \
-	}
-
-// Create a (possibly polymorphic) msg function
-#define _EHM_DEFINE_FORALL_MSG(exception_name, forall_clause, parameters) \
-	forall_clause const char * msg(exception_name parameters * this) { \
-		return #exception_name #parameters; \
-	}
-
-#define _EHM_DEFINE_MSG(exception_name, arguments) \
-	const char * msg(exception_name arguments * this) { \
-		return #exception_name #arguments; \
-	}
-
-// Produces the C compatable name of the virtual table type for a virtual type.
-#define _EHM_VTABLE_TYPE(type_name) struct _GLUE2(type_name,_vtable)
-
-// Create the vtable type for exception name.
-#define _EHM_VIRTUAL_TABLE_STRUCT(exception_name, forall_clause, parameters) \
-	forall_clause struct exception_name; \
-	forall_clause _EHM_VTABLE_TYPE(exception_name) { \
-		_EHM_TYPE_ID_TYPE(exception_name) parameters const * __cfavir_typeid; \
-		size_t size; \
-		void (*copy)(exception_name parameters * this, exception_name parameters * other); \
-		void (*^?{})(exception_name parameters & this); \
-		const char * (*msg)(exception_name parameters * this); \
-	}
-
-// Define the function required to satify the trait for exceptions.
-#define _EHM_TRAIT_FUNCTION(exception_name, forall_clause, parameters) \
-	forall_clause inline void mark_exception( \
-		exception_name parameters const &, \
-		_EHM_VTABLE_TYPE(exception_name) parameters const &) {} \
-
-#define __EHM_TRAIT_FUNCTION(exception_name, forall_clause, parameters) \
-	forall_clause inline _EHM_VTABLE_TYPE(exception_name) parameters const & \
-			get_exception_vtable(exception_name parameters const & this) { \
-		/* This comes before the structure definition, but we know the offset. */ \
-		/* return (_EHM_VTABLE_TYPE(exception_name) parameters const &)this; */ \
-		assert(false); \
-	}
-
-// Generates a new type-id structure. This is used to mangle the name of the
-// type-id instance so it also includes polymorphic information. Must be the
-// direct decendent of exception_t.
-// The second field is used to recover type information about the exception.
-#define _EHM_TYPE_ID_STRUCT(exception_name, forall_clause) \
-	forall_clause _EHM_TYPE_ID_TYPE(exception_name) { \
-		__cfavir_type_info const * parent; \
-	}
-
-// Generate a new type-id value.
-#define _EHM_TYPE_ID_VALUE(exception_name, arguments) \
-	__attribute__((cfa_linkonce)) \
-	_EHM_TYPE_ID_TYPE(exception_name) arguments const \
-			_EHM_TYPE_ID_NAME(exception_name) = { \
-		&__cfatid_exception_t, \
-	}
-
-// _EHM_TYPE_ID_STRUCT and _EHM_TYPE_ID_VALUE are the two that would need to
-// be updated to extend the hierarchy if we are still using macros when that
-// is added.
-
-// Produce the C compatable name of the type-id type for an exception type.
-#define _EHM_TYPE_ID_TYPE(exception_name) \
-	struct _GLUE2(__cfatid_struct_, exception_name)
-
-// Produce the name of the instance of the type-id for an exception type.
-#define _EHM_TYPE_ID_NAME(exception_name) _GLUE2(__cfatid_,exception_name)
-
-#define _IS_EXCEPTION(kind, exception_name, parameters, ...) \
-	kind(exception_name parameters, _EHM_VTABLE_TYPE(exception_name) parameters)
-
-// Internal helper macros:
-#define _CLOSE(...) __VA_ARGS__ }
-#define _GLUE2(left, right) left##right
+// IS_EXCEPTION(exception_type)
+// IS_RESUMPTION_EXCEPTION(exception_type)
+// IS_TERMINATION_EXCEPTION(exception_type)
+// Create an assertion that exception_type is the given kind of exception.
+// This is used to mimic associated types so the vtable type is unmentioned.
+#define IS_EXCEPTION(type) is_exception(type, vtable(type))
+#define IS_RESUMPTION_EXCEPTION(type) is_resumption_exception(type, vtable(type))
+#define IS_TERMINATION_EXCEPTION(type) is_termination_exception(type, vtable(type))
Index: libcfa/src/fstream.cfa
===================================================================
--- libcfa/src/fstream.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/fstream.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -22,4 +22,6 @@
 #include <assert.h>
 #include <errno.h>										// errno
+
+#pragma GCC visibility push(default)
 
 // *********************************** ofstream ***********************************
@@ -118,5 +120,5 @@
 		// abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
 	} // if
-	(os){ file };										// initialize 
+	(os){ file };										// initialize
 } // open
 
@@ -157,5 +159,5 @@
 	va_list args;
 	va_start( args, format );
-		
+
 	int len;
     for ( cnt; 10 ) {
@@ -241,5 +243,5 @@
 		// abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
 	} // if
-	(is){ file };										// initialize 
+	(is){ file };										// initialize
 } // open
 
Index: libcfa/src/fstream.hfa
===================================================================
--- libcfa/src/fstream.hfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/fstream.hfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -18,5 +18,4 @@
 #include "bits/weakso_locks.hfa"						// mutex_lock
 #include "iostream.hfa"
-#include <exception.hfa>
 
 
Index: libcfa/src/heap.cfa
===================================================================
--- libcfa/src/heap.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/heap.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -36,7 +36,7 @@
 static bool traceHeap = false;
 
-inline bool traceHeap() { return traceHeap; }
-
-bool traceHeapOn() {
+inline bool traceHeap() libcfa_public { return traceHeap; }
+
+bool traceHeapOn() libcfa_public {
 	bool temp = traceHeap;
 	traceHeap = true;
@@ -44,5 +44,5 @@
 } // traceHeapOn
 
-bool traceHeapOff() {
+bool traceHeapOff() libcfa_public {
 	bool temp = traceHeap;
 	traceHeap = false;
@@ -50,14 +50,14 @@
 } // traceHeapOff
 
-bool traceHeapTerm() { return false; }
+bool traceHeapTerm() libcfa_public { return false; }
 
 
 static bool prtFree = false;
 
-bool prtFree() {
+static bool prtFree() {
 	return prtFree;
 } // prtFree
 
-bool prtFreeOn() {
+static bool prtFreeOn() {
 	bool temp = prtFree;
 	prtFree = true;
@@ -65,5 +65,5 @@
 } // prtFreeOn
 
-bool prtFreeOff() {
+static bool prtFreeOff() {
 	bool temp = prtFree;
 	prtFree = false;
@@ -388,6 +388,7 @@
 static unsigned int maxBucketsUsed;						// maximum number of buckets in use
 // extern visibility, used by runtime kernel
-size_t __page_size;										// architecture pagesize
-int __map_prot;											// common mmap/mprotect protection
+// would be cool to remove libcfa_public but it's needed for libcfathread
+libcfa_public size_t __page_size;							// architecture pagesize
+libcfa_public int __map_prot;								// common mmap/mprotect protection
 
 
@@ -727,5 +728,5 @@
 
 
-size_t prtFree( Heap & manager ) with( manager ) {
+static size_t prtFree( Heap & manager ) with( manager ) {
 	size_t total = 0;
 	#ifdef __STATISTICS__
@@ -879,5 +880,5 @@
 	// Allocates size bytes and returns a pointer to the allocated memory.  The contents are undefined. If size is 0,
 	// then malloc() returns a unique pointer value that can later be successfully passed to free().
-	void * malloc( size_t size ) {
+	void * malloc( size_t size ) libcfa_public {
 		#ifdef __STATISTICS__
 		if ( likely( size > 0 ) ) {
@@ -894,5 +895,5 @@
 
 	// Same as malloc() except size bytes is an array of dim elements each of elemSize bytes.
-	void * aalloc( size_t dim, size_t elemSize ) {
+	void * aalloc( size_t dim, size_t elemSize ) libcfa_public {
 		size_t size = dim * elemSize;
 		#ifdef __STATISTICS__
@@ -910,5 +911,5 @@
 
 	// Same as aalloc() with memory set to zero.
-	void * calloc( size_t dim, size_t elemSize ) {
+	void * calloc( size_t dim, size_t elemSize ) libcfa_public {
 		size_t size = dim * elemSize;
 	  if ( unlikely( size ) == 0 ) {			// 0 BYTE ALLOCATION RETURNS NULL POINTER
@@ -951,5 +952,5 @@
 	// not 0p, then the call is equivalent to free(oaddr). Unless oaddr is 0p, it must have been returned by an earlier
 	// call to malloc(), alloc(), calloc() or realloc(). If the area pointed to was moved, a free(oaddr) is done.
-	void * resize( void * oaddr, size_t size ) {
+	void * resize( void * oaddr, size_t size ) libcfa_public {
 		// If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
 	  if ( unlikely( size == 0 ) ) {					// special cases
@@ -996,5 +997,5 @@
 	// Same as resize() but the contents are unchanged in the range from the start of the region up to the minimum of
 	// the old and new sizes.
-	void * realloc( void * oaddr, size_t size ) {
+	void * realloc( void * oaddr, size_t size ) libcfa_public {
 		// If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
 	  if ( unlikely( size == 0 ) ) {					// special cases
@@ -1060,5 +1061,5 @@
 
 	// Same as realloc() except the new allocation size is large enough for an array of nelem elements of size elsize.
-	void * reallocarray( void * oaddr, size_t dim, size_t elemSize ) {
+	void * reallocarray( void * oaddr, size_t dim, size_t elemSize ) libcfa_public {
 		return realloc( oaddr, dim * elemSize );
 	} // reallocarray
@@ -1066,5 +1067,5 @@
 
 	// Same as malloc() except the memory address is a multiple of alignment, which must be a power of two. (obsolete)
-	void * memalign( size_t alignment, size_t size ) {
+	void * memalign( size_t alignment, size_t size ) libcfa_public {
 		#ifdef __STATISTICS__
 		if ( likely( size > 0 ) ) {
@@ -1081,5 +1082,5 @@
 
 	// Same as aalloc() with memory alignment.
-	void * amemalign( size_t alignment, size_t dim, size_t elemSize ) {
+	void * amemalign( size_t alignment, size_t dim, size_t elemSize ) libcfa_public {
 		size_t size = dim * elemSize;
 		#ifdef __STATISTICS__
@@ -1097,5 +1098,5 @@
 
 	// Same as calloc() with memory alignment.
-	void * cmemalign( size_t alignment, size_t dim, size_t elemSize ) {
+	void * cmemalign( size_t alignment, size_t dim, size_t elemSize ) libcfa_public {
 		size_t size = dim * elemSize;
 	  if ( unlikely( size ) == 0 ) {					// 0 BYTE ALLOCATION RETURNS NULL POINTER
@@ -1136,5 +1137,5 @@
 	// Same as memalign(), but ISO/IEC 2011 C11 Section 7.22.2 states: the value of size shall be an integral multiple
 	// of alignment. This requirement is universally ignored.
-	void * aligned_alloc( size_t alignment, size_t size ) {
+	void * aligned_alloc( size_t alignment, size_t size ) libcfa_public {
 		return memalign( alignment, size );
 	} // aligned_alloc
@@ -1145,5 +1146,5 @@
 	// is 0, then posix_memalign() returns either 0p, or a unique pointer value that can later be successfully passed to
 	// free(3).
-	int posix_memalign( void ** memptr, size_t alignment, size_t size ) {
+	int posix_memalign( void ** memptr, size_t alignment, size_t size ) libcfa_public {
 	  if ( unlikely( alignment < libAlign() || ! is_pow2( alignment ) ) ) return EINVAL; // check alignment
 		*memptr = memalign( alignment, size );
@@ -1154,5 +1155,5 @@
 	// Allocates size bytes and returns a pointer to the allocated memory. The memory address shall be a multiple of the
 	// page size.  It is equivalent to memalign(sysconf(_SC_PAGESIZE),size).
-	void * valloc( size_t size ) {
+	void * valloc( size_t size ) libcfa_public {
 		return memalign( __page_size, size );
 	} // valloc
@@ -1160,5 +1161,5 @@
 
 	// Same as valloc but rounds size to multiple of page size.
-	void * pvalloc( size_t size ) {
+	void * pvalloc( size_t size ) libcfa_public {
 		return memalign( __page_size, ceiling2( size, __page_size ) ); // round size to multiple of page size
 	} // pvalloc
@@ -1168,5 +1169,5 @@
 	// or realloc().  Otherwise, or if free(ptr) has already been called before, undefined behaviour occurs. If ptr is
 	// 0p, no operation is performed.
-	void free( void * addr ) {
+	void free( void * addr ) libcfa_public {
 	  if ( unlikely( addr == 0p ) ) {					// special case
 			#ifdef __STATISTICS__
@@ -1189,5 +1190,5 @@
 
 	// Returns the alignment of an allocation.
-	size_t malloc_alignment( void * addr ) {
+	size_t malloc_alignment( void * addr ) libcfa_public {
 	  if ( unlikely( addr == 0p ) ) return libAlign();	// minimum alignment
 		Heap.Storage.Header * header = HeaderAddr( addr );
@@ -1201,5 +1202,5 @@
 
 	// Returns true if the allocation is zero filled, e.g., allocated by calloc().
-	bool malloc_zero_fill( void * addr ) {
+	bool malloc_zero_fill( void * addr ) libcfa_public {
 	  if ( unlikely( addr == 0p ) ) return false;		// null allocation is not zero fill
 		Heap.Storage.Header * header = HeaderAddr( addr );
@@ -1212,5 +1213,5 @@
 
 	// Returns original total allocation size (not bucket size) => array size is dimension * sizeof(T).
-	size_t malloc_size( void * addr ) {
+	size_t malloc_size( void * addr ) libcfa_public {
 	  if ( unlikely( addr == 0p ) ) return 0;			// null allocation has zero size
 		Heap.Storage.Header * header = HeaderAddr( addr );
@@ -1224,5 +1225,5 @@
 	// Returns the number of usable bytes in the block pointed to by ptr, a pointer to a block of memory allocated by
 	// malloc or a related function.
-	size_t malloc_usable_size( void * addr ) {
+	size_t malloc_usable_size( void * addr ) libcfa_public {
 	  if ( unlikely( addr == 0p ) ) return 0;			// null allocation has 0 size
 		Heap.Storage.Header * header;
@@ -1236,5 +1237,5 @@
 
 	// Prints (on default standard error) statistics about memory allocated by malloc and related functions.
-	void malloc_stats( void ) {
+	void malloc_stats( void ) libcfa_public {
 		#ifdef __STATISTICS__
 		printStats();
@@ -1245,5 +1246,5 @@
 
 	// Changes the file descriptor where malloc_stats() writes statistics.
-	int malloc_stats_fd( int fd __attribute__(( unused )) ) {
+	int malloc_stats_fd( int fd __attribute__(( unused )) ) libcfa_public {
 		#ifdef __STATISTICS__
 		int temp = stats_fd;
@@ -1259,5 +1260,5 @@
 	// The string is printed on the file stream stream.  The exported string includes information about all arenas (see
 	// malloc).
-	int malloc_info( int options, FILE * stream __attribute__(( unused )) ) {
+	int malloc_info( int options, FILE * stream __attribute__(( unused )) ) libcfa_public {
 	  if ( options != 0 ) { errno = EINVAL; return -1; }
 		#ifdef __STATISTICS__
@@ -1271,5 +1272,5 @@
 	// Adjusts parameters that control the behaviour of the memory-allocation functions (see malloc). The param argument
 	// specifies the parameter to be modified, and value specifies the new value for that parameter.
-	int mallopt( int option, int value ) {
+	int mallopt( int option, int value ) libcfa_public {
 	  if ( value < 0 ) return 0;
 		choose( option ) {
@@ -1285,5 +1286,5 @@
 
 	// Attempt to release free memory at the top of the heap (by calling sbrk with a suitable argument).
-	int malloc_trim( size_t ) {
+	int malloc_trim( size_t ) libcfa_public {
 		return 0;										// => impossible to release memory
 	} // malloc_trim
@@ -1294,5 +1295,5 @@
 	// structure dynamically allocated via malloc, and a pointer to that data structure is returned as the function
 	// result.  (The caller must free this memory.)
-	void * malloc_get_state( void ) {
+	void * malloc_get_state( void ) libcfa_public {
 		return 0p;										// unsupported
 	} // malloc_get_state
@@ -1301,5 +1302,5 @@
 	// Restores the state of all malloc internal bookkeeping variables to the values recorded in the opaque data
 	// structure pointed to by state.
-	int malloc_set_state( void * ) {
+	int malloc_set_state( void * ) libcfa_public {
 		return 0;										// unsupported
 	} // malloc_set_state
@@ -1307,16 +1308,16 @@
 
 	// Sets the amount (bytes) to extend the heap when there is insufficent free storage to service an allocation.
-	__attribute__((weak)) size_t malloc_expansion() { return __CFA_DEFAULT_HEAP_EXPANSION__; }
+	__attribute__((weak)) size_t malloc_expansion() libcfa_public { return __CFA_DEFAULT_HEAP_EXPANSION__; }
 
 	// Sets the crossover point between allocations occuring in the sbrk area or separately mmapped.
-	__attribute__((weak)) size_t malloc_mmap_start() { return __CFA_DEFAULT_MMAP_START__; }
+	__attribute__((weak)) size_t malloc_mmap_start() libcfa_public { return __CFA_DEFAULT_MMAP_START__; }
 
 	// Amount subtracted to adjust for unfreed program storage (debug only).
-	__attribute__((weak)) size_t malloc_unfreed() { return __CFA_DEFAULT_HEAP_UNFREED__; }
+	__attribute__((weak)) size_t malloc_unfreed() libcfa_public { return __CFA_DEFAULT_HEAP_UNFREED__; }
 } // extern "C"
 
 
 // Must have CFA linkage to overload with C linkage realloc.
-void * resize( void * oaddr, size_t nalign, size_t size ) {
+void * resize( void * oaddr, size_t nalign, size_t size ) libcfa_public {
 	// If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
   if ( unlikely( size == 0 ) ) {						// special cases
@@ -1380,5 +1381,5 @@
 
 
-void * realloc( void * oaddr, size_t nalign, size_t size ) {
+void * realloc( void * oaddr, size_t nalign, size_t size ) libcfa_public {
 	// If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
   if ( unlikely( size == 0 ) ) {						// special cases
Index: libcfa/src/interpose.cfa
===================================================================
--- libcfa/src/interpose.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/interpose.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -36,5 +36,5 @@
 //=============================================================================================
 
-void preload_libgcc(void) {
+static void preload_libgcc(void) {
 	dlopen( "libgcc_s.so.1", RTLD_NOW );
 	if ( const char * error = dlerror() ) abort( "interpose_symbol : internal error pre-loading libgcc, %s\n", error );
@@ -42,5 +42,5 @@
 
 typedef void (* generic_fptr_t)(void);
-generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) {
+static generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) {
 	const char * error;
 
@@ -83,16 +83,16 @@
 //=============================================================================================
 
-void sigHandler_segv( __CFA_SIGPARMS__ );
-void sigHandler_ill ( __CFA_SIGPARMS__ );
-void sigHandler_fpe ( __CFA_SIGPARMS__ );
-void sigHandler_abrt( __CFA_SIGPARMS__ );
-void sigHandler_term( __CFA_SIGPARMS__ );
-
-struct {
+static void sigHandler_segv( __CFA_SIGPARMS__ );
+static void sigHandler_ill ( __CFA_SIGPARMS__ );
+static void sigHandler_fpe ( __CFA_SIGPARMS__ );
+static void sigHandler_abrt( __CFA_SIGPARMS__ );
+static void sigHandler_term( __CFA_SIGPARMS__ );
+
+static struct {
 	void (* exit)( int ) __attribute__(( __noreturn__ ));
 	void (* abort)( void ) __attribute__(( __noreturn__ ));
 } __cabi_libc;
 
-int cfa_main_returned;
+libcfa_public int cfa_main_returned;
 
 extern "C" {
@@ -148,15 +148,15 @@
 
 // Forward declare abort after the __typeof__ call to avoid ambiguities
-void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
-void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
-void abort( bool signalAbort, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
-void __abort( bool signalAbort, const char fmt[], va_list args ) __attribute__(( __nothrow__, __leaf__, __noreturn__ ));
+libcfa_public void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
+libcfa_public void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
+libcfa_public void abort( bool signalAbort, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
+libcfa_public void __abort( bool signalAbort, const char fmt[], va_list args ) __attribute__(( __nothrow__, __leaf__, __noreturn__ ));
 
 extern "C" {
-	void abort( void ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
+	libcfa_public void abort( void ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
 		abort( false, "%s", "" );
 	}
 
-	void __cabi_abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )) {
+	libcfa_public void __cabi_abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )) {
 		va_list argp;
 		va_start( argp, fmt );
@@ -165,5 +165,5 @@
 	}
 
-	void exit( int status ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
+	libcfa_public void exit( int status ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
 		__cabi_libc.exit( status );
 	}
Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/iostream.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -32,4 +32,5 @@
 #include "bitmanip.hfa"									// high1
 
+#pragma GCC visibility push(default)
 
 // *********************************** ostream ***********************************
Index: libcfa/src/limits.cfa
===================================================================
--- libcfa/src/limits.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/limits.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -20,4 +20,6 @@
 #include <complex.h>
 #include "limits.hfa"
+
+#pragma GCC visibility push(default)
 
 // Integral Constants
Index: libcfa/src/memory.cfa
===================================================================
--- libcfa/src/memory.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/memory.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -16,4 +16,6 @@
 #include "memory.hfa"
 #include "stdlib.hfa"
+
+#pragma GCC visibility push(default)
 
 // Internal data object.
Index: libcfa/src/parseargs.cfa
===================================================================
--- libcfa/src/parseargs.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/parseargs.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -24,4 +24,6 @@
 #include "common.hfa"
 #include "limits.hfa"
+
+#pragma GCC visibility push(default)
 
 extern int cfa_args_argc __attribute__((weak));
Index: libcfa/src/parseconfig.cfa
===================================================================
--- libcfa/src/parseconfig.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/parseconfig.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -14,9 +14,11 @@
 
 
+#pragma GCC visibility push(default)
+
 // *********************************** exceptions ***********************************
 
 
 // TODO: Add names of missing config entries to exception (see further below)
-static vtable(Missing_Config_Entries) Missing_Config_Entries_vt;
+vtable(Missing_Config_Entries) Missing_Config_Entries_vt;
 
 [ void ] ?{}( & Missing_Config_Entries this, unsigned int num_missing ) {
@@ -31,5 +33,5 @@
 
 
-static vtable(Parse_Failure) Parse_Failure_vt;
+vtable(Parse_Failure) Parse_Failure_vt;
 
 [ void ] ?{}( & Parse_Failure this, [] char failed_key, [] char failed_value ) {
@@ -53,5 +55,5 @@
 
 
-static vtable(Validation_Failure) Validation_Failure_vt;
+vtable(Validation_Failure) Validation_Failure_vt;
 
 [ void ] ?{}( & Validation_Failure this, [] char failed_key, [] char failed_value ) {
@@ -110,5 +112,5 @@
 
 
-[ bool ] comments( & ifstream in, [] char name ) {
+static [ bool ] comments( & ifstream in, [] char name ) {
 	while () {
 		in | name;
Index: libcfa/src/rational.cfa
===================================================================
--- libcfa/src/rational.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/rational.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -17,4 +17,6 @@
 #include "fstream.hfa"
 #include "stdlib.hfa"
+
+#pragma GCC visibility push(default)
 
 forall( T | Arithmetic( T ) ) {
Index: libcfa/src/startup.cfa
===================================================================
--- libcfa/src/startup.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/startup.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -41,6 +41,6 @@
 	} // __cfaabi_appready_shutdown
 
-	void disable_interrupts() __attribute__(( weak )) {}
-	void enable_interrupts() __attribute__(( weak )) {}
+	void disable_interrupts() __attribute__(( weak )) libcfa_public {}
+	void enable_interrupts() __attribute__(( weak )) libcfa_public {}
 
 
@@ -64,5 +64,5 @@
 struct __spinlock_t;
 extern "C" {
-	void __cfaabi_dbg_record_lock(struct __spinlock_t & this, const char prev_name[]) __attribute__(( weak )) {}
+	void __cfaabi_dbg_record_lock(struct __spinlock_t & this, const char prev_name[]) __attribute__(( weak )) libcfa_public {}
 }
 
Index: libcfa/src/stdlib.cfa
===================================================================
--- libcfa/src/stdlib.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/stdlib.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -25,4 +25,6 @@
 #include <complex.h>									// _Complex_I
 #include <assert.h>
+
+#pragma GCC visibility push(default)
 
 //---------------------------------------
@@ -225,6 +227,7 @@
 #define GENERATOR LCG
 
-uint32_t __global_random_seed;							// sequential/concurrent
-uint32_t __global_random_state;							// sequential only
+// would be cool to make hidden but it's needed for libcfathread
+__attribute__((visibility("default"))) uint32_t __global_random_seed;							// sequential/concurrent
+__attribute__((visibility("hidden"))) uint32_t __global_random_state;							// sequential only
 
 void set_seed( PRNG & prng, uint32_t seed_ ) with( prng ) { state = seed = seed_; GENERATOR( state ); } // set seed
Index: libcfa/src/strstream.cfa
===================================================================
--- libcfa/src/strstream.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/strstream.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -1,10 +1,10 @@
-// 
+//
 // Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
-// 
+//
 // The contents of this file are covered under the licence agreement in the
 // file "LICENCE" distributed with Cforall.
 //
-// strstream.cfa -- 
-// 
+// strstream.cfa --
+//
 // Author           : Peter A. Buhr
 // Created On       : Thu Apr 22 22:24:35 2021
@@ -12,5 +12,5 @@
 // Last Modified On : Sun Oct 10 16:13:20 2021
 // Update Count     : 101
-// 
+//
 
 #include "strstream.hfa"
@@ -24,4 +24,5 @@
 #include <unistd.h>										// sbrk, sysconf
 
+#pragma GCC visibility push(default)
 
 // *********************************** strstream ***********************************
Index: libcfa/src/time.cfa
===================================================================
--- libcfa/src/time.cfa	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/time.cfa	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -18,4 +18,6 @@
 #include <stdio.h>										// snprintf
 #include <assert.h>
+
+#pragma GCC visibility push(default)
 
 static char * nanomsd( long int ns, char * buf ) {		// most significant digits
Index: libcfa/src/virtual.c
===================================================================
--- libcfa/src/virtual.c	(revision bf0263c9b7b4fb1f0eeb41eb13f2e11fe44991d3)
+++ libcfa/src/virtual.c	(revision 90a812553b6fb7bc8cf5dadc34f305f3df56721e)
@@ -16,4 +16,6 @@
 #include "virtual.h"
 #include "assert.h"
+
+#pragma GCC visibility push(default)
 
 int __cfavir_is_parent(
