Index: benchmark/io/http/protocol.cfa
===================================================================
--- benchmark/io/http/protocol.cfa	(revision 32d13834026c45a070b8ffbeecf6d71de04dd54a)
+++ benchmark/io/http/protocol.cfa	(revision 17c6edeb339dc43e034adb29e39cc81cc5739ede)
@@ -522,5 +522,5 @@
 		// 	struct io_uring_sqe * sqes[3];
 		// 	__u32 idxs[3];
-		// 	struct $io_context * ctx = cfa_io_allocate(sqes, idxs, have);
+		// 	struct io_context$ * ctx = cfa_io_allocate(sqes, idxs, have);
 
 		// 	if(need(splice_in.res)) { fill(splice_in, sqes[idx++]); }
Index: benchmark/plot.py
===================================================================
--- benchmark/plot.py	(revision 32d13834026c45a070b8ffbeecf6d71de04dd54a)
+++ benchmark/plot.py	(revision 17c6edeb339dc43e034adb29e39cc81cc5739ede)
@@ -14,45 +14,60 @@
 import math
 import numpy
+import os
 import re
 import statistics
 import sys
-
+import time
+
+import matplotlib
 import matplotlib.pyplot as plt
-from matplotlib.ticker import EngFormatter
+from matplotlib.ticker import EngFormatter, ScalarFormatter
+
+def fmtDur( duration ):
+	if duration :
+		hours, rem = divmod(duration, 3600)
+		minutes, rem = divmod(rem, 60)
+		seconds, millis = divmod(rem, 1)
+		return "%2d:%02d.%03d" % (minutes, seconds, millis * 1000)
+	return " n/a"
 
 class Field:
-	def __init__(self, unit, _min, _log, _name=None):
+	def __init__(self, unit, _min, _log, _name=None, _factor=1.0):
 		self.unit = unit
 		self.min  = _min
 		self.log  = _log
 		self.name = _name
+		self.factor = _factor
 
 field_names = {
 	"ns per ops"            : Field('ns'    , 0, False),
-	"Number of processors"  : Field(''      , 1, False),
+	"Number of processors"  : Field(''      , 1, "exact"),
 	"Ops per procs"         : Field('Ops'   , 0, False),
 	"Ops per threads"       : Field('Ops'   , 0, False),
-	"ns per ops/procs"      : Field(''    , 0, False, _name = "Latency (ns $/$ (Processor $\\times$ Operation))" ),
+	"ns per ops/procs"      : Field(''      , 0, False, _name = "ns $\\times$ (Processor $/$ Total Ops)" ),
 	"Number of threads"     : Field(''      , 1, False),
 	"Total Operations(ops)" : Field('Ops'   , 0, False),
 	"Ops/sec/procs"         : Field('Ops'   , 0, False),
 	"Total blocks"          : Field('Blocks', 0, False),
-	"Ops per second"        : Field(''   , 0, False),
+	"Ops per second"        : Field(''      , 0, False),
 	"Cycle size (# thrds)"  : Field('thrd'  , 1, False),
 	"Duration (ms)"         : Field('ms'    , 0, False),
 	"Target QPS"            : Field(''      , 0, False),
 	"Actual QPS"            : Field(''      , 0, False),
-	"Average Read Latency"  : Field('us'    , 0, True),
-	"Median Read Latency"   : Field('us'    , 0, True),
-	"Tail Read Latency"     : Field('us'    , 0, True),
-	"Average Update Latency": Field('us'    , 0, True),
-	"Median Update Latency" : Field('us'    , 0, True),
-	"Tail Update Latency"   : Field('us'    , 0, True),
-	"Update Ratio"          : Field('\%'    , 0, False),
+	"Average Read Latency"  : Field('s'     , 0, False, _factor = 0.000001),
+	"Median Read Latency"   : Field('s'     , 0, True, _factor = 0.000001),
+	"Tail Read Latency"     : Field('s'     , 0, True, _factor = 0.000001),
+	"Average Update Latency": Field('s'     , 0, True, _factor = 0.000001),
+	"Median Update Latency" : Field('s'     , 0, True, _factor = 0.000001),
+	"Tail Update Latency"   : Field('s'     , 0, True, _factor = 0.000001),
+	"Update Ratio"          : Field('%'   , 0, False),
+	"Request Rate"          : Field('req/s' , 0, False),
+	"Data Rate"             : Field('b/s'   , 0, False, _factor = 1000 * 1000, _name = "Response Throughput"),
+	"Errors"                : Field('%'   , 0, False),
 }
 
-def plot(in_data, x, y, options):
+def plot(in_data, x, y, options, prefix):
 	fig, ax = plt.subplots()
-	colors = itertools.cycle(['#0095e3','#006cb4','#69df00','#0aa000','#fb0300','#e30002','#fd8f00','#ff7f00','#8f00d6','#4b009a','#ffff00','#b13f00'])
+	colors = itertools.cycle(['#006cb4','#0aa000','#ff6600','#8510a1','#0095e3','#fd8f00','#e30002','#8f00d6','#4b009a','#ffff00','#69df00','#fb0300','#b13f00'])
 	series = {} # scatter data for each individual data point
 	groups = {} # data points for x value
@@ -62,4 +77,7 @@
 	for entry in in_data:
 		name = entry[0]
+		if options.filter and not name.startswith(options.filter):
+			continue
+
 		if not name in series:
 			series[name] = {'x':[], 'y':[]}
@@ -70,5 +88,5 @@
 		if x in entry[2] and y in entry[2]:
 			xval = entry[2][x]
-			yval = entry[2][y]
+			yval = entry[2][y] * field_names[y].factor
 			series[name]['x'].append(xval)
 			series[name]['y'].append(yval)
@@ -98,5 +116,5 @@
 	for name, data in sorted(series.items()):
 		_col = next(colors)
-		plt.scatter(data['x'], data['y'], color=_col, label=name, marker='x')
+		plt.scatter(data['x'], data['y'], color=_col, label=name[len(prefix):], marker='x')
 		plt.plot(lines[name]['x'], lines[name]['min'], '--', color=_col)
 		plt.plot(lines[name]['x'], lines[name]['max'], '--', color=_col)
@@ -119,8 +137,14 @@
 	elif field_names[x].log:
 		ax.set_xscale('log')
+		if field_names[x].log == "exact":
+			xvals = set()
+			for s in series.values():
+				xvals |= set(s['x'])
+			ax.set_xticks(sorted(xvals))
+			ax.get_xaxis().set_major_formatter(ScalarFormatter())
+			plt.xticks(rotation = 45)
 	else:
 		plt.xlim(field_names[x].min, mx + 0.25)
 
-	ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
 	if options.logy:
 		ax.set_yscale('log')
@@ -130,11 +154,16 @@
 		plt.ylim(field_names[y].min, options.MaxY if options.MaxY else my*1.2)
 
+	ax.yaxis.set_major_formatter( EngFormatter(unit=field_names[y].unit) )
+
 	plt.legend(loc='upper left')
 
 	print("Results Ready")
+	start = time.time()
 	if options.out:
 		plt.savefig(options.out, bbox_inches='tight')
 	else:
 		plt.show()
+	end = time.time()
+	print("Took {}".format(fmtDur(end - start)))
 
 
@@ -150,6 +179,10 @@
 	parser.add_argument('--logy', action='store_true', help="if set, makes the y-axis logscale")
 	parser.add_argument('--MaxY', nargs='?', type=int, help="maximum value of the y-axis")
+	parser.add_argument('--filter', nargs='?', type=str, default="", help="if not empty, only print series that start with specified filter")
 
 	options =  parser.parse_args()
+
+	# if not options.out:
+	# 	matplotlib.use('SVG')
 
 	# ================================================================================
@@ -173,4 +206,11 @@
 			fields.add(label)
 
+	# filter out the series if needed
+	if options.filter:
+		series = set(filter(lambda elem: elem.startswith(options.filter), series))
+
+	# find the common prefix on series for removal (only if no filter)
+	prefix = os.path.commonprefix(list(series))
+
 	if not options.out :
 		print(series)
@@ -193,3 +233,3 @@
 
 
-	plot(data, wantx, wanty, options)
+	plot(data, wantx, wanty, options, prefix)
Index: benchmark/process-trun.py
===================================================================
--- benchmark/process-trun.py	(revision 17c6edeb339dc43e034adb29e39cc81cc5739ede)
+++ benchmark/process-trun.py	(revision 17c6edeb339dc43e034adb29e39cc81cc5739ede)
@@ -0,0 +1,111 @@
+#!/usr/bin/python3
+
+"""
+Python Script to convert output from trun to rmit like output
+"""
+import argparse
+import json
+import locale
+import os
+import re
+import sys
+
+locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' )
+
+parser = argparse.ArgumentParser(description='Python Script to convert output from trun to rmit like output')
+parser.add_argument('--out', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
+parser.add_argument('files', nargs='+')
+options =  parser.parse_args()
+
+def extract(file):
+	raw = []
+	with open(file, "r") as f:
+		for line in f:
+			if line.startswith("Combined"):
+				break
+
+		h = next(f)
+		next(f)
+
+		columns = h.strip().split()
+		if not len(columns) == 20:
+			print("{}: Failed to split header row '{}', unexpected number of columns.".format(file, h), file=sys.stderr)
+			raise ValueError
+
+		for line in f:
+			line = line.strip()
+			if not line:
+				break
+
+			raw.append(line)
+
+	results = []
+	for l in raw:
+		vals = l.split()
+		if not len(vals) == 21:
+			print("{}: Failed to split result row '{}', unexpected number of columns ({}).".format(file, l, len(vals)), file=sys.stderr)
+			raise ValueError
+		d = {
+			'Request Rate': float(vals[0]),
+			'MinReplies':   float(vals[1]),
+			'MeanReplies':  float(vals[2]),
+			'MaxReplies':   float(vals[3]),
+			'StdReplies':   float(vals[4]),
+			'Conn':         float(vals[5]),
+			'Resp':         float(vals[6]),
+			'Xfer':         float(vals[7]),
+			'Total':        float(vals[8]),
+			'Std':          float(vals[9]),
+			'Med':          float(vals[10]),
+			'Min':          float(vals[11]),
+			'Max':          float(vals[12]),
+			'Data Rate':    float(vals[13]),
+			'Errors':       float(vals[14]),
+			'Reqs':         float(vals[15]),
+			'ActRateC':     float(vals[16]),
+			'ActRate':      float(vals[17]),
+			'Error Rate':   float(vals[18]),
+			'SamplesT':     float(vals[19]),
+			'SamplesR':     float(vals[20])
+		}
+		results.append(d)
+
+	return results
+
+
+
+
+data = []
+
+print(options.files)
+
+for file in options.files:
+	# checking if it is a file
+	if os.path.isfile(file):
+		filename = os.path.basename(file)
+		match = re.search("swbsrv\.([0-9]+)gb\.(cfa|nginx)", filename)
+		try:
+			series = match[2]
+			memory = match[1]
+		except:
+			print("Can't parse filename '{}' from File '{}'.".format(filename, file), file=sys.stderr)
+			continue
+
+		try:
+			results = extract(file)
+		except OSError:
+			print("Cannot open File '{}'.".format(file), file=sys.stderr)
+			continue
+		except ValueError:
+			continue
+
+		for result in results:
+			d = [series, memory, result]
+			data.append(d)
+
+	else:
+		print("File '{}' does not exist.".format(file), file=sys.stderr)
+
+options.out.write(json.dumps(data))
+options.out.flush()
+options.out.write("\n")
Index: benchmark/readyQ/churn.go
===================================================================
--- benchmark/readyQ/churn.go	(revision 32d13834026c45a070b8ffbeecf6d71de04dd54a)
+++ benchmark/readyQ/churn.go	(revision 17c6edeb339dc43e034adb29e39cc81cc5739ede)
@@ -72,4 +72,8 @@
 		for i := range spots {
 			select {
+			case <- spots[i]:
+			default:
+			}
+			select {
 			case spots[i] <- (struct {}{}):
 			default:
Index: benchmark/rmit.py
===================================================================
--- benchmark/rmit.py	(revision 32d13834026c45a070b8ffbeecf6d71de04dd54a)
+++ benchmark/rmit.py	(revision 17c6edeb339dc43e034adb29e39cc81cc5739ede)
@@ -22,14 +22,14 @@
 
 def parse_range(x):
-    result = []
-    for part in x.split(','):
-        if '-' in part:
-            a, b = part.split('-')
-            a, b = int(a), int(b)
-            result.extend(range(a, b + 1))
-        else:
-            a = int(part)
-            result.append(a)
-    return result
+	result = []
+	for part in x.split(','):
+		if '-' in part:
+			a, b = part.split('-')
+			a, b = int(a), int(b)
+			result.extend(range(a, b + 1))
+		else:
+			a = int(part)
+			result.append(a)
+	return result
 
 class DependentOpt:
@@ -190,7 +190,11 @@
 			range(193, 257) : "0-255",
 		},
+		"ocean": {
+			range(  1,  33) : "0-31",
+		},
 	}
 
-	if (host := socket.gethostname()) in known_hosts:
+	host = socket.gethostname()
+	if host in known_hosts:
 		taskset_maps = known_hosts[host]
 		return True
@@ -229,4 +233,5 @@
 	parser.add_argument('--trials', help='Number of trials to run per combinaison', type=int, default=3)
 	parser.add_argument('--notaskset', help='If specified, the trial will not use taskset to match the -p option', action='store_true')
+	parser.add_argument('--extra', help='Extra arguments to be added unconditionally', action='append', type=str)
 	parser.add_argument('command', metavar='command', type=str, nargs=1, help='the command prefix to run')
 	parser.add_argument('candidates', metavar='candidates', type=str, nargs='*', help='the candidate suffix to run')
@@ -283,4 +288,10 @@
 	# ================================================================================
 	# Fixup the different commands
+
+	# add extras
+	if options.extra:
+		for act in actions:
+			for e in options.extra:
+				act.append(e)
 
 	# Add tasksets
