Index: tests/concurrent/.expect/semaphore.txt
===================================================================
--- tests/concurrent/.expect/semaphore.txt	(revision 976bc68bf62844647c302f52740892262d6884c4)
+++ tests/concurrent/.expect/semaphore.txt	(revision 976bc68bf62844647c302f52740892262d6884c4)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/concurrent/semaphore.cfa
===================================================================
--- tests/concurrent/semaphore.cfa	(revision 976bc68bf62844647c302f52740892262d6884c4)
+++ tests/concurrent/semaphore.cfa	(revision 976bc68bf62844647c302f52740892262d6884c4)
@@ -0,0 +1,77 @@
+#include <fstream.hfa>
+#include <locks.hfa>
+#include <thread.hfa>
+
+enum { num_blockers = 17, num_unblockers = 13 };
+
+void thrash() {
+	unsigned t[100];
+	for(i; 100) {
+		t[i] = 0xDEADBEEF;
+	}
+}
+
+ThreadBenaphore ben;
+
+// const unsigned int num_blocks = 25000;
+const unsigned int num_blocks = 5;
+
+thread Blocker {
+	size_t sum;
+};
+
+void main(Blocker & this) {
+	$thread * me = active_thread();
+	this.sum = 0;
+	for(num_blocks) {
+		this.sum += (unsigned)me;
+		thrash();
+		P(ben);
+		if(((thread&)this).seqable.next != 0p) sout | acquire |"Link not invalidated";
+		thrash();
+	}
+}
+
+thread Unblocker {
+	size_t sum;
+};
+
+void main(Unblocker & this) {
+	this.sum = 0;
+	LOOP: for() {
+		waitfor( ^?{} : this) {
+			break LOOP;
+		}
+		or else {}
+
+		$thread * t = V(ben, false);
+		if(t) {
+			this.sum += (unsigned)t;
+			unpark(t);
+		}
+		yield(random(10));
+	}
+}
+
+int main() {
+	size_t usum = 0;
+	size_t bsum = 0;
+
+	sout | "Starting";
+	{
+		Blocker   blockers  [num_blockers  ];
+		Unblocker unblockers[num_unblockers];
+
+		for(i;num_blockers) {
+			bsum += join(blockers[i]).sum;
+		}
+
+		sout | "Done!";
+
+		for(i;num_unblockers) {
+			usum += join(unblockers[i]).sum;
+		}
+	}
+	if(bsum == usum) sout | "Match!";
+	else sout | "No Match!" | usum | "!=" | bsum;
+}
Index: tests/unified_locking/.expect/fast.txt
===================================================================
--- tests/unified_locking/.expect/fast.txt	(revision 976bc68bf62844647c302f52740892262d6884c4)
+++ tests/unified_locking/.expect/fast.txt	(revision 976bc68bf62844647c302f52740892262d6884c4)
@@ -0,0 +1,3 @@
+Starting
+Done!
+Match!
Index: tests/unified_locking/fast.cfa
===================================================================
--- tests/unified_locking/fast.cfa	(revision 976bc68bf62844647c302f52740892262d6884c4)
+++ tests/unified_locking/fast.cfa	(revision 976bc68bf62844647c302f52740892262d6884c4)
@@ -0,0 +1,65 @@
+#include <fstream.hfa>
+#include <locks.hfa>
+#include <thread.hfa>
+
+const unsigned int num_times = 50;
+
+struct MutexObj {
+	fast_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;
+	lock(mo.l);
+	{
+		size_t tsum = mo.sum;
+		mo.id = me;
+		yield(random(5));
+		if(mo.id != me) sout | "Intruder!";
+		mo.sum = tsum + value;
+	}
+	unlock(mo.l);
+	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;
+}
