Index: tests/concurrent/park/.expect/contention.txt
===================================================================
--- tests/concurrent/park/.expect/contention.txt	(revision 3381ed7a703d0c964d6e94bffab7c58f0cdf0d17)
+++ tests/concurrent/park/.expect/contention.txt	(revision 3381ed7a703d0c964d6e94bffab7c58f0cdf0d17)
@@ -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/concurrent/park/.expect/force_preempt.txt
===================================================================
--- tests/concurrent/park/.expect/force_preempt.txt	(revision 3381ed7a703d0c964d6e94bffab7c58f0cdf0d17)
+++ tests/concurrent/park/.expect/force_preempt.txt	(revision 3381ed7a703d0c964d6e94bffab7c58f0cdf0d17)
@@ -0,0 +1,150 @@
+0 Calling unpark (No Force) 0
+1 Calling unpark (No Force) 0
+2 Calling unpark (No Force) 0
+3 Calling unpark (No Force) 0
+4 Calling unpark (No Force) 0
+0 Parking (No Force) 0
+0 Unparked (No Force) 0
+0 Calling unpark (No Force) 1
+1 Parking (No Force) 0
+1 Unparked (No Force) 0
+1 Calling unpark (No Force) 1
+2 Parking (No Force) 0
+2 Unparked (No Force) 0
+2 Calling unpark (No Force) 1
+3 Parking (No Force) 0
+3 Unparked (No Force) 0
+3 Calling unpark (No Force) 1
+4 Parking (No Force) 0
+4 Unparked (No Force) 0
+4 Calling unpark (No Force) 1
+0 Parking (No Force) 1
+0 Unparked (No Force) 1
+0 Calling unpark (No Force) 2
+1 Parking (No Force) 1
+1 Unparked (No Force) 1
+1 Calling unpark (No Force) 2
+2 Parking (No Force) 1
+2 Unparked (No Force) 1
+2 Calling unpark (No Force) 2
+3 Parking (No Force) 1
+3 Unparked (No Force) 1
+3 Calling unpark (No Force) 2
+4 Parking (No Force) 1
+4 Unparked (No Force) 1
+4 Calling unpark (No Force) 2
+0 Parking (No Force) 2
+0 Unparked (No Force) 2
+0 Calling unpark (No Force) 3
+1 Parking (No Force) 2
+1 Unparked (No Force) 2
+1 Calling unpark (No Force) 3
+2 Parking (No Force) 2
+2 Unparked (No Force) 2
+2 Calling unpark (No Force) 3
+3 Parking (No Force) 2
+3 Unparked (No Force) 2
+3 Calling unpark (No Force) 3
+4 Parking (No Force) 2
+4 Unparked (No Force) 2
+4 Calling unpark (No Force) 3
+0 Parking (No Force) 3
+0 Unparked (No Force) 3
+0 Calling unpark (No Force) 4
+1 Parking (No Force) 3
+1 Unparked (No Force) 3
+1 Calling unpark (No Force) 4
+2 Parking (No Force) 3
+2 Unparked (No Force) 3
+2 Calling unpark (No Force) 4
+3 Parking (No Force) 3
+3 Unparked (No Force) 3
+3 Calling unpark (No Force) 4
+4 Parking (No Force) 3
+4 Unparked (No Force) 3
+4 Calling unpark (No Force) 4
+0 Parking (No Force) 4
+0 Unparked (No Force) 4
+0 Calling unpark (Force) 0
+1 Parking (No Force) 4
+1 Unparked (No Force) 4
+1 Calling unpark (Force) 0
+2 Parking (No Force) 4
+2 Unparked (No Force) 4
+2 Calling unpark (Force) 0
+3 Parking (No Force) 4
+3 Unparked (No Force) 4
+3 Calling unpark (Force) 0
+4 Parking (No Force) 4
+4 Unparked (No Force) 4
+4 Calling unpark (Force) 0
+0 Parking (Force) 0
+1 Parking (Force) 0
+2 Parking (Force) 0
+3 Parking (Force) 0
+4 Parking (Force) 0
+0 Unparked (Force) 0
+0 Calling unpark (Force) 1
+1 Unparked (Force) 0
+1 Calling unpark (Force) 1
+2 Unparked (Force) 0
+2 Calling unpark (Force) 1
+3 Unparked (Force) 0
+3 Calling unpark (Force) 1
+4 Unparked (Force) 0
+4 Calling unpark (Force) 1
+0 Parking (Force) 1
+1 Parking (Force) 1
+2 Parking (Force) 1
+3 Parking (Force) 1
+4 Parking (Force) 1
+0 Unparked (Force) 1
+0 Calling unpark (Force) 2
+1 Unparked (Force) 1
+1 Calling unpark (Force) 2
+2 Unparked (Force) 1
+2 Calling unpark (Force) 2
+3 Unparked (Force) 1
+3 Calling unpark (Force) 2
+4 Unparked (Force) 1
+4 Calling unpark (Force) 2
+0 Parking (Force) 2
+1 Parking (Force) 2
+2 Parking (Force) 2
+3 Parking (Force) 2
+4 Parking (Force) 2
+0 Unparked (Force) 2
+0 Calling unpark (Force) 3
+1 Unparked (Force) 2
+1 Calling unpark (Force) 3
+2 Unparked (Force) 2
+2 Calling unpark (Force) 3
+3 Unparked (Force) 2
+3 Calling unpark (Force) 3
+4 Unparked (Force) 2
+4 Calling unpark (Force) 3
+0 Parking (Force) 3
+1 Parking (Force) 3
+2 Parking (Force) 3
+3 Parking (Force) 3
+4 Parking (Force) 3
+0 Unparked (Force) 3
+0 Calling unpark (Force) 4
+1 Unparked (Force) 3
+1 Calling unpark (Force) 4
+2 Unparked (Force) 3
+2 Calling unpark (Force) 4
+3 Unparked (Force) 3
+3 Calling unpark (Force) 4
+4 Unparked (Force) 3
+4 Calling unpark (Force) 4
+0 Parking (Force) 4
+1 Parking (Force) 4
+2 Parking (Force) 4
+3 Parking (Force) 4
+4 Parking (Force) 4
+0 Unparked (Force) 4
+1 Unparked (Force) 4
+2 Unparked (Force) 4
+3 Unparked (Force) 4
+4 Unparked (Force) 4
Index: tests/concurrent/park/contention.cfa
===================================================================
--- tests/concurrent/park/contention.cfa	(revision 3381ed7a703d0c964d6e94bffab7c58f0cdf0d17)
+++ tests/concurrent/park/contention.cfa	(revision 3381ed7a703d0c964d6e94bffab7c58f0cdf0d17)
@@ -0,0 +1,62 @@
+#include <kernel.hfa>
+#include <thread.hfa>
+
+thread_local 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/concurrent/park/force_preempt.cfa
===================================================================
--- tests/concurrent/park/force_preempt.cfa	(revision 3381ed7a703d0c964d6e94bffab7c58f0cdf0d17)
+++ tests/concurrent/park/force_preempt.cfa	(revision 3381ed7a703d0c964d6e94bffab7c58f0cdf0d17)
@@ -0,0 +1,57 @@
+#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;
+thread Waiter {};
+
+
+void park_loop(Waiter & this, int id, bool force) {
+	for(int i = 0; i < 5; i++) {
+		// Unpark this thread, don't force a yield
+		sout | id | "Calling unpark" | (force ? "(Force)" : "(No Force)") | i;
+		unpark(this, force);
+
+		// Force a preemption before the call to park
+		int prev = global;
+		while(prev == global) {}
+
+		// Park this thread,
+		sout | id | "Parking"  | (force ? "(Force)" : "(No Force)") | i;
+		park();
+		sout | id | "Unparked" | (force ? "(Force)" : "(No Force)") | i;
+	}
+}
+
+volatile int count = 0;
+
+void main(Waiter & this) {
+	// Get a unique id
+	int id = __atomic_fetch_add(&count, 1, __ATOMIC_SEQ_CST);
+
+	// First without forcing yield
+	park_loop( this, id, false );
+
+	// First with forcing yield
+	park_loop( this, id, true  );
+}
+
+int main() {
+	Poller p;
+	{
+		Waiter waiters[5];
+	}
+}
