Index: benchmark/rmit.py
===================================================================
--- benchmark/rmit.py	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ benchmark/rmit.py	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -12,4 +12,5 @@
 import datetime
 import itertools
+import json
 import os
 import random
@@ -117,8 +118,8 @@
 	# ================================================================================
 	# parse command line arguments
-	formats = ['raw', 'csv']
+	formats = ['raw', 'csv', 'json']
 	parser = argparse.ArgumentParser(description='Python Script to implement R.M.I.T. testing : Randomized Multiple Interleaved Trials')
 	parser.add_argument('--list', help='List all the commands that would be run', action='store_true')
-	parser.add_argument('--format', help='How to print the result', choices=formats, default='csv')
+	parser.add_argument('--format', help='How to print the result', choices=formats, default='json')
 	parser.add_argument('--file', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
 	parser.add_argument('-t', '--trials', help='Number of trials to run per combinaison', type=int, default=3)
@@ -203,8 +204,14 @@
 
 	# ================================================================================
-	# Print csv
+	# Print raw
 	if options.format == 'raw':
 		for r in result:
 			print(r, file=options.file)
+		sys.exit(0)
+
+	# ================================================================================
+	# Print json
+	if options.format == 'json':
+		json.dump(result, options.file)
 		sys.exit(0)
 
Index: doc/theses/andrew_beach_MMath/features.tex
===================================================================
--- doc/theses/andrew_beach_MMath/features.tex	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
+++ doc/theses/andrew_beach_MMath/features.tex	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -0,0 +1,307 @@
+\chapter{Features}
+
+This chapter covers the design and user interface of the \CFA exception
+handling mechanism.
+
+\section{Virtual Casts}
+
+Virtual casts and virtual types are not truly part of the exception system but
+they did not exist in \CFA and are useful in exceptions. So a minimal version
+of they virtual system was designed and implemented.
+
+Virtual types are organizied in simple hierarchies. Each virtual type may have
+a parent and can have any number of children. A type's descendants are its
+children and its children's descendants. A type may not be its own descendant.
+
+Each virtual type has an associated virtual table type. A virtual table is a
+structure that has fields for all the virtual members of a type. A virtual
+type has all the virtual members of its parent and can add more. It may also
+update the values of the virtual members.
+
+Except for virtual casts, this is only used internally in the exception
+system. There is no general purpose interface for the other features. A
+a virtual cast has the following syntax:
+
+\begin{lstlisting}
+(virtual TYPE)EXPRESSION
+\end{lstlisting}
+
+This has the same precidence as a traditional C-cast and can be used in the
+same places. This will convert the result of EXPRESSION to the type TYPE. Both
+the type of EXPRESSION and TYPE must be pointers to virtual types.
+
+The cast is checked and will either return the original value or null, based
+on the result of the check. The check is does the object pointed at have a
+type that is a descendant of the target type. If it is the result is the
+pointer, otherwise the result is null.
+
+\section{Exceptions}
+% Leaving until later, hopefully it can talk about actual syntax instead
+% of my many strange macros. Syntax aside I will also have to talk about the
+% features all exceptions support.
+
+\section{Termination}
+
+Termination exception throws are likely the most framilar kind, as they are
+used in several popular programming languages. A termination will throw an
+exception, search the stack for a handler, unwind the stack to where the
+handler is defined, execute the handler and then continue execution after
+the handler. They are used when execution cannot continue here.
+
+Termination has two pieces of syntax it uses. The first is the throw:
+\begin{lstlisting}
+throw EXPRESSION;
+\end{lstlisting}
+
+The expression must evaluate to a reference to a termination exception. A
+termination exception is any exception with a
+\codeCFA{void defaultTerminationHandler(T &);} (the default handler) defined
+on it. The handler is taken from the call sight with \CFA's trait system and
+passed into the exception system along with the exception itself.
+
+The exception passed into the system is then copied into managed memory.
+This is to ensure it remains in scope during unwinding. It is the user's
+responsibility to make sure the original exception is freed when it goes out
+of scope. Being allocated on the stack is sufficient for this.
+
+Then the exception system will search the stack starting from the throw and
+proceding towards the base of the stack, from callee to caller. As it goes
+it will check any termination handlers it finds:
+
+\begin{lstlisting}
+try {
+    TRY_BLOCK
+} catch (EXCEPTION_TYPE * NAME) {
+    HANDLER
+}
+\end{lstlisting}
+
+This shows a try statement with a single termination handler. The statements
+in TRY\_BLOCK will be executed when control reaches this statement. While
+those statements are being executed if a termination exception is thrown and
+it is not handled by a try statement further up the stack the EHM will check
+all of the terminations handlers attached to the try block, top to bottom.
+
+At each handler the EHM will check to see if the thrown exception is a
+descendant of EXCEPTION\_TYPE. If it is the pointer to the exception is
+bound to NAME and the statements in HANDLER are executed. If control reaches
+the end of the handler then it exits the block, the exception is freed and
+control continues after the try statement.
+
+The default handler is only used if no handler for the exception is found
+after the entire stack is searched. When that happens the default handler
+is called with a reference to the exception as its only argument. If the
+handler returns control continues from after the throw statement.
+
+\paragraph{Conditional Catches}
+
+Catch clauses may also be written as:
+\begin{lstlisting}
+catch (EXCEPTION_TYPE * NAME ; CONDITION)
+\end{lstlisting}
+This has the same behaviour as a regular catch clause except that if the
+exception matches the given type the condition is also run. If the result is
+true only then is this considered a matching handler. If the result is false
+then the handler does not match and the search continues with the next clause
+in the try block.
+
+The condition considers all names in scope at the beginning of the try block
+to be in scope along with the name introduce in the catch clause itself.
+
+\paragraph{Re-Throwing}
+
+You can also rethrow the most recent termination exception with
+\codeCFA{throw;}. % This is terrible and you should never do it.
+This can be done in a handler or any function that could be called from a
+handler.
+
+This will start another termination throw reusing the exception, meaning it
+does not copy the exception or allocated any more memory for it. However the
+default handler is still at the original through and could refer to data that
+was on the unwound section of the stack. So instead a new default handler that
+does a program level abort is used.
+
+\section{Resumption}
+
+Resumption exceptions are less popular then termination but in many
+regards are simpler and easier to understand. A resumption throws an exception,
+searches for a handler on the stack, executes that handler on top of the stack
+and then continues execution from the throw. These are used when a problem
+needs to be fixed before execution continues.
+
+A resumption is thrown with a throw resume statement:
+\begin{lstlisting}
+throwResume EXPRESSION;
+\end{lstlisting}
+The result of EXPRESSION must be a resumption exception type. A resumption
+exception type is any type that satifies the assertion
+\codeCFA{void defaultResumptionHandler(T &);} (the default handler). When the
+statement is executed the expression is evaluated and the result is thrown.
+
+Handlers are declared using clauses in try statements:
+\begin{lstlisting}
+try {
+    TRY_BLOCK
+} catchResume (EXCEPTION_TYPE * NAME) {
+    HANDLER
+}
+\end{lstlisting}
+This is a simple example with the try block and a single resumption handler.
+Multiple resumption handlers can be put in a try statement and they can be
+mixed with termination handlers.
+
+When a resumption begins it will start searching the stack starting from
+the throw statement and working its way to the callers. In each try statement
+handlers will be tried top to bottom. Each handler is checked by seeing if
+the thrown exception is a descendant of EXCEPTION\_TYPE. If not the search
+continues. Otherwise NAME is bound to a pointer to the exception and the
+HANDLER statements are executed. After they are finished executing control
+continues from the throw statement.
+
+If no approprate handler is found then the default handler is called. The
+throw statement acts as a regular function call passing the exception to
+the default handler and after the handler finishes executing control continues
+from the throw statement.
+
+The exception system also tracks the position of a search on the stack. If
+another resumption exception is thrown while a resumption handler is running
+it will first check handlers pushed to the stack by the handler and any
+functions it called, then it will continue from the try statement that the
+handler is a part of; except for the default handler where it continues from
+the throw the default handler was passed to.
+
+This makes the search pattern for resumption reflect the one for termination,
+which is what most users expect.
+
+% This might need a diagram. But it is an important part of the justifaction
+% of the design of the traversal order.
+It also avoids the recursive resumption problem. If the entire stack is
+searched loops of resumption can form. Consider a handler that handles an
+exception of type A by resuming an exception of type B and on the same stack,
+later in the search path, is a second handler that handles B by resuming A.
+
+Assuming no other handlers on the stack handle A or B then in either traversal
+system an A resumed from the top of the stack will be handled by the first
+handler. A B resumed from the top or from the first handler it will be handled
+by the second hander. The only difference is when A is thrown from the second
+handler. The entire stack search will call the first handler again, creating a
+loop. Starting from the position in the stack though will break this loop.
+
+\paragraph{Conditional Catches}
+
+Resumption supports conditional catch clauses like termination does. They
+use the same syntax except the keyword is changed:
+\begin{lstlisting}
+catchResume (EXCEPTION_TYPE * NAME ; CONDITION)  
+\end{lstlisting}
+
+It also has the same behaviour, after the exception type has been matched
+with the EXCEPTION\_TYPE the CONDITION is evaluated with NAME in scope. If
+the result is true then the hander is run, otherwise the search continues
+just as if there had been a type mismatch.
+
+\paragraph{Re-Throwing}
+
+You may also re-throw resumptions with a \codeCFA{throwResume;} statement.
+This can only be done from inside of a \codeCFA{catchResume} block.
+
+Outside of any side effects of any code already run in the handler this will
+have the same effect as if the exception had not been caught in the first
+place.
+
+\section{Finally Clauses}
+
+A \codeCFA{finally} clause may be placed at the end of a try statement after
+all the handler clauses. In the simply case, with no handlers, it looks like
+this:
+
+\begin{lstlisting}
+try {
+    TRY_BLOCK
+} finally {
+    FINAL_STATEMENTS
+}
+\end{lstlisting}
+
+Any number of termination handlers and resumption handlers may proceed the
+finally clause.
+
+The FINAL\_STATEMENTS, the finally block, are executed whenever the try
+statement is removed from the stack. This includes: the TRY\_BLOCK finishes
+executing, a termination exception finishes executing and the stack unwinds.
+
+Execution of the finally block should finish by letting control run off
+the end of the block. This is because after the finally block is complete
+control will continue to where ever it would if the finally clause was not
+present.
+
+Because of this local control flow out of the finally block is forbidden.
+The compiler rejects uses of \codeCFA{break}, \codeCFA{continue},
+\codeCFA{fallthru} and \codeCFA{return} that would cause control to leave
+the finally block. Other ways to leave the finally block - such as a long
+jump or termination - are much harder to check, at best requiring additional
+runtime overhead, and so are merely discouraged.
+
+\section{Cancellation}
+
+Cancellation can be thought of as a stack-level abort or as an uncatchable
+termination. It unwinds the entirety of the current exception and if possible
+passes an exception to a different stack as a message.
+
+There is no special statement for starting a cancellation, instead you call
+the standard libary function \codeCFA{cancel\_stack} which takes an exception.
+Unlike in a throw this exception is not used in control flow but is just there
+to pass information about why the cancellation happened.
+
+The handler is decided entirely by which stack is being cancelled. There are
+three handlers that apply to three different groups of stacks:
+\begin{itemize}
+\item Main Stack:
+The main stack is the one on which the program main is called at the beginning
+of your program. It is also the only stack you have without the libcfathreads.
+
+Because of this there is no other stack ``above" (or possibly at all) for main
+to notify when a cancellation occurs. So after the stack is unwound we do a
+program level abort.
+
+\item Thread Stack:
+Thread stacks are those created \codeCFA{thread} or otherwise satify the
+\codeCFA{is\_thread} trait.
+
+Threads only have two structural points of communication that must happen,
+start and join. As the thread must be running to preform a cancellation it
+will be after start and before join, so join is one cancellation uses.
+
+After the stack is unwound the thread will halt as if had completed normally
+and wait for another thread to join with it. The other thread, when it joins,
+checks for a cancellation. If so it will throw the resumption exception
+\codeCFA{ThreadCancelled}.
+
+There is a difference here in how explicate joins (with the \codeCFA{join}
+function) and implicate joins (from a destructor call). Explicate joins will
+take the default handler (\codeCFA{defaultResumptionHandler}) from the context
+and use like a regular through does if the exception is not caught. The
+implicate join does a program abort instead.
+
+This is for safety. One of the big problems in exceptions is you cannot handle
+two terminations or cancellations on the same stack as either can destroy the
+context required for the other. This can happen with join but as the
+destructors will always be run when the stack is being unwound and one
+termination/cancellation is already active. Also since they are implicite they
+are easier to forget about.
+
+\item Coroutine Stack:
+Coroutine stacks are those created with \codeCFA{coroutine} or otherwise
+satify the \codeCFA{is\_coroutine} trait.
+
+A coroutine knows of two other coroutines, its starter and its last resumer.
+The last resumer is ``closer" so that is the one notified.
+
+After the stack is unwound control goes to the last resumer.
+Resume will resume throw a \codeCFA{CoroutineCancelled} exception, which is
+polymorphic over the coroutine type and has a pointer to the coroutine being
+cancelled and the cancelling exception. The resume function also has an
+assertion that the \codeCFA{defaultResumptionHandler} for the exception. So it
+will use the default handler like a regular throw.
+
+\end{itemize}
Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ libcfa/src/Makefile.am	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -96,4 +96,5 @@
 	concurrency/exception.hfa \
 	concurrency/kernel.hfa \
+	concurrency/locks.hfa \
 	concurrency/monitor.hfa \
 	concurrency/mutex.hfa \
Index: libcfa/src/concurrency/locks.cfa
===================================================================
--- libcfa/src/concurrency/locks.cfa	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ libcfa/src/concurrency/locks.cfa	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -51,9 +51,9 @@
 }
 
-void ?{}( mutex_lock & this ) {
+void ?{}( single_acquisition_lock & this ) {
 	((blocking_lock &)this){ false, false };
 }
 
-void ^?{}( mutex_lock & this ) {
+void ^?{}( single_acquisition_lock & this ) {
 	// default
 }
@@ -67,28 +67,27 @@
 }
 
-void ?{}( recursive_mutex_lock & this ) {
+void ?{}( multiple_acquisition_lock & this ) {
 	((blocking_lock &)this){ true, false };
 }
 
-void ^?{}( recursive_mutex_lock & this ) {
+void ^?{}( multiple_acquisition_lock & this ) {
 	// default
 }
 
 void lock( blocking_lock & this ) with( this ) {
-	$thread * thrd = active_thread();
 	lock( lock __cfaabi_dbg_ctx2 );
-	if ( owner == thrd && !multi_acquisition) {
+	if ( owner == active_thread() && !multi_acquisition) {
 		fprintf(stderr, "A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); // Possibly throw instead
     	exit(EXIT_FAILURE);
-	} else if ( owner != 0p && owner != thrd ) {
-		append( blocked_threads, thrd );
+	} else if ( owner != 0p && owner != active_thread() ) {
+		append( blocked_threads, active_thread() );
 		wait_count++;
 		unlock( lock );
 		park( );
-	} else if ( owner == thrd && multi_acquisition ) {
+	} else if ( owner == active_thread() && multi_acquisition ) {
 		recursion_count++;
 		unlock( lock );
 	} else {
-		owner = thrd;
+		owner = active_thread();
 		recursion_count = 1;
 		unlock( lock );
@@ -97,12 +96,11 @@
 
 bool try_lock( blocking_lock & this ) with( this ) {
-	$thread * thrd = active_thread();
 	bool ret = false;
 	lock( lock __cfaabi_dbg_ctx2 );
 	if ( owner == 0p ) {
-		owner = thrd;
-		if ( multi_acquisition ) recursion_count = 1;
+		owner = active_thread();
+		recursion_count = 1;
 		ret = true;
-	} else if ( owner == thrd && multi_acquisition ) {
+	} else if ( owner == active_thread() && multi_acquisition ) {
 		recursion_count++;
 		ret = true;
@@ -115,8 +113,8 @@
 	lock( lock __cfaabi_dbg_ctx2 );
 	if ( owner == 0p ){ // no owner implies lock isn't held
-		fprintf( stderr, "There was an attempt to release a lock that isn't held" );
+		fprintf( stderr, "There was an attempt to release a lock that isn't held" ); 
 		return;
-	} else if ( strict_owner && active_thread() ) {
-		fprintf( stderr, "A thread other than the owner attempted to release an owner lock" );
+	} else if ( strict_owner && owner != active_thread() ) {
+		fprintf( stderr, "A thread other than the owner attempted to release an owner lock" ); 
 		return;
 	}
@@ -125,5 +123,5 @@
 		$thread * thrd = pop_head( blocked_threads );
 		owner = thrd;
-		recursion_count = ( thrd && multi_acquisition ? 1 : 0 );
+		recursion_count = ( thrd ? 1 : 0 );
 		wait_count--;
 		unpark( thrd );
@@ -153,7 +151,7 @@
 	} else {
 		owner = t;
-		if ( multi_acquisition ) recursion_count = 1;
+		recursion_count = 1;
 		#if !defined( __CFA_NO_STATISTICS__ )
-			kernelTLS.this_stats = t->curr_cluster->stats;
+			//kernelTLS.this_stats = t->curr_cluster->stats;
 		#endif
 		unpark( t );
@@ -165,11 +163,11 @@
     lock( lock __cfaabi_dbg_ctx2 );
 	if ( owner == 0p ){ // no owner implies lock isn't held
-		fprintf( stderr, "A lock that is not held was passed to a synchronization lock" );
-	} else if ( strict_owner && active_thread() ) {
-		fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" );
+		fprintf( stderr, "A lock that is not held was passed to a synchronization lock" ); 
+	} else if ( strict_owner && owner != active_thread() ) {
+		fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" ); 
 	} else {
 		$thread * thrd = pop_head( blocked_threads );
 		owner = thrd;
-		recursion_count = ( thrd && multi_acquisition ? 1 : 0 );
+		recursion_count = ( thrd ? 1 : 0 );
 		wait_count--;
 		unpark( thrd );
@@ -184,50 +182,74 @@
 // This is temporary until an inheritance bug is fixed
 
-void lock( mutex_lock & this ){
+void lock( single_acquisition_lock & this ){
 	lock( (blocking_lock &)this );
 }
 
-void unlock( mutex_lock & this ){
+void unlock( single_acquisition_lock & this ){
 	unlock( (blocking_lock &)this );
 }
 
-void add_( mutex_lock & this, struct $thread * t ){
+void add_( single_acquisition_lock & this, struct $thread * t ){
 	add_( (blocking_lock &)this, t );
 }
 
-void remove_( mutex_lock & this ){
+void remove_( single_acquisition_lock & this ){
 	remove_( (blocking_lock &)this );
 }
 
-void set_recursion_count( mutex_lock & this, size_t recursion ){
+void set_recursion_count( single_acquisition_lock & this, size_t recursion ){
 	set_recursion_count( (blocking_lock &)this, recursion );
 }
 
-size_t get_recursion_count( mutex_lock & this ){
-	get_recursion_count( (blocking_lock &)this );
-}
-
-void lock( recursive_mutex_lock & this ){
+size_t get_recursion_count( single_acquisition_lock & this ){
+	return get_recursion_count( (blocking_lock &)this );
+}
+
+void lock( owner_lock & this ){
 	lock( (blocking_lock &)this );
 }
 
-void unlock( recursive_mutex_lock & this ){
+void unlock( owner_lock & this ){
 	unlock( (blocking_lock &)this );
 }
 
-void add_( recursive_mutex_lock & this, struct $thread * t ){
+void add_( owner_lock & this, struct $thread * t ){
 	add_( (blocking_lock &)this, t );
 }
 
-void remove_( recursive_mutex_lock & this ){
+void remove_( owner_lock & this ){
 	remove_( (blocking_lock &)this );
 }
 
-void set_recursion_count( recursive_mutex_lock & this, size_t recursion ){
+void set_recursion_count( owner_lock & this, size_t recursion ){
 	set_recursion_count( (blocking_lock &)this, recursion );
 }
 
-size_t get_recursion_count( recursive_mutex_lock & this ){
-	get_recursion_count( (blocking_lock &)this );
+size_t get_recursion_count( owner_lock & this ){
+	return get_recursion_count( (blocking_lock &)this );
+}
+
+void lock( multiple_acquisition_lock & this ){
+	lock( (blocking_lock &)this );
+}
+
+void unlock( multiple_acquisition_lock & this ){
+	unlock( (blocking_lock &)this );
+}
+
+void add_( multiple_acquisition_lock & this, struct $thread * t ){
+	add_( (blocking_lock &)this, t );
+}
+
+void remove_( multiple_acquisition_lock & this ){
+	remove_( (blocking_lock &)this );
+}
+
+void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){
+	set_recursion_count( (blocking_lock &)this, recursion );
+}
+
+size_t get_recursion_count( multiple_acquisition_lock & this ){
+	return get_recursion_count( (blocking_lock &)this );
 }
 
@@ -244,10 +266,8 @@
 	    	info_thread(L) * copy = *i;
 			remove( cond->blocked_threads, i );		 //remove this thread O(1)
-			cond->wait_count--;
+			cond->count--;
 			if( !copy->lock ) {
-				unlock( cond->lock );
 				#if !defined( __CFA_NO_STATISTICS__ )
-					#warning unprotected access to tls TODO discuss this
-					kernelTLS.this_stats = copy->t->curr_cluster->stats;
+					//kernelTLS.this_stats = copy->t->curr_cluster->stats;
 				#endif
 				unpark( copy->t );
@@ -285,6 +305,6 @@
 		bool ret = !!blocked_threads;
 		info_thread(L) * popped = pop_head( blocked_threads );
-		popped->listed = false;
 		if(popped != 0p) {
+			popped->listed = false;
 			count--;
 			if (popped->lock) {
@@ -303,6 +323,6 @@
 		while( blocked_threads ) {
 			info_thread(L) * popped = pop_head( blocked_threads );
-			popped->listed = false;
 			if(popped != 0p){
+				popped->listed = false;
 				count--;
 				if (popped->lock) {
@@ -341,5 +361,5 @@
 			remove_( *i.lock );
 		}
-
+		
 		unlock( lock );
 		park( ); // blocks here
@@ -385,5 +405,5 @@
 		queue_info_thread( this, i );
 	}
-
+	
 	void wait( condition_variable(L) & this, Duration duration ) with(this) {
 		info_thread( L ) i = { active_thread() };
@@ -391,5 +411,5 @@
 	}
 
-	void wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) {
+	void wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) { 
 		info_thread( L ) i = { active_thread(), info };
 		queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
@@ -417,5 +437,5 @@
 		queue_info_thread( this, i );
 	}
-
+	
 	void wait( condition_variable(L) & this, L & l, Duration duration ) with(this) {
 		info_thread(L) i = { active_thread() };
@@ -423,5 +443,5 @@
 		queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
 	}
-
+	
 	void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) {
 		info_thread(L) i = { active_thread(), info };
@@ -429,5 +449,5 @@
 		queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
 	}
-
+	
 	void wait( condition_variable(L) & this, L & l, Time time ) with(this) {
 		info_thread(L) i = { active_thread() };
@@ -435,5 +455,5 @@
 		queue_info_thread_timeout(this, i, time );
 	}
-
+	
 	void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) {
 		info_thread(L) i = { active_thread(), info };
@@ -442,2 +462,54 @@
 	}
 }
+
+// thread T1 {};
+// thread T2 {};
+
+// multiple_acquisition_lock m;
+// condition_variable( multiple_acquisition_lock ) c;
+
+// void main( T1 & this ) {
+// 	printf("T1 start\n");
+// 	lock(m);
+// 	printf("%d\n", counter(c));
+// 	if(empty(c)) {
+// 		printf("T1 wait\n");
+// 		wait(c,m,12);
+// 	}else{
+// 		printf("%d\n", front(c));
+// 		notify_one(c);
+// 	}
+// 	unlock(m);
+// 	printf("curr thd in main %p \n", active_thread());
+// 	printf("T1 waits for 2s\n");
+// 	lock(m);
+// 	wait( c, m, 2`s );
+// 	unlock(m);
+// 	printf("T1 wakes\n");
+// 	printf("T1 done\n");
+// }
+
+// void main( T2 & this ) {
+// 	printf("T2 start\n");
+// 	lock(m);
+// 	printf("%d\n", counter(c));
+// 	if(empty(c)) {
+// 		printf("T2 wait\n");
+// 		wait(c,m,12);
+// 	}else{
+// 		printf("%d\n", front(c));
+// 		notify_one(c);
+// 	}
+// 	unlock(m);
+// 	printf("T2 done\n");
+// }
+
+// int main() {
+// 	printf("start\n");
+// 	processor p[2];
+// 	{
+// 		T1 t1;
+// 		T2 t2;
+// 	}
+// 	printf("done\n");
+// }
Index: libcfa/src/concurrency/locks.hfa
===================================================================
--- libcfa/src/concurrency/locks.hfa	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ libcfa/src/concurrency/locks.hfa	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -49,4 +49,5 @@
 //// Blocking Locks
 ///////////////////////////////////////////////////////////////////
+
 struct blocking_lock {
 	// Spin lock used for mutual exclusion
@@ -72,5 +73,5 @@
 };
 
-struct mutex_lock {
+struct single_acquisition_lock {
 	inline blocking_lock;
 };
@@ -80,5 +81,5 @@
 };
 
-struct recursive_mutex_lock {
+struct multiple_acquisition_lock {
 	inline blocking_lock;
 };
@@ -87,12 +88,12 @@
 void ^?{}( blocking_lock & this );
 
-void ?{}( mutex_lock & this );
-void ^?{}( mutex_lock & this );
+void ?{}( single_acquisition_lock & this );
+void ^?{}( single_acquisition_lock & this );
 
 void ?{}( owner_lock & this );
 void ^?{}( owner_lock & this );
 
-void ?{}( recursive_mutex_lock & this );
-void ^?{}( recursive_mutex_lock & this );
+void ?{}( multiple_acquisition_lock & this );
+void ^?{}( multiple_acquisition_lock & this );
 
 void lock( blocking_lock & this );
@@ -105,17 +106,24 @@
 size_t get_recursion_count( blocking_lock & this );
 
-void lock( mutex_lock & this );
-void unlock( mutex_lock & this );
-void add_( mutex_lock & this, struct $thread * t );
-void remove_( mutex_lock & this );
-void set_recursion_count( mutex_lock & this, size_t recursion );
-size_t get_recursion_count( mutex_lock & this );
+void lock( single_acquisition_lock & this );
+void unlock( single_acquisition_lock & this );
+void add_( single_acquisition_lock & this, struct $thread * t );
+void remove_( single_acquisition_lock & this );
+void set_recursion_count( single_acquisition_lock & this, size_t recursion );
+size_t get_recursion_count( single_acquisition_lock & this );
 
-void lock( recursive_mutex_lock & this );
-void unlock( recursive_mutex_lock & this );
-void add_( recursive_mutex_lock & this, struct $thread * t );
-void remove_( recursive_mutex_lock & this );
-void set_recursion_count( recursive_mutex_lock & this, size_t recursion );
-size_t get_recursion_count( recursive_mutex_lock & this );
+void lock( owner_lock & this );
+void unlock( owner_lock & this );
+void add_( owner_lock & this, struct $thread * t );
+void remove_( owner_lock & this );
+void set_recursion_count( owner_lock & this, size_t recursion );
+size_t get_recursion_count( owner_lock & this );
+
+void lock( multiple_acquisition_lock & this );
+void unlock( multiple_acquisition_lock & this );
+void add_( multiple_acquisition_lock & this, struct $thread * t );
+void remove_( multiple_acquisition_lock & this );
+void set_recursion_count( multiple_acquisition_lock & this, size_t recursion );
+size_t get_recursion_count( multiple_acquisition_lock & this );
 
 ///////////////////////////////////////////////////////////////////
Index: libcfa/src/stdlib.cfa
===================================================================
--- libcfa/src/stdlib.cfa	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ libcfa/src/stdlib.cfa	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jan 28 17:10:29 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Jul 19 15:05:28 2020
-// Update Count     : 501
+// Last Modified On : Thu Nov 12 07:46:09 2020
+// Update Count     : 503
 //
 
@@ -26,28 +26,8 @@
 //---------------------------------------
 
-// allocation/deallocation and constructor/destructor, non-array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
-T * new( Params p ) {
-	return &(*malloc()){ p };							// run constructor
-} // new
-
-forall( dtype T | { void ^?{}( T & ); } )
-void delete( T * ptr ) {
-	if ( ptr ) {										// ignore null
-		^(*ptr){};										// run destructor
-		free( ptr );
-	} // if
-} // delete
-
-forall( dtype T, ttype Params | { void ^?{}( T & ); void delete( Params ); } )
-void delete( T * ptr, Params rest ) {
-	delete( ptr );
-	delete( rest );
-} // delete
-
-
-// allocation/deallocation and constructor/destructor, array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
-T * anew( size_t dim, Params p ) {
+// Cforall allocation/deallocation and constructor/destructor, array types
+
+forall( dtype T | sized(T), ttype TT | { void ?{}( T &, TT ); } )
+T * anew( size_t dim, TT p ) {
 	T * arr = alloc( dim );
 	for ( unsigned int i = 0; i < dim; i += 1 ) {
@@ -68,6 +48,6 @@
 } // adelete
 
-forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } )
-void adelete( T arr[], Params rest ) {
+forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype TT | { void adelete( TT ); } )
+void adelete( T arr[], TT rest ) {
 	if ( arr ) {										// ignore null
 		size_t dim = malloc_size( arr ) / sizeof( T );
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ libcfa/src/stdlib.hfa	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -10,12 +10,12 @@
 // Created On       : Thu Jan 28 17:12:35 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Sep  1 20:32:34 2020
-// Update Count     : 505
+// Last Modified On : Thu Nov 12 08:12:08 2020
+// Update Count     : 515
 //
 
 #pragma once
 
-#include "bits/defs.hfa"
-#include "bits/align.hfa"
+#include "bits/defs.hfa"								// OPTIONAL_THREAD
+#include "bits/align.hfa"								// libAlign
 
 #include <stdlib.h>										// *alloc, strto*, ato*
@@ -107,19 +107,4 @@
 } // distribution
 
-static inline forall( ttype TT | { void free( TT ); } ) {
-	// T* does not take void* and vice-versa
-
-	void free( void * addr, TT rest ) {
-		free( addr );
-		free( rest );
-	} // free
-
-	forall( dtype T | sized(T) )
-	void free( T * addr, TT rest ) {
-		free( addr );
-		free( rest );
-	} // free
-} // distribution
-
 /*
 	FIX ME : fix alloc interface after Ticker Number 214 is resolved, define and add union to S_fill. Then, modify postfix-fill functions to support T * with nmemb, char, and T object of any size. Finally, change alloc_internal.
@@ -129,5 +114,5 @@
 		forall( dtype T | sized(T) ) {
 			union  U_fill 		{ char c; T * a; T t; };
-			struct S_fill 		{ char tag; char c; size_t size; T * at; char t[50]; };
+			struct S_fill 		{ char tag; U_fill(T) fill; };
 			struct S_realloc	{ inline T *; };
 		}
@@ -177,6 +162,6 @@
 static inline T_align 	?`align   ( size_t a ) 	{ return (T_align){a}; }
 static inline T_resize 	?`resize  ( void * a )	{ return (T_resize){a}; }
+
 static inline forall( dtype T | sized(T) ) {
-
 	S_fill(T) ?`fill ( T t ) {
 		S_fill(T) ret = { 't' };
@@ -250,5 +235,4 @@
 
 	} // distribution TT
-
 } // distribution T
 
@@ -262,7 +246,5 @@
 		return (T *)memcpy( dest, src, sizeof(T) );
 	} // memcpy
-} // distribution
-
-static inline forall( dtype T | sized(T) ) {
+
 	// Cforall safe initialization/copy, i.e., implicit size specification, array types
 	T * amemset( T dest[], char fill, size_t dim ) {
@@ -275,13 +257,35 @@
 } // distribution
 
+// Cforall deallocation for multiple objects
+static inline forall( dtype T, ttype TT | { void free( TT ); } )
+void free( T * addr, TT rest ) {
+	free( addr );
+	free( rest );
+} // free
+
 // Cforall allocation/deallocation and constructor/destructor, non-array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );
-forall( dtype T | { void ^?{}( T & ); } ) void delete( T * ptr );
-forall( dtype T, ttype Params | { void ^?{}( T & ); void delete( Params ); } ) void delete( T * ptr, Params rest );
+static inline forall( dtype T | sized(T), ttype TT | { void ?{}( T &, TT ); } )
+T * new( TT p ) {
+	return &(*malloc()){ p };							// run constructor
+} // new
+
+static inline forall( dtype T | { void ^?{}( T & ); } )
+void delete( T * ptr ) {
+	if ( ptr ) {										// ignore null
+		^(*ptr){};										// run destructor
+		free( ptr );
+	} // if
+} // delete
+
+static inline forall( dtype T, ttype TT | { void ^?{}( T & ); void delete( TT ); } )
+void delete( T * ptr, TT rest ) {
+	delete( ptr );
+	delete( rest );
+} // delete
 
 // Cforall allocation/deallocation and constructor/destructor, array types
-forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );
+forall( dtype T | sized(T), ttype TT | { void ?{}( T &, TT ); } ) T * anew( size_t dim, TT p );
 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( T arr[] );
-forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } ) void adelete( T arr[], Params rest );
+forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype TT | { void adelete( TT ); } ) void adelete( T arr[], TT rest );
 
 //---------------------------------------
@@ -379,5 +383,5 @@
 //---------------------------------------
 
-extern bool threading_enabled(void) OPTIONAL_THREAD;
+extern bool threading_enabled( void ) OPTIONAL_THREAD;
 
 // Local Variables: //
Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ src/AST/Convert.cpp	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -9,7 +9,7 @@
 // Author           : Thierry Delisle
 // Created On       : Thu May 09 15::37::05 2019
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Dec 11 21:39:32 2019
-// Update Count     : 33
+// Last Modified By : Andrew Beach
+// Last Modified On : Thr Nov 12 10:07:00 2020
+// Update Count     : 34
 //
 
@@ -187,5 +187,5 @@
 		auto init = get<Initializer>().accept1( node->init );
 		decl->init = init;
-		
+
 		this->node = decl;
 		return nullptr;
@@ -2812,4 +2812,11 @@
 	}
 	deleteAll(translationUnit);
+
+	// Load the local static varables into the global store.
+	unit.global.sizeType = ast::sizeType;
+	unit.global.dereference = ast::dereferenceOperator;
+	unit.global.dtorStruct = ast::dtorStruct;
+	unit.global.dtorDestroy = ast::dtorStructDestroy;
+
 	return unit;
 }
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ src/AST/Pass.impl.hpp	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -423,5 +423,5 @@
 		}
 		catch( SemanticErrorException &e ) {
-			if (__pass::onError (visitor.core, *i, 0))
+			if (__pass::on_error (visitor.core, *i, 0))
 				errors.append( e );
 		}
Index: src/AST/Pass.proto.hpp
===================================================================
--- src/AST/Pass.proto.hpp	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ src/AST/Pass.proto.hpp	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -270,9 +270,9 @@
 
 	template< typename core_t >
-	static bool onError (core_t &, ptr<Decl> &, long) { return true; }
-
-	template< typename core_t >
-	static auto onError (core_t & core, ptr<Decl> & decl, int) -> decltype(core.onError(decl)) {
-		return core.onError(decl); 
+	static bool on_error (core_t &, ptr<Decl> &, long) { return true; }
+
+	template< typename core_t >
+	static auto on_error (core_t & core, ptr<Decl> & decl, int) -> decltype(core.on_error(decl)) {
+		return core.on_error(decl); 
 	}
 
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ src/InitTweak/GenInit.cc	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -202,8 +202,7 @@
 			}
 			// don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
-			// xxx - hoisting has no side effects anyways, so don't skip since we delay resolve	
-			// only skip in the most trivial case, which does not require resolve
-			if (dynamic_cast<ConstantExpr *>(arrayType->dimension)) return;
-			// if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
+			// xxx - hoisting has no side effects anyways, so don't skip since we delay resolve
+			// still try to detect constant expressions
+			if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
 
 			ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ src/ResolvExpr/Resolver.cc	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -1289,5 +1289,5 @@
 		void beginScope() { managedTypes.beginScope(); }
 		void endScope() { managedTypes.endScope(); }
-		bool onError(ast::ptr<ast::Decl> & decl);
+		bool on_error(ast::ptr<ast::Decl> & decl);
 	};
 	// size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver");
@@ -2068,5 +2068,5 @@
 
 	// suppress error on autogen functions and mark invalid autogen as deleted.
-	bool Resolver_new::onError(ast::ptr<ast::Decl> & decl) {
+	bool Resolver_new::on_error(ast::ptr<ast::Decl> & decl) {
 		if (auto functionDecl = decl.as<ast::FunctionDecl>()) {
 			// xxx - can intrinsic gen ever fail?
Index: src/main.cc
===================================================================
--- src/main.cc	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ src/main.cc	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -341,4 +341,8 @@
 
 		if( useNewAST) {
+			if (Stats::Counters::enabled) {
+				ast::pass_visitor_stats.avg = Stats::Counters::build<Stats::Counters::AverageCounter<double>>("Average Depth - New");
+				ast::pass_visitor_stats.max = Stats::Counters::build<Stats::Counters::MaxCounter<double>>("Max depth - New");
+			}
 			auto transUnit = convert( move( translationUnit ) );
 			PASS( "Resolve", ResolvExpr::resolve( transUnit ) );
Index: tests/.expect/alloc-ERROR.txt
===================================================================
--- tests/.expect/alloc-ERROR.txt	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ tests/.expect/alloc-ERROR.txt	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -1,3 +1,3 @@
-alloc.cfa:361:1 error: No reasonable alternatives for expression Applying untyped:
+alloc.cfa:382:1 error: No reasonable alternatives for expression Applying untyped:
   Name: ?=?
 ...to:
@@ -19,5 +19,5 @@
 
 
-alloc.cfa:362:1 error: No reasonable alternatives for expression Applying untyped:
+alloc.cfa:383:1 error: No reasonable alternatives for expression Applying untyped:
   Name: ?=?
 ...to:
@@ -30,5 +30,5 @@
 
 
-alloc.cfa:363:1 error: No reasonable alternatives for expression Applying untyped:
+alloc.cfa:384:1 error: No reasonable alternatives for expression Applying untyped:
   Name: ?=?
 ...to:
Index: tests/alloc.cfa
===================================================================
--- tests/alloc.cfa	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ tests/alloc.cfa	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -10,6 +10,6 @@
 // Created On       : Wed Feb  3 07:56:22 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Oct  9 23:03:11 2020
-// Update Count     : 431
+// Last Modified On : Thu Nov 12 10:02:18 2020
+// Update Count     : 432
 //
 
@@ -375,5 +375,5 @@
 	dp = alloc(5.0`fill); // just for testing multiple free
 	assert(*dp == 5.0);
-	free( ip, dp );
+	free( ip, dp, 0p );
 
 #ifdef ERR1
Index: tests/malloc.cfa
===================================================================
--- tests/malloc.cfa	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ tests/malloc.cfa	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -319,5 +319,5 @@
 	free(ip);
 
-	free( (void*) 0p ); // sanity check
+	free( (void *) 0p ); // sanity check
 	free( NULL ); // sanity check
 
@@ -605,2 +605,7 @@
 	return 0;
 }
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa malloc.cfa" //
+// End: //
Index: tests/manipulatorsOutput3.cfa
===================================================================
--- tests/manipulatorsOutput3.cfa	(revision d6ad99ef0767ccc9b7f111ddeef69eaa4a2e66a3)
+++ tests/manipulatorsOutput3.cfa	(revision 9d264e18fc76fe0f9f57293b506d3984d46e5d7d)
@@ -156,7 +156,4 @@
 	sout | nl;
 
-	ui128 = 0x7fffffffffffffff;
-	ui128 <<= 64;
-	ui128 += 0xffffffffffffffff;
 	sout | left( wd( 160, i128 ) );
 	sout | left( sign( wd( 0, i128 ) ) );
@@ -177,7 +174,7 @@
 	sout | left( wd( 160, bin( i128 ) ) );
 	sout | left( sign( wd( 160, i128 ) ) );
-	sout | left( wd( 160, upcase(hex( i128 )) ) );
-	sout | left( wd( 160, upcase(oct( i128 ) )) );
-	sout | left( wd( 160, upcase(bin( i128 )) ) );
+	sout | left( wd( 160, upcase( hex( i128 ) ) ) );
+	sout | left( wd( 160, upcase( oct( i128 ) ) ) );
+	sout | left( wd( 160, upcase( bin( i128 ) ) ) );
 
 	x = 1234;
@@ -316,5 +313,4 @@
 	}
 
-
 	// int128 constants (and printing)
 	int128 v = 0xffff_ffffffff_ffffffff_L128 + 0xffffffff_ffffffff_ffffffff_ffffffff_L128;
