Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision 0bdfcc3388f9d38f0193e11bf3fda5e335326dff)
+++ libcfa/src/Makefile.am	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -111,4 +111,5 @@
 	concurrency/invoke.h \
 	concurrency/future.hfa \
+	concurrency/once.hfa \
 	concurrency/kernel/fwd.hfa \
 	concurrency/mutex_stmt.hfa
Index: libcfa/src/bits/defs.hfa
===================================================================
--- libcfa/src/bits/defs.hfa	(revision 0bdfcc3388f9d38f0193e11bf3fda5e335326dff)
+++ libcfa/src/bits/defs.hfa	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -31,7 +31,9 @@
 #define __cfa_anonymous_object(x) inline struct x
 #define __cfa_dlink1(x) dlink(x)
+#define __cfa_dlink2(x, name) inline struct name { inline dlink(x); }
 #else
 #define __cfa_anonymous_object(x) struct x __cfa_anonymous_object
 #define __cfa_dlink1(x) struct { struct x * next; struct x * back; }
+#define __cfa_dlink2(x, name) struct { struct x * next; struct x * back; } __dlink ## name
 #endif
 
Index: libcfa/src/concurrency/invoke.h
===================================================================
--- libcfa/src/concurrency/invoke.h	(revision 0bdfcc3388f9d38f0193e11bf3fda5e335326dff)
+++ libcfa/src/concurrency/invoke.h	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -195,11 +195,11 @@
 		struct __monitor_group_t monitors;
 
-		// used to put threads on dlist data structure
+		// intrusive link fields, used for locks, monitors and any user defined data structure
+		// default link fields for dlist
 		__cfa_dlink1(thread$) user_link;
 
-		struct {
-			struct thread$ * next;
-			struct thread$ * prev;
-		} node;
+		// secondary intrusive link fields, used for global cluster list
+		// default link fields for dlist
+		__cfa_dlink2(thread$, cltr_link);
 
 		// used to store state between clh lock/unlock
@@ -230,11 +230,10 @@
 	#ifdef __cforall
 	extern "Cforall" {
+		static inline thread$ * volatile & ?`next ( thread$ * this ) {
+			return this->user_link.next;
+		}
 
 		static inline thread$ *& get_next( thread$ & this ) __attribute__((const)) {
 			return this.user_link.next;
-		}
-
-		static inline [thread$ *&, thread$ *& ] __get( thread$ & this ) __attribute__((const)) {
-			return this.node.[next, prev];
 		}
 
@@ -244,4 +243,7 @@
 			return result;
 		}
+
+		P9_EMBEDDED(thread$, thread$.cltr_link)
+		P9_EMBEDDED(thread$.cltr_link, dlink(thread$))
 
 		static inline void ?{}(__monitor_group_t & this) {
Index: libcfa/src/concurrency/kernel.hfa
===================================================================
--- libcfa/src/concurrency/kernel.hfa	(revision 0bdfcc3388f9d38f0193e11bf3fda5e335326dff)
+++ libcfa/src/concurrency/kernel.hfa	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -256,5 +256,5 @@
 	// List of threads
 	__spinlock_t thread_list_lock;
-	__dllist_t(struct thread$) threads;
+	dlist(struct thread$, thread$.cltr_link) threads;
 	unsigned int nthreads;
 
Index: libcfa/src/concurrency/kernel/startup.cfa
===================================================================
--- libcfa/src/concurrency/kernel/startup.cfa	(revision 0bdfcc3388f9d38f0193e11bf3fda5e335326dff)
+++ libcfa/src/concurrency/kernel/startup.cfa	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -535,6 +535,4 @@
 	#endif
 
-	node.next = 0p;
-	node.prev = 0p;
 	doregister(curr_cluster, this);
 
@@ -659,5 +657,5 @@
 	#endif
 
-	threads{ __get };
+	threads{};
 
 	io.arbiter = create();
@@ -739,5 +737,5 @@
 	lock      (cltr->thread_list_lock __cfaabi_dbg_ctx2);
 	cltr->nthreads += 1;
-	push_front(cltr->threads, thrd);
+	insert_first(cltr->threads, thrd);
 	unlock    (cltr->thread_list_lock);
 }
@@ -745,6 +743,10 @@
 void unregister( cluster * cltr, thread$ & thrd ) {
 	lock  (cltr->thread_list_lock __cfaabi_dbg_ctx2);
-	remove(cltr->threads, thrd );
-	cltr->nthreads -= 1;
+	{
+		tytagref( dlink(thread$), dlink(thread$) ) ?`inner( thread$ & this ) = void;
+		with( DLINK_VIA( thread$, thread$.cltr_link ) )
+			remove( thrd );
+		cltr->nthreads -= 1;
+	}
 	unlock(cltr->thread_list_lock);
 }
Index: libcfa/src/concurrency/once.hfa
===================================================================
--- libcfa/src/concurrency/once.hfa	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
+++ libcfa/src/concurrency/once.hfa	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -0,0 +1,106 @@
+//
+// 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.
+//
+// once.hfa -- Algorithms to prevent concurrent calls to cause duplicate calls
+//
+// Author           : Thierry Delisle
+// Created On       : Thu Oct 11:40:47 2022
+// Last Modified By :
+// Last Modified On :
+// Update Count     :
+//
+
+#pragma once
+
+#include "containers/lockfree.hfa"
+#include "kernel/fwd.hfa"
+
+enum once_state {
+	ARMED = 0,
+	IN_PROGRESS,
+	READY
+};
+
+struct once_flag {
+	volatile int state;
+	poison_list( thread$ ) waiters;
+};
+
+static inline {
+	void ?{}(once_flag & this) { this.state = ARMED; }
+
+	void once_wait$(once_flag & this) {
+		// just push the thread to the list
+		if(push( this.waiters, active_thread() )) {
+			// the list wasn't poisoned, push was successful, just park.
+			park();
+		}
+	}
+
+	void once_call$( once_flag & this, void (*func)(void) ) {
+		/* paranoid */ verify( once_state.IN_PROGRESS == __atomic_load_n(&this.state, __ATOMIC_RELAXED) );
+		/* paranoid */ verify( ! is_poisoned(this.waiters) );
+
+		// call the thing we are here for!
+		func();
+
+		/* paranoid */ verify( ! is_poisoned(this.waiters) );
+		/* paranoid */ verify( once_state.IN_PROGRESS == __atomic_load_n(&this.state, __ATOMIC_RELAXED) );
+
+		// Mark the call as being done.
+		__atomic_store_n( &this.state, (int)once_state.IN_PROGRESS, __ATOMIC_SEQ_CST );
+
+		// wake up the sleepers and make sure no new sleeper arrives
+		thread$ * sleeper = poison( this.waiters );
+
+		/* paranoid */ verify( ! is_poisoned(this.waiters) );
+		/* paranoid */ verify( once_state.READY == __atomic_load_n(&this.state, __ATOMIC_RELAXED) );
+
+		while(sleeper != 0p) {
+			// find the next thread now because unpark invalidates the pointer
+			thread$ * next = advance(sleeper);
+
+			// wake-up the thread, invalidates pointer
+			unpark( sleeper );
+
+			// update the current
+			sleeper = next;
+		}
+	}
+
+	bool call_once( once_flag & this, void (*func)(void) ) {
+		// is the call already done?
+		if(likely(once_state.READY == __atomic_load_n(&this.state, __ATOMIC_RELAXED))) {
+			/* paranoid */ verify( is_poisoned(this.waiters) );
+			return false;
+		}
+
+		// Try to CAS ourself as the thread that will actually call the function
+		int expected = ARMED;
+		if( __atomic_compare_exchange_n( &this.state, &expected, (int)once_state.IN_PROGRESS, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ) {
+
+			// we won the race, call the function
+			once_call$( this, func );
+
+			/* paranoid */ verify( is_poisoned(this.waiters) );
+			/* paranoid */ verify( once_state.READY == __atomic_load_n(&this.state, __ATOMIC_RELAXED) );
+
+			// in case someone cares, this call did do the underlying call
+			return true;
+		}
+		else {
+
+			// someone else is doing the call, just wait
+			once_wait$( this );
+
+			/* paranoid */ verify( is_poisoned(this.waiters) );
+			/* paranoid */ verify( once_state.READY == __atomic_load_n(&this.state, __ATOMIC_RELAXED) );
+
+			// in case someone cares, someone else did the call
+			return false;
+		}
+	}
+}
Index: libcfa/src/concurrency/thread.cfa
===================================================================
--- libcfa/src/concurrency/thread.cfa	(revision 0bdfcc3388f9d38f0193e11bf3fda5e335326dff)
+++ libcfa/src/concurrency/thread.cfa	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -54,7 +54,4 @@
 	#endif
 
-	node.next = 0p;
-	node.prev = 0p;
-
 	clh_node = malloc( );
 	*clh_node = false;
Index: libcfa/src/containers/lockfree.hfa
===================================================================
--- libcfa/src/containers/lockfree.hfa	(revision 0bdfcc3388f9d38f0193e11bf3fda5e335326dff)
+++ libcfa/src/containers/lockfree.hfa	(revision 4da152af87cdafc91c96ad9ffda2dff105a17db6)
@@ -142,4 +142,5 @@
 
 	static inline void ?{}(poison_list(T) & this) { this.head = 0p; }
+	static inline bool is_poisoned( const poison_list(T) & this ) { return 1p == this.head; }
 
  	static inline forall(| { T * volatile & ?`next ( T * ); })
@@ -147,6 +148,6 @@
 		// Adds an element to the list
 		// Multi-Thread Safe, Lock-Free
-		T * push(poison_list(T) & this, T * elem) __attribute__((artificial));
-		T * push(poison_list(T) & this, T * elem) {
+		bool push(poison_list(T) & this, T * elem) __attribute__((artificial));
+		bool push(poison_list(T) & this, T * elem) {
 			/* paranoid */ verify(0p == (elem`next));
 			__atomic_store_n( &elem`next, (T*)1p, __ATOMIC_RELAXED );
@@ -156,5 +157,5 @@
 			for() {
 				// check if it's poisoned
-				if(expected == 1p) return 0p;
+				if(expected == 1p) return false;
 
 				// try to CAS the elem in
@@ -162,11 +163,12 @@
 					// We managed to exchange in, we are done
 
-					// We should never succeed the CAS if it's poisonned.
-					/* paranoid */ verify( expected != 1p );
+					// We should never succeed the CAS if it's poisonned and the elem should be 1p.
+					/* paranoid */ verify( expected  != 1p );
+					/* paranoid */ verify( elem`next == 1p );
 
 					// If we aren't the first, we need to tell the person before us
 					// No need to
 					elem`next = expected;
-					return expected;
+					return true;
 				}
 			}
@@ -190,5 +192,5 @@
 		T * poison(poison_list(T) & this) {
 			T * ret = __atomic_exchange_n( &this.head, (T*)1p, __ATOMIC_SEQ_CST );
-			/* paranoid */ verify( ret != (T*)1p );
+			/* paranoid */ verifyf( ret != (T*)1p, "Poison list %p poisoned more than once!", &this );
 			return ret;
 		}
