Index: configure.ac
===================================================================
--- configure.ac	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ configure.ac	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -226,7 +226,7 @@
 AC_PROG_YACC
 if test "${YACC}" = "yacc" ; then echo "Error: bison required." ; exit 1 ; fi
-AC_PROG_LEX
+AC_PROG_LEX(yywrap)
 if test "${LEX}" = "lex" ; then echo "Error: flex required." ; exit 1 ; fi
-AC_PROG_LIBTOOL
+LT_INIT
 AC_PROG_INSTALL
 
@@ -284,12 +284,12 @@
 		tools/Makefile
 		tools/prettyprinter/Makefile
+		benchmark/Cargo.toml
 	])
-
-	AC_OUTPUT(benchmark/Cargo.toml)
 ])
 
 AC_CONFIG_LINKS([tests/test.py:tests/test.py])
-
-AC_OUTPUT(tests/config.py)
+AC_CONFIG_FILES([tests/config.py])
+
+AC_OUTPUT
 
 # Final text
Index: libcfa/configure.ac
===================================================================
--- libcfa/configure.ac	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ libcfa/configure.ac	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -122,5 +122,5 @@
 AC_PROG_CC
 AM_PROG_AS
-AC_PROG_LIBTOOL
+LT_INIT
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
@@ -246,5 +246,5 @@
 AC_CONFIG_HEADERS(prelude/defines.hfa)
 
-AC_OUTPUT()
+AC_OUTPUT
 
 # Final text
Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ libcfa/src/Makefile.am	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -113,5 +113,7 @@
 	concurrency/once.hfa \
 	concurrency/kernel/fwd.hfa \
-	concurrency/mutex_stmt.hfa
+	concurrency/mutex_stmt.hfa \
+    concurrency/select.hfa \
+    concurrency/channel.hfa
 
 inst_thread_headers_src = \
Index: libcfa/src/concurrency/channel.hfa
===================================================================
--- libcfa/src/concurrency/channel.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ libcfa/src/concurrency/channel.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,108 @@
+#include <locks.hfa>
+
+struct no_reacq_lock {
+    inline exp_backoff_then_block_lock;
+};
+
+// have to override these by hand to get around plan 9 inheritance bug where resolver can't find the appropriate routine to call
+static inline void   ?{}( no_reacq_lock & this ) { ((exp_backoff_then_block_lock &)this){}; }
+static inline bool   try_lock(no_reacq_lock & this) { return try_lock(((exp_backoff_then_block_lock &)this)); }
+static inline void   lock(no_reacq_lock & this) { lock(((exp_backoff_then_block_lock &)this)); }
+static inline void   unlock(no_reacq_lock & this) { unlock(((exp_backoff_then_block_lock &)this)); }
+static inline void   on_notify(no_reacq_lock & this, struct thread$ * t ) { on_notify(((exp_backoff_then_block_lock &)this), t); }
+static inline size_t on_wait(no_reacq_lock & this) { return on_wait(((exp_backoff_then_block_lock &)this)); }
+// override wakeup so that we don't reacquire the lock if using a condvar
+static inline void   on_wakeup( no_reacq_lock & this, size_t recursion ) {}
+
+forall( T ) {
+struct channel {
+    size_t size;
+    size_t front, back, count;
+    T * buffer;
+    fast_cond_var( no_reacq_lock ) prods, cons;
+    no_reacq_lock mutex_lock;
+};
+
+static inline void ?{}( channel(T) &c, size_t _size ) with(c) {
+    size = _size;
+    front = back = count = 0;
+    buffer = anew( size );
+    prods{};
+    cons{};
+    mutex_lock{};
+}
+
+static inline void ?{}( channel(T) &c ){ ((channel(T) &)c){ 0 }; }
+static inline void ^?{}( channel(T) &c ) with(c) { delete( buffer ); }
+static inline size_t get_count( channel(T) & chan ) with(chan) { return count; }
+static inline size_t get_size( channel(T) & chan ) with(chan) { return size; }
+static inline bool has_waiters( channel(T) & chan ) with(chan) { return !empty( cons ) || !empty( prods ); }
+static inline bool has_waiting_consumers( channel(T) & chan ) with(chan) { return !empty( cons ); }
+static inline bool has_waiting_producers( channel(T) & chan ) with(chan) { return !empty( prods ); }
+
+static inline void insert_( channel(T) & chan, T elem ) with(chan) {
+    memcpy((void *)&buffer[back], (void *)&elem, sizeof(T));
+    count += 1;
+    back++;
+    if ( back == size ) back = 0;
+}
+
+
+static inline void insert( channel(T) & chan, T elem ) with(chan) {
+    lock( mutex_lock );
+
+    // have to check for the zero size channel case
+    if ( size == 0 && !empty( cons ) ) {
+        memcpy((void *)front( cons ), (void *)&elem, sizeof(T));
+        notify_one( cons );
+        unlock( mutex_lock );
+        return;
+    }
+
+    // wait if buffer is full, work will be completed by someone else
+    if ( count == size ) { 
+        wait( prods, mutex_lock, (uintptr_t)&elem );
+        return;
+    } // if
+
+    if ( count == 0 && !empty( cons ) )
+        // do waiting consumer work
+        memcpy((void *)front( cons ), (void *)&elem, sizeof(T)); 
+    else insert_( chan, elem );
+    
+    notify_one( cons );
+    unlock( mutex_lock );
+}
+
+static inline T remove( channel(T) & chan ) with(chan) {
+    lock( mutex_lock );
+    T retval;
+
+    // have to check for the zero size channel case
+    if ( size == 0 && !empty( prods ) ) {
+        memcpy((void *)&retval, (void *)front( prods ), sizeof(T));
+        notify_one( prods );
+        unlock( mutex_lock );
+        return retval;
+    }
+
+    // wait if buffer is empty, work will be completed by someone else
+    if (count == 0) { 
+        wait( cons, mutex_lock, (uintptr_t)&retval );
+        return retval;
+    }
+
+    // Remove from buffer
+    memcpy((void *)&retval, (void *)&buffer[front], sizeof(T));
+    count -= 1;
+    front = (front + 1) % size;
+
+    if (count == size - 1 && !empty( prods ) ) 
+        insert_( chan, *((T *)front( prods )) );  // do waiting producer work
+
+    notify_one( prods );
+    unlock( mutex_lock );
+    return retval;
+}
+
+} // forall( T )
Index: libcfa/src/concurrency/clib/cfathread.cfa
===================================================================
--- libcfa/src/concurrency/clib/cfathread.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ libcfa/src/concurrency/clib/cfathread.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -439,5 +439,5 @@
 	// Mutex
 	struct cfathread_mutex {
-		linear_backoff_then_block_lock impl;
+		exp_backoff_then_block_lock impl;
 	};
 	int cfathread_mutex_init(cfathread_mutex_t *restrict mut, const cfathread_mutexattr_t *restrict) __attribute__((nonnull (1))) { *mut = new(); return 0; }
@@ -454,5 +454,5 @@
 	// Condition
 	struct cfathread_condition {
-		condition_variable(linear_backoff_then_block_lock) impl;
+		condition_variable(exp_backoff_then_block_lock) impl;
 	};
 	int cfathread_cond_init(cfathread_cond_t *restrict cond, const cfathread_condattr_t *restrict) __attribute__((nonnull (1))) { *cond = new(); return 0; }
Index: libcfa/src/concurrency/future.hfa
===================================================================
--- libcfa/src/concurrency/future.hfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ libcfa/src/concurrency/future.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -5,7 +5,7 @@
 // file "LICENCE" distributed with Cforall.
 //
-// io/types.hfa --
-//
-// Author           : Thierry Delisle & Peiran Hong
+// concurrency/future.hfa --
+//
+// Author           : Thierry Delisle & Peiran Hong & Colby Parsons
 // Created On       : Wed Jan 06 17:33:18 2021
 // Last Modified By :
@@ -14,11 +14,184 @@
 //
 
-#pragma once
+// #pragma once
 
 #include "bits/locks.hfa"
 #include "monitor.hfa"
-
+#include "select.hfa"
+
+//----------------------------------------------------------------------------
+// future
+// I don't use future_t here since I need to use a lock for this future
+//  since it supports multiple consumers
+//  future_t is lockfree and uses atomics which aren't needed given we use locks here
 forall( T ) {
+    // enum(int) { FUTURE_EMPTY = 0, FUTURE_FULFILLED = 1 }; // Enums seem to be broken so feel free to add this back afterwards
+
+    // temporary enum replacement
+    const int FUTURE_EMPTY = 0;
+    const int FUTURE_FULFILLED = 1;
+
 	struct future {
+		int state;
+		T result;
+		dlist( select_node ) waiters;
+        futex_mutex lock;
+	};
+
+    struct future_node {
+        inline select_node;
+        T * my_result;
+    };
+
+    // C_TODO: perhaps allow exceptions to be inserted like uC++?
+
+	static inline {
+
+        void ?{}( future_node(T) & this, thread$ * blocked_thread, T * my_result ) {
+            ((select_node &)this){ blocked_thread };
+            this.my_result = my_result;
+        }
+
+        void ?{}(future(T) & this) {
+			this.waiters{};
+            this.state = FUTURE_EMPTY;
+            this.lock{};
+		}
+
+		// Reset future back to original state
+		void reset(future(T) & this) with(this)
+        {
+            lock( lock );
+            if( ! waiters`isEmpty )
+                abort("Attempting to reset a future with blocked waiters");
+            state = FUTURE_EMPTY;
+            unlock( lock );
+        }
+
+		// check if the future is available
+        // currently no mutual exclusion because I can't see when you need this call to be synchronous or protected
+		bool available( future(T) & this ) { return this.state; }
+
+
+        // memcpy wrapper to help copy values
+        void copy_T( T & from, T & to ) {
+            memcpy((void *)&to, (void *)&from, sizeof(T));
+        }
+
+        // internal helper to signal waiters off of the future
+        void _internal_flush( future(T) & this ) with(this) {
+            while( ! waiters`isEmpty ) {
+                select_node &s = try_pop_front( waiters );
+
+                if ( s.race_flag == 0p )
+                    // poke in result so that woken threads do not need to reacquire any locks
+                    // *(((future_node(T) &)s).my_result) = result;
+                    copy_T( result, *(((future_node(T) &)s).my_result) );
+                else if ( !install_select_winner( s, &this ) ) continue;
+                
+                // only unpark if future is not selected
+                // or if it is selected we only unpark if we win the race
+                unpark( s.blocked_thread );
+            }
+        }
+
+		// Fulfil the future, returns whether or not someone was unblocked
+		bool fulfil( future(T) & this, T & val ) with(this) {
+            lock( lock );
+            if( state != FUTURE_EMPTY )
+                abort("Attempting to fulfil a future that has already been fulfilled");
+
+            copy_T( val, result );
+
+            bool ret_val = ! waiters`isEmpty;
+            state = FUTURE_FULFILLED;
+			_internal_flush( this );
+            unlock( lock );
+            return ret_val;
+		}
+
+		// Wait for the future to be fulfilled
+		// Also return whether the thread had to block or not
+		[T, bool] get( future(T) & this ) with( this ) {
+            lock( lock );
+            T ret_val;
+            if( state == FUTURE_FULFILLED ) {
+                copy_T( result, ret_val );
+                unlock( lock );
+                return [ret_val, false];
+            }
+
+            future_node(T) node = { active_thread(), &ret_val };
+            insert_last( waiters, ((select_node &)node) );
+            unlock( lock );
+            park( );
+
+			return [ret_val, true];
+		}
+
+		// Wait for the future to be fulfilled
+		T get( future(T) & this ) {
+			[T, bool] tt;
+			tt = get(this);
+			return tt.0;
+		}
+
+        // Gets value if it is available and returns [ val, true ]
+        // otherwise returns [ default_val, false]
+        // will not block
+        [T, bool] try_get( future(T) & this ) with(this) {
+            lock( lock );
+            T ret_val;
+            if( state == FUTURE_FULFILLED ) {
+                copy_T( result, ret_val );
+                unlock( lock );
+                return [ret_val, true];
+            }
+            unlock( lock );
+            
+            return [ret_val, false];
+        }
+
+        void * register_select( future(T) & this, select_node & s ) with(this) {
+            lock( lock );
+
+            // future not ready -> insert select node and return 0p
+            if( state == FUTURE_EMPTY ) {
+                insert_last( waiters, s );
+                unlock( lock );
+                return 0p;
+            }
+
+            // future ready and we won race to install it as the select winner return 1p
+            if ( install_select_winner( s, &this ) ) {
+                unlock( lock );
+                return 1p;
+            }
+
+            unlock( lock );
+            // future ready and we lost race to install it as the select winner
+            return 2p;
+        }
+
+        void unregister_select( future(T) & this, select_node & s ) with(this) {
+            lock( lock );
+            if ( s`isListed ) remove( s );
+            unlock( lock );
+        }
+		
+	}
+}
+
+//--------------------------------------------------------------------------------------------------------
+// These futures below do not support select statements so they may not be as useful as 'future'
+//  however the 'single_future' is cheap and cheerful and is most likely more performant than 'future'
+//  since it uses raw atomics and no locks afaik
+//
+// As far as 'multi_future' goes I can't see many use cases as it will be less performant than 'future'
+//  since it is monitor based and also is not compatible with select statements
+//--------------------------------------------------------------------------------------------------------
+
+forall( T ) {
+	struct single_future {
 		inline future_t;
 		T result;
@@ -27,15 +200,15 @@
 	static inline {
 		// Reset future back to original state
-		void reset(future(T) & this) { reset( (future_t&)this ); }
+		void reset(single_future(T) & this) { reset( (future_t&)this ); }
 
 		// check if the future is available
-		bool available( future(T) & this ) { return available( (future_t&)this ); }
+		bool available( single_future(T) & this ) { return available( (future_t&)this ); }
 
 		// Mark the future as abandoned, meaning it will be deleted by the server
 		// This doesn't work beause of the potential need for a destructor
-		void abandon( future(T) & this );
+		void abandon( single_future(T) & this );
 
 		// Fulfil the future, returns whether or not someone was unblocked
-		thread$ * fulfil( future(T) & this, T result ) {
+		thread$ * fulfil( single_future(T) & this, T result ) {
 			this.result = result;
 			return fulfil( (future_t&)this );
@@ -44,5 +217,5 @@
 		// Wait for the future to be fulfilled
 		// Also return whether the thread had to block or not
-		[T, bool] wait( future(T) & this ) {
+		[T, bool] wait( single_future(T) & this ) {
 			bool r = wait( (future_t&)this );
 			return [this.result, r];
@@ -50,5 +223,5 @@
 
 		// Wait for the future to be fulfilled
-		T wait( future(T) & this ) {
+		T wait( single_future(T) & this ) {
 			[T, bool] tt;
 			tt = wait(this);
Index: libcfa/src/concurrency/locks.hfa
===================================================================
--- libcfa/src/concurrency/locks.hfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ libcfa/src/concurrency/locks.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -38,6 +38,8 @@
 #include <unistd.h>
 
-// undef to make a number of the locks not reacquire upon waking from a condlock
-#define REACQ 1
+// C_TODO: cleanup this and locks.cfa
+// - appropriate separation of interface and impl
+// - clean up unused/unneeded locks
+// - change messy big blocking lock from inheritance to composition to remove need for flags
 
 //-----------------------------------------------------------------------------
@@ -249,14 +251,10 @@
 static inline void on_notify(clh_lock & this, struct thread$ * t ) { unpark(t); }
 static inline size_t on_wait(clh_lock & this) { unlock(this); return 0; }
-static inline void on_wakeup(clh_lock & this, size_t recursion ) {
-	#ifdef REACQ
-	lock(this);
-	#endif
-}
-
-
-//-----------------------------------------------------------------------------
-// Linear backoff Spinlock
-struct linear_backoff_then_block_lock {
+static inline void on_wakeup(clh_lock & this, size_t recursion ) { lock(this); }
+
+
+//-----------------------------------------------------------------------------
+// Exponential backoff then block lock
+struct exp_backoff_then_block_lock {
 	// Spin lock used for mutual exclusion
 	__spinlock_t spinlock;
@@ -269,14 +267,14 @@
 };
 
-static inline void  ?{}( linear_backoff_then_block_lock & this ) {
+static inline void  ?{}( exp_backoff_then_block_lock & this ) {
 	this.spinlock{};
 	this.blocked_threads{};
 	this.lock_value = 0;
 }
-static inline void ^?{}( linear_backoff_then_block_lock & this ) {}
-// static inline void ?{}( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
-// static inline void ?=?( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
-
-static inline bool internal_try_lock(linear_backoff_then_block_lock & this, size_t & compare_val) with(this) {
+static inline void ^?{}( exp_backoff_then_block_lock & this ) {}
+// static inline void ?{}( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;
+// static inline void ?=?( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;
+
+static inline bool internal_try_lock(exp_backoff_then_block_lock & this, size_t & compare_val) with(this) {
 	if (__atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
 		return true;
@@ -285,7 +283,7 @@
 }
 
-static inline bool try_lock(linear_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }
-
-static inline bool try_lock_contention(linear_backoff_then_block_lock & this) with(this) {
+static inline bool try_lock(exp_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }
+
+static inline bool try_lock_contention(exp_backoff_then_block_lock & this) with(this) {
 	if (__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE) == 0) {
 		return true;
@@ -294,5 +292,5 @@
 }
 
-static inline bool block(linear_backoff_then_block_lock & this) with(this) {
+static inline bool block(exp_backoff_then_block_lock & this) with(this) {
 	lock( spinlock __cfaabi_dbg_ctx2 ); // TODO change to lockfree queue (MPSC)
 	if (lock_value != 2) {
@@ -306,5 +304,5 @@
 }
 
-static inline void lock(linear_backoff_then_block_lock & this) with(this) {
+static inline void lock(exp_backoff_then_block_lock & this) with(this) {
 	size_t compare_val = 0;
 	int spin = 4;
@@ -324,5 +322,5 @@
 }
 
-static inline void unlock(linear_backoff_then_block_lock & this) with(this) {
+static inline void unlock(exp_backoff_then_block_lock & this) with(this) {
     if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return;
 	lock( spinlock __cfaabi_dbg_ctx2 );
@@ -332,11 +330,7 @@
 }
 
-static inline void on_notify(linear_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
-static inline size_t on_wait(linear_backoff_then_block_lock & this) { unlock(this); return 0; }
-static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) { 
-	#ifdef REACQ
-	lock(this);
-	#endif
-}
+static inline void on_notify(exp_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
+static inline size_t on_wait(exp_backoff_then_block_lock & this) { unlock(this); return 0; }
+static inline void on_wakeup(exp_backoff_then_block_lock & this, size_t recursion ) { lock(this); }
 
 //-----------------------------------------------------------------------------
@@ -390,11 +384,7 @@
 
 static inline void on_notify(fast_block_lock & this, struct thread$ * t ) with(this) {
-	#ifdef REACQ
-		lock( lock __cfaabi_dbg_ctx2 );
-		insert_last( blocked_threads, *t );
-		unlock( lock );
-	#else
-		unpark(t);
-	#endif
+    lock( lock __cfaabi_dbg_ctx2 );
+    insert_last( blocked_threads, *t );
+    unlock( lock );
 }
 static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; }
@@ -553,9 +543,5 @@
 }
 static inline size_t on_wait(spin_queue_lock & this) { unlock(this); return 0; }
-static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) {
-	#ifdef REACQ
-	lock(this);
-	#endif
-}
+static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { lock(this); }
 
 
@@ -598,9 +584,5 @@
 static inline void on_notify(mcs_block_spin_lock & this, struct thread$ * t ) { unpark(t); }
 static inline size_t on_wait(mcs_block_spin_lock & this) { unlock(this); return 0; }
-static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {
-	#ifdef REACQ
-	lock(this);
-	#endif
-}
+static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {lock(this); }
 
 //-----------------------------------------------------------------------------
@@ -640,5 +622,4 @@
 
 static inline void on_notify(block_spin_lock & this, struct thread$ * t ) with(this.lock) {
-  #ifdef REACQ
 	// first we acquire internal fast_block_lock
 	lock( lock __cfaabi_dbg_ctx2 );
@@ -652,16 +633,12 @@
 	unlock( lock );
 
-  #endif
 	unpark(t);
-	
 }
 static inline size_t on_wait(block_spin_lock & this) { unlock(this); return 0; }
 static inline void on_wakeup(block_spin_lock & this, size_t recursion ) with(this) {
-  #ifdef REACQ
 	// now we acquire the entire block_spin_lock upon waking up
 	while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause();
 	__atomic_store_n(&held, true, __ATOMIC_RELEASE);
 	unlock( lock ); // Now we release the internal fast_spin_lock
-  #endif
 }
 
Index: libcfa/src/concurrency/select.hfa
===================================================================
--- libcfa/src/concurrency/select.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ libcfa/src/concurrency/select.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,61 @@
+#include "containers/list.hfa"
+#include <stdint.h>
+#include <kernel.hfa>
+#include <locks.hfa>
+
+struct select_node {
+    thread$ * blocked_thread;
+    void ** race_flag;
+    inline dlink(select_node);
+};
+P9_EMBEDDED( select_node, dlink(select_node) )
+
+void ?{}( select_node & this ) {
+    this.blocked_thread = 0p;
+    this.race_flag = 0p;
+}
+
+void ?{}( select_node & this, thread$ * blocked_thread ) {
+    this.blocked_thread = blocked_thread;
+    this.race_flag = 0p;
+}
+
+void ?{}( select_node & this, thread$ * blocked_thread, void ** race_flag ) {
+    this.blocked_thread = blocked_thread;
+    this.race_flag = race_flag;
+}
+
+void ^?{}( select_node & this ) {}
+
+
+//-----------------------------------------------------------------------------
+// is_selectable
+trait is_selectable(T & | sized(T)) {
+    // For registering a select on a selectable concurrency primitive
+    // return 0p if primitive not accessible yet
+    // return 1p if primitive gets acquired
+    // return 2p if primitive is accessible but some other primitive won the race
+    // C_TODO: add enum for return values
+    void * register_select( T &, select_node & );
+
+    void unregister_select( T &, select_node &  );
+};
+
+static inline bool install_select_winner( select_node & this, void * primitive_ptr ) with(this) {
+    // temporary needed for atomic instruction
+    void * cmp_flag = 0p;
+    
+    // if we dont win the selector race we need to potentially 
+    //   ignore this node and move to the next one so we return accordingly
+    if ( *race_flag != 0p || 
+        !__atomic_compare_exchange_n(
+            race_flag, 
+            &cmp_flag, 
+            primitive_ptr, 
+            false,
+            __ATOMIC_SEQ_CST,
+            __ATOMIC_SEQ_CST
+        )
+    ) return false; // lost race and some other node triggered select
+    return true; // won race so this node is what the select proceeds with
+}
Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/AST/Expr.cpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -30,5 +30,5 @@
 #include "Common/SemanticError.h"
 #include "GenPoly/Lvalue.h"        // for referencesPermissable
-#include "ResolvExpr/typeops.h"    // for extractResultType
+#include "ResolvExpr/Unify.h"      // for extractResultType
 #include "Tuples/Tuples.h"         // for makeTupleType
 
Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/AST/Node.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -19,5 +19,4 @@
 #include <cstddef>     // for nullptr_t
 #include <iosfwd>
-#include <type_traits> // for remove_reference
 
 #include "Common/ErrorObjects.h"  // for SemanticErrorException
@@ -36,6 +35,6 @@
 	Node(const Node&) : strong_count(0), weak_count(0) {}
 	Node(Node&&) : strong_count(0), weak_count(0) {}
-	Node& operator= (const Node&) = delete;
-	Node& operator= (Node&&) = delete;
+	Node& operator=(const Node&) = delete;
+	Node& operator=(Node&&) = delete;
 	virtual ~Node() {}
 
Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/AST/SymbolTable.cpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -22,5 +22,5 @@
 #include "Inspect.hpp"
 #include "Type.hpp"
-#include "CodeGen/OperatorTable.h"  // for isCtorDtorAssign
+#include "CodeGen/OperatorTable.h"         // for isCtorDtorAssign
 #include "Common/SemanticError.h"
 #include "Common/Stats/Counter.h"
@@ -28,5 +28,6 @@
 #include "InitTweak/InitTweak.h"
 #include "ResolvExpr/Cost.h"
-#include "ResolvExpr/typeops.h"
+#include "ResolvExpr/CandidateFinder.hpp"  // for referenceToRvalueConversion
+#include "ResolvExpr/Unify.h"
 #include "SymTab/Mangler.h"
 
Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/CodeGen/CodeGenerator.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -273,36 +273,37 @@
 	}
 
+	template<typename pass_type>
+	inline void genEnumInitializer( PassVisitor<pass_type> * visitor, Type * baseType, std::ostream & output,
+	Initializer * init, long long * cur_val, Options options) {
+		auto baseTypeAsBasic = baseType ? dynamic_cast<BasicType *>( baseType ) : nullptr;
+		if ( init ) { // If value has an explicit initiazatior 
+			output << " = "; 
+			output << "(" << genType(baseType, "", options) << ")";
+			init->accept( *visitor );
+			if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // if it is an integral type and initilizer offered, 
+			// need to update the cur_val
+				Expression* expr = ((SingleInit *)(init))->value;
+				while ( auto temp = dynamic_cast<CastExpr *>(expr) ) { // unwrap introduced cast
+					expr = temp->arg;
+				}
+				*cur_val = ((ConstantExpr *)expr)->constant.get_ival()+1;
+			}
+		} else if ( baseTypeAsBasic && baseTypeAsBasic->isInteger() ) { // integral implicitly init to cur_val + 1
+			output << " = " << "(" << genType(baseType, "", options) << ")";
+			output << (*cur_val)++;
+		}
+	}
+
 	void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
 		extension( enumDecl );
 		std::list< Declaration* > &memb = enumDecl->get_members();
 		if (enumDecl->base && ! memb.empty()) {
-			unsigned long long last_val = -1; // if the first enum value has no explicit initializer,
-			// as other
+			long long cur_val = 0;
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
 				ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
 				assert( obj );
 				output << "static ";
-				output << genType(enumDecl->base, "", options) << " const ";
-				output << mangleName( obj ) << " ";
-				output << " = ";
-				output << "(" << genType(enumDecl->base, "", options) << ")";
-				if ( (BasicType *)(enumDecl->base) && ((BasicType *)(enumDecl->base))->isWholeNumber() ) {
-					if ( obj->get_init() ) {
-						obj->get_init()->accept( *visitor );
-						Expression* expr = ((SingleInit *)(obj->init))->value;
-						while ( auto temp = dynamic_cast<CastExpr *>(expr) ) {
-							expr = temp->arg;
-						}
-						last_val = ((ConstantExpr *)expr)->constant.get_ival();
-					} else {
-						output << ++last_val;
-					} // if
-				} else {
-					if ( obj->get_init() ) {
-						obj->get_init()->accept( *visitor );
-					} else {
-						// Should not reach here!
-					}
-				}
+				output << genType(enumDecl->base, mangleName( obj ), options);
+				genEnumInitializer( visitor, enumDecl->base, output, obj->get_init(), &cur_val, options);
 				output << ";" << endl;
 			} // for
Index: src/CodeGen/GenType.cc
===================================================================
--- src/CodeGen/GenType.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/CodeGen/GenType.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -255,5 +255,5 @@
 	void GenType::postvisit( EnumInstType * enumInst ) {
 		if ( enumInst->baseEnum && enumInst->baseEnum->base ) {
-			typeString = genType(enumInst->baseEnum->base, "", options) + typeString;
+			typeString = genType(enumInst->baseEnum->base, typeString, options);
 		} else {
 			typeString = enumInst->name + " " + typeString;
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/GenPoly/Box.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -14,4 +14,6 @@
 //
 
+#include "Box.h"
+
 #include <algorithm>                     // for mismatch
 #include <cassert>                       // for assert, strict_dynamic_cast
@@ -23,6 +25,4 @@
 #include <string>                        // for string, allocator, basic_string
 #include <utility>                       // for pair
-
-#include "Box.h"
 
 #include "CodeGen/OperatorTable.h"
@@ -37,5 +37,5 @@
 #include "InitTweak/InitTweak.h"         // for getFunctionName, isAssignment
 #include "Lvalue.h"                      // for generalizedLvalue
-#include "ResolvExpr/typeops.h"          // for typesCompatible
+#include "ResolvExpr/Unify.h"            // for typesCompatible
 #include "ScopedSet.h"                   // for ScopedSet, ScopedSet<>::iter...
 #include "ScrubTyVars.h"                 // for ScrubTyVars
@@ -911,33 +911,31 @@
 
 			for ( FunctionType const * const funType : functions ) {
-				FunctionType *originalFunction = funType->clone();
-				FunctionType *realFunction = funType->clone();
-				std::string mangleName = SymTab::Mangler::mangle( realFunction );
+				std::string mangleName = SymTab::Mangler::mangle( funType );
 
 				// only attempt to create an adapter or pass one as a parameter if we haven't already done so for this
 				// pre-substitution parameter function type.
 				// The second part of the insert result is "is the value new".
-				if ( adaptersDone.insert( mangleName ).second ) {
-
-					// apply substitution to type variables to figure out what the adapter's type should look like
-					assert( env );
-					env->apply( realFunction );
-					mangleName = SymTab::Mangler::mangle( realFunction );
-					mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
-
-					typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
-					AdapterIter adapter = adapters.find( mangleName );
-					if ( adapter == adapters.end() ) {
-						// adapter has not been created yet in the current scope, so define it
-						FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars );
-						std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
-						adapter = answer.first;
-						stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) );
-					} // if
-					assert( adapter != adapters.end() );
-
-					// add the appropriate adapter as a parameter
-					appExpr->get_args().push_front( new VariableExpr( adapter->second ) );
+				if ( !adaptersDone.insert( mangleName ).second ) continue;
+
+				// Apply substitution to type variables to figure out what the adapter's type should look like.
+				assert( env );
+				FunctionType *realType = funType->clone();
+				env->apply( realType );
+				mangleName = SymTab::Mangler::mangle( realType );
+				mangleName += makePolyMonoSuffix( funType, exprTyVars );
+
+				typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
+				AdapterIter adapter = adapters.find( mangleName );
+				if ( adapter == adapters.end() ) {
+					// Adapter has not been created yet in the current scope, so define it.
+					FunctionDecl *newAdapter = makeAdapter( funType, realType, mangleName, exprTyVars );
+					std::pair< AdapterIter, bool > answer = adapters.insert( mangleName, newAdapter );
+					adapter = answer.first;
+					stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) );
 				} // if
+				assert( adapter != adapters.end() );
+
+				// Add the appropriate adapter as a parameter.
+				appExpr->args.push_front( new VariableExpr( adapter->second ) );
 			} // for
 		} // passAdapters
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/GenPoly/GenPoly.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -24,5 +24,7 @@
 #include <vector>                       // for vector
 
+#include "AST/Expr.hpp"
 #include "AST/Type.hpp"
+#include "AST/TypeSubstitution.hpp"
 #include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::const_it...
 #include "ResolvExpr/typeops.h"         // for flatten
@@ -490,4 +492,6 @@
 		}
 
+		/// Flattens a list of types.
+		// There is another flattenList in Unify.
 		void flattenList( vector<ast::ptr<ast::Type>> const & src,
 				vector<ast::ptr<ast::Type>> & out ) {
Index: src/GenPoly/InstantiateGeneric.cc
===================================================================
--- src/GenPoly/InstantiateGeneric.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/GenPoly/InstantiateGeneric.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -28,5 +28,6 @@
 #include "GenPoly.h"                   // for isPolyType, typesPolyCompatible
 #include "InitTweak/InitTweak.h"
-#include "ResolvExpr/typeops.h"
+#include "ResolvExpr/AdjustExprType.hpp"  // for adjustExprType
+#include "ResolvExpr/Unify.h"          // for typesCompatible
 #include "ScopedSet.h"                 // for ScopedSet, ScopedSet<>::iterator
 #include "ScrubTyVars.h"               // for ScrubTyVars
Index: src/GenPoly/InstantiateGenericNew.cpp
===================================================================
--- src/GenPoly/InstantiateGenericNew.cpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/GenPoly/InstantiateGenericNew.cpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -32,5 +32,6 @@
 #include "GenPoly/GenPoly.h"           // for isPolyType, typesPolyCompatible
 #include "GenPoly/ScrubTyVars.h"       // for scrubAll
-#include "ResolvExpr/typeops.h"        // for typesCompatible
+#include "ResolvExpr/AdjustExprType.hpp"  // for adjustExprType
+#include "ResolvExpr/Unify.h"          // for typesCompatible
 
 namespace GenPoly {
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/InitTweak/FixInit.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -39,5 +39,5 @@
 #include "InitTweak.h"                 // for getFunctionName, getCallArg
 #include "ResolvExpr/Resolver.h"       // for findVoidExpression
-#include "ResolvExpr/typeops.h"        // for typesCompatible
+#include "ResolvExpr/Unify.h"          // for typesCompatible
 #include "SymTab/Autogen.h"            // for genImplicitCall
 #include "SymTab/Indexer.h"            // for Indexer
Index: src/InitTweak/FixInitNew.cpp
===================================================================
--- src/InitTweak/FixInitNew.cpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/InitTweak/FixInitNew.cpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -26,5 +26,5 @@
 #include "GenPoly/GenPoly.h"           // for getFunctionType
 #include "ResolvExpr/Resolver.h"       // for findVoidExpression
-#include "ResolvExpr/typeops.h"        // for typesCompatible
+#include "ResolvExpr/Unify.h"          // for typesCompatible
 #include "SymTab/Autogen.h"            // for genImplicitCall
 #include "SymTab/Indexer.h"            // for Indexer
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/InitTweak/InitTweak.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -35,5 +35,5 @@
 #include "GenPoly/GenPoly.h"       // for getFunctionType
 #include "InitTweak.h"
-#include "ResolvExpr/typeops.h"    // for typesCompatibleIgnoreQualifiers
+#include "ResolvExpr/Unify.h"      // for typesCompatibleIgnoreQualifiers
 #include "SymTab/Autogen.h"
 #include "SymTab/Indexer.h"        // for Indexer
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/Parser/TypeData.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -933,5 +933,5 @@
 			member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
 		} else if ( !cur->initializer ) {
-			if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) {
+			if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) {
 				SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
 			}
Index: src/ResolvExpr/AdjustExprType.hpp
===================================================================
--- src/ResolvExpr/AdjustExprType.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ src/ResolvExpr/AdjustExprType.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,56 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// AdjustExprType.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Wed Jan 18  9:56:00 2023
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Jan 18  9:56:00 2023
+// Update Count     : 0
+//
+
+#pragma once
+
+class Type;
+namespace SymTab {
+	class Indexer;
+}
+namespace ast {
+	class SymbolTable;
+	class Type;
+	class TypeEnvironment;
+}
+
+namespace ResolvExpr {
+
+class TypeEnvironment;
+
+/// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
+void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
+
+/// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer.
+void adjustExprType( Type *& type );
+
+template< typename ForwardIterator >
+void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {
+	while ( begin != end ) {
+		adjustExprType( *begin++, env, indexer );
+	} // while
+}
+
+/// Replaces array types with equivalent pointer,
+/// and function types with a pointer-to-function.
+const ast::Type * adjustExprType( const ast::Type * type,
+	const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -14,4 +14,6 @@
 //
 
+#include "AlternativeFinder.h"
+
 #include <algorithm>               // for copy
 #include <cassert>                 // for strict_dynamic_cast, assert, assertf
@@ -26,18 +28,22 @@
 
 #include "CompilationState.h"      // for resolvep
+#include "AdjustExprType.hpp"      // for adjustExprType
 #include "Alternative.h"           // for AltList, Alternative
-#include "AlternativeFinder.h"
 #include "AST/Expr.hpp"
 #include "AST/SymbolTable.hpp"
 #include "AST/Type.hpp"
+#include "CastCost.hpp"            // for castCost
 #include "Common/SemanticError.h"  // for SemanticError
 #include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
+#include "ConversionCost.h"        // for conversionCost
 #include "Cost.h"                  // for Cost, Cost::zero, operator<<, Cost...
 #include "ExplodedActual.h"        // for ExplodedActual
 #include "InitTweak/InitTweak.h"   // for getFunctionName
+#include "PolyCost.hpp"            // for polyCost
 #include "RenameVars.h"            // for RenameVars, global_renamer
 #include "ResolveAssertions.h"     // for resolveAssertions
 #include "ResolveTypeof.h"         // for resolveTypeof
 #include "Resolver.h"              // for resolveStmtExpr
+#include "SpecCost.hpp"            // for specCost
 #include "SymTab/Indexer.h"        // for Indexer
 #include "SymTab/Mangler.h"        // for Mangler
@@ -51,6 +57,6 @@
 #include "Tuples/Explode.h"        // for explode
 #include "Tuples/Tuples.h"         // for isTtype, handleTupleAssignment
+#include "typeops.h"               // for combos
 #include "Unify.h"                 // for unify
-#include "typeops.h"               // for adjustExprType, polyCost, castCost
 
 #define PRINT( text ) if ( resolvep ) { text }
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/AlternativeFinder.h	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -34,4 +34,9 @@
 namespace ResolvExpr {
 	struct ArgPack;
+
+	Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env );
+
+	void referenceToRvalueConversion( Expression *& expr, Cost & cost );
 
 	/// First index is which argument, second index is which alternative for that argument,
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -23,13 +23,18 @@
 #include <vector>
 
+#include "AdjustExprType.hpp"
 #include "Candidate.hpp"
+#include "CastCost.hpp"           // for castCost
 #include "CompilationState.h"
+#include "ConversionCost.h"       // for conversionCast
 #include "Cost.h"
 #include "ExplodedArg.hpp"
+#include "PolyCost.hpp"
 #include "RenameVars.h"           // for renameTyVars
 #include "Resolver.h"
 #include "ResolveTypeof.h"
 #include "SatisfyAssertions.hpp"
-#include "typeops.h"              // for adjustExprType, conversionCost, polyCost, specCost
+#include "SpecCost.hpp"
+#include "typeops.h"              // for combos
 #include "Unify.h"
 #include "AST/Expr.hpp"
Index: src/ResolvExpr/CandidateFinder.hpp
===================================================================
--- src/ResolvExpr/CandidateFinder.hpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/CandidateFinder.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -63,4 +63,9 @@
 	const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
 
+/// Create an expression that preforms reference to rvalue conversion on
+/// the given expression and update the cost of the expression.
+const ast::Expr * referenceToRvalueConversion(
+	const ast::Expr * expr, Cost & cost );
+
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/CastCost.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -13,4 +13,6 @@
 // Update Count     : 9
 //
+
+#include "CastCost.hpp"
 
 #include <cassert>                       // for assert
@@ -22,9 +24,12 @@
 #include "ConversionCost.h"              // for ConversionCost
 #include "Cost.h"                        // for Cost, Cost::infinity
+#include "ResolvExpr/ConversionCost.h"   // for conversionCost
+#include "ResolvExpr/PtrsCastable.hpp"   // for ptrsCastable
 #include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment, EqvClass
+#include "ResolvExpr/typeops.h"          // for ptrsCastable
+#include "ResolvExpr/Unify.h"            // for typesCompatibleIgnoreQualifiers
 #include "SymTab/Indexer.h"              // for Indexer
 #include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
 #include "SynTree/Type.h"                // for PointerType, Type, TypeInstType
-#include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
 
 #if 0
Index: src/ResolvExpr/CastCost.hpp
===================================================================
--- src/ResolvExpr/CastCost.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ src/ResolvExpr/CastCost.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,47 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// CastCost.hpp -- Cost of a cast.
+//
+// Author           : Andrew Beach
+// Created On       : Fri Dec  9 11:28:00 2022
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Dec  9 11:28:00 2022
+// Update Count     : 0
+//
+
+#pragma once
+
+#include "ResolvExpr/Cost.h"     // for Cost
+
+class Type;
+namespace SymTab {
+	class Indexer;
+}
+namespace ast {
+	class SymbolTable;
+	class Type;
+	class TypeEnvironment;
+}
+
+namespace ResolvExpr {
+
+class TypeEnvironment;
+
+Cost castCost(
+	const Type * src, const Type * dest, bool srcIsLvalue,
+	const SymTab::Indexer & indexer, const TypeEnvironment & env );
+Cost castCost(
+	const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
+	const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/CommonType.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -13,4 +13,6 @@
 // Update Count     : 24
 //
+
+#include "CommonType.hpp"
 
 #include <cassert>                       // for strict_dynamic_cast
Index: src/ResolvExpr/CommonType.hpp
===================================================================
--- src/ResolvExpr/CommonType.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ src/ResolvExpr/CommonType.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,47 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// CommonType.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Tue Jan 17 16:52:00 2023
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Jan 17 16:52:00 2023
+// Update Count     : 0
+//
+
+#pragma once
+
+#include "AST/Fwd.hpp"
+#include "AST/TypeEnvironment.hpp"  // for AssertionSet, OpenVarSet
+#include "TypeEnvironment.h"        // for AssertionSet, OpenVarSet
+#include "WidenMode.h"              // for WidenMode
+
+class Type;
+namespace SymTab {
+	class Indexer;
+}
+
+namespace ResolvExpr {
+
+Type * commonType(
+	Type * type1, Type * type2, bool widenFirst, bool widenSecond,
+	const SymTab::Indexer & indexer, TypeEnvironment & env,
+	const OpenVarSet & openVars );
+ast::ptr< ast::Type > commonType(
+	const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
+	ast::TypeEnvironment & env,
+	ast::AssertionSet & need, ast::AssertionSet & have,
+	const ast::OpenVarSet & open, WidenMode widen,
+	const ast::SymbolTable & symtab );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/ConversionCost.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -22,9 +22,9 @@
 #include "ResolvExpr/Cost.h"             // for Cost
 #include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
-#include "ResolvExpr/Unify.h"
+#include "ResolvExpr/Unify.h"            // for typesCompatibleIgnoreQualifiers
+#include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
 #include "SymTab/Indexer.h"              // for Indexer
 #include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
 #include "SynTree/Type.h"                // for Type, BasicType, TypeInstType
-#include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
 
 
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/ConversionCost.h	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -32,4 +32,8 @@
 namespace ResolvExpr {
 	class TypeEnvironment;
+
+	Cost conversionCost(
+		const Type * src, const Type * dest, bool srcIsLvalue,
+		const SymTab::Indexer & indexer, const TypeEnvironment & env );
 
 	typedef std::function<Cost(const Type *, const Type *, bool,
@@ -80,4 +84,12 @@
 	const ast::SymbolTable &, const ast::TypeEnvironment &)>;
 
+Cost conversionCost(
+	const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
+	const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
+
+Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,
+	bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env,
+	PtrsCalculation func );
+
 #warning when the old ConversionCost is removed, get ride of the _new suffix.
 class ConversionCost_new : public ast::WithShortCircuiting {
@@ -119,8 +131,4 @@
 };
 
-Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,
-	bool srcIsLvalue, const ast::SymbolTable & indexer, const ast::TypeEnvironment & env,
-	PtrsCalculation func );
-
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/PolyCost.hpp
===================================================================
--- src/ResolvExpr/PolyCost.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ src/ResolvExpr/PolyCost.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,43 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// PolyCost.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Tue Jan 17 16:45:00 2023
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Jan 17 16:45:00 2023
+// Update Count     : 0
+//
+
+#pragma once
+
+class Type;
+namespace SymTab {
+    class Indexer;
+}
+namespace ast {
+    class SymbolTable;
+    class Type;
+    class TypeEnvironment;
+}
+
+namespace ResolvExpr {
+
+class TypeEnvironment;
+
+int polyCost( Type * type,
+	const TypeEnvironment & env, const SymTab::Indexer & indexer );
+int polyCost( const ast::Type * type,
+	const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -14,5 +14,5 @@
 //
 
-#include "typeops.h"
+#include "PtrsAssignable.hpp"
 
 #include "AST/Pass.hpp"
Index: src/ResolvExpr/PtrsAssignable.hpp
===================================================================
--- src/ResolvExpr/PtrsAssignable.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ src/ResolvExpr/PtrsAssignable.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,39 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// PtrsAssignable.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Fri Dec  9 11:40:00 2022
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Dec  9 11:40:00 2022
+// Update Count     : 0
+//
+
+#pragma once
+
+class Type;
+namespace ast {
+	class Type;
+	class TypeEnvironment;
+}
+
+namespace ResolvExpr {
+
+class TypeEnvironment;
+
+int ptrsAssignable( const Type * src, const Type * dest,
+	const TypeEnvironment & env );
+int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
+	const ast::TypeEnvironment & env );
+
+} // namespace ResolvExpr
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/PtrsCastable.cc
===================================================================
--- src/ResolvExpr/PtrsCastable.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/PtrsCastable.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -14,4 +14,6 @@
 //
 
+#include "PtrsCastable.hpp"
+
 #include "AST/Decl.hpp"
 #include "AST/Pass.hpp"
@@ -19,4 +21,5 @@
 #include "AST/TypeEnvironment.hpp"
 #include "Common/PassVisitor.h"
+#include "ResolvExpr/PtrsAssignable.hpp" // for ptrsAssignable
 #include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
 #include "SymTab/Indexer.h"              // for Indexer
@@ -24,5 +27,4 @@
 #include "SynTree/Type.h"                // for TypeInstType, Type, BasicType
 #include "SynTree/Visitor.h"             // for Visitor
-#include "typeops.h"                     // for ptrsAssignable
 
 namespace ResolvExpr {
@@ -291,7 +293,5 @@
 		return objectCast( src, env, symtab );
 	} else {
-		ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab };
-		src->accept( ptrs );
-		return ptrs.core.result;
+		return ast::Pass<PtrsCastable_new>::read( src, dst, env, symtab );
 	}
 }
Index: src/ResolvExpr/PtrsCastable.hpp
===================================================================
--- src/ResolvExpr/PtrsCastable.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ src/ResolvExpr/PtrsCastable.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,45 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// PtrsCastable.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Mon Jan 16 17:04:00 2023
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Jan 16 17:04:00 2023
+// Update Count     : 0
+//
+
+#pragma once
+
+class Type;
+namespace SymTab {
+    class Indexer;
+}
+namespace ast {
+    class SymbolTable;
+    class Type;
+    class TypeEnvironment;
+}
+
+namespace ResolvExpr {
+
+class TypeEnvironment;
+
+int ptrsCastable(
+	const Type * src, const Type * dst,
+	const TypeEnvironment & env, const SymTab::Indexer & indexer );
+int ptrsCastable(
+	const ast::Type * src, const ast::Type * dst,
+	const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/RenameVars.cc
===================================================================
--- src/ResolvExpr/RenameVars.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/RenameVars.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -83,17 +83,14 @@
 
 		const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
-			// rename
 			auto it = idMap.find( type->name );
-			if ( it != idMap.end() ) {
-				// unconditionally mutate because map will *always* have different name
-				ast::TypeInstType * mut = ast::shallowCopy( type );
-				// reconcile base node since some copies might have been made
-				mut->base = it->second.base;
-				mut->formal_usage = it->second.formal_usage;
-				mut->expr_id = it->second.expr_id;
-	            type = mut;
-			}
-
-			return type;
+			if ( it == idMap.end() ) return type;
+
+			// Unconditionally mutate because map will *always* have different name.
+			ast::TypeInstType * mut = ast::shallowCopy( type );
+			// Reconcile base node since some copies might have been made.
+			mut->base = it->second.base;
+			mut->formal_usage = it->second.formal_usage;
+			mut->expr_id = it->second.expr_id;
+			return mut;
 		}
 
@@ -187,5 +184,4 @@
 
 const ast::Type * renameTyVars( const ast::Type * t, RenameMode mode, bool reset ) {
-	// ast::Type *tc = ast::deepCopy(t);
 	ast::Pass<RenameVars_new> renamer;
 	renamer.core.mode = mode;
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -26,4 +26,5 @@
 #include <vector>                   // for vector
 
+#include "AdjustExprType.hpp"       // for adjustExprType
 #include "Alternative.h"            // for Alternative, AssertionItem, AssertionList
 #include "Common/FilterCombos.h"    // for filterCombos
@@ -31,10 +32,11 @@
 #include "Common/utility.h"         // for sort_mins
 #include "GenPoly/GenPoly.h"        // for getFunctionType
+#include "ResolvExpr/AlternativeFinder.h"  // for computeConversionCost
 #include "ResolvExpr/RenameVars.h"  // for renameTyVars
+#include "SpecCost.hpp"             // for specCost
 #include "SymTab/Indexer.h"         // for Indexer
 #include "SymTab/Mangler.h"         // for Mangler
 #include "SynTree/Expression.h"     // for InferredParams
 #include "TypeEnvironment.h"        // for TypeEnvironment, etc.
-#include "typeops.h"                // for adjustExprType, specCost
 #include "Unify.h"                  // for unify
 
Index: src/ResolvExpr/SatisfyAssertions.cpp
===================================================================
--- src/ResolvExpr/SatisfyAssertions.cpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/SatisfyAssertions.cpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -23,8 +23,11 @@
 #include <vector>
 
+#include "AdjustExprType.hpp"
 #include "Candidate.hpp"
 #include "CandidateFinder.hpp"
+#include "CommonType.hpp"
 #include "Cost.h"
 #include "RenameVars.h"
+#include "SpecCost.hpp"
 #include "typeops.h"
 #include "Unify.h"
Index: src/ResolvExpr/SpecCost.hpp
===================================================================
--- src/ResolvExpr/SpecCost.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ src/ResolvExpr/SpecCost.hpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,34 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// SpecCost.hpp --
+//
+// Author           : Andrew Beach
+// Created On       : Tue Jan 17 16:49:00 2023
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Jan 17 16:49:00 2023
+// Update Count     : 0
+//
+
+#pragma once
+
+class Type;
+namespace ast {
+    class Type;
+}
+
+namespace ResolvExpr {
+
+int specCost( Type * type );
+int specCost( const ast::Type * type );
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/Unify.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -33,5 +33,7 @@
 #include "AST/TypeEnvironment.hpp"
 #include "Common/PassVisitor.h"     // for PassVisitor
+#include "CommonType.hpp"           // for commonType
 #include "FindOpenVars.h"           // for findOpenVars
+#include "SpecCost.hpp"             // for SpecCost
 #include "SynTree/LinkageSpec.h"    // for C
 #include "SynTree/Constant.h"       // for Constant
@@ -43,5 +45,5 @@
 #include "Tuples/Tuples.h"          // for isTtype
 #include "TypeEnvironment.h"        // for EqvClass, AssertionSet, OpenVarSet
-#include "typeops.h"                // for flatten, occurs, commonType
+#include "typeops.h"                // for flatten, occurs
 
 namespace ast {
@@ -50,5 +52,5 @@
 
 namespace SymTab {
-class Indexer;
+	class Indexer;
 }  // namespace SymTab
 
@@ -56,4 +58,28 @@
 
 namespace ResolvExpr {
+
+// Template Helpers:
+template< typename Iterator1, typename Iterator2 >
+bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
+	for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
+		Type *commonType = 0;
+		if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
+			return false;
+		} // if
+		commonTypes.push_back( commonType );
+	} // for
+	return ( list1Begin == list1End && list2Begin == list2End );
+}
+
+template< typename Iterator1, typename Iterator2 >
+bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
+	std::list< Type* > commonTypes;
+	if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions,  openVars, indexer, commonTypes ) ) {
+		deleteAll( commonTypes );
+		return true;
+	} else {
+		return false;
+	} // if
+}
 
 	struct Unify_old : public WithShortCircuiting {
Index: src/ResolvExpr/Unify.h
===================================================================
--- src/ResolvExpr/Unify.h	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/Unify.h	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 13:09:04 2015
-// Last Modified By : Aaron B. Moss
-// Last Modified On : Mon Jun 18 11:58:00 2018
-// Update Count     : 4
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Jan 17 11:12:00 2023
+// Update Count     : 5
 //
 
@@ -37,56 +37,61 @@
 
 namespace ResolvExpr {
-	bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
-	bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
-	bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
-	bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );
 
-	template< typename Iterator1, typename Iterator2 >
-	bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, std::list< Type* > &commonTypes ) {
-		for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
-			Type *commonType = 0;
-			if ( ! unify( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
-				return false;
-			} // if
-			commonTypes.push_back( commonType );
-		} // for
-		if ( list1Begin != list1End || list2Begin != list2End ) {
-			return false;
-		} else {
-			return true;
-		} // if
-	}
+bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
+bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
+bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
+bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );
 
-	template< typename Iterator1, typename Iterator2 >
-	bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
-		std::list< Type* > commonTypes;
-		if ( unifyList( list1Begin, list1End, list2Begin, list2End, env, needAssertions, haveAssertions, openVars, indexer, commonTypes ) ) {
-			deleteAll( commonTypes );
-			return true;
-		} else {
-			return false;
-		} // if
-	}
+bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
+bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
 
-	bool unify( 
-		const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-		ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
-		ast::OpenVarSet & open, const ast::SymbolTable & symtab );
+inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
+	TypeEnvironment env;
+	return typesCompatible( t1, t2, indexer, env );
+}
 
-	bool unify( 
-		const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-		ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
-		ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
+inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
+	TypeEnvironment env;
+	return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
+}
 
-	bool unifyExact( 
-		const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
-		ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
-		WidenMode widen, const ast::SymbolTable & symtab );
+bool unify(
+	const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+	ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
+	ast::OpenVarSet & open, const ast::SymbolTable & symtab );
 
-	bool unifyInexact( 
-		const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
-		ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
-		const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 
-		ast::ptr<ast::Type> & common );
+bool unify(
+	const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+	ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
+	ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
+
+bool unifyExact(
+	const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
+	ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
+	WidenMode widen, const ast::SymbolTable & symtab );
+
+bool unifyInexact(
+	const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
+	ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
+	const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
+	ast::ptr<ast::Type> & common );
+
+bool typesCompatible(
+	const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
+	const ast::TypeEnvironment & env = {} );
+
+bool typesCompatibleIgnoreQualifiers(
+	const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
+	const ast::TypeEnvironment & env = {} );
+
+/// Creates the type represented by the list of returnVals in a FunctionType.
+/// The caller owns the return value.
+Type * extractResultType( FunctionType * functionType );
+/// Creates or extracts the type represented by returns in a `FunctionType`.
+ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );
+
+std::vector<ast::ptr<ast::Type>> flattenList(
+	const std::vector<ast::ptr<ast::Type>> & src, ast::TypeEnvironment & env
+);
 
 } // namespace ResolvExpr
Index: src/ResolvExpr/WidenMode.h
===================================================================
--- src/ResolvExpr/WidenMode.h	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/WidenMode.h	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -19,5 +19,5 @@
 	struct WidenMode {
 		WidenMode( bool first, bool second ): first( first ), second( second ) {}
-		
+
 		WidenMode &operator|=( const WidenMode &other ) {
 			first |= other.first; second |= other.second; return *this;
@@ -35,5 +35,5 @@
 			WidenMode newWM( *this ); newWM &= other; return newWM;
 		}
-		
+
 		operator bool() { return first && second; }
 
Index: src/ResolvExpr/module.mk
===================================================================
--- src/ResolvExpr/module.mk	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/module.mk	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -17,4 +17,5 @@
 SRC_RESOLVEXPR = \
       ResolvExpr/AdjustExprType.cc \
+      ResolvExpr/AdjustExprType.hpp \
       ResolvExpr/Alternative.cc \
       ResolvExpr/AlternativeFinder.cc \
@@ -26,5 +27,7 @@
       ResolvExpr/Candidate.hpp \
       ResolvExpr/CastCost.cc \
+      ResolvExpr/CastCost.hpp \
       ResolvExpr/CommonType.cc \
+      ResolvExpr/CommonType.hpp \
       ResolvExpr/ConversionCost.cc \
       ResolvExpr/ConversionCost.h \
@@ -40,6 +43,9 @@
       ResolvExpr/Occurs.cc \
       ResolvExpr/PolyCost.cc \
+      ResolvExpr/PolyCost.hpp \
       ResolvExpr/PtrsAssignable.cc \
+      ResolvExpr/PtrsAssignable.hpp \
       ResolvExpr/PtrsCastable.cc \
+      ResolvExpr/PtrsCastable.hpp \
       ResolvExpr/RenameVars.cc \
       ResolvExpr/RenameVars.h \
@@ -54,4 +60,5 @@
       ResolvExpr/SatisfyAssertions.hpp \
       ResolvExpr/SpecCost.cc \
+      ResolvExpr/SpecCost.hpp \
       ResolvExpr/TypeEnvironment.cc \
       ResolvExpr/TypeEnvironment.h \
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/ResolvExpr/typeops.h	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 07:28:22 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Oct  1 09:45:00 2019
-// Update Count     : 6
+// Last Modified On : Wed Jan 18 11:54:00 2023
+// Update Count     : 7
 //
 
@@ -18,13 +18,5 @@
 #include <vector>
 
-#include "Cost.h"
-#include "TypeEnvironment.h"
-#include "WidenMode.h"
-#include "AST/Fwd.hpp"
-#include "AST/Node.hpp"
-#include "AST/SymbolTable.hpp"
 #include "AST/Type.hpp"
-#include "AST/TypeEnvironment.hpp"
-#include "SynTree/SynTree.h"
 #include "SynTree/Type.h"
 
@@ -34,4 +26,6 @@
 
 namespace ResolvExpr {
+	class TypeEnvironment;
+
 	// combos: takes a list of sets and returns a set of lists representing every possible way of forming a list by
 	// picking one element out of each set
@@ -61,99 +55,4 @@
 	}
 
-	// in AdjustExprType.cc
-	/// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
-	void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
-
-	/// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer
-	void adjustExprType( Type *& type );
-
-	template< typename ForwardIterator >
-	void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {
-		while ( begin != end ) {
-			adjustExprType( *begin++, env, indexer );
-		} // while
-	}
-
-	/// Replaces array types with equivalent pointer, and function types with a pointer-to-function
-	const ast::Type * adjustExprType(
-		const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
-
-	// in CastCost.cc
-	Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
-		const SymTab::Indexer & indexer, const TypeEnvironment & env );
-	Cost castCost(
-		const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
-		const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
-
-	// in ConversionCost.cc
-	Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
-		const SymTab::Indexer & indexer, const TypeEnvironment & env );
-	Cost conversionCost(
-		const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
-		const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
-
-	// in AlternativeFinder.cc
-	Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
-		const SymTab::Indexer & indexer, const TypeEnvironment & env );
-
-	// in PtrsAssignable.cc
-	int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );
-	int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
-		const ast::TypeEnvironment & env );
-
-	// in PtrsCastable.cc
-	int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer );
-	int ptrsCastable(
-		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
-		const ast::TypeEnvironment & env );
-
-	// in Unify.cc
-	bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
-	bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
-
-	inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
-		TypeEnvironment env;
-		return typesCompatible( t1, t2, indexer, env );
-	}
-
-	inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
-		TypeEnvironment env;
-		return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
-	}
-
-	bool typesCompatible(
-		const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
-		const ast::TypeEnvironment & env = {} );
-
-	bool typesCompatibleIgnoreQualifiers(
-		const ast::Type *, const ast::Type *, const ast::SymbolTable &,
-		const ast::TypeEnvironment & env = {} );
-
-	/// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
-	Type * extractResultType( FunctionType * functionType );
-	/// Creates or extracts the type represented by the list of returns in a `FunctionType`.
-	ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );
-
-	// in CommonType.cc
-	Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars );
-	ast::ptr< ast::Type > commonType(
-		const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
-			ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
-			const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab
-	);
-	// in Unify.cc
-	std::vector< ast::ptr< ast::Type > > flattenList(
-		const std::vector< ast::ptr< ast::Type > > & src, ast::TypeEnvironment & env
-	);
-
-	// in PolyCost.cc
-	int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
-	int polyCost(
-		const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
-
-	// in SpecCost.cc
-	int specCost( Type * type );
-	int specCost( const ast::Type * type );
-
 	// in Occurs.cc
 	bool occurs( const Type * type, const std::string & varName, const TypeEnvironment & env );
@@ -168,9 +67,4 @@
 		return false;
 	}
-
-	// in AlternativeFinder.cc
-	void referenceToRvalueConversion( Expression *& expr, Cost & cost );
-	// in CandidateFinder.cpp
-	const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost );
 
 	/// flatten tuple type into list of types
@@ -218,5 +112,4 @@
 		}
 
-
 		return new ast::TupleType{ std::move(types) };
 	}
@@ -227,6 +120,4 @@
 		return tupleFromTypes( tys.begin(), tys.end() );
 	}
-
-	
 
 	// in TypeEnvironment.cc
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/SymTab/Indexer.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -31,5 +31,6 @@
 #include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
 #include "Mangler.h"               // for Mangler
-#include "ResolvExpr/typeops.h"    // for typesCompatible
+#include "ResolvExpr/AlternativeFinder.h"  // for referenceToRvalueConversion
+#include "ResolvExpr/Unify.h"      // for typesCompatible
 #include "SynTree/LinkageSpec.h"   // for isMangled, isOverridable, Spec
 #include "SynTree/Constant.h"      // for Constant
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/SymTab/Mangler.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -439,5 +439,5 @@
 		  private:
 			void mangleDecl( const ast::DeclWithType *declaration );
-			void mangleRef( const ast::BaseInstType *refType, std::string prefix );
+			void mangleRef( const ast::BaseInstType *refType, const std::string & prefix );
 
 			void printQualifiers( const ast::Type *type );
@@ -535,12 +535,4 @@
 		}
 
-		__attribute__((unused))
-		inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
-			std::vector< ast::ptr< ast::Type > > ret;
-			std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
-							std::mem_fun( &ast::DeclWithType::get_type ) );
-			return ret;
-		}
-
 		void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
 			printQualifiers( functionType );
@@ -558,19 +550,18 @@
 		}
 
-		void Mangler_new::mangleRef( const ast::BaseInstType * refType, std::string prefix ) {
+		void Mangler_new::mangleRef(
+				const ast::BaseInstType * refType, const std::string & prefix ) {
 			printQualifiers( refType );
 
 			mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
 
-			if ( mangleGenericParams ) {
-				if ( ! refType->params.empty() ) {
-					mangleName += "_";
-					for ( const ast::Expr * param : refType->params ) {
-						auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
-						assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
-						maybeAccept( paramType->type.get(), *visitor );
-					}
-					mangleName += "_";
+			if ( mangleGenericParams && ! refType->params.empty() ) {
+				mangleName += "_";
+				for ( const ast::Expr * param : refType->params ) {
+					auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
+					assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
+					maybeAccept( paramType->type.get(), *visitor );
 				}
+				mangleName += "_";
 			}
 		}
@@ -656,4 +647,5 @@
 		}
 
+		// For debugging:
 		__attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
 			for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
@@ -665,36 +657,34 @@
 			// skip if not including qualifiers
 			if ( typeMode ) return;
-			if ( auto ptype = dynamic_cast< const ast::FunctionType * >(type) ) {
-				if ( ! ptype->forall.empty() ) {
-					std::list< std::string > assertionNames;
-					int dcount = 0, fcount = 0, vcount = 0, acount = 0;
-					mangleName += Encoding::forall;
-					for ( auto & decl : ptype->forall ) {
-						switch ( decl->kind ) {
-						  case ast::TypeDecl::Kind::Dtype:
-							dcount++;
-							break;
-						  case ast::TypeDecl::Kind::Ftype:
-							fcount++;
-							break;
-						  case ast::TypeDecl::Kind::Ttype:
-							vcount++;
-							break;
-						  default:
-							assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
-						} // switch
-						varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
-					} // for
-					for ( auto & assert : ptype->assertions ) {
-						assertionNames.push_back( ast::Pass<Mangler_new>::read(
-							assert->var.get(),
-							mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
-						acount++;
-					} // for
-					mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
-					for(const auto & a : assertionNames) mangleName += a;
-//					std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
-					mangleName += "_";
-				} // if
+			auto funcType = dynamic_cast<const ast::FunctionType *>( type );
+			if ( funcType && !funcType->forall.empty() ) {
+				std::list< std::string > assertionNames;
+				int dcount = 0, fcount = 0, vcount = 0, acount = 0;
+				mangleName += Encoding::forall;
+				for ( auto & decl : funcType->forall ) {
+					switch ( decl->kind ) {
+					case ast::TypeDecl::Dtype:
+						dcount++;
+						break;
+					case ast::TypeDecl::Ftype:
+						fcount++;
+						break;
+					case ast::TypeDecl::Ttype:
+						vcount++;
+						break;
+					default:
+						assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
+					} // switch
+					varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
+				} // for
+				for ( auto & assert : funcType->assertions ) {
+					assertionNames.push_back( ast::Pass<Mangler_new>::read(
+						assert->var.get(),
+						mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
+					acount++;
+				} // for
+				mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
+				for ( const auto & a : assertionNames ) mangleName += a;
+				mangleName += "_";
 			} // if
 			if ( ! inFunctionType ) {
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/SymTab/Validate.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -63,5 +63,6 @@
 #include "InitTweak/GenInit.h"         // for fixReturnStatements
 #include "InitTweak/InitTweak.h"       // for isCtorDtorAssign
-#include "ResolvExpr/typeops.h"        // for typesCompatible
+#include "ResolvExpr/typeops.h"        // for extractResultType
+#include "ResolvExpr/Unify.h"          // for typesCompatible
 #include "ResolvExpr/Resolver.h"       // for findSingleExpression
 #include "ResolvExpr/ResolveTypeof.h"  // for resolveTypeof
Index: src/SynTree/ApplicationExpr.cc
===================================================================
--- src/SynTree/ApplicationExpr.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/SynTree/ApplicationExpr.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// ApplicationExpr.cc.cc --
+// ApplicationExpr.cc --
 //
 // Author           : Richard C. Bilson
@@ -26,5 +26,5 @@
 #include "Expression.h"          // for ParamEntry, ApplicationExpr, Expression
 #include "InitTweak/InitTweak.h" // for getFunction
-#include "ResolvExpr/typeops.h"  // for extractResultType
+#include "ResolvExpr/Unify.h"    // for extractResultType
 #include "Type.h"                // for Type, PointerType, FunctionType
 
Index: src/SynTree/BasicType.cc
===================================================================
--- src/SynTree/BasicType.cc	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/SynTree/BasicType.cc	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -29,21 +29,4 @@
 }
 
-bool BasicType::isWholeNumber() const {
-	return kind == Bool || 
-		kind ==Char ||
-		kind == SignedChar ||
-		kind == UnsignedChar ||
-		kind == ShortSignedInt ||
-		kind == ShortUnsignedInt ||
-		kind == SignedInt ||
-		kind == UnsignedInt ||
-		kind == LongSignedInt ||
-		kind == LongUnsignedInt ||
-		kind == LongLongSignedInt ||
-		kind ==LongLongUnsignedInt ||
-		kind == SignedInt128 ||
-		kind == UnsignedInt128;
-}
-
 bool BasicType::isInteger() const {
 	return kind <= UnsignedInt128;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/SynTree/Type.h	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -271,5 +271,4 @@
 	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
-	bool isWholeNumber() const;
 	bool isInteger() const;
 };
Index: src/Validate/FixReturnTypes.cpp
===================================================================
--- src/Validate/FixReturnTypes.cpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/Validate/FixReturnTypes.cpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -20,5 +20,5 @@
 #include "AST/Type.hpp"
 #include "CodeGen/CodeGenerator.h"
-#include "ResolvExpr/typeops.h"
+#include "ResolvExpr/Unify.h"
 
 namespace ast {
Index: src/Validate/ReplaceTypedef.cpp
===================================================================
--- src/Validate/ReplaceTypedef.cpp	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ src/Validate/ReplaceTypedef.cpp	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -20,5 +20,5 @@
 #include "Common/UniqueName.h"
 #include "Common/utility.h"
-#include "ResolvExpr/typeops.h"
+#include "ResolvExpr/Unify.h"
 
 namespace Validate {
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ tests/Makefile.am	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -88,5 +88,6 @@
 	io/.in/many_read.data \
 	meta/fork+exec.hfa \
-	unified_locking/mutex_test.hfa
+	concurrent/unified_locking/mutex_test.hfa \
+    concurrent/channels/parallel_harness.hfa
 
 dist-hook:
Index: tests/concurrent/channels/.expect/big_elems.txt
===================================================================
--- tests/concurrent/channels/.expect/big_elems.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/channels/.expect/big_elems.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,5 @@
+start
+prods
+cons
+flush
+done
Index: tests/concurrent/channels/.expect/zero_size.txt
===================================================================
--- tests/concurrent/channels/.expect/zero_size.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/channels/.expect/zero_size.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,5 @@
+start
+prods
+cons
+flush
+done
Index: tests/concurrent/channels/big_elems.cfa
===================================================================
--- tests/concurrent/channels/big_elems.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/channels/big_elems.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#define BIG 1
+#include "parallel_harness.hfa"
+
+size_t Processors = 10, Channels = 10, Producers = 40, Consumers = 40, ChannelSize = 128;
+
+int main() {
+    test(Processors, Channels, Producers, Consumers, ChannelSize);
+}
Index: tests/concurrent/channels/parallel_harness.hfa
===================================================================
--- tests/concurrent/channels/parallel_harness.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/channels/parallel_harness.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,198 @@
+#include <locks.hfa>
+#include <fstream.hfa>
+#include <stdio.h>
+#include <channel.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+// user defines this
+// #define BIG 1
+
+owner_lock o;
+
+unsigned long long total_operations = 0;
+
+struct bigObject {
+    size_t a;
+    size_t b;
+    size_t c;
+    size_t d;
+    size_t e;
+    size_t f;
+    size_t g;
+    size_t h;
+};
+
+void ?{}( bigObject & this, size_t i ) with(this) { a = i; b = i; c = i; d = i; e = i; f = i; g = i; h = i; }
+void ?{}( bigObject & this ) { this{0}; }
+
+#ifdef BIG
+typedef channel( bigObject ) Channel;
+#else
+typedef channel( size_t ) Channel;
+#endif
+
+Channel * channels;
+
+volatile bool cons_done = false, prod_done = false;
+volatile int cons_done_count = 0;
+size_t cons_check = 0, prod_check = 0;
+
+thread Consumer {
+    size_t i;
+};
+static inline void ?{}( Consumer & c, size_t i, cluster & clu ) {
+    ((thread &)c){ clu };
+    c.i = i; 
+}
+void main(Consumer & this) {
+    unsigned long long runs = 0;
+    size_t my_check = 0;
+    for ( ;; ) {
+        if ( cons_done ) break;
+        #ifdef BIG
+        bigObject j = remove( channels[ this.i ] );
+        my_check = my_check ^ (j.a + j.b + j.c + j.d + j.d + j.e + j.f + j.g + j.h);
+        #else
+        size_t j = remove( channels[ this.i ] );
+        my_check = my_check ^ j;
+        #endif
+        
+        if ( !prod_done ) runs++;
+    }
+    lock(o);
+    total_operations += runs;
+    cons_done_count++;
+    cons_check = cons_check ^ my_check;
+    // sout | "C: " | runs;
+    unlock(o);
+}
+
+thread Producer {
+    size_t i;
+};
+static inline void ?{}( Producer & p, size_t i, cluster & clu ) {
+    ((thread &)p){ clu };
+    p.i = i;
+}
+void main(Producer & this) {
+    unsigned long long runs = 0;
+    size_t my_check = 0;
+    for ( ;; ) {
+        if ( prod_done ) break;
+        #ifdef BIG
+        bigObject j{(size_t)runs};
+        insert( channels[ this.i ], j );
+        my_check = my_check ^ (j.a + j.b + j.c + j.d + j.d + j.e + j.f + j.g + j.h);
+        #else
+        insert( channels[ this.i ], (size_t)runs );
+        my_check = my_check ^ ((size_t)runs);
+        #endif
+        runs++;
+    }
+    lock(o);
+    total_operations += runs;
+    prod_check = prod_check ^ my_check;
+    // sout | "P: " | runs;
+    unlock(o);
+}
+
+
+int test( size_t Processors, size_t Channels, size_t Producers, size_t Consumers, size_t ChannelSize ) {
+    size_t Clusters = 1;
+    // create a cluster
+    cluster clus[Clusters];
+    processor * proc[Processors];
+    for ( i; Processors ) {
+        (*(proc[i] = alloc())){clus[i % Clusters]};
+    }
+
+    channels = anew( Channels );
+
+    // sout | "Processors: " | Processors | " ProdsPerChan: " | Producers | " ConsPerChan: " | Consumers | "Channels: " | Channels | " Channel Size: " | ChannelSize;
+    
+    for ( i; Channels ) {
+        channels[i]{ ChannelSize };
+    }
+
+    sout | "start";
+    Consumer * c[Consumers * Channels];
+    Producer * p[Producers * Channels];
+
+    for ( i; Consumers * Channels ) {
+        (*(c[i] = alloc())){ i % Channels, clus[i % Clusters] };
+    }
+
+    for ( i; Producers * Channels ) {
+        (*(p[i] = alloc())){ i % Channels, clus[i % Clusters] };
+    }
+
+    sleep(10`s);
+    prod_done = true;
+
+    for ( i; Producers * Channels ) {
+        delete(p[i]);
+    }
+
+    sout | "prods";
+    cons_done = true;
+    while( cons_done_count != Consumers * Channels ) {
+        for ( i; Channels ) {
+            if ( has_waiting_consumers( channels[i] ) ){
+                #ifdef BIG
+                bigObject b{0};
+                insert( channels[i], b );
+                #else
+                insert( channels[i], 0 );
+                #endif
+            }
+        }
+        
+    }
+    // for ( i; Channels ) {
+    //     // sout | get_count( channels[i] );
+    //     if ( get_count( channels[i] ) < Consumers ){
+    //         #ifdef BIG
+    //         bigObject b{0};
+    //         #endif
+    //         for ( j; Consumers ) {
+    //             #ifdef BIG
+    //             insert( channels[i], b );
+    //             #else
+    //             insert( channels[i], 0 );
+    //             #endif
+    //         }
+    //     }
+    // }
+    sout | "cons";
+    for ( i; Consumers * Channels ) {
+        delete(c[i]);
+    }
+
+    sout | "flush";
+    for ( i; Channels ) {
+        for ( ;; ) {
+            if ( get_count( channels[i] ) > 0 ) {
+                #ifdef BIG
+                bigObject j = remove( channels[ i ] );
+                cons_check = cons_check ^ (j.a + j.b + j.c + j.d + j.d + j.e + j.f + j.g + j.h);
+                #else
+                size_t j = remove( channels[ i ] );
+                cons_check = cons_check ^ j;
+                #endif
+            } else break;
+        }
+    }
+
+    adelete( channels );
+    // sout | "total channel ops: " | total_operations;
+    if ( cons_check != prod_check )
+        sout | "CHECKSUM MISMATCH !!!";
+    // print_stats_now( *active_cluster(), CFA_STATS_READY_Q);
+
+    for ( i; Processors ) {
+        delete(proc[i]);
+    }
+    sout | "done";
+    return 0;
+}
Index: tests/concurrent/channels/zero_size.cfa
===================================================================
--- tests/concurrent/channels/zero_size.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/channels/zero_size.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,7 @@
+#include "parallel_harness.hfa"
+
+size_t Processors = 10, Channels = 1, Producers = 10, Consumers = 10, ChannelSize = 0;
+
+int main() {
+    test(Processors, Channels, Producers, Consumers, ChannelSize);
+}
Index: tests/concurrent/futures/.expect/select_future.txt
===================================================================
--- tests/concurrent/futures/.expect/select_future.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/futures/.expect/select_future.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,6 @@
+start 1: blocking path future test
+done 1
+start 2: nonblocking path future test
+done 2
+start 3: try_get future test
+done 3
Index: tests/concurrent/futures/select_future.cfa
===================================================================
--- tests/concurrent/futures/select_future.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/futures/select_future.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,200 @@
+#include <thread.hfa>
+#include <future.hfa>
+#include <concurrency/barrier.hfa>
+
+enum {NFUTURES = 10};
+
+thread Server {
+	int pending, done, iteration;
+	future(int) * request;
+};
+
+void ?{}( Server & this ) {
+	((thread&)this){"Server Thread"};
+	this.pending = 0;
+	this.done = 0;
+	this.iteration = 0;
+	this.request = 0p;
+}
+
+void ^?{}( Server & mutex this ) {
+	assert(this.pending == 0);
+	this.request = 0p;
+}
+
+void init( Server & this , future(int) * f ) {
+	this.request = f;
+}
+
+void call( Server & mutex this ) {
+	this.pending++;
+}
+
+void finish( Server & mutex this ) {
+	this.done++;
+}
+
+void main( Server & this ) {
+	MAIN_LOOP:
+	for() {
+		waitfor( ^?{} : this ) {
+			break;
+		}
+		or waitfor( call: this ) {
+			if (this.pending != NFUTURES) { continue MAIN_LOOP; }
+
+			this.pending = 0;
+			fulfil( *this.request, this.iteration );
+			this.iteration++;
+
+			for(NFUTURES) {
+				waitfor( finish: this );
+			}
+
+			reset( *this.request );
+			this.done = 0;
+		}
+	}
+
+}
+
+Server * the_server;
+thread Worker {};
+void ?{}(Worker & this) {
+	((thread&)this){"Worker Thread"};
+}
+
+future(int) * shared_future;
+
+void thrash(void) {
+	volatile int locals[250];
+	for(i; 250) {
+		locals[i] = 0xdeadbeef;
+	}
+}
+
+void work(int num) {
+	call( *the_server );
+	int res = get( *shared_future );
+	if( res != num ) abort();
+	finish( *the_server );
+}
+
+void main( Worker & ) {
+	for (i; 10) {
+		thrash();
+		work(i);
+		thrash();
+	}
+}
+
+thread Worker2 {};
+
+semaphore before{0};
+semaphore after_server{0};
+semaphore after_worker{0};
+
+void work2( int num ) {
+    P( before );
+	int res = get( *shared_future );
+	if( res != num ) abort();
+	V( after_server );
+    P( after_worker );
+}
+
+void main( Worker2 & ) {
+	for (i; 10) {
+		thrash();
+		work2(i);
+		thrash();
+	}
+}
+
+thread Server2 {};
+
+void main( Server2 & ) {
+	for (i; 10) {
+		fulfil( *shared_future , i );
+        V( before, NFUTURES );
+        for ( i; NFUTURES ) P( after_server );
+        reset( *shared_future );
+        V( after_worker, NFUTURES );
+	}
+}
+
+barrier bar = { NFUTURES + 1 };
+
+thread Worker3 {};
+
+void work3( int num ) {
+    [int, bool] tt;
+    do {
+        tt = try_get( *shared_future );
+    } while ( ! tt.1 );
+	if( tt.0 != num ) abort();
+	V( after_server );
+    block(bar);
+}
+
+void main( Worker3 & ) {
+	for (i; 10) {
+		thrash();
+		work3(i);
+		thrash();
+	}
+}
+
+thread Server3 {};
+
+void main( Server3 & ) {
+	for (i; 10) {
+		fulfil( *shared_future , i );
+        for ( i; NFUTURES ) P( after_server );
+        reset( *shared_future );
+        block(bar);
+	}
+}
+
+int main() {
+	printf( "start 1: blocking path future test\n" );
+	processor procs[11];
+	shared_future = new();
+	{
+		Server server;
+		the_server = &server;
+		init(server, shared_future);
+		{
+			Worker workers[NFUTURES];
+		}
+	}
+	delete( shared_future );
+	printf( "done 1\n" );
+
+    printf( "start 2: nonblocking path future test\n" );
+    shared_future = new();
+
+    {
+        Server2 server;
+		{
+			Worker2 workers[NFUTURES];
+		}
+	}
+
+    delete( shared_future );
+	printf( "done 2\n" );
+
+    printf( "start 3: try_get future test\n" );
+    shared_future = new();
+
+    {
+        Worker3 workers[NFUTURES];
+		{
+			Server3 server;
+		}
+	}
+
+    delete( shared_future );
+	printf( "done 3\n" );
+
+    // C_TODO: add test for select statement once it is implemented
+}
Index: tests/concurrent/futures/typed.cfa
===================================================================
--- tests/concurrent/futures/typed.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ tests/concurrent/futures/typed.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -5,5 +5,5 @@
 thread Server {
 	int cnt;
-	future(int) * requests[NFUTURES];
+	single_future(int) * requests[NFUTURES];
 };
 
@@ -24,5 +24,5 @@
 void process( Server & this, int i ) {
 	if( this.requests[i] == 0p ) return;
-	future(int) * f = this.requests[i];
+	single_future(int) * f = this.requests[i];
 	this.requests[i] = 0p;
 	this.cnt--;
@@ -30,5 +30,5 @@
 }
 
-void call( Server & mutex this, future(int) & f ) {
+void call( Server & mutex this, single_future(int) & f ) {
 	for(i; NFUTURES) {
 		if( this.requests[i] == 0p ) {
@@ -70,5 +70,5 @@
 
 void work(void) {
-	future(int) mine;
+	single_future(int) mine;
 	call( *the_server, mine );
 	wait( mine );
Index: tests/concurrent/mutexstmt/locks.cfa
===================================================================
--- tests/concurrent/mutexstmt/locks.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ tests/concurrent/mutexstmt/locks.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -72,5 +72,5 @@
 
 single_acquisition_lock l1;
-linear_backoff_then_block_lock l2;
+exp_backoff_then_block_lock l2;
 owner_lock l3;
 
Index: tests/concurrent/unified_locking/.expect/block_spin_lock.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/block_spin_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/block_spin_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/clh.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/clh.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/clh.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/exp_backoff.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/exp_backoff.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/exp_backoff.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/fast_block_lock.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/fast_block_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/fast_block_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/futex_mutex.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/futex_mutex.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/futex_mutex.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/locks.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/locks.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/locks.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,26 @@
+Start Test 1: multi acquisition lock and condition variable single wait/notify
+Done Test 1
+Start Test 2: multi acquisition lock and condition variable 3 wait/notify all
+Done Test 2
+Start Test 3: single acquisition lock and condition variable single wait/notify
+Done Test 3
+Start Test 4: single acquisition lock and condition variable 3 wait/notify all
+Done Test 4
+Start Test 5: owner lock and condition variable single wait/notify
+Done Test 5
+Start Test 6: owner lock and condition variable 3 wait/notify all
+Done Test 6
+Start Test 7: linear backoff lock and condition variable single wait/notify
+Done Test 7
+Start Test 8: linear backoff lock and condition variable 3 wait/notify all
+Done Test 8
+Start Test 9: multi acquisiton lock and condition variable multiple acquire and wait/notify
+Done Test 9
+Start Test 10: owner lock and condition variable multiple acquire and wait/notify
+Done Test 10
+Start Test 11: no lock condition variable wait/notify
+Done Test 11
+Start Test 12: locked condition variable wait/notify with front()
+Done Test 12
+Start Test 13: fast block lock and fast cond var single wait/notify
+Done Test 13
Index: tests/concurrent/unified_locking/.expect/mcs.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/mcs.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/mcs.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/mcs_block_spin_lock.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/mcs_block_spin_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/mcs_block_spin_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/mcs_spin.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/mcs_spin.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/mcs_spin.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/pthread_locks.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/pthread_locks.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/pthread_locks.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+Start Test 1: lock and condition variable single wait/notify
+Done Test 1
+Start Test 2: lock and condition variable 3 wait/notify all
+Done Test 2
+Start Test 3: lock and condition variable multiple acquire and wait/notify
+Done Test 3
+Start Test 4: lock and condition variable single timed wait/notify
+Done Test 4
Index: tests/concurrent/unified_locking/.expect/simple_owner_lock.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/simple_owner_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/simple_owner_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/spin_queue_lock.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/spin_queue_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/spin_queue_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/unified_locking/.expect/timeout_lock.txt
===================================================================
--- tests/concurrent/unified_locking/.expect/timeout_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/.expect/timeout_lock.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,4 @@
+Start Test 1: surface testing condition variable timeout routines
+Done Test 1
+Start Test 2: testing timeout vs signalling with varying timeout durations
+Done Test 2
Index: tests/concurrent/unified_locking/block_spin_lock.cfa
===================================================================
--- tests/concurrent/unified_locking/block_spin_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/block_spin_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#include <locks.hfa>
+
+#define LOCK block_spin_lock
+#include "mutex_test.hfa"
+
+int main() {
+    test();
+}
Index: tests/concurrent/unified_locking/clh.cfa
===================================================================
--- tests/concurrent/unified_locking/clh.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/clh.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#include <locks.hfa>
+
+#define LOCK clh_lock
+#include "mutex_test.hfa"
+
+int main() {
+    test();
+}
Index: tests/concurrent/unified_locking/exp_backoff.cfa
===================================================================
--- tests/concurrent/unified_locking/exp_backoff.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/exp_backoff.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#include <locks.hfa>
+
+#define LOCK exp_backoff_then_block_lock
+#include "mutex_test.hfa"
+
+int main() {
+    test();
+}
Index: tests/concurrent/unified_locking/fast_block_lock.cfa
===================================================================
--- tests/concurrent/unified_locking/fast_block_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/fast_block_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#include <locks.hfa>
+
+#define LOCK fast_block_lock
+#include "mutex_test.hfa"
+
+int main() {
+    test();
+}
Index: tests/concurrent/unified_locking/futex_mutex.cfa
===================================================================
--- tests/concurrent/unified_locking/futex_mutex.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/futex_mutex.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#include <locks.hfa>
+
+#define LOCK futex_mutex
+#include "mutex_test.hfa"
+
+int main() {
+    test();
+}
Index: tests/concurrent/unified_locking/locks.cfa
===================================================================
--- tests/concurrent/unified_locking/locks.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/locks.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,348 @@
+#include <stdio.h>
+#include "locks.hfa"
+#include <stdlib.hfa>
+#include <thread.hfa>
+
+const unsigned int num_times = 50000;
+
+multiple_acquisition_lock m;
+condition_variable( multiple_acquisition_lock ) c_m;
+
+single_acquisition_lock s;
+condition_variable( single_acquisition_lock ) c_s;
+
+owner_lock o;
+condition_variable( owner_lock ) c_o;
+
+exp_backoff_then_block_lock l;
+condition_variable( exp_backoff_then_block_lock ) c_l;
+
+fast_block_lock f;
+fast_cond_var( fast_block_lock ) f_c_f;
+
+thread T_C_M_WS1 {};
+
+void main( T_C_M_WS1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(m);
+		if(empty(c_m) && i != num_times - 1) {
+			wait(c_m,m);
+		}else{
+			notify_one(c_m);
+		}
+		unlock(m);
+	}
+}
+
+thread T_C_M_WB1 {};
+
+void main( T_C_M_WB1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(m);
+		if(counter(c_m) == 3 || i == num_times - 1) {
+			notify_all(c_m);
+		}else{
+			wait(c_m,m);
+		}
+		unlock(m);
+	}
+}
+
+thread T_C_S_WS1 {};
+
+void main( T_C_S_WS1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(s);
+		if(empty(c_s) && i != num_times - 1) {
+			wait(c_s,s);
+		}else{
+			notify_one(c_s);
+		}
+		unlock(s);
+	}
+}
+
+thread T_C_S_WB1 {};
+
+void main( T_C_S_WB1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(s);
+		if(counter(c_s) == 3 || i == num_times - 1) {
+			notify_all(c_s);
+		}else{
+			wait(c_s,s);
+		}
+		unlock(s);
+	}
+}
+
+thread T_C_L_WS1 {};
+
+void main( T_C_L_WS1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(l);
+		if(empty(c_l) && i != num_times - 1) {
+			wait(c_l,l);
+		}else{
+			notify_one(c_l);
+		}
+		unlock(l);
+	}
+}
+
+thread T_C_L_WB1 {};
+
+void main( T_C_L_WB1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(l);
+		if(counter(c_l) == 3 || i == num_times - 1) {
+			notify_all(c_l);
+		}else{
+			wait(c_l,l);
+		}
+		unlock(l);
+	}
+}
+
+thread T_F_C_F_WS1 {};
+
+void main( T_F_C_F_WS1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(f);
+		if(empty(f_c_f) && i != num_times - 1) {
+			wait(f_c_f,f);
+		}else{
+			notify_one(f_c_f);
+		}
+		unlock(f);
+	}
+}
+
+thread T_C_O_WS1 {};
+
+void main( T_C_O_WS1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(o);
+		if(empty(c_o) && i != num_times - 1) {
+			wait(c_o,o);
+		}else{
+			notify_one(c_o);
+		}
+		unlock(o);
+	}
+}
+
+thread T_C_O_WB1 {};
+
+void main( T_C_O_WB1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(o);
+		if(counter(c_o) == 3 || i == num_times - 1) {
+			notify_all(c_o);
+		}else{
+			wait(c_o,o);
+		}
+		unlock(o);
+	}
+}
+
+thread T_C_M_WS2 {};
+
+void main( T_C_M_WS2 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(m);
+		lock(m);
+		lock(m);
+		if(empty(c_m) && i != num_times - 1) {
+			wait(c_m,m);
+		}else{
+			notify_one(c_m);
+		}
+		unlock(m);
+		unlock(m);
+		unlock(m);
+	}
+}
+
+thread T_C_O_WS2 {};
+
+void main( T_C_O_WS2 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(o);
+		lock(o);
+		lock(o);
+		if(empty(c_o) && i != num_times - 1) {
+			wait(c_o,o);
+		}else{
+			notify_one(c_o);
+		}
+		unlock(o);
+		unlock(o);
+		unlock(o);
+	}
+}
+
+thread T_C_NLW {};
+
+void main( T_C_NLW & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		wait(c_o);
+	}
+}
+
+thread T_C_NLS {};
+
+void main( T_C_NLS & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		while (empty(c_o)) { }
+		notify_one(c_o);
+	}
+}
+
+thread T_C_S_WNF {};
+
+void main( T_C_S_WNF & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(s);
+		if(empty(c_s) && i != num_times - 1) {
+			wait(c_s, s, 10);
+		}else{
+			if(!empty(c_s)) assert(front(c_s) == 10);
+			notify_one(c_s);
+		}
+		unlock(s);
+	}
+}
+
+bool done = false;
+
+thread T_C_NLWD {};
+
+void main( T_C_NLWD & this ) {
+	done = false;
+	for (unsigned int i = 0; i < num_times/5; i++) {
+		if (i % 1000 == 0) printf("Iteration: %d\n", i);
+		wait(c_s, 1`ns);
+	}
+	done = true;
+}
+
+thread T_C_WDS {};
+
+void main( T_C_WDS & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		while (empty(c_s) && !done) { }
+		notify_one(c_s);
+		sleep(1`ns);
+		if(done) break;
+	}
+}
+
+thread T_C_LWD {};
+
+void main( T_C_LWD & this ) {
+	done = false;
+	for (unsigned int i = 0; i < num_times/5; i++) {
+		if (i % 1000 == 0) printf("Iteration: %d\n", i);
+		lock(s);
+		wait(c_s, s, 1`ns);
+		unlock(s);
+	}
+	done = true;
+}
+
+thread T_C_LWDS {};
+
+void main( T_C_LWDS & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		while (empty(c_s) && !done) { }
+		lock(s);
+		notify_one(c_s);
+		unlock(s);
+		sleep(1`ns);
+		if(done) break;
+	}
+}
+
+int main() {
+	processor p[2];
+	printf("Start Test 1: multi acquisition lock and condition variable single wait/notify\n");
+	{
+		T_C_M_WS1 t1[2];
+	}
+	printf("Done Test 1\n");
+
+	printf("Start Test 2: multi acquisition lock and condition variable 3 wait/notify all\n");
+	{
+		T_C_M_WB1 t1[4];
+	}
+	printf("Done Test 2\n");
+
+	printf("Start Test 3: single acquisition lock and condition variable single wait/notify\n");
+	{
+		T_C_S_WS1 t1[2];
+	}
+	printf("Done Test 3\n");
+
+	printf("Start Test 4: single acquisition lock and condition variable 3 wait/notify all\n");
+	{
+		T_C_S_WB1 t1[4];
+	}
+	printf("Done Test 4\n");
+
+	printf("Start Test 5: owner lock and condition variable single wait/notify\n");
+	{
+		T_C_O_WS1 t1[2];
+	}
+	printf("Done Test 5\n");
+
+	printf("Start Test 6: owner lock and condition variable 3 wait/notify all\n");
+	{
+		T_C_O_WB1 t1[4];
+	}
+	printf("Done Test 6\n");
+
+	printf("Start Test 7: linear backoff lock and condition variable single wait/notify\n");
+	{
+		T_C_L_WS1 t1[2];
+	}
+	printf("Done Test 7\n");
+
+	printf("Start Test 8: linear backoff lock and condition variable 3 wait/notify all\n");
+	{
+		T_C_L_WB1 t1[4];
+	}
+	printf("Done Test 8\n");
+
+	printf("Start Test 9: multi acquisiton lock and condition variable multiple acquire and wait/notify\n");
+	{
+		T_C_M_WS2 t1[2];
+	}
+	printf("Done Test 9\n");
+
+	printf("Start Test 10: owner lock and condition variable multiple acquire and wait/notify\n");
+	{
+		T_C_O_WS2 t1[2];
+	}
+	printf("Done Test 10\n");
+
+	printf("Start Test 11: no lock condition variable wait/notify\n");
+	{
+		T_C_NLW t1;
+		T_C_NLS t2;
+	}
+	printf("Done Test 11\n");
+
+	printf("Start Test 12: locked condition variable wait/notify with front()\n");
+	{
+		T_C_S_WNF t1[2];
+	}
+	printf("Done Test 12\n");
+
+	printf("Start Test 13: fast block lock and fast cond var single wait/notify\n");
+	{
+		T_F_C_F_WS1 t1[2];
+	}
+	printf("Done Test 13\n");
+	
+}
Index: tests/concurrent/unified_locking/mcs.cfa
===================================================================
--- tests/concurrent/unified_locking/mcs.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/mcs.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,66 @@
+#include <fstream.hfa>
+#include <locks.hfa>
+#include <thread.hfa>
+
+const unsigned int num_times = 50000;
+
+struct MutexObj {
+	mcs_lock l;
+	thread$ * id;
+	size_t sum;
+};
+
+MutexObj mo;
+
+void trash() {
+	unsigned t[100];
+	for(i; 100) {
+		t[i] = 0xDEADBEEF;
+	}
+}
+
+unsigned cs() {
+	thread$ * me = active_thread();
+	unsigned value = (unsigned)me;
+	mcs_node n;
+	lock(mo.l, n);
+	{
+		size_t tsum = mo.sum;
+		mo.id = me;
+		yield(random(5));
+		if(mo.id != me) sout | "Intruder!";
+		mo.sum = tsum + value;
+	}
+	unlock(mo.l, n);
+	return value;
+}
+
+thread LockCheck {
+	size_t sum;
+};
+
+void main(LockCheck & this) {
+	this.sum = 0;
+	for(num_times) {
+		trash();
+		this.sum += cs();
+		trash();
+		yield(random(10));
+	}
+}
+
+int main() {
+	size_t sum = -32;
+	mo.sum = -32;
+	processor p[2];
+	sout | "Starting";
+	{
+		LockCheck checkers[13];
+		for(i;13) {
+			sum += join(checkers[i]).sum;
+		}
+	}
+	sout | "Done!";
+	if(sum == mo.sum) sout | "Match!";
+	else sout | "No Match!" | sum | "vs" | mo.sum;
+}
Index: tests/concurrent/unified_locking/mcs_block_spin_lock.cfa
===================================================================
--- tests/concurrent/unified_locking/mcs_block_spin_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/mcs_block_spin_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#include <locks.hfa>
+
+#define LOCK mcs_block_spin_lock
+#include "mutex_test.hfa"
+
+int main() {
+    test();
+}
Index: tests/concurrent/unified_locking/mcs_spin.cfa
===================================================================
--- tests/concurrent/unified_locking/mcs_spin.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/mcs_spin.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,78 @@
+
+#include <fstream.hfa>
+#include <locks.hfa>
+#include <thread.hfa>
+
+const unsigned int num_times = 50;
+
+struct MutexObj {
+	mcs_spin_lock l;
+	thread$ * id;
+	uint32_t sum;
+	uint32_t cnt;
+};
+
+MutexObj mo;
+
+void trash() {
+	unsigned t[100];
+	for(i; 100) {
+		t[i] = 0xDEADBEEF;
+	}
+}
+
+uint32_t cs() {
+	thread$ * me = active_thread();
+	uint32_t value;
+    mcs_spin_node node;
+	lock(mo.l, node);
+	{
+		uint32_t tsum = mo.sum;
+		uint32_t cnt = mo.cnt;
+		mo.id = me;
+		yield(random(5));
+		value = ((uint32_t)random()) ^ ((uint32_t)me);
+		if(mo.id != me) sout | "Intruder!";
+		mo.cnt = cnt + 1;
+		mo.sum = tsum + value;
+	}
+	unlock(mo.l, node);
+	return value;
+}
+
+thread LockCheck {
+	uint32_t sum;
+};
+
+void main(LockCheck & this) {
+	this.sum = 0;
+	for(num_times) {
+		trash();
+		this.sum += cs();
+		trash();
+		yield(random(10));
+	}
+}
+
+void test() {
+	uint32_t sum = -32;
+	mo.sum = -32;
+	mo.cnt = 0;
+	processor p[2];
+	sout | "Starting";
+	{
+		LockCheck checkers[13];
+		for(i;13) {
+			sum += join(checkers[i]).sum;
+		}
+	}
+	sout | "Done!";
+	if(mo.cnt != (13 * num_times)) sout | "Invalid cs count!" | mo.cnt | "vs "| (13 * num_times) | "(13 *" | num_times | ')';
+	if(sum == mo.sum) sout | "Match!";
+	else sout | "No Match!" | sum | "vs" | mo.sum;
+}
+
+int main() {
+    test();
+	return 0;
+}
Index: tests/concurrent/unified_locking/mutex_test.hfa
===================================================================
--- tests/concurrent/unified_locking/mutex_test.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/mutex_test.hfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,79 @@
+
+#include <fstream.hfa>
+#include <locks.hfa>
+#include <thread.hfa>
+
+const unsigned int num_times = 50;
+
+struct MutexObj {
+	LOCK l;
+	thread$ * id;
+	uint32_t sum;
+	uint32_t cnt;
+};
+
+MutexObj mo;
+
+void trash() {
+	unsigned t[100];
+	for(i; 100) {
+		t[i] = 0xDEADBEEF;
+	}
+}
+
+uint32_t cs(uint32_t & entries) {
+	thread$ * me = active_thread();
+	uint32_t value;
+	lock(mo.l);
+	{
+		entries++;
+		uint32_t tsum = mo.sum;
+		uint32_t cnt = mo.cnt;
+		mo.id = me;
+		yield(random(5));
+		value = ((uint32_t)random()) ^ ((uint32_t)me);
+		if(mo.id != me) sout | "Intruder!";
+		mo.cnt = cnt + 1;
+		mo.sum = tsum + value;
+	}
+	unlock(mo.l);
+	return value;
+}
+
+thread LockCheck {
+	uint32_t sum;
+	uint32_t entries;
+};
+
+void main(LockCheck & this) {
+	this.sum = 0;
+	this.entries = 0;
+	for(num_times) {
+		trash();
+		this.sum += cs( this.entries );
+		trash();
+		yield(random(10));
+	}
+}
+
+void test() {
+	uint32_t sum = -32;
+	mo.sum = -32;
+	mo.cnt = 0;
+	uint32_t real_entries = 0;
+	processor p[2];
+	sout | "Starting";
+	{
+		LockCheck checkers[13];
+		for(i;13) {
+			LockCheck & curr = join(checkers[i]);
+			sum += curr.sum;
+			real_entries += curr.entries;
+		}
+	}
+	sout | "Done!";
+	if(real_entries != (13 * num_times)) sout | "Invalid real cs count!" | mo.cnt | "vs "| (13 * num_times) | "(13 *" | num_times | ')';
+	if(mo.cnt != (13 * num_times)) sout | "Invalid concurrent cs count!" | mo.cnt | "vs "| (13 * num_times) | "(13 *" | num_times | ')';
+	if(sum == mo.sum) sout | "Match!";
+	else sout | "No Match!" | sum | "vs" | mo.sum;
+}
Index: tests/concurrent/unified_locking/pthread_locks.cfa
===================================================================
--- tests/concurrent/unified_locking/pthread_locks.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/pthread_locks.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,108 @@
+#include <stdio.h>
+#include "locks.hfa"
+#include <stdlib.hfa>
+#include <thread.hfa>
+#include <time.h>
+#include <stdlib.hfa>
+
+const unsigned int num_times = 50;
+
+simple_owner_lock l;
+pthread_cond_var( simple_owner_lock ) c;
+
+owner_lock l2;
+condition_variable( owner_lock ) c2;
+
+volatile int counter = 0;
+
+thread Wait_Signal_1 {};
+
+void main( Wait_Signal_1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(l);
+		if(empty(c) && i != num_times - 1) {
+			wait(c,l);
+		}else{
+			notify_one(c);
+		}
+		unlock(l);
+	}
+}
+
+thread Wait_3_Signal_3 {};
+
+void main( Wait_3_Signal_3 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(l);
+        counter++;
+		if(counter == 4 || i == num_times - 1) {
+            counter = 0;
+			notify_all(c);
+		}else{
+			wait(c,l);
+		}
+		unlock(l);
+	}
+}
+
+thread Rec_Lock_Wait_Signal_1 {};
+
+void main( Rec_Lock_Wait_Signal_1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(l);
+		lock(l);
+		lock(l);
+		if(empty(c) && i != num_times - 1) {
+			wait(c,l);
+		}else{
+			notify_one(c);
+		}
+		unlock(l);
+		unlock(l);
+		unlock(l);
+	}
+}
+
+thread Wait_Time_Signal_1 {};
+
+void main( Wait_Time_Signal_1 & this ) {
+	for (unsigned int i = 0; i < num_times; i++) {
+		lock(l);
+		if(empty(c) || random(10) >= 9 ) {
+			timespec t;
+			clock_gettime(CLOCK_REALTIME, &t);
+			timespec waitTime{0,1};
+			bool woken = wait(c,l, t + waitTime);
+		}else{
+			notify_one(c);
+		}
+		unlock(l);
+	}
+}
+
+int main() {
+	processor p[1];
+	printf("Start Test 1: lock and condition variable single wait/notify\n");
+	{
+		Wait_Signal_1 t1[2];
+	}
+	printf("Done Test 1\n");
+
+	printf("Start Test 2: lock and condition variable 3 wait/notify all\n");
+	{
+		Wait_3_Signal_3 t1[4];
+	}
+	printf("Done Test 2\n");
+
+	printf("Start Test 3: lock and condition variable multiple acquire and wait/notify\n");
+	{
+		Rec_Lock_Wait_Signal_1 t1[2];
+	}
+	printf("Done Test 3\n");
+
+	printf("Start Test 4: lock and condition variable single timed wait/notify\n");
+	{
+		Wait_Time_Signal_1 t1[2];
+	}
+	printf("Done Test 4\n");
+}
Index: tests/concurrent/unified_locking/simple_owner_lock.cfa
===================================================================
--- tests/concurrent/unified_locking/simple_owner_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/simple_owner_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#include <locks.hfa>
+
+#define LOCK simple_owner_lock
+#include "mutex_test.hfa"
+
+int main() {
+    test();
+}
Index: tests/concurrent/unified_locking/spin_queue_lock.cfa
===================================================================
--- tests/concurrent/unified_locking/spin_queue_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/spin_queue_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,8 @@
+#include <locks.hfa>
+
+#define LOCK spin_queue_lock
+#include "mutex_test.hfa"
+
+int main() {
+    test();
+}
Index: tests/concurrent/unified_locking/test_debug.cfa
===================================================================
--- tests/concurrent/unified_locking/test_debug.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/test_debug.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,31 @@
+#include "locks.hfa"
+
+fast_block_lock f;
+fast_block_lock f2;
+fast_cond_var( fast_block_lock ) f_c_f;
+
+thread T1 {};
+bool wait = true;
+bool wait2 = true;
+void main( T1 & this ) {
+    lock(f);
+    if (wait) {
+        wait = false;
+        wait(f_c_f, f);
+    } else {
+        notify_one(f_c_f);
+        unlock(f);
+    }
+    lock(f2);
+    if (wait2) {
+        wait2 = false;
+        wait(f_c_f, f2);
+    } else {
+        notify_one(f_c_f);
+        unlock(f2);
+    }
+}
+
+int main() {
+    T1 t[2];
+}
Index: tests/concurrent/unified_locking/thread_test.cfa
===================================================================
--- tests/concurrent/unified_locking/thread_test.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/thread_test.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,108 @@
+#include <stdio.h>
+#include "locks.hfa"
+#include <stdlib.hfa>
+#include <thread.hfa>
+#include <containers/array.hfa>
+
+static unsigned int taskCount = 4;
+static unsigned int threadCount = 2;
+static unsigned int lockCount = 1;
+static unsigned int total_times = 320000;
+static unsigned int num_times;
+static const int workBufferSize = 16;
+static unsigned int work_unlocked = 10000;
+static unsigned int work_locked = 10000;
+
+// taken from martin's thread_test
+static inline void dowork(volatile int* buffer, unsigned int steps) {
+  int value = 0;
+  for (unsigned int i = 0; i < steps; i += 1) {
+    // a little more work than just a single memory access helps with stability
+    value += (buffer[i % workBufferSize] * 17) / 23 + 55;
+  }
+  buffer[0] += value;
+}
+
+thread worker {
+    exp_backoff_then_block_lock * locks;
+    bool improved;
+};
+
+void ?{}( worker & w, exp_backoff_then_block_lock * locks, bool improved ) {
+	w.locks = locks;
+    w.improved = improved;
+}
+
+
+void main( worker & this ) with(this) {
+	int buffer[workBufferSize];
+    for (int i = 0; i < workBufferSize; i += 1) buffer[i] = rand() % 1024;
+    unsigned int lck = rand() % lockCount;
+    exp_backoff_then_block_lock * curr_lock = &locks[lck];
+    for (unsigned int i = 0; i < num_times; i++) {
+        dowork(buffer, work_unlocked);
+        if (improved) lock_improved(*curr_lock);
+        else lock(*curr_lock);
+        dowork(buffer, work_locked);
+        unlock(*curr_lock);
+        lck = rand() % lockCount;
+        curr_lock = &locks[lck];
+    }
+}
+
+int doOne = 0;
+int main(int argc, char* argv[]) {
+    switch (argc) {
+        case 8:
+            doOne = atoi(argv[7]);
+        case 7:
+            work_unlocked = atoi(argv[6]);
+        case 6:
+            work_locked = atoi(argv[5]);
+        case 5:
+            total_times = atoi(argv[4]);
+        case 4:
+            lockCount = atoi(argv[3]);
+        case 3:
+            threadCount = atoi(argv[2]);
+        case 2:
+            taskCount = atoi(argv[1]);
+        case 1:
+            break;
+        default:
+            break;
+    }
+	processor p[threadCount];
+    exp_backoff_then_block_lock locks[lockCount];
+    worker * worker_arr[taskCount];
+    num_times = total_times  / taskCount;
+    //printf("%d\n", doOne);
+	//
+	//clock_t begin = clock();
+    if (doOne == 1) {
+        printf("Start Test: martin lock simple %d\n", num_times);
+	for (unsigned int i = 0; i < taskCount; i++) {
+        worker_arr[i] = new( locks, false );
+    }
+    for (unsigned int i = 0; i < taskCount; i++) {
+        delete( worker_arr[i] );
+    }
+    }
+	//clock_t end = clock();
+	//double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
+	//printf("norm: %f\n", time_spent);
+
+    //printf("Start Test: martin lock improved\n");
+	//begin = clock();
+    if (doOne == 2) {
+	for (unsigned int i = 0; i < taskCount; i++) {
+        worker_arr[i] = new( locks, true );
+    }
+    for (unsigned int i = 0; i < taskCount; i++) {
+        delete( worker_arr[i] );
+    }
+    }
+	//end = clock();
+	//time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
+	//printf("improved: %f\n", time_spent);
+}
Index: tests/concurrent/unified_locking/timeout_lock.cfa
===================================================================
--- tests/concurrent/unified_locking/timeout_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
+++ tests/concurrent/unified_locking/timeout_lock.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -0,0 +1,87 @@
+#include <stdio.h>
+#include <locks.hfa>
+#include <alarm.hfa>
+#include <stdlib.hfa>
+#include <thread.hfa>
+#include <kernel.hfa>
+
+multiple_acquisition_lock m, n;
+condition_variable( multiple_acquisition_lock ) c_m, c_n;
+
+const unsigned int NoOfTimes = 20;
+
+void block() { // used for barrier like behaviour
+	lock(n);
+	if (empty( c_n )) {
+		wait( c_n, n );
+	} else {
+		notify_one( c_n );
+	}
+	unlock(n);
+}
+
+thread T1 {};
+
+void main( T1 & this ) {
+	lock(m);
+	wait( c_m, m, 1`s );
+	// printf("Thread: %p timedout\n", active_thread()); // removed since can't expect non deterministic output
+
+	block();
+
+	// Test calls which occur increasingly close to timeout value.
+
+	for ( unsigned int i = 0; i < NoOfTimes + 3; i += 1 ) {
+	    if ( wait( c_m, m, 1000000`ns ) ) {
+			// printf("Thread: %p signalled\n", active_thread()); // removed since can't expect non deterministic output
+	    } else {
+			// printf("Thread: %p timedout\n", active_thread()); // removed since can't expect non deterministic output
+	    } // if
+
+	    block();
+	} // for
+}
+
+
+thread T2 {};
+
+void main( T2 & this ) {
+	block();
+
+	// Test calls which occur increasingly close to timeout value.
+
+	sleep( 100000`ns );
+	notify_one(c_m);
+	block();
+
+	sleep( 500000`ns );
+	notify_one(c_m);
+	block();
+
+	sleep( 900000`ns );
+	notify_one(c_m);
+	block();
+
+	for ( unsigned int i = 0; i < NoOfTimes; i += 1 ) {
+	    sleep( 999700`ns );
+		notify_one(c_m);
+	    block();
+	} // for
+}
+
+int main() {
+	processor p[2];
+	printf("Start Test 1: surface testing condition variable timeout routines\n");
+	wait( c_m, 1`ns );														// bool wait( condition_variable(L) & this, Duration duration );
+	wait( c_m, 10, 1`ns );													// bool wait( condition_variable(L) & this, uintptr_t info, Duration duration );
+	lock(m); wait( c_m, m, 1`ns ); unlock(m); 								// bool wait( condition_variable(L) & this, L & l, Duration duration );
+	lock(m); wait( c_m, m, 10, 1`ns ); unlock(m);							// bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
+	printf("Done Test 1\n");
+
+	printf("Start Test 2: testing timeout vs signalling with varying timeout durations\n");
+	{
+		T1 t1;
+		T2 t2;
+	}
+	printf("Done Test 2\n");
+}
Index: sts/enum_tests/.expect/pointerEnum.cfa
===================================================================
--- tests/enum_tests/.expect/pointerEnum.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,1 +1,0 @@
-v: 1
Index: sts/enum_tests/.expect/qualifiedEnum.cfa
===================================================================
--- tests/enum_tests/.expect/qualifiedEnum.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,1 +1,0 @@
-l :1
Index: tests/enum_tests/.expect/typedIntEnum.txt
===================================================================
--- tests/enum_tests/.expect/typedIntEnum.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ tests/enum_tests/.expect/typedIntEnum.txt	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -1,7 +1,7 @@
-0
-1
-1000
-1001
-2000
-2001
-2002
+0=0
+1=1
+1000=1000
+1001=1001
+2000=2000
+2001=2001
+2002=2002
Index: tests/enum_tests/pointerEnum.cfa
===================================================================
--- tests/enum_tests/pointerEnum.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ tests/enum_tests/pointerEnum.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -11,4 +11,4 @@
 int main() {
     E * v = First;
-    sout | "v: " | e.x;
+    // sout | "v: " | e.x;
 }
Index: tests/enum_tests/typedIntEnum.cfa
===================================================================
--- tests/enum_tests/typedIntEnum.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ tests/enum_tests/typedIntEnum.cfa	(revision ad861ef542966cb370b0bd630dcdc2e48cd4ecb8)
@@ -12,11 +12,11 @@
 
 int main() {
-    printf("%d\n", zero);
-    printf("%d\n", one);
-    printf("%d\n", thousand);
-    printf("%d\n", thousand_one);
-    printf("%d\n", two_thousand);
-    printf("%d\n", two_thousand_one);
-    printf("%d\n", two_thousand_two);
+    printf("0=%d\n", zero);
+    printf("1=%d\n", one);
+    printf("1000=%d\n", thousand);
+    printf("1001=%d\n", thousand_one);
+    printf("2000=%d\n", two_thousand);
+    printf("2001=%d\n", two_thousand_one);
+    printf("2002=%d\n", two_thousand_two);
     return 0;
 }
Index: sts/unified_locking/.expect/block_spin_lock.txt
===================================================================
--- tests/unified_locking/.expect/block_spin_lock.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/clh.txt
===================================================================
--- tests/unified_locking/.expect/clh.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/fast_block_lock.txt
===================================================================
--- tests/unified_locking/.expect/fast_block_lock.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/futex_mutex.txt
===================================================================
--- tests/unified_locking/.expect/futex_mutex.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/lin_backoff.txt
===================================================================
--- tests/unified_locking/.expect/lin_backoff.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/locks.txt
===================================================================
--- tests/unified_locking/.expect/locks.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,26 +1,0 @@
-Start Test 1: multi acquisition lock and condition variable single wait/notify
-Done Test 1
-Start Test 2: multi acquisition lock and condition variable 3 wait/notify all
-Done Test 2
-Start Test 3: single acquisition lock and condition variable single wait/notify
-Done Test 3
-Start Test 4: single acquisition lock and condition variable 3 wait/notify all
-Done Test 4
-Start Test 5: owner lock and condition variable single wait/notify
-Done Test 5
-Start Test 6: owner lock and condition variable 3 wait/notify all
-Done Test 6
-Start Test 7: linear backoff lock and condition variable single wait/notify
-Done Test 7
-Start Test 8: linear backoff lock and condition variable 3 wait/notify all
-Done Test 8
-Start Test 9: multi acquisiton lock and condition variable multiple acquire and wait/notify
-Done Test 9
-Start Test 10: owner lock and condition variable multiple acquire and wait/notify
-Done Test 10
-Start Test 11: no lock condition variable wait/notify
-Done Test 11
-Start Test 12: locked condition variable wait/notify with front()
-Done Test 12
-Start Test 13: fast block lock and fast cond var single wait/notify
-Done Test 13
Index: sts/unified_locking/.expect/mcs.txt
===================================================================
--- tests/unified_locking/.expect/mcs.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/mcs_block_spin_lock.txt
===================================================================
--- tests/unified_locking/.expect/mcs_block_spin_lock.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/mcs_spin.txt
===================================================================
--- tests/unified_locking/.expect/mcs_spin.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/pthread_locks.txt
===================================================================
--- tests/unified_locking/.expect/pthread_locks.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-Start Test 1: lock and condition variable single wait/notify
-Done Test 1
-Start Test 2: lock and condition variable 3 wait/notify all
-Done Test 2
-Start Test 3: lock and condition variable multiple acquire and wait/notify
-Done Test 3
-Start Test 4: lock and condition variable single timed wait/notify
-Done Test 4
Index: sts/unified_locking/.expect/simple_owner_lock.txt
===================================================================
--- tests/unified_locking/.expect/simple_owner_lock.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/spin_queue_lock.txt
===================================================================
--- tests/unified_locking/.expect/spin_queue_lock.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,3 +1,0 @@
-Starting
-Done!
-Match!
Index: sts/unified_locking/.expect/timeout_lock.txt
===================================================================
--- tests/unified_locking/.expect/timeout_lock.txt	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,4 +1,0 @@
-Start Test 1: surface testing condition variable timeout routines
-Done Test 1
-Start Test 2: testing timeout vs signalling with varying timeout durations
-Done Test 2
Index: sts/unified_locking/block_spin_lock.cfa
===================================================================
--- tests/unified_locking/block_spin_lock.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include <locks.hfa>
-
-#define LOCK block_spin_lock
-#include "mutex_test.hfa"
-
-int main() {
-    test();
-}
Index: sts/unified_locking/clh.cfa
===================================================================
--- tests/unified_locking/clh.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include <locks.hfa>
-
-#define LOCK clh_lock
-#include "mutex_test.hfa"
-
-int main() {
-    test();
-}
Index: sts/unified_locking/fast_block_lock.cfa
===================================================================
--- tests/unified_locking/fast_block_lock.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include <locks.hfa>
-
-#define LOCK fast_block_lock
-#include "mutex_test.hfa"
-
-int main() {
-    test();
-}
Index: sts/unified_locking/futex_mutex.cfa
===================================================================
--- tests/unified_locking/futex_mutex.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include <locks.hfa>
-
-#define LOCK futex_mutex
-#include "mutex_test.hfa"
-
-int main() {
-    test();
-}
Index: sts/unified_locking/lin_backoff.cfa
===================================================================
--- tests/unified_locking/lin_backoff.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include <locks.hfa>
-
-#define LOCK linear_backoff_then_block_lock
-#include "mutex_test.hfa"
-
-int main() {
-    test();
-}
Index: sts/unified_locking/locks.cfa
===================================================================
--- tests/unified_locking/locks.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,348 +1,0 @@
-#include <stdio.h>
-#include "locks.hfa"
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-const unsigned int num_times = 50000;
-
-multiple_acquisition_lock m;
-condition_variable( multiple_acquisition_lock ) c_m;
-
-single_acquisition_lock s;
-condition_variable( single_acquisition_lock ) c_s;
-
-owner_lock o;
-condition_variable( owner_lock ) c_o;
-
-linear_backoff_then_block_lock l;
-condition_variable( linear_backoff_then_block_lock ) c_l;
-
-fast_block_lock f;
-fast_cond_var( fast_block_lock ) f_c_f;
-
-thread T_C_M_WS1 {};
-
-void main( T_C_M_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		if(empty(c_m) && i != num_times - 1) {
-			wait(c_m,m);
-		}else{
-			notify_one(c_m);
-		}
-		unlock(m);
-	}
-}
-
-thread T_C_M_WB1 {};
-
-void main( T_C_M_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		if(counter(c_m) == 3 || i == num_times - 1) {
-			notify_all(c_m);
-		}else{
-			wait(c_m,m);
-		}
-		unlock(m);
-	}
-}
-
-thread T_C_S_WS1 {};
-
-void main( T_C_S_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(empty(c_s) && i != num_times - 1) {
-			wait(c_s,s);
-		}else{
-			notify_one(c_s);
-		}
-		unlock(s);
-	}
-}
-
-thread T_C_S_WB1 {};
-
-void main( T_C_S_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(counter(c_s) == 3 || i == num_times - 1) {
-			notify_all(c_s);
-		}else{
-			wait(c_s,s);
-		}
-		unlock(s);
-	}
-}
-
-thread T_C_L_WS1 {};
-
-void main( T_C_L_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(l);
-		if(empty(c_l) && i != num_times - 1) {
-			wait(c_l,l);
-		}else{
-			notify_one(c_l);
-		}
-		unlock(l);
-	}
-}
-
-thread T_C_L_WB1 {};
-
-void main( T_C_L_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(l);
-		if(counter(c_l) == 3 || i == num_times - 1) {
-			notify_all(c_l);
-		}else{
-			wait(c_l,l);
-		}
-		unlock(l);
-	}
-}
-
-thread T_F_C_F_WS1 {};
-
-void main( T_F_C_F_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(f);
-		if(empty(f_c_f) && i != num_times - 1) {
-			wait(f_c_f,f);
-		}else{
-			notify_one(f_c_f);
-		}
-		unlock(f);
-	}
-}
-
-thread T_C_O_WS1 {};
-
-void main( T_C_O_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		if(empty(c_o) && i != num_times - 1) {
-			wait(c_o,o);
-		}else{
-			notify_one(c_o);
-		}
-		unlock(o);
-	}
-}
-
-thread T_C_O_WB1 {};
-
-void main( T_C_O_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		if(counter(c_o) == 3 || i == num_times - 1) {
-			notify_all(c_o);
-		}else{
-			wait(c_o,o);
-		}
-		unlock(o);
-	}
-}
-
-thread T_C_M_WS2 {};
-
-void main( T_C_M_WS2 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		lock(m);
-		lock(m);
-		if(empty(c_m) && i != num_times - 1) {
-			wait(c_m,m);
-		}else{
-			notify_one(c_m);
-		}
-		unlock(m);
-		unlock(m);
-		unlock(m);
-	}
-}
-
-thread T_C_O_WS2 {};
-
-void main( T_C_O_WS2 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		lock(o);
-		lock(o);
-		if(empty(c_o) && i != num_times - 1) {
-			wait(c_o,o);
-		}else{
-			notify_one(c_o);
-		}
-		unlock(o);
-		unlock(o);
-		unlock(o);
-	}
-}
-
-thread T_C_NLW {};
-
-void main( T_C_NLW & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		wait(c_o);
-	}
-}
-
-thread T_C_NLS {};
-
-void main( T_C_NLS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_o)) { }
-		notify_one(c_o);
-	}
-}
-
-thread T_C_S_WNF {};
-
-void main( T_C_S_WNF & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(empty(c_s) && i != num_times - 1) {
-			wait(c_s, s, 10);
-		}else{
-			if(!empty(c_s)) assert(front(c_s) == 10);
-			notify_one(c_s);
-		}
-		unlock(s);
-	}
-}
-
-bool done = false;
-
-thread T_C_NLWD {};
-
-void main( T_C_NLWD & this ) {
-	done = false;
-	for (unsigned int i = 0; i < num_times/5; i++) {
-		if (i % 1000 == 0) printf("Iteration: %d\n", i);
-		wait(c_s, 1`ns);
-	}
-	done = true;
-}
-
-thread T_C_WDS {};
-
-void main( T_C_WDS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_s) && !done) { }
-		notify_one(c_s);
-		sleep(1`ns);
-		if(done) break;
-	}
-}
-
-thread T_C_LWD {};
-
-void main( T_C_LWD & this ) {
-	done = false;
-	for (unsigned int i = 0; i < num_times/5; i++) {
-		if (i % 1000 == 0) printf("Iteration: %d\n", i);
-		lock(s);
-		wait(c_s, s, 1`ns);
-		unlock(s);
-	}
-	done = true;
-}
-
-thread T_C_LWDS {};
-
-void main( T_C_LWDS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_s) && !done) { }
-		lock(s);
-		notify_one(c_s);
-		unlock(s);
-		sleep(1`ns);
-		if(done) break;
-	}
-}
-
-int main() {
-	processor p[2];
-	printf("Start Test 1: multi acquisition lock and condition variable single wait/notify\n");
-	{
-		T_C_M_WS1 t1[2];
-	}
-	printf("Done Test 1\n");
-
-	printf("Start Test 2: multi acquisition lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_M_WB1 t1[4];
-	}
-	printf("Done Test 2\n");
-
-	printf("Start Test 3: single acquisition lock and condition variable single wait/notify\n");
-	{
-		T_C_S_WS1 t1[2];
-	}
-	printf("Done Test 3\n");
-
-	printf("Start Test 4: single acquisition lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_S_WB1 t1[4];
-	}
-	printf("Done Test 4\n");
-
-	printf("Start Test 5: owner lock and condition variable single wait/notify\n");
-	{
-		T_C_O_WS1 t1[2];
-	}
-	printf("Done Test 5\n");
-
-	printf("Start Test 6: owner lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_O_WB1 t1[4];
-	}
-	printf("Done Test 6\n");
-
-	printf("Start Test 7: linear backoff lock and condition variable single wait/notify\n");
-	{
-		T_C_L_WS1 t1[2];
-	}
-	printf("Done Test 7\n");
-
-	printf("Start Test 8: linear backoff lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_L_WB1 t1[4];
-	}
-	printf("Done Test 8\n");
-
-	printf("Start Test 9: multi acquisiton lock and condition variable multiple acquire and wait/notify\n");
-	{
-		T_C_M_WS2 t1[2];
-	}
-	printf("Done Test 9\n");
-
-	printf("Start Test 10: owner lock and condition variable multiple acquire and wait/notify\n");
-	{
-		T_C_O_WS2 t1[2];
-	}
-	printf("Done Test 10\n");
-
-	printf("Start Test 11: no lock condition variable wait/notify\n");
-	{
-		T_C_NLW t1;
-		T_C_NLS t2;
-	}
-	printf("Done Test 11\n");
-
-	printf("Start Test 12: locked condition variable wait/notify with front()\n");
-	{
-		T_C_S_WNF t1[2];
-	}
-	printf("Done Test 12\n");
-
-	printf("Start Test 13: fast block lock and fast cond var single wait/notify\n");
-	{
-		T_F_C_F_WS1 t1[2];
-	}
-	printf("Done Test 13\n");
-	
-}
Index: sts/unified_locking/mcs.cfa
===================================================================
--- tests/unified_locking/mcs.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,66 +1,0 @@
-#include <fstream.hfa>
-#include <locks.hfa>
-#include <thread.hfa>
-
-const unsigned int num_times = 50000;
-
-struct MutexObj {
-	mcs_lock l;
-	thread$ * id;
-	size_t sum;
-};
-
-MutexObj mo;
-
-void trash() {
-	unsigned t[100];
-	for(i; 100) {
-		t[i] = 0xDEADBEEF;
-	}
-}
-
-unsigned cs() {
-	thread$ * me = active_thread();
-	unsigned value = (unsigned)me;
-	mcs_node n;
-	lock(mo.l, n);
-	{
-		size_t tsum = mo.sum;
-		mo.id = me;
-		yield(random(5));
-		if(mo.id != me) sout | "Intruder!";
-		mo.sum = tsum + value;
-	}
-	unlock(mo.l, n);
-	return value;
-}
-
-thread LockCheck {
-	size_t sum;
-};
-
-void main(LockCheck & this) {
-	this.sum = 0;
-	for(num_times) {
-		trash();
-		this.sum += cs();
-		trash();
-		yield(random(10));
-	}
-}
-
-int main() {
-	size_t sum = -32;
-	mo.sum = -32;
-	processor p[2];
-	sout | "Starting";
-	{
-		LockCheck checkers[13];
-		for(i;13) {
-			sum += join(checkers[i]).sum;
-		}
-	}
-	sout | "Done!";
-	if(sum == mo.sum) sout | "Match!";
-	else sout | "No Match!" | sum | "vs" | mo.sum;
-}
Index: sts/unified_locking/mcs_block_spin_lock.cfa
===================================================================
--- tests/unified_locking/mcs_block_spin_lock.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include <locks.hfa>
-
-#define LOCK mcs_block_spin_lock
-#include "mutex_test.hfa"
-
-int main() {
-    test();
-}
Index: sts/unified_locking/mcs_spin.cfa
===================================================================
--- tests/unified_locking/mcs_spin.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,78 +1,0 @@
-
-#include <fstream.hfa>
-#include <locks.hfa>
-#include <thread.hfa>
-
-const unsigned int num_times = 50;
-
-struct MutexObj {
-	mcs_spin_lock l;
-	thread$ * id;
-	uint32_t sum;
-	uint32_t cnt;
-};
-
-MutexObj mo;
-
-void trash() {
-	unsigned t[100];
-	for(i; 100) {
-		t[i] = 0xDEADBEEF;
-	}
-}
-
-uint32_t cs() {
-	thread$ * me = active_thread();
-	uint32_t value;
-    mcs_spin_node node;
-	lock(mo.l, node);
-	{
-		uint32_t tsum = mo.sum;
-		uint32_t cnt = mo.cnt;
-		mo.id = me;
-		yield(random(5));
-		value = ((uint32_t)random()) ^ ((uint32_t)me);
-		if(mo.id != me) sout | "Intruder!";
-		mo.cnt = cnt + 1;
-		mo.sum = tsum + value;
-	}
-	unlock(mo.l, node);
-	return value;
-}
-
-thread LockCheck {
-	uint32_t sum;
-};
-
-void main(LockCheck & this) {
-	this.sum = 0;
-	for(num_times) {
-		trash();
-		this.sum += cs();
-		trash();
-		yield(random(10));
-	}
-}
-
-void test() {
-	uint32_t sum = -32;
-	mo.sum = -32;
-	mo.cnt = 0;
-	processor p[2];
-	sout | "Starting";
-	{
-		LockCheck checkers[13];
-		for(i;13) {
-			sum += join(checkers[i]).sum;
-		}
-	}
-	sout | "Done!";
-	if(mo.cnt != (13 * num_times)) sout | "Invalid cs count!" | mo.cnt | "vs "| (13 * num_times) | "(13 *" | num_times | ')';
-	if(sum == mo.sum) sout | "Match!";
-	else sout | "No Match!" | sum | "vs" | mo.sum;
-}
-
-int main() {
-    test();
-	return 0;
-}
Index: sts/unified_locking/mutex_test.hfa
===================================================================
--- tests/unified_locking/mutex_test.hfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,79 +1,0 @@
-
-#include <fstream.hfa>
-#include <locks.hfa>
-#include <thread.hfa>
-
-const unsigned int num_times = 50;
-
-struct MutexObj {
-	LOCK l;
-	thread$ * id;
-	uint32_t sum;
-	uint32_t cnt;
-};
-
-MutexObj mo;
-
-void trash() {
-	unsigned t[100];
-	for(i; 100) {
-		t[i] = 0xDEADBEEF;
-	}
-}
-
-uint32_t cs(uint32_t & entries) {
-	thread$ * me = active_thread();
-	uint32_t value;
-	lock(mo.l);
-	{
-		entries++;
-		uint32_t tsum = mo.sum;
-		uint32_t cnt = mo.cnt;
-		mo.id = me;
-		yield(random(5));
-		value = ((uint32_t)random()) ^ ((uint32_t)me);
-		if(mo.id != me) sout | "Intruder!";
-		mo.cnt = cnt + 1;
-		mo.sum = tsum + value;
-	}
-	unlock(mo.l);
-	return value;
-}
-
-thread LockCheck {
-	uint32_t sum;
-	uint32_t entries;
-};
-
-void main(LockCheck & this) {
-	this.sum = 0;
-	this.entries = 0;
-	for(num_times) {
-		trash();
-		this.sum += cs( this.entries );
-		trash();
-		yield(random(10));
-	}
-}
-
-void test() {
-	uint32_t sum = -32;
-	mo.sum = -32;
-	mo.cnt = 0;
-	uint32_t real_entries = 0;
-	processor p[2];
-	sout | "Starting";
-	{
-		LockCheck checkers[13];
-		for(i;13) {
-			LockCheck & curr = join(checkers[i]);
-			sum += curr.sum;
-			real_entries += curr.entries;
-		}
-	}
-	sout | "Done!";
-	if(real_entries != (13 * num_times)) sout | "Invalid real cs count!" | mo.cnt | "vs "| (13 * num_times) | "(13 *" | num_times | ')';
-	if(mo.cnt != (13 * num_times)) sout | "Invalid concurrent cs count!" | mo.cnt | "vs "| (13 * num_times) | "(13 *" | num_times | ')';
-	if(sum == mo.sum) sout | "Match!";
-	else sout | "No Match!" | sum | "vs" | mo.sum;
-}
Index: sts/unified_locking/pthread_locks.cfa
===================================================================
--- tests/unified_locking/pthread_locks.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,108 +1,0 @@
-#include <stdio.h>
-#include "locks.hfa"
-#include <stdlib.hfa>
-#include <thread.hfa>
-#include <time.h>
-#include <stdlib.hfa>
-
-const unsigned int num_times = 50;
-
-simple_owner_lock l;
-pthread_cond_var( simple_owner_lock ) c;
-
-owner_lock l2;
-condition_variable( owner_lock ) c2;
-
-volatile int counter = 0;
-
-thread Wait_Signal_1 {};
-
-void main( Wait_Signal_1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(l);
-		if(empty(c) && i != num_times - 1) {
-			wait(c,l);
-		}else{
-			notify_one(c);
-		}
-		unlock(l);
-	}
-}
-
-thread Wait_3_Signal_3 {};
-
-void main( Wait_3_Signal_3 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(l);
-        counter++;
-		if(counter == 4 || i == num_times - 1) {
-            counter = 0;
-			notify_all(c);
-		}else{
-			wait(c,l);
-		}
-		unlock(l);
-	}
-}
-
-thread Rec_Lock_Wait_Signal_1 {};
-
-void main( Rec_Lock_Wait_Signal_1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(l);
-		lock(l);
-		lock(l);
-		if(empty(c) && i != num_times - 1) {
-			wait(c,l);
-		}else{
-			notify_one(c);
-		}
-		unlock(l);
-		unlock(l);
-		unlock(l);
-	}
-}
-
-thread Wait_Time_Signal_1 {};
-
-void main( Wait_Time_Signal_1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(l);
-		if(empty(c) || random(10) >= 9 ) {
-			timespec t;
-			clock_gettime(CLOCK_REALTIME, &t);
-			timespec waitTime{0,1};
-			bool woken = wait(c,l, t + waitTime);
-		}else{
-			notify_one(c);
-		}
-		unlock(l);
-	}
-}
-
-int main() {
-	processor p[1];
-	printf("Start Test 1: lock and condition variable single wait/notify\n");
-	{
-		Wait_Signal_1 t1[2];
-	}
-	printf("Done Test 1\n");
-
-	printf("Start Test 2: lock and condition variable 3 wait/notify all\n");
-	{
-		Wait_3_Signal_3 t1[4];
-	}
-	printf("Done Test 2\n");
-
-	printf("Start Test 3: lock and condition variable multiple acquire and wait/notify\n");
-	{
-		Rec_Lock_Wait_Signal_1 t1[2];
-	}
-	printf("Done Test 3\n");
-
-	printf("Start Test 4: lock and condition variable single timed wait/notify\n");
-	{
-		Wait_Time_Signal_1 t1[2];
-	}
-	printf("Done Test 4\n");
-}
Index: sts/unified_locking/simple_owner_lock.cfa
===================================================================
--- tests/unified_locking/simple_owner_lock.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include <locks.hfa>
-
-#define LOCK simple_owner_lock
-#include "mutex_test.hfa"
-
-int main() {
-    test();
-}
Index: sts/unified_locking/spin_queue_lock.cfa
===================================================================
--- tests/unified_locking/spin_queue_lock.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#include <locks.hfa>
-
-#define LOCK spin_queue_lock
-#include "mutex_test.hfa"
-
-int main() {
-    test();
-}
Index: sts/unified_locking/thread_test.cfa
===================================================================
--- tests/unified_locking/thread_test.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#include <stdio.h>
-#include "locks.hfa"
-#include <stdlib.hfa>
-#include <thread.hfa>
-#include <containers/array.hfa>
-
-static unsigned int taskCount = 4;
-static unsigned int threadCount = 2;
-static unsigned int lockCount = 1;
-static unsigned int total_times = 320000;
-static unsigned int num_times;
-static const int workBufferSize = 16;
-static unsigned int work_unlocked = 10000;
-static unsigned int work_locked = 10000;
-
-// taken from martin's thread_test
-static inline void dowork(volatile int* buffer, unsigned int steps) {
-  int value = 0;
-  for (unsigned int i = 0; i < steps; i += 1) {
-    // a little more work than just a single memory access helps with stability
-    value += (buffer[i % workBufferSize] * 17) / 23 + 55;
-  }
-  buffer[0] += value;
-}
-
-thread worker {
-    linear_backoff_then_block_lock * locks;
-    bool improved;
-};
-
-void ?{}( worker & w, linear_backoff_then_block_lock * locks, bool improved ) {
-	w.locks = locks;
-    w.improved = improved;
-}
-
-
-void main( worker & this ) with(this) {
-	int buffer[workBufferSize];
-    for (int i = 0; i < workBufferSize; i += 1) buffer[i] = rand() % 1024;
-    unsigned int lck = rand() % lockCount;
-    linear_backoff_then_block_lock * curr_lock = &locks[lck];
-    for (unsigned int i = 0; i < num_times; i++) {
-        dowork(buffer, work_unlocked);
-        if (improved) lock_improved(*curr_lock);
-        else lock(*curr_lock);
-        dowork(buffer, work_locked);
-        unlock(*curr_lock);
-        lck = rand() % lockCount;
-        curr_lock = &locks[lck];
-    }
-}
-
-
-int main(int argc, char* argv[]) {
-    switch (argc) {
-        case 7:
-            work_unlocked = atoi(argv[5]);
-        case 6:
-            work_locked = atoi(argv[5]);
-        case 5:
-            num_times = atoi(argv[4]);
-        case 4:
-            lockCount = atoi(argv[3]);
-        case 3:
-            threadCount = atoi(argv[2]);
-        case 2:
-            taskCount = atoi(argv[1]);
-        case 1:
-            break;
-        default:
-            break;
-    }
-	processor p[threadCount];
-    linear_backoff_then_block_lock locks[lockCount];
-    worker * worker_arr[taskCount];
-    num_times = total_times  / taskCount;
-
-	//printf("Start Test: martin lock simple\n");
-	clock_t begin = clock();
-	for (unsigned int i = 0; i < taskCount; i++) {
-        worker_arr[i] = new( locks, false );
-    }
-    for (unsigned int i = 0; i < taskCount; i++) {
-        delete( worker_arr[i] );
-    }
-	clock_t end = clock();
-	double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
-	printf("norm: %f\n", time_spent);
-
-    //printf("Start Test: martin lock improved\n");
-	begin = clock();
-	for (unsigned int i = 0; i < taskCount; i++) {
-        worker_arr[i] = new( locks, true );
-    }
-    for (unsigned int i = 0; i < taskCount; i++) {
-        delete( worker_arr[i] );
-    }
-	end = clock();
-	time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
-	printf("improved: %f\n", time_spent);
-}
Index: sts/unified_locking/timeout_lock.cfa
===================================================================
--- tests/unified_locking/timeout_lock.cfa	(revision 466787ab63d68db4ce9258a2f78369073fd88777)
+++ 	(revision )
@@ -1,87 +1,0 @@
-#include <stdio.h>
-#include <locks.hfa>
-#include <alarm.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-#include <kernel.hfa>
-
-multiple_acquisition_lock m, n;
-condition_variable( multiple_acquisition_lock ) c_m, c_n;
-
-const unsigned int NoOfTimes = 20;
-
-void block() { // used for barrier like behaviour
-	lock(n);
-	if (empty( c_n )) {
-		wait( c_n, n );
-	} else {
-		notify_one( c_n );
-	}
-	unlock(n);
-}
-
-thread T1 {};
-
-void main( T1 & this ) {
-	lock(m);
-	wait( c_m, m, 1`s );
-	// printf("Thread: %p timedout\n", active_thread()); // removed since can't expect non deterministic output
-
-	block();
-
-	// Test calls which occur increasingly close to timeout value.
-
-	for ( unsigned int i = 0; i < NoOfTimes + 3; i += 1 ) {
-	    if ( wait( c_m, m, 1000000`ns ) ) {
-			// printf("Thread: %p signalled\n", active_thread()); // removed since can't expect non deterministic output
-	    } else {
-			// printf("Thread: %p timedout\n", active_thread()); // removed since can't expect non deterministic output
-	    } // if
-
-	    block();
-	} // for
-}
-
-
-thread T2 {};
-
-void main( T2 & this ) {
-	block();
-
-	// Test calls which occur increasingly close to timeout value.
-
-	sleep( 100000`ns );
-	notify_one(c_m);
-	block();
-
-	sleep( 500000`ns );
-	notify_one(c_m);
-	block();
-
-	sleep( 900000`ns );
-	notify_one(c_m);
-	block();
-
-	for ( unsigned int i = 0; i < NoOfTimes; i += 1 ) {
-	    sleep( 999700`ns );
-		notify_one(c_m);
-	    block();
-	} // for
-}
-
-int main() {
-	processor p[2];
-	printf("Start Test 1: surface testing condition variable timeout routines\n");
-	wait( c_m, 1`ns );														// bool wait( condition_variable(L) & this, Duration duration );
-	wait( c_m, 10, 1`ns );													// bool wait( condition_variable(L) & this, uintptr_t info, Duration duration );
-	lock(m); wait( c_m, m, 1`ns ); unlock(m); 								// bool wait( condition_variable(L) & this, L & l, Duration duration );
-	lock(m); wait( c_m, m, 10, 1`ns ); unlock(m);							// bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
-	printf("Done Test 1\n");
-
-	printf("Start Test 2: testing timeout vs signalling with varying timeout durations\n");
-	{
-		T1 t1;
-		T2 t2;
-	}
-	printf("Done Test 2\n");
-}
