Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision d8b17e288787116fc5ad3ad24e8a2dda6b099f94)
+++ libcfa/src/Makefile.am	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
@@ -88,4 +88,5 @@
 inst_thread_headers_nosrc = \
 	bits/random.hfa \
+	concurrency/clib/cfathread.h \
 	concurrency/invoke.h \
 	concurrency/kernel/fwd.hfa
@@ -103,4 +104,5 @@
 	concurrency/alarm.cfa \
 	concurrency/alarm.hfa \
+	concurrency/clib/cfathread.cfa \
 	concurrency/CtxSwitch-@ARCHITECTURE@.S \
 	concurrency/invoke.c \
Index: libcfa/src/concurrency/clib/cfathread.cfa
===================================================================
--- libcfa/src/concurrency/clib/cfathread.cfa	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
+++ libcfa/src/concurrency/clib/cfathread.cfa	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
@@ -0,0 +1,66 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// clib/cfathread.cfa --
+//
+// Author           : Thierry Delisle
+// Created On       : Tue Sep 22 15:31:20 2020
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include "kernel.hfa"
+#include "thread.hfa"
+
+thread CRunner {
+	void (*themain)( CRunner * );
+};
+
+static void ?{}( CRunner & this, void (*themain)( CRunner * ) ) {
+	this.themain = themain;
+}
+
+void main( CRunner & this ) {
+	this.themain( &this );
+}
+
+processor * procs = 0p;
+int proc_cnt = 1;
+
+extern "C" {
+	//--------------------
+	// Basic thread managenemt
+	CRunner * cfathread_create( void (*main)( CRunner * ) ) {
+		return new( main );
+	}
+
+	void cfathread_join( CRunner * thrd ) {
+		delete( thrd );
+	}
+
+	void cfathread_park( void ) {
+		park( __cfaabi_dbg_ctx );
+	}
+
+	void cfathread_unpark( CRunner * thrd ) {
+		unpark( *thrd __cfaabi_dbg_ctx2 );
+	}
+
+	void cfathread_yield( void ) {
+		yield();
+	}
+
+	//--------------------
+	// Basic kernel features
+	void cfathread_setproccnt( int ncnt ) {
+		assert( ncnt >= 1 );
+		adelete(proc_cnt, procs);
+
+		proc_cnt = ncnt - 1;
+		procs = anew(proc_cnt);
+	}
+}
Index: libcfa/src/concurrency/clib/cfathread.h
===================================================================
--- libcfa/src/concurrency/clib/cfathread.h	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
+++ libcfa/src/concurrency/clib/cfathread.h	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
@@ -0,0 +1,43 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// clib/cfathread.h --
+//
+// Author           : Thierry Delisle
+// Created On       : Tue Sep 22 15:31:20 2020
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#include "stddef.h"
+#include "invoke.h"
+
+#if defined(__cforall) || defined(__cpluplus)
+extern "C" {
+#endif
+	//--------------------
+	// Basic types
+	struct cfathread_CRunner_t;
+	typedef struct cfathread_CRunner_t * cfathread_t;
+
+	//--------------------
+	// Basic thread support
+	cfathread_t cfathread_create( void (*main)( cfathread_t ) );
+	void cfathread_join( cfathread_t );
+
+	void cfathread_park( void );
+	void cfathread_unpark( cfathread_t );
+	void cfathread_yield( void );
+
+	//--------------------
+	// Basic kernel features
+	void cfathread_setproccnt( int );
+
+
+#if defined(__cforall) || defined(__cpluplus)
+}
+#endif
Index: tests/concurrent/.expect/clib.txt
===================================================================
--- tests/concurrent/.expect/clib.txt	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
+++ tests/concurrent/.expect/clib.txt	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
@@ -0,0 +1,21 @@
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done Unparker
Index: tests/concurrent/clib.c
===================================================================
--- tests/concurrent/clib.c	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
+++ tests/concurrent/clib.c	(revision bb6620274a509c003557406a0e5bf61a36ffc572)
@@ -0,0 +1,67 @@
+#include <clib/cfathread.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+thread_local struct drand48_data buffer = { 0 };
+int myrand() {
+	long int result;
+	lrand48_r(&buffer, &result);
+	return result;
+}
+
+
+enum Constants { blocked_size = 20 };
+cfathread_t volatile blocked[blocked_size];
+
+void Worker( cfathread_t this ) {
+	for(int i = 0; i < 1000; i++) {
+		int idx = myrand() % blocked_size;
+		if(blocked[idx]) {
+			cfathread_t thrd = __atomic_exchange_n(&blocked[idx], NULL, __ATOMIC_SEQ_CST);
+			cfathread_unpark( thrd );
+		} else {
+			cfathread_t thrd = __atomic_exchange_n(&blocked[idx], this, __ATOMIC_SEQ_CST);
+			cfathread_unpark( thrd );
+			cfathread_park();
+		}
+	}
+	printf("Done\n");
+}
+
+volatile bool stop;
+void Unparker( cfathread_t this ) {
+	while(!stop) {
+		int idx = myrand() % blocked_size;
+		cfathread_t thrd = __atomic_exchange_n(&blocked[idx], NULL, __ATOMIC_SEQ_CST);
+		cfathread_unpark( thrd );
+		int r = myrand() % 20;
+		for( int i = 0; i < r; i++ ) {
+			cfathread_yield();
+		}
+	}
+	printf("Done Unparker\n");
+}
+
+
+int main() {
+	stop = false;
+	for(int i = 0; i < blocked_size; i++) {
+		blocked[i] = NULL;
+	}
+
+	cfathread_setproccnt( 4 );
+	cfathread_t u = cfathread_create( Unparker );
+	{
+		cfathread_t t[20];
+		for(int i = 0; i < 20; i++) {
+			t[i] = cfathread_create( Worker );
+		}
+		for(int i = 0; i < 20; i++) {
+			cfathread_join( t[i] );
+		}
+	}
+	stop = true;
+	cfathread_join(u);
+	cfathread_setproccnt( 1 );
+}
