Index: benchmark/io/http/filecache.cfa
===================================================================
--- benchmark/io/http/filecache.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ benchmark/io/http/filecache.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -4,4 +4,5 @@
 #include <string.h>
 
+#include <fstream.hfa>
 #include <stdlib.hfa>
 
@@ -182,7 +183,7 @@
 		conflicts += put_file( raw[i], fd );
 	}
-	printf("Filled cache from path \"%s\" with %zu files\n", path, fcount);
+	sout | "Filled cache from path \"" | path | "\" with" | fcount | "files";
 	if( conflicts > 0 ) {
-		printf("Found %d conflicts (seed: %u)\n", conflicts, options.file_cache.hash_seed);
+		sout | "Found" | conflicts | "conflicts (seed: " | options.file_cache.hash_seed | ")";
 		#if defined(REJECT_CONFLICTS)
 			abort("Conflicts found in the cache");
@@ -191,9 +192,9 @@
 
 	if(options.file_cache.list) {
-		printf("Listing files and exiting\n");
+		sout | "Listing files and exiting";
 		for(i; fcount) {
 			int s; char u;
 			[s, u] = human_size(raw[i].size);
-			printf("%4d%c - %s\n", s, u, raw[i].file);
+			sout | s | u | "-" | raw[i].file;
 			free(raw[i].file);
 		}
Index: benchmark/io/http/main.cfa
===================================================================
--- benchmark/io/http/main.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ benchmark/io/http/main.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -10,5 +10,7 @@
 }
 
+#include <fstream.hfa>
 #include <kernel.hfa>
+#include <iofwd.hfa>
 #include <stats.hfa>
 #include <time.hfa>
@@ -50,4 +52,27 @@
 
 //=============================================================================================
+// Stats Printer
+//============================================================================================='
+
+thread StatsPrinter {};
+
+void ?{}( StatsPrinter & this ) {
+	((thread&)this){ "Stats Printer Thread" };
+}
+
+void main(StatsPrinter & this) {
+	LOOP: for() {
+		waitfor( ^?{} : this) {
+			break LOOP;
+		}
+		or else {}
+
+		sleep(10`s);
+
+		print_stats_now( *options.clopts.instance, CFA_STATS_READY_Q | CFA_STATS_IO );
+	}
+}
+
+//=============================================================================================
 // Main
 //============================================================================================='
@@ -59,10 +84,10 @@
 	//===================
 	// Open Files
-	printf("Filling cache from %s\n", path);
+	sout | "Filling cache from" | path;
 	fill_cache( path );
 
 	//===================
 	// Open Socket
-	printf("%ld : Listening on port %d\n", getpid(), options.socket.port);
+	sout | getpid() | ": Listening on port" | options.socket.port;
 	int server_fd = socket(AF_INET, SOCK_STREAM, 0);
 	if(server_fd < 0) {
@@ -84,8 +109,8 @@
 			if(errno == EADDRINUSE) {
 				if(waited == 0) {
-					printf("Waiting for port\n");
+					sout | "Waiting for port";
 				} else {
-					printf("\r%d", waited);
-					fflush(stdout);
+					sout | "\r" | waited | nonl;
+					flush( sout );
 				}
 				waited ++;
@@ -128,4 +153,5 @@
 		{
 			ServerProc procs[options.clopts.nprocs];
+			StatsPrinter printer;
 
 			init_protocol();
@@ -148,21 +174,21 @@
 					unpark( workers[i] );
 				}
-				printf("%d workers started on %d processors\n", options.clopts.nworkers, options.clopts.nprocs);
+				sout | options.clopts.nworkers | "workers started on" | options.clopts.nprocs | "processors";
 				{
 					char buffer[128];
-					while(!feof(stdin)) {
-						fgets(buffer, 128, stdin);
+					while(int ret = cfa_read(0, buffer, 128, 0, -1`s, 0p, 0p); ret != 0) {
+						if(ret < 0) abort( "main read error: (%d) %s\n", (int)errno, strerror(errno) );
 					}
 
-					printf("Shutting Down\n");
-				}
-
+					sout | "Shutdown received";
+				}
+
+				sout | "Notifying connections";
 				for(i; options.clopts.nworkers) {
-					printf("Cancelling %p\n", (void*)workers[i].cancel.target);
 					workers[i].done = true;
 					cancel(workers[i].cancel);
 				}
 
-				printf("Shutting down socket\n");
+				sout | "Shutting down socket";
 				int ret = shutdown( server_fd, SHUT_RD );
 				if( ret < 0 ) { abort( "shutdown error: (%d) %s\n", (int)errno, strerror(errno) ); }
@@ -170,15 +196,22 @@
 				//===================
 				// Close Socket
-				printf("Closing Socket\n");
+				sout | "Closing Socket";
 				ret = close( server_fd );
 				if(ret < 0) {
 					abort( "close socket error: (%d) %s\n", (int)errno, strerror(errno) );
 				}
+				sout | "Stopping connection threads..." | nonl;
 			}
-			printf("Workers Closed\n");
-
+			sout | "done";
+
+			sout | "Stopping protocol threads..." | nonl;
 			deinit_protocol();
-		}
-
+			sout | "done";
+
+			sout | "Stopping processors..." | nonl;
+		}
+		sout | "done";
+
+		sout | "Closing splice fds..." | nonl;
 		for(i; pipe_cnt) {
 			ret = close( fds[pipe_off + i] );
@@ -188,10 +221,14 @@
 		}
 		free(fds);
-
-	}
+		sout | "done";
+
+		sout | "Stopping processors..." | nonl;
+	}
+	sout | "done";
 
 	//===================
 	// Close Files
-	printf("Closing Files\n");
+	sout | "Closing open files..." | nonl;
 	close_cache();
-}
+	sout | "done";
+}
Index: benchmark/io/http/options.cfa
===================================================================
--- benchmark/io/http/options.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ benchmark/io/http/options.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -50,19 +50,19 @@
 
 	static cfa_option opt[] = {
-		{'p', "port",           "Port the server will listen on", options.socket.port},
-		{'c', "cpus",           "Number of processors to use", options.clopts.nprocs},
-		{'L', "log",            "Enable logs", options.log, parse_settrue},
-		{'t', "threads",        "Number of worker threads to use", options.clopts.nworkers},
-		{'b', "accept-backlog", "Maximum number of pending accepts", options.socket.backlog},
-		{'r', "request_len",    "Maximum number of bytes in the http request, requests with more data will be answered with Http Code 414", options.socket.buflen},
-		{'S', "seed",           "seed to use for hashing", options.file_cache.hash_seed },
-		{'C', "cache-size",     "Size of the cache to use, if set to small, will uses closes power of 2", options.file_cache.size },
-		{'l', "list-files",     "List the files in the specified path and exit", options.file_cache.list, parse_settrue },
-		{'s', "submitthread",   "If set, cluster uses polling thread to submit I/O", subthrd, parse_settrue },
-		{'e', "eagersubmit",    "If set, cluster submits I/O eagerly but still aggregates submits", eagrsub, parse_settrue},
-		{'f', "fixed-fds",      "If set, files are open eagerly and pre-registered with the cluster", fixedfd, parse_settrue},
-		{'k', "kpollsubmit",    "If set, cluster uses IORING_SETUP_SQPOLL, implies -f", sqkpoll, parse_settrue },
-		{'i', "kpollcomplete",  "If set, cluster uses IORING_SETUP_IOPOLL", iokpoll, parse_settrue },
-		{'L', "submitlength",   "Max number of submitions that can be submitted together", sublen },
+		{ 'p', "port",           "Port the server will listen on", options.socket.port},
+		{ 'c', "cpus",           "Number of processors to use", options.clopts.nprocs},
+		{ 't', "threads",        "Number of worker threads to use", options.clopts.nworkers},
+		{'\0', "log",            "Enable logs", options.log, parse_settrue},
+		{'\0', "accept-backlog", "Maximum number of pending accepts", options.socket.backlog},
+		{'\0', "request_len",    "Maximum number of bytes in the http request, requests with more data will be answered with Http Code 414", options.socket.buflen},
+		{'\0', "seed",           "seed to use for hashing", options.file_cache.hash_seed },
+		{'\0', "cache-size",     "Size of the cache to use, if set to small, will uses closes power of 2", options.file_cache.size },
+		{'\0', "list-files",     "List the files in the specified path and exit", options.file_cache.list, parse_settrue },
+		{ 's', "submitthread",   "If set, cluster uses polling thread to submit I/O", subthrd, parse_settrue },
+		{ 'e', "eagersubmit",    "If set, cluster submits I/O eagerly but still aggregates submits", eagrsub, parse_settrue},
+		{ 'f', "fixed-fds",      "If set, files are open eagerly and pre-registered with the cluster", fixedfd, parse_settrue},
+		{ 'k', "kpollsubmit",    "If set, cluster uses IORING_SETUP_SQPOLL, implies -f", sqkpoll, parse_settrue },
+		{ 'i', "kpollcomplete",  "If set, cluster uses IORING_SETUP_IOPOLL", iokpoll, parse_settrue },
+		{'\0', "submitlength",   "Max number of submitions that can be submitted together", sublen },
 
 	};
Index: benchmark/io/http/protocol.cfa
===================================================================
--- benchmark/io/http/protocol.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ benchmark/io/http/protocol.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -5,4 +5,6 @@
 	#include <fcntl.h>
 }
+
+#include <fstream.hfa>
 #include <iofwd.hfa>
 
@@ -11,5 +13,5 @@
 extern "C" {
       int snprintf ( char * s, size_t n, const char * format, ... );
-	#include <linux/io_uring.h>
+	// #include <linux/io_uring.h>
 }
 #include <string.h>
@@ -24,4 +26,5 @@
 	"HTTP/1.1 400 Bad Request\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
 	"HTTP/1.1 404 Not Found\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
+	"HTTP/1.1 408 Request Timeout\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
 	"HTTP/1.1 413 Payload Too Large\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
 	"HTTP/1.1 414 URI Too Long\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
@@ -34,4 +37,5 @@
 	400,
 	404,
+	408,
 	413,
 	414,
@@ -49,5 +53,10 @@
 		int ret = cfa_write(fd, it, len, 0, -1`s, 0p, 0p);
 		// int ret = write(fd, it, len);
-		if( ret < 0 ) { if( errno != EAGAIN && errno != EWOULDBLOCK) abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) ); }
+		if( ret < 0 ) {
+			if( errno == ECONNRESET || errno == EPIPE ) return -ECONNRESET;
+			if( errno == EAGAIN || errno == EWOULDBLOCK) return -EAGAIN;
+
+			abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) );
+		}
 
 		// update it/len
@@ -94,5 +103,5 @@
 		if(ret < 0 ) {
 			if( errno == EAGAIN || errno == EWOULDBLOCK) continue READ;
-			// if( errno == EINVAL ) return [E400, true, 0, 0];
+			if( errno == ECONNRESET ) return [E408, true, 0, 0];
 			abort( "read error: (%d) %s\n", (int)errno, strerror(errno) );
 		}
@@ -108,5 +117,8 @@
 	}
 
-	if( options.log ) printf("%.*s\n", rlen, buffer);
+	if( options.log ) {
+		write(sout, buffer, rlen);
+		sout | nl;
+	}
 
 	it = buffer;
@@ -119,5 +131,5 @@
 }
 
-void sendfile( int pipe[2], int fd, int ans_fd, size_t count ) {
+int sendfile( int pipe[2], int fd, int ans_fd, size_t count ) {
 	unsigned sflags = SPLICE_F_MOVE; // | SPLICE_F_MORE;
 	off_t offset = 0;
@@ -128,4 +140,6 @@
 		if( ret < 0 ) {
 			if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE1;
+			if( errno == ECONNRESET ) return -ECONNRESET;
+			if( errno == EPIPE ) return -EPIPE;
 			abort( "splice [0] error: (%d) %s\n", (int)errno, strerror(errno) );
 		}
@@ -139,4 +153,6 @@
 			if( ret < 0 ) {
 				if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE2;
+				if( errno == ECONNRESET ) return -ECONNRESET;
+				if( errno == EPIPE ) return -EPIPE;
 				abort( "splice [1] error: (%d) %s\n", (int)errno, strerror(errno) );
 			}
@@ -145,4 +161,5 @@
 
 	}
+	return count;
 }
 
Index: benchmark/io/http/protocol.hfa
===================================================================
--- benchmark/io/http/protocol.hfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ benchmark/io/http/protocol.hfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -7,4 +7,5 @@
 	E400,
 	E404,
+	E408,
 	E413,
 	E414,
@@ -21,3 +22,3 @@
 [HttpCode code, bool closed, * const char file, size_t len] http_read(int fd, []char buffer, size_t len, io_cancellation *);
 
-void sendfile( int pipe[2], int fd, int ans_fd, size_t count );
+int sendfile( int pipe[2], int fd, int ans_fd, size_t count );
Index: benchmark/io/http/worker.cfa
===================================================================
--- benchmark/io/http/worker.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ benchmark/io/http/worker.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -6,4 +6,5 @@
 #include <unistd.h>
 
+#include <fstream.hfa>
 #include <iofwd.hfa>
 
@@ -33,14 +34,14 @@
 	CONNECTION:
 	for() {
-		if( options.log ) printf("=== Accepting connection ===\n");
+		if( options.log ) sout | "=== Accepting connection ===";
 		int fd = cfa_accept4( this.[sockfd, addr, addrlen, flags], 0, -1`s, &this.cancel, 0p );
 		// int fd = accept4( this.[sockfd, addr, addrlen, flags] );
 		if(fd < 0) {
 			if( errno == ECONNABORTED ) break;
-			if( errno == EINVAL && this.done ) break;
+			if( this.done && (errno == EINVAL || errno == EBADF) ) break;
 			abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
 		}
 
-		if( options.log ) printf("=== New connection %d, waiting for requests ===\n", fd);
+		if( options.log ) sout | "=== New connection" | fd | "" | ", waiting for requests ===";
 		REQUEST:
 		for() {
@@ -53,17 +54,13 @@
 			size_t len = options.socket.buflen;
 			char buffer[len];
-			if( options.log ) printf("=== Reading request ===\n");
+			if( options.log ) sout | "=== Reading request ===";
 			[code, closed, file, name_size] = http_read(fd, buffer, len, &this.cancel);
 
 			// if we are done, break out of the loop
-			if( closed ) {
-				if( options.log ) printf("=== Connection closed ===\n");
-				close(fd);
-				continue CONNECTION;
-			}
+			if( closed ) break REQUEST;
 
 			// If this wasn't a request retrun 400
 			if( code != OK200 ) {
-				printf("=== Invalid Request : %d ===\n", code_val(code));
+				sout | "=== Invalid Request :" | code_val(code) | "===";
 				answer_error(fd, code);
 				continue REQUEST;
@@ -71,26 +68,32 @@
 
 			if(0 == strncmp(file, "plaintext", min(name_size, sizeof("plaintext") ))) {
-				if( options.log ) printf("=== Request for /plaintext ===\n");
+				if( options.log ) sout | "=== Request for /plaintext ===";
 
 				char text[] = "Hello, World!\n";
 
 				// Send the header
-				answer_plain(fd, text, sizeof(text));
+				int ret = answer_plain(fd, text, sizeof(text));
+				if( ret == -ECONNRESET ) break REQUEST;
 
-				if( options.log ) printf("=== Answer sent ===\n");
+				if( options.log ) sout | "=== Answer sent ===";
 				continue REQUEST;
 			}
 
 			if(0 == strncmp(file, "ping", min(name_size, sizeof("ping") ))) {
-				if( options.log ) printf("=== Request for /ping ===\n");
+				if( options.log ) sout | "=== Request for /ping ===";
 
 				// Send the header
-				answer_empty(fd);
+				int ret = answer_empty(fd);
+				if( ret == -ECONNRESET ) break REQUEST;
 
-				if( options.log ) printf("=== Answer sent ===\n");
+				if( options.log ) sout | "=== Answer sent ===";
 				continue REQUEST;
 			}
 
-			if( options.log ) printf("=== Request for file %.*s ===\n", (int)name_size, file);
+			if( options.log ) {
+				sout | "=== Request for file " | nonl;
+				write(sout, file, name_size);
+				sout | " ===";
+			}
 
 			// Get the fd from the file cache
@@ -101,5 +104,7 @@
 			// If we can't find the file, return 404
 			if( ans_fd < 0 ) {
-				printf("=== File Not Found ===\n");
+				sout | "=== File Not Found (" | nonl;
+				write(sout, file, name_size);
+				sout | ") ===";
 				answer_error(fd, E404);
 				continue REQUEST;
@@ -107,11 +112,17 @@
 
 			// Send the header
-			answer_header(fd, count);
+			int ret = answer_header(fd, count);
+			if( ret == -ECONNRESET ) break REQUEST;
 
 			// Send the desired file
-			sendfile( this.pipe, fd, ans_fd, count);
+			ret = sendfile( this.pipe, fd, ans_fd, count);
+			if( ret == -ECONNRESET ) break REQUEST;
 
-			if( options.log ) printf("=== Answer sent ===\n");
+			if( options.log ) sout | "=== Answer sent ===";
 		}
+
+		if( options.log ) sout | "=== Connection closed ===";
+		close(fd);
+		continue CONNECTION;
 	}
 }
Index: doc/theses/fangren_yu_COOP_F20/Report.tex
===================================================================
--- doc/theses/fangren_yu_COOP_F20/Report.tex	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ doc/theses/fangren_yu_COOP_F20/Report.tex	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -87,7 +87,18 @@
 
 \begin{abstract}
+
+\CFA is an evolutionary extension to the C programming language, featuring a parametric type system, and is currently under active development. The reference compiler for \CFA language, @cfa-cc@, has some of its major components dated back to early 2000s, and is based on inefficient data structures and algorithms. Some improvements targeting the expression resolution algorithm, suggested by a recent prototype experiment on a simplified model, are implemented in @cfa-cc@ to support the full \CFA language. These optimizations speed up the compiler significantly by a factor of 20 across the existing \CFA codebase, bringing the compilation time of a mid-sized \CFA source file down to 10-second level. A few cases derived from realistic code examples that causes trouble to the compiler are analyzed in detail, with proposed solutions. This step of \CFA project development is critical to its eventual goal to be used alongside C for large software systems.
+
 \end{abstract}
 
 \section{Introduction}
+
+\CFA language, developed by the Programming Language Group at University of Waterloo, has a long history, with the first proof-of-concept compiler built in 2003 by Richard Bilson~\cite{Bilson03}. Many new features are added to the language over time, but the core of \CFA, parametric functions introduced by the @forall@ clause (hence the name of the language), with the type system supporting parametric overloading, remains mostly unchanged. 
+
+The current \CFA reference compiler @cfa-cc@ still includes many parts taken directly from the original Bilson's implementation, and serves as a starting point for the enhancement work to the type system. Unfortunately, it does not provide the efficiency required for the language to be used practically: a \CFA source file of approximately 1000 lines of code can take a few minutes to compile. The cause of the problem is that the old compiler used inefficient data structures and algorithms for expression resolution, which involved a lot of copying and redundant work. 
+
+This paper presents a series of optimizations to the performance-critical parts of the resolver, with a major rework of the data structure used by the compiler, using a functional programming approach to reduce memory complexity. Subsequent improvements are mostly suggested by running the compiler builds with a performance profiler against the \CFA standard library source code and a test suite to find the most underperforming components in the compiler algorithm.
+
+The \CFA team endorses a pragmatic philosophy in work that mostly focuses on practical implications of language design and implementation, rather than the theoretical limits. In particular, the compiler is designed to work on production \CFA code efficiently and keep type safety, while sometimes making compromises to expressiveness in extreme corner cases. However, when these corner cases do appear in actual usage, they need to be thoroughly investigated. Analysis presented in this paper, therefore, are conducted on a case-by-case basis. Some of them eventually point to certain weaknesses in the language design and solutions are proposed based on experimental results.
 
 \section{Completed work}
@@ -444,5 +455,5 @@
 \section{Timing results}
 
-For the timing results presented here, the \CFA compiler is built with gcc 9.3.0, and tested on a server machine running Ubuntu 20.04, 64GB RAM and 32-core 2.2 GHz CPU, results reported by the time command, and using only 8 cores in parallel such that the time is close to the case with 100% CPU utilization on a single thread.
+For the timing results presented here, the \CFA compiler is built with gcc 9.3.0, and tested on a server machine running Ubuntu 20.04, 64GB RAM and 32-core 2.2 GHz CPU, results reported by the time command, and using only 8 cores in parallel such that the time is close to the case with 100\% CPU utilization on a single thread.
 
 On the most recent build, the \CFA standard library (~1.3 MB of source code) compiles in 4 minutes 47 seconds total processor time (single thread equivalent), with the slowest file taking 13 seconds. The test suite (178 test cases, ~2.2MB of source code) completes within 25 minutes total processor time,\footnote{Including a few runtime tests; total time spent in compilation is approximately 21 minutes.} with the slowest file taking 23 seconds. In contrast, the library build on old compiler takes 85 minutes total, 5 minutes for the slowest file. Full test suite takes too long with old compiler build and is therefore not run, but the slowest test cases take approximately 5 minutes. Overall, the most recent build compared to old build in April 2020, before the project started, is consistently faster by a factor of 20.
Index: libcfa/src/concurrency/io.cfa
===================================================================
--- libcfa/src/concurrency/io.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ libcfa/src/concurrency/io.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -390,6 +390,4 @@
 			block++;
 
-			abort( "Kernel I/O : all submit queue entries used, yielding\n" );
-
 			yield();
 		}
Index: libcfa/src/concurrency/io/setup.cfa
===================================================================
--- libcfa/src/concurrency/io/setup.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ libcfa/src/concurrency/io/setup.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -42,4 +42,7 @@
 	void ^?{}(io_context & this, bool cluster_context) {}
 
+	void register_fixed_files( io_context &, int *, unsigned ) {}
+	void register_fixed_files( cluster    &, int *, unsigned ) {}
+
 #else
 	#include <errno.h>
Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ libcfa/src/concurrency/kernel.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -140,4 +140,9 @@
 		preemption_scope scope = { this };
 
+		#if !defined(__CFA_NO_STATISTICS__)
+			unsigned long long last_tally = rdtscl();
+		#endif
+
+
 		__cfadbg_print_safe(runtime_core, "Kernel : core %p started\n", this);
 
@@ -206,4 +211,12 @@
 			// Are we done?
 			if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
+
+			#if !defined(__CFA_NO_STATISTICS__)
+				unsigned long long curr = rdtscl();
+				if(curr > (last_tally + 500000000)) {
+					__tally_stats(this->cltr->stats, __cfaabi_tls.this_stats);
+					last_tally = curr;
+				}
+			#endif
 		}
 
@@ -611,30 +624,24 @@
 // Unexpected Terminating logic
 //=============================================================================================
-static __spinlock_t kernel_abort_lock;
-static bool kernel_abort_called = false;
+
+extern "C" {
+	extern void __cfaabi_real_abort(void);
+}
+static volatile bool kernel_abort_called = false;
 
 void * kernel_abort(void) __attribute__ ((__nothrow__)) {
 	// abort cannot be recursively entered by the same or different processors because all signal handlers return when
 	// the globalAbort flag is true.
-	lock( kernel_abort_lock __cfaabi_dbg_ctx2 );
+	bool first = __atomic_test_and_set( &kernel_abort_called, __ATOMIC_SEQ_CST);
+
+	// first task to abort ?
+	if ( !first ) {
+		// We aren't the first to abort.
+		// I give up, just let C handle it
+		__cfaabi_real_abort();
+	}
 
 	// disable interrupts, it no longer makes sense to try to interrupt this processor
 	disable_interrupts();
-
-	// first task to abort ?
-	if ( kernel_abort_called ) {			// not first task to abort ?
-		unlock( kernel_abort_lock );
-
-		sigset_t mask;
-		sigemptyset( &mask );
-		sigaddset( &mask, SIGALRM );		// block SIGALRM signals
-		sigaddset( &mask, SIGUSR1 );		// block SIGALRM signals
-		sigsuspend( &mask );				// block the processor to prevent further damage during abort
-		_exit( EXIT_FAILURE );				// if processor unblocks before it is killed, terminate it
-	}
-	else {
-		kernel_abort_called = true;
-		unlock( kernel_abort_lock );
-	}
 
 	return __cfaabi_tls.this_thread;
Index: libcfa/src/concurrency/stats.hfa
===================================================================
--- libcfa/src/concurrency/stats.hfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ libcfa/src/concurrency/stats.hfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -2,4 +2,9 @@
 
 #include <stdint.h>
+
+enum {
+	CFA_STATS_READY_Q  = 0x01,
+	CFA_STATS_IO = 0x02,
+};
 
 #if defined(__CFA_NO_STATISTICS__)
@@ -9,10 +14,4 @@
 	static inline void __print_stats( struct __stats_t *, int, const char *, const char *, void * ) {}
 #else
-	enum {
-		CFA_STATS_READY_Q  = 0x01,
-		#if defined(CFA_HAVE_LINUX_IO_URING_H)
-			CFA_STATS_IO = 0x02,
-		#endif
-	};
 
 	struct __attribute__((aligned(64))) __stats_readQ_t {
Index: libcfa/src/interpose.cfa
===================================================================
--- libcfa/src/interpose.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ libcfa/src/interpose.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -284,4 +284,10 @@
 }
 
+extern "C" {
+	void __cfaabi_real_abort(void) {
+		__cabi_libc.abort();
+	}
+}
+
 void sigHandler_segv( __CFA_SIGPARMS__ ) {
 		if ( sfp->si_addr == 0p ) {
Index: libcfa/src/parseargs.cfa
===================================================================
--- libcfa/src/parseargs.cfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ libcfa/src/parseargs.cfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -30,5 +30,23 @@
 
 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * usage, FILE * out)  __attribute__ ((noreturn));
-
+//-----------------------------------------------------------------------------
+// checking
+static void check_args(cfa_option options[], size_t opt_count) {
+	for(i; opt_count) {
+		for(j; opt_count) {
+			if(i == j) continue;
+
+			if( options[i].short_name != '\0'
+			&& options[i].short_name == options[j].short_name)
+				abort("Parse Args error: two options have short name '%c' (%zu & %zu)", options[i].short_name, i, j);
+
+			if(0 == strcmp(options[i].long_name, options[j].long_name)) abort("Parse Args error: two options have long name '%s' (%zu & %zu)", options[i].long_name, i, j);
+		}
+	}
+}
+
+
+//-----------------------------------------------------------------------------
+// Parsing args
 void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) {
 	if( 0p != &cfa_args_argc ) {
@@ -41,6 +59,4 @@
 }
 
-//-----------------------------------------------------------------------------
-// getopt_long wrapping
 void parse_args(
 	int argc,
@@ -51,4 +67,26 @@
 	char ** & left
 ) {
+	check_args(options, opt_count);
+
+	int maxv = 'h';
+	char optstring[opt_count * 3] = { '\0' };
+	{
+		int idx = 0;
+		for(i; opt_count) {
+			if (options[i].short_name) {
+				maxv = max(options[i].short_name, maxv);
+				optstring[idx] = options[i].short_name;
+				idx++;
+				if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
+				&& ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
+					optstring[idx] = ':';
+					idx++;
+				}
+			}
+		}
+		optstring[idx+0] = 'h';
+		optstring[idx+1] = '\0';
+	}
+
 	struct option optarr[opt_count + 2];
 	{
@@ -56,7 +94,8 @@
 		for(i; opt_count) {
 			if(options[i].long_name) {
+				options[i].val = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv;
 				optarr[idx].name = options[i].long_name;
 				optarr[idx].flag = 0p;
-				optarr[idx].val  = options[i].short_name;
+				optarr[idx].val  = options[i].val;
 				if(    ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue)
 				    || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) {
@@ -70,20 +109,4 @@
 		optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h'];
 		optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0];
-	}
-
-	char optstring[opt_count * 3] = { '\0' };
-	{
-		int idx = 0;
-		for(i; opt_count) {
-			optstring[idx] = options[i].short_name;
-			idx++;
-			if(    ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)
-			    && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {
-				optstring[idx] = ':';
-				idx++;
-			}
-		}
-		optstring[idx+0] = 'h';
-		optstring[idx+1] = '\0';
 	}
 
@@ -103,5 +126,5 @@
 			default:
 				for(i; opt_count) {
-					if(opt == options[i].short_name) {
+					if(opt == options[i].val) {
 						const char * arg = optarg ? optarg : "";
 						if( arg[0] == '=' ) { arg++; }
Index: libcfa/src/parseargs.hfa
===================================================================
--- libcfa/src/parseargs.hfa	(revision 03ecdcf16d53730a25586c191b15bc11f9ee350b)
+++ libcfa/src/parseargs.hfa	(revision 77ff383eca61df055b8f1a57b7cdd4a01415f8b6)
@@ -2,4 +2,5 @@
 
 struct cfa_option {
+      int val; // reserved
       char short_name;
       const char * long_name;
@@ -15,4 +16,5 @@
 forall(dtype T | { bool parse(const char *, T & ); })
 static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable ) {
+      this.val        = 0;
       this.short_name = short_name;
       this.long_name  = long_name;
@@ -24,4 +26,5 @@
 forall(dtype T)
 static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) {
+      this.val        = 0;
       this.short_name = short_name;
       this.long_name  = long_name;
