Index: libcfa/src/bits/weakso_locks.cfa
===================================================================
--- libcfa/src/bits/weakso_locks.cfa	(revision e20eaf46ee86f55e4384db669ba550042979fa39)
+++ libcfa/src/bits/weakso_locks.cfa	(revision 22b7579d6fadb3c0f02cdb4dbfbc418a2df14457)
@@ -18,13 +18,12 @@
 #include "bits/weakso_locks.hfa"
 
-void  ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner ) {}
-void ^?{}( blocking_lock & this ) {}
+void  ?{}( blocking_lock &, bool, bool ) {}
+void ^?{}( blocking_lock & ) {}
 
-void lock( blocking_lock & this ) {}
-bool try_lock( blocking_lock & this ) { return false; }
-void unlock( blocking_lock & this ) {}
-void on_notify( blocking_lock & this, struct $thread * t ) {}
-void on_wait( blocking_lock & this ) {}
-size_t wait_count( blocking_lock & this ) { return 0; }
-void set_recursion_count( blocking_lock & this, size_t recursion ) {}
-size_t get_recursion_count( blocking_lock & this ) { return 0; }
+void lock( blocking_lock & ) {}
+bool try_lock( blocking_lock & ) { return false; }
+void unlock( blocking_lock & ) {}
+void on_notify( blocking_lock &, struct $thread * ) {}
+size_t on_wait( blocking_lock & ) {}
+void on_wakeup( blocking_lock &, size_t ) {}
+size_t wait_count( blocking_lock & ) { return 0; }
Index: libcfa/src/bits/weakso_locks.hfa
===================================================================
--- libcfa/src/bits/weakso_locks.hfa	(revision e20eaf46ee86f55e4384db669ba550042979fa39)
+++ libcfa/src/bits/weakso_locks.hfa	(revision 22b7579d6fadb3c0f02cdb4dbfbc418a2df14457)
@@ -56,8 +56,7 @@
 void unlock( blocking_lock & this ) OPTIONAL_THREAD;
 void on_notify( blocking_lock & this, struct $thread * t ) OPTIONAL_THREAD;
-void on_wait( blocking_lock & this ) OPTIONAL_THREAD;
+size_t on_wait( blocking_lock & this ) OPTIONAL_THREAD;
+void on_wakeup( blocking_lock & this, size_t ) OPTIONAL_THREAD;
 size_t wait_count( blocking_lock & this ) OPTIONAL_THREAD;
-void set_recursion_count( blocking_lock & this, size_t recursion ) OPTIONAL_THREAD;
-size_t get_recursion_count( blocking_lock & this ) OPTIONAL_THREAD;
 
 //----------
@@ -72,6 +71,5 @@
 static inline bool   try_lock ( multiple_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); }
 static inline void   unlock   ( multiple_acquisition_lock & this ) { unlock  ( (blocking_lock &)this ); }
-static inline void   on_wait  ( multiple_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); }
+static inline size_t on_wait  ( multiple_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); }
+static inline void   on_wakeup( multiple_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
 static inline void   on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }
-static inline void   set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
-static inline size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
Index: libcfa/src/concurrency/locks.cfa
===================================================================
--- libcfa/src/concurrency/locks.cfa	(revision e20eaf46ee86f55e4384db669ba550042979fa39)
+++ libcfa/src/concurrency/locks.cfa	(revision 22b7579d6fadb3c0f02cdb4dbfbc418a2df14457)
@@ -134,5 +134,6 @@
 	lock( lock __cfaabi_dbg_ctx2 );
 	/* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
-	/* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
+	/* paranoid */ verifyf( owner == active_thread() || !strict_owner , "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
+	/* paranoid */ verifyf( recursion_count == 1 || multi_acquisition, "Thread %p attempted to release owner lock %p which is not recursive but has a recursive count of %zu", active_thread(), &this, recursion_count );
 
 	// if recursion count is zero release lock and set new owner if one is waiting
@@ -146,12 +147,4 @@
 size_t wait_count( blocking_lock & this ) with( this ) {
 	return wait_count;
-}
-
-void set_recursion_count( blocking_lock & this, size_t recursion ) with( this ) {
-	recursion_count = recursion;
-}
-
-size_t get_recursion_count( blocking_lock & this ) with( this ) {
-	return recursion_count;
 }
 
@@ -173,11 +166,18 @@
 }
 
-void on_wait( blocking_lock & this ) with( this ) {
+size_t on_wait( blocking_lock & this ) with( this ) {
 	lock( lock __cfaabi_dbg_ctx2 );
 	/* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
 	/* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
 
+	size_t ret = recursion_count;
+
 	pop_and_set_new_owner( this );
 	unlock( lock );
+	return ret;
+}
+
+void on_wakeup( blocking_lock & this, size_t recursion ) with( this ) {
+	recursion_count = recursion;
 }
 
@@ -274,5 +274,10 @@
 	}
 
-	bool empty( condition_variable(L) & this ) with(this) { return empty(blocked_threads); }
+	bool empty( condition_variable(L) & this ) with(this) {
+		lock( lock __cfaabi_dbg_ctx2 );
+		bool ret = empty(blocked_threads);
+		unlock( lock );
+		return ret;
+	}
 
 	int counter( condition_variable(L) & this ) with(this) { return count; }
@@ -285,6 +290,5 @@
 		if (i->lock) {
 			// if lock was passed get recursion count to reset to after waking thread
-			recursion_count = get_recursion_count(*i->lock);
-			on_wait( *i->lock );
+			recursion_count = on_wait( *i->lock );
 		}
 		return recursion_count;
@@ -301,5 +305,5 @@
 
 		// resets recursion count here after waking
-		if (i.lock) set_recursion_count(*i.lock, recursion_count);
+		if (i.lock) on_wakeup(*i.lock, recursion_count);
 	}
 
@@ -323,5 +327,5 @@
 
 		// resets recursion count here after waking
-		if (info.lock) set_recursion_count(*info.lock, recursion_count);
+		if (info.lock) on_wakeup(*info.lock, recursion_count);
 	}
 
@@ -373,5 +377,5 @@
 }
 
-bool V(semaphore & this) with( this ) {
+$thread * V (semaphore & this, const bool doUnpark ) with( this ) {
 	$thread * thrd = 0p;
 	lock( lock __cfaabi_dbg_ctx2 );
@@ -385,6 +389,11 @@
 
 	// make new owner
-	unpark( thrd );
-
+	if( doUnpark ) unpark( thrd );
+
+	return thrd;
+}
+
+bool V(semaphore & this) with( this ) {
+	$thread * thrd = V(this, true);
 	return thrd != 0p;
 }
Index: libcfa/src/concurrency/locks.hfa
===================================================================
--- libcfa/src/concurrency/locks.hfa	(revision e20eaf46ee86f55e4384db669ba550042979fa39)
+++ libcfa/src/concurrency/locks.hfa	(revision 22b7579d6fadb3c0f02cdb4dbfbc418a2df14457)
@@ -119,5 +119,4 @@
 
 static inline bool P(ThreadBenaphore & this)              { return P(this.ben) ? false : P(this.sem); }
-static inline bool P(ThreadBenaphore & this, $thread * t) { return P(this.ben) ? false : P(this.sem, t ); }
 static inline bool tryP(ThreadBenaphore & this)           { return tryP(this.ben); }
 static inline bool P(ThreadBenaphore & this, bool wait)   { return wait ? P(this) : tryP(this); }
@@ -141,4 +140,5 @@
 bool   V (semaphore & this);
 bool   V (semaphore & this, unsigned count);
+$thread * V (semaphore & this, bool );
 
 //----------
@@ -149,11 +149,10 @@
 static inline void  ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
 static inline void ^?{}( single_acquisition_lock & this ) {}
-static inline void   lock      ( single_acquisition_lock & this ) { lock    ( (blocking_lock &)this ); }
-static inline bool   try_lock  ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); }
-static inline void   unlock    ( single_acquisition_lock & this ) { unlock  ( (blocking_lock &)this ); }
-static inline void   on_wait   ( single_acquisition_lock & this ) { on_wait ( (blocking_lock &)this ); }
-static inline void   on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
-static inline void   set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
-static inline size_t get_recursion_count( single_acquisition_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
+static inline void   lock     ( single_acquisition_lock & this ) { lock    ( (blocking_lock &)this ); }
+static inline bool   try_lock ( single_acquisition_lock & this ) { return try_lock( (blocking_lock &)this ); }
+static inline void   unlock   ( single_acquisition_lock & this ) { unlock  ( (blocking_lock &)this ); }
+static inline size_t on_wait  ( single_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); }
+static inline void   on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
+static inline void   on_notify( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
 
 //----------
@@ -167,8 +166,7 @@
 static inline bool   try_lock ( owner_lock & this ) { return try_lock( (blocking_lock &)this ); }
 static inline void   unlock   ( owner_lock & this ) { unlock  ( (blocking_lock &)this ); }
-static inline void   on_wait  ( owner_lock & this ) { on_wait ( (blocking_lock &)this ); }
+static inline size_t on_wait  ( owner_lock & this ) { return on_wait ( (blocking_lock &)this ); }
+static inline void   on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
 static inline void   on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
-static inline void   set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
-static inline size_t get_recursion_count( owner_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
 
 struct fast_lock {
@@ -182,13 +180,5 @@
 }
 
-static inline void $lock(fast_lock & this, $thread * thrd) {
-	/* paranoid */verify(thrd != this.owner);
-
-	for (;;) {
-		if ($try_lock(this, thrd)) return;
-		P(this.sem, thrd);
-	}
-}
-
+static inline void lock( fast_lock & this ) __attribute__((artificial));
 static inline void lock( fast_lock & this ) {
 	$thread * thrd = active_thread();
@@ -201,5 +191,6 @@
 }
 
-static inline void try_lock ( fast_lock & this ) {
+static inline bool try_lock( fast_lock & this ) __attribute__((artificial));
+static inline bool try_lock ( fast_lock & this ) {
 	$thread * thrd = active_thread();
 	/* paranoid */ verify(thrd != this.owner);
@@ -207,27 +198,23 @@
 }
 
-static inline void unlock( fast_lock & this ) {
+static inline $thread * unlock( fast_lock & this ) __attribute__((artificial));
+static inline $thread * unlock( fast_lock & this ) {
 	$thread * thrd = active_thread();
 	/* paranoid */ verify(thrd == this.owner);
-	$thread * next = V(this.sem, false); // implicit fence
-	// open 'owner' only after fence
+
+	// open 'owner' before unlocking anyone
+	// so new and unlocked threads don't park incorrectly.
 	this.owner = 0p;
 
-	// Unpark the next person (can be 0p, unpark handles it)
-	unpark(next);
-}
-
-static inline void on_wait( fast_lock & this ) {
-	unlock(this);
-	#warning this is broken
-}
-
-static inline void on_notify( fast_lock & this, struct $thread * t ) {
-	$lock(this, t);
-	#warning this is broken
-}
-
-static inline void   set_recursion_count( fast_lock & this, size_t recursion ) {}
-static inline size_t get_recursion_count( fast_lock & this ) { return 0; }
+	return V(this.sem,true);
+}
+
+static inline size_t on_wait( fast_lock & this ) __attribute__((artificial));
+static inline void on_wakeup( fast_lock & this, size_t ) __attribute__((artificial));
+static inline void on_notify( fast_lock &, struct $thread * t ) __attribute__((artificial));
+
+static inline size_t on_wait( fast_lock & this ) { unlock(this); return 0; }
+static inline void on_wakeup( fast_lock & this, size_t ) { lock(this); }
+static inline void on_notify( fast_lock &, struct $thread * t ) { unpark(t); }
 
 struct mcs_node {
@@ -263,11 +250,8 @@
 
 	// For synchronization locks to use when releasing
-	void on_wait( L & );
-
-	// to get recursion count for cond lock to reset after waking
-	size_t get_recursion_count( L & );
+	size_t on_wait( L & );
 
 	// to set recursion count after getting signalled;
-	void set_recursion_count( L &, size_t recursion );
+	void on_wakeup( L &, size_t recursion );
 };
 
