Index: doc/theses/colby_parsons_MMAth/benchmarks/waituntil/cfa/future.cfa
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/waituntil/cfa/future.cfa	(revision 2cb8bf71ee22c19594b82251503bc555aa250fc9)
+++ doc/theses/colby_parsons_MMAth/benchmarks/waituntil/cfa/future.cfa	(revision 2cb8bf71ee22c19594b82251503bc555aa250fc9)
@@ -0,0 +1,105 @@
+#include <select.hfa>
+#include <thread.hfa>
+#include <future.hfa>
+#include <fstream.hfa>
+#include <stdio.h>
+#include <time.hfa>
+#include <string.h>
+
+size_t Clients = 1, Time = 10;
+
+size_t globalTotal = 0;
+future(size_t) A, B, C;
+volatile bool server_done_loop = false;
+volatile bool client_done_loop = false;
+volatile bool client_done = false;
+volatile bool server_done = false;
+
+volatile size_t client_count = 0;
+volatile size_t client_loop_count = 0;
+thread Client {};
+void main( Client & this ) {
+    size_t i = 0;
+    for(;; i++ ) {
+        waituntil( A ) { get(A); }
+        and waituntil( B ) { get(B); }
+        or waituntil( C ) { get(C); }
+
+        // needs to check after waituntil for termination synchronization
+        if ( client_done ) break;
+
+        // Barrier-like synch needed to reset futures safely
+        if ( __atomic_add_fetch( &client_count, 1, __ATOMIC_SEQ_CST ) == Clients ) { // synchronize reset
+            client_count = 0;
+            reset( A );
+            reset( B );
+            reset( C );
+            client_done_loop = true; // unblock clients
+        }
+        while( !client_done_loop ) {} // client barrier
+        if ( __atomic_add_fetch( &client_loop_count, 1, __ATOMIC_SEQ_CST ) == Clients ) { 
+            client_done_loop = false; // reset barrier before clients can proceed past waituntil
+            server_done_loop = true; // unblock server to restart iteration
+            client_loop_count = 0;
+        }
+    }
+    __atomic_fetch_add( &globalTotal, i, __ATOMIC_SEQ_CST );
+}
+
+thread Server {};
+void main( Server & this ) {
+    for( size_t i = 0; !server_done; i++ ) {
+        if ( i % 4 == 0 ) {
+            fulfil(A, i);
+            fulfil(B, i);
+        } else if ( i % 4 == 1 ) {
+            fulfil(A, i);
+            fulfil(C, i);
+        } else if ( i % 4 == 2 ) {
+            fulfil(B, i);
+            fulfil(C, i);
+        } else {
+            fulfil(C, i);
+        }
+        while( !server_done_loop && !server_done ) {} // server barrier
+        server_done_loop = false; // reset server barrier
+    }
+}
+
+int main( int argc, char * argv[] ) {
+    switch ( argc ) {
+	  case 3:
+		if ( strcmp( argv[2], "d" ) != 0 ) {			// default ?
+			Time = atoi( argv[2] );
+		} // if
+	  case 2:
+		if ( strcmp( argv[1], "d" ) != 0 ) {			// default ?
+			Clients = atoi( argv[1] );
+			if ( Clients < 1 ) goto Usage;
+		} // if
+	  case 1:											// use defaults
+		break;
+	  default:
+	  Usage:
+		sout | "Usage: " | argv[0]
+             | " [ clients (> 0) | 'd' (default " | Clients
+			 | ") ] [ time (>= 0) | 'd' (default " | Time
+			 | ") ]" ;
+		exit( EXIT_FAILURE );
+	} // switch
+    processor p[Clients];
+
+    {
+        Client c[Clients];
+        {
+            Server s;
+
+            sleep(Time`s);
+            server_done = true;
+        }
+        while( available(A) || available(B) || available(C) ) {}
+        client_done = true;
+        fulfil( C, 0 );
+    }
+    printf("%zu\n", globalTotal);
+}
Index: doc/theses/colby_parsons_MMAth/benchmarks/waituntil/run
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/waituntil/run	(revision 44198fb9159caf1a5c6b949919830261ff7d2f2c)
+++ doc/theses/colby_parsons_MMAth/benchmarks/waituntil/run	(revision 2cb8bf71ee22c19594b82251503bc555aa250fc9)
@@ -94,4 +94,5 @@
 
 chan_size='10'
+future_time='10'
 
 # toggle benchmarks
@@ -99,12 +100,16 @@
 contend=${true}
 sidechan=${true}
-# spin=${false}
-# contend=${false}
-# sidechan=${false}
+future=${true}
+spin=${false}
+contend=${false}
+sidechan=${false}
+# future=${false}
 
 runCFA=${true}
 runGO=${true}
+runUCPP=${true}
 # runCFA=${false}
-# runGO=${false}
+runGO=${false}
+# runUCPP=${false}
 
 cfa=~/cfa-cc/driver/cfa
@@ -158,4 +163,13 @@
 }
 
+run_future() {
+    for p in ${num_threads} ; do
+        pre_args=$(( ${p} - 1 ))
+        affinity ${p}
+        preprint="${p}\t"
+        repeat_command taskset -c ${taskset} ./a.${hostname} ${pre_args} ${post_args}
+    done
+}
+
 arch # get hostname
 
@@ -177,4 +191,8 @@
 # cfa flags
 cfa_flags='-quiet -O3 -nodebug -DNDEBUG'
+
+# UCPP flags
+UCPPflags="-quiet -g -Wall -Wextra -O3 -nodebug -DNDEBUG -multi"
+UCPP=~/ucpp/u++-7.0.0/bin/u++
 
 # run the benchmarks
@@ -243,2 +261,24 @@
 fi
 
+if [ ${future} -eq ${true} ] ; then
+    echo "future: "
+    post_args=${future_time}
+    if [ ${runCFA} -eq ${true} ] ; then
+        cd cfa # CFA RUN
+        print_header 'CFA'
+        ${cfa} ${cfa_flags} future.cfa -o a.${hostname} > /dev/null 2>&1
+        run_future
+        rm a.${hostname}
+        cd - > /dev/null
+    fi # done CFA
+
+    if [ ${runUCPP} -eq ${true} ] ; then
+        cd ucpp
+        print_header 'uC++'
+        ${UCPP} ${UCPPflags} future.cc -o a.${hostname} > /dev/null 2>&1
+        run_future
+        rm a.${hostname}
+        cd - > /dev/null
+    fi # done Go
+fi
+
Index: doc/theses/colby_parsons_MMAth/benchmarks/waituntil/ucpp/future.cc
===================================================================
--- doc/theses/colby_parsons_MMAth/benchmarks/waituntil/ucpp/future.cc	(revision 2cb8bf71ee22c19594b82251503bc555aa250fc9)
+++ doc/theses/colby_parsons_MMAth/benchmarks/waituntil/ucpp/future.cc	(revision 2cb8bf71ee22c19594b82251503bc555aa250fc9)
@@ -0,0 +1,104 @@
+#include <iostream>
+using namespace std;
+#include <uFuture.h>
+
+size_t Clients = 2, Time = 10;
+
+size_t globalTotal = 0;
+Future_ISM<size_t> A, B, C;
+volatile bool server_done_loop = false;
+volatile bool client_done_loop = false;
+volatile bool client_done = false;
+volatile bool server_done = false;
+
+volatile size_t client_count = 0;
+volatile size_t client_loop_count = 0;
+_Task Client {
+	void main() {
+		size_t i = 0;
+        for(;; i++ ) {
+            _Select( A ) { A(); }
+            and _Select( B ) { B(); }
+            or _Select( C ) { C(); }
+
+            // needs to check after waituntil for termination synchronization
+            if ( client_done ) break;
+            
+            // Barrier-like synch needed to reset futures safely
+            if ( __atomic_add_fetch(&client_count, 1, __ATOMIC_SEQ_CST) == Clients ) {
+                client_count = 0;
+                A.reset();
+                B.reset();
+                C.reset();
+                client_done_loop = true;
+            }
+            while( !client_done_loop ) {} // client barrier
+            if ( __atomic_add_fetch( &client_loop_count, 1, __ATOMIC_SEQ_CST ) == Clients ) { 
+                client_done_loop = false; // reset barrier before clients can proceed past waituntil
+                server_done_loop = true; // unblock server to restart iteration
+                client_loop_count = 0;
+            }
+        }
+        __atomic_fetch_add( &globalTotal, i, __ATOMIC_SEQ_CST );
+	} 
+};
+
+_Task Server {
+	void main() {
+		for( size_t i = 0; !server_done; i++ ) {
+            if ( i % 4 == 0 ) {
+                A.delivery(i);
+                B.delivery(i);
+            } else if ( i % 4 == 1 ) {
+                A.delivery(i);
+                C.delivery(i);
+            } else if ( i % 4 == 2 ) {
+                B.delivery(i);
+                C.delivery(i);
+            } else {
+                C.delivery(i);
+            }
+            while( !server_done_loop && !server_done ) {} // server barrier
+            server_done_loop = false; // reset server barrier
+        }
+	}
+};
+
+int main( int argc, char * argv[] ) {
+	switch ( argc ) {
+	  case 3:
+		if ( strcmp( argv[2], "d" ) != 0 ) {			// default ?
+			Time = atoi( argv[2] );
+		} // if
+	  case 2:
+		if ( strcmp( argv[1], "d" ) != 0 ) {			// default ?
+			Clients = atoi( argv[1] );
+			if ( Clients < 1 ) goto Usage;
+		} // if
+	  case 1:											// use defaults
+		break;
+	  default:
+	  Usage:
+		cerr << "Usage: " << argv[0]
+             << " [ clients (> 0) | 'd' (default " << Clients
+			 << ") ] [ time (>= 0) | 'd' (default " << Time
+			 << ") ]" ;
+		exit( EXIT_FAILURE );
+	} // switch
+    uProcessor p[Clients];
+
+    {
+        Client c[Clients];
+        {
+            Server s;
+
+            uBaseTask::sleep( uDuration( Time ) );
+
+            server_done = true;
+        }
+        while( A.available() || B.available() || C.available() ) {}
+        client_done = true;
+        C.delivery(1); // can't deliver 0 since it causes ambiguity
+    }
+    cout << globalTotal << endl;
+} // main
