Index: tests/concurrency/park/.expect/contention.txt
===================================================================
--- tests/concurrency/park/.expect/contention.txt	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
+++ tests/concurrency/park/.expect/contention.txt	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
@@ -0,0 +1,21 @@
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done
+Done Unparker
Index: tests/concurrency/park/.expect/force_preempt.txt
===================================================================
--- tests/concurrency/park/.expect/force_preempt.txt	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
+++ tests/concurrency/park/.expect/force_preempt.txt	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
@@ -0,0 +1,1 @@
+done
Index: tests/concurrency/park/.expect/start_parked.txt
===================================================================
--- tests/concurrency/park/.expect/start_parked.txt	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
+++ tests/concurrency/park/.expect/start_parked.txt	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
@@ -0,0 +1,1 @@
+done
Index: tests/concurrency/park/contention.cfa
===================================================================
--- tests/concurrency/park/contention.cfa	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
+++ tests/concurrency/park/contention.cfa	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
@@ -0,0 +1,62 @@
+#include <kernel.hfa>
+#include <thread.hfa>
+
+__thread drand48_data buffer = { 0 };
+int myrand() {
+	long int result;
+	lrand48_r(&buffer, &result);
+	return result;
+}
+
+
+thread Thread {};
+void ^?{}(Thread & mutex this) {}
+
+enum Constants { blocked_size = 20 };
+Thread * volatile blocked[blocked_size];
+
+void main( Thread & this ) {
+	for(int i = 0; i < 1000; i++) {
+		int idx = myrand() % blocked_size;
+		if(blocked[idx]) {
+			Thread * thrd = __atomic_exchange_n(&blocked[idx], 0p, __ATOMIC_SEQ_CST);
+			unpark( *thrd );
+		} else {
+			Thread * thrd = __atomic_exchange_n(&blocked[idx], &this, __ATOMIC_SEQ_CST);
+			unpark( *thrd );
+			park();
+		}
+	}
+	printf("Done\n");
+}
+
+// Extra thread to avoid deadlocking
+thread Unparker {};
+
+void main( Unparker & this ) {
+	while(true) {
+		waitfor( ^?{} : this ) {
+			break;
+		} or else {
+			int idx = myrand() % blocked_size;
+			Thread * thrd = __atomic_exchange_n(&blocked[idx], 0p, __ATOMIC_SEQ_CST);
+			unpark( *thrd );
+			yield( myrand() % 20 );
+		}
+	}
+	printf("Done Unparker\n");
+}
+
+
+int main() {
+	for(i ; blocked_size) {
+		blocked[i] = 0p;
+	}
+
+	processor p[3];
+
+	Unparker u;
+	{
+		Thread t[20];
+	}
+}
Index: tests/concurrency/park/force_preempt.cfa
===================================================================
--- tests/concurrency/park/force_preempt.cfa	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
+++ tests/concurrency/park/force_preempt.cfa	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
@@ -0,0 +1,60 @@
+#include <thread.hfa>
+#include <fstream.hfa>
+
+volatile int global = 0;
+
+thread Poller {};
+void main(Poller & this) {
+	while(true) {
+		waitfor( ^?{} : this ) {
+			break;
+		} or else {
+			global = (global + 1) % 10;
+			yield();
+		}
+	}
+}
+
+thread Waiter {};
+
+volatile int count = 0;
+
+void main(Waiter & this) {
+	// Get a unique id
+	int id = __atomic_fetch_add(&count, 1, __ATOMIC_SEQ_CST);
+	int id_hash = id | (id << 8) | (id << 16) | (id << 24);
+	int mask = 0xCAFEBABA;
+
+	for(int i = 0; i < 5; i++) {
+		assert(mask == 0xCAFEBABA);
+
+		// Unpark this thread, don't force a yield
+		unpark( this );
+		assert(mask == 0xCAFEBABA);
+
+		// Hash the mask to make sure no one else messes with them
+		mask ^= id_hash;
+		assert(mask == (id_hash ^ 0xCAFEBABA));
+
+		// Force a preemption before the call to park
+		int prev = global;
+		while(prev == global) {}
+
+		// Park this thread,
+		assert(mask == (id_hash ^ 0xCAFEBABA));
+		park();
+		assert(mask == (id_hash ^ 0xCAFEBABA));
+
+		// Reset the hash and recheck it
+		mask ^= id_hash;
+		assert(mask == 0xCAFEBABA);
+	}
+}
+
+int main() {
+	Poller p;
+	{
+		Waiter waiters[5];
+	}
+	printf( "done\n" );				// non-empty .expect file
+}
Index: tests/concurrency/park/start_parked.cfa
===================================================================
--- tests/concurrency/park/start_parked.cfa	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
+++ tests/concurrency/park/start_parked.cfa	(revision c26bea2aa0f87b4b070349c5801adc32fb0d4cf9)
@@ -0,0 +1,14 @@
+#include <thread.hfa>
+
+thread Parker {};
+void main( Parker & ) {
+	park();
+}
+
+int main() {
+	for(1000) {
+		Parker parker;
+		unpark( parker );
+	}
+	printf( "done\n" );									// non-empty .expect file
+}
