diff --git a/benches/barbershop.rs b/benches/barbershop.rs
index ff9d392197b64d86080e5a249cd260dcf3abf645..ce7f58c374d3b9ffc38c7f5dfd90903031f13569 100644
--- a/benches/barbershop.rs
+++ b/benches/barbershop.rs
@@ -1,13 +1,16 @@
-use criterion::{Criterion, BenchmarkId, criterion_group, criterion_main, BatchSize, PlotConfiguration, AxisScale, SamplingMode};
-use std::{process::Command, time::Duration};
-use itertools::Itertools;
+use criterion::{Criterion, BenchmarkId, criterion_group, criterion_main,
+                BatchSize, PlotConfiguration, AxisScale, SamplingMode};
 
-const RANGE :  u32 =   10;
-const STEP  : Time = 1000.0;
+mod support;
+
+const SLX_PATH: &'static str = "C:/Wolverine/SLX/sse.exe";
+const RANGE: u32 =   10;
+const STEP: Time = 16000.0;
 
 fn barbershop_bench(c: &mut Criterion) {
 	let mut group = c.benchmark_group("Barbershop");
 	
+	// set-up the benchmark parameters
 	group.confidence_level(0.99);
 	group.plot_config(
 		PlotConfiguration::default()
@@ -15,8 +18,8 @@ fn barbershop_bench(c: &mut Criterion) {
 	);
 	group.sampling_mode(SamplingMode::Linear);
 	
+	// vary in the length of the simulation run
 	for sim_duration in (0..RANGE).map(|c| Time::from(1 << c)*STEP) {
-		// benchmark the SLX implementation
 		let duration = sim_duration.to_string();
 		let args = [
 			"/silent",
@@ -29,43 +32,19 @@ fn barbershop_bench(c: &mut Criterion) {
 			duration.as_str()
 		];
 		
-		group.measurement_time(Duration::from_secs(60));
+		// benchmark the SLX implementation
 		group.bench_function(
 			BenchmarkId::new("SLX", sim_duration),
-			|b| b.iter_custom(|iters| {
-				(0..iters)
-					.into_iter()
-					.chunks(3200000/(sim_duration as usize))
-					.into_iter()
-					.map(|range| {
-						let rc = Command::new("C:/Wolverine/SLX/sse.exe")
-							.args(args.iter())
-							.arg(range.count().to_string())
-							.output()
-							.expect("failed to run the SLX program");
-						
-						if !rc.status.success() {
-							panic!(match rc.status.code().unwrap() {
-								-10001 => "Unable to find a security key with SLX permission",
-								-10002 => "The command line includes an invalid option",
-								-10003 => "The source file cannot be found",
-								-10004 => "The specified/implied output file cannot be written",
-								-10005 => "The program contains compile-time errors",
-								-10006 => "The program has terminated with a run-time error",
-								-10007 => "The /genrts option failed",
-								_      => "Unknown error code"
-							})
-						}
-						
-						Duration::from_secs_f64(
-							(&String::from_utf8_lossy(&rc.stdout)).trim().parse().unwrap()
-						)
-					}).sum()
-			})
+			|b| b.iter_custom(|iters|
+				support::slx_bench(
+					SLX_PATH, 
+					&args, 
+					iters as usize
+				).expect("couldn't benchmark the SLX program")
+			)
 		);
 		
 		// benchmark the Rust implementation
-		group.measurement_time(Duration::from_secs(5));
 		group.bench_function(
 			BenchmarkId::new("Rust", sim_duration),
 			|b| b.iter_batched(
diff --git a/benches/ferry.rs b/benches/ferry.rs
index b5667915873bd41d3f5dd2bcef3d055a3be600c4..c7c46c60b9d28809139361470e17b95a1bf2db96 100644
--- a/benches/ferry.rs
+++ b/benches/ferry.rs
@@ -1,14 +1,17 @@
-use criterion::{Criterion, BenchmarkId, criterion_group, criterion_main, BatchSize, PlotConfiguration, AxisScale, SamplingMode};
-use std::{process::Command, time::Duration};
-use itertools::Itertools;
+use criterion::{Criterion, BenchmarkId, criterion_group, criterion_main,
+                BatchSize, PlotConfiguration, AxisScale, SamplingMode};
 
-const SEED  :  u64 = 100000;
-const RANGE :  u32 =     10;
-const STEP  : Time =   1000.0;
+mod support;
+
+const SLX_PATH: &'static str = "C:/Wolverine/SLX/sse.exe";
+const SEED:  u64 = 100000;
+const RANGE: u32 =     10;
+const STEP: Time =   1000.0;
 
 fn ferry_bench(c: &mut Criterion) {
 	let mut group = c.benchmark_group("Ferry");
 	
+	// set-up the benchmark parameters
 	group.confidence_level(0.99);
 	group.plot_config(
 		PlotConfiguration::default()
@@ -16,8 +19,8 @@ fn ferry_bench(c: &mut Criterion) {
 	);
 	group.sampling_mode(SamplingMode::Linear);
 	
+	// vary in the length of the simulation run
 	for (i, sim_duration) in (0..RANGE).map(|c| Time::from(1 << c)*STEP).enumerate() {
-		// benchmark the SLX implementation
 		let duration = sim_duration.to_string();
 		let args = [
 			"/silent",
@@ -30,43 +33,19 @@ fn ferry_bench(c: &mut Criterion) {
 			duration.as_str()
 		];
 		
-		group.measurement_time(Duration::from_secs(60));
+		// benchmark the SLX implementation
 		group.bench_function(
 			BenchmarkId::new("SLX", sim_duration),
-			|b| b.iter_custom(|iters| {
-				(0..iters)
-					.into_iter()
-					.chunks(620000/(sim_duration as usize))
-					.into_iter()
-					.map(|range| {
-						let rc = Command::new("C:/Wolverine/SLX/sse.exe")
-							.args(args.iter())
-							.arg(range.count().to_string())
-							.output()
-							.expect("failed to run the SLX program");
-						
-						if !rc.status.success() {
-							panic!(match rc.status.code().unwrap() {
-								-10001 => "Unable to find a security key with SLX permission",
-								-10002 => "The command line includes an invalid option",
-								-10003 => "The source file cannot be found",
-								-10004 => "The specified/implied output file cannot be written",
-								-10005 => "The program contains compile-time errors",
-								-10006 => "The program has terminated with a run-time error",
-								-10007 => "The /genrts option failed",
-								_      => "Unknown error code"
-							})
-						}
-						
-						Duration::from_secs_f64(
-							(&String::from_utf8_lossy(&rc.stdout)).trim().parse().unwrap()
-						)
-					}).sum()
-			})
+			|b| b.iter_custom(|iters|
+				support::slx_bench(
+					SLX_PATH,
+					&args,
+					iters as usize
+				).expect("couldn't benchmark the SLX program")
+			)
 		);
 		
 		// benchmark the Rust implementation
-		group.measurement_time(Duration::from_secs(5));
 		group.bench_function(
 			BenchmarkId::new("Rust", sim_duration),
 			|b| b.iter_batched(
diff --git a/benches/philosophers.rs b/benches/philosophers.rs
index 654cc1b60893dd2ab6a6bd59e1dfaa8f6b80adbf..cb4aae7832579dc0c3c98274cea4f08a190c2707 100644
--- a/benches/philosophers.rs
+++ b/benches/philosophers.rs
@@ -1,15 +1,18 @@
-use criterion::{Criterion, BenchmarkId, criterion_group, criterion_main, BatchSize, PlotConfiguration, AxisScale, SamplingMode};
-use std::{process::Command, time::Duration};
-use itertools::Itertools;
+use criterion::{Criterion, BenchmarkId, criterion_group, criterion_main,
+                PlotConfiguration, AxisScale, SamplingMode};
 
-const SEED  :  u64  = 100000;
-const RANGE :  u32  =     10;
-const STEP  : usize =     10;
+mod support;
+
+const SLX_PATH: &'static str = "C:/Wolverine/SLX/sse.exe";
+const SEED:  u64 = 100000;
+const RANGE: u32 =     10;
+const STEP:  u64 =     10;
 const PHILOSOPHER_COUNT: usize = 5;
 
 fn philosopher_bench(c: &mut Criterion) {
 	let mut group = c.benchmark_group("Philosophers");
 	
+	// benchmark the SLX implementation
 	group.confidence_level(0.99);
 	group.plot_config(
 		PlotConfiguration::default()
@@ -17,8 +20,8 @@ fn philosopher_bench(c: &mut Criterion) {
 	);
 	group.sampling_mode(SamplingMode::Linear);
 	
-	for (i, experiment_count) in (0..RANGE).map(|c| (1 << c)*STEP).enumerate() {
-		// benchmark the SLX implementation
+	// vary in the number of performed experiments
+	for experiment_count in (0..RANGE).map(|c| (1 << c)*STEP) {
 		let count = experiment_count.to_string();
 		let args = [
 			"/silent",
@@ -31,46 +34,28 @@ fn philosopher_bench(c: &mut Criterion) {
 			count.as_str()
 		];
 		
-		group.measurement_time(Duration::from_secs(60));
+		// benchmark the SLX implementation
 		group.bench_function(
 			BenchmarkId::new("SLX", experiment_count),
-			|b| b.iter_custom(|iters| {
-				let rc = Command::new("C:/Wolverine/SLX/sse.exe")
-					.args(args.iter())
-					.arg(iters.to_string())
-					.output()
-					.expect("failed to run the SLX program");
-				
-				if !rc.status.success() {
-					panic!(match rc.status.code().unwrap() {
-						-10001 => "Unable to find a security key with SLX permission",
-						-10002 => "The command line includes an invalid option",
-						-10003 => "The source file cannot be found",
-						-10004 => "The specified/implied output file cannot be written",
-						-10005 => "The program contains compile-time errors",
-						-10006 => "The program has terminated with a run-time error",
-						-10007 => "The /genrts option failed",
-						_      => "Unknown error code"
-					})
-				}
-				
-				Duration::from_secs_f64(
-					(&String::from_utf8_lossy(&rc.stdout)).trim().parse().unwrap()
-				)
-			})
+			|b| b.iter_custom(|iters|
+				support::slx_bench(
+					SLX_PATH,
+					&args,
+					iters as usize
+				).expect("couldn't benchmark the SLX program")
+			)
 		);
 		
 		// benchmark the Rust implementation
-		group.measurement_time(Duration::from_secs(5));
 		group.bench_function(
 			BenchmarkId::new("Rust", experiment_count),
 			|b| b.iter(|| (1..=experiment_count)
 				.into_par_iter()
-				.map(|j|
+				.map(|experiment_no|
 					simulation(
 						// global data
 						Shared {
-							master_rng: RefCell::new(SmallRng::seed_from_u64(SEED*(((i+1)*j) as u64))),
+							master_rng: RefCell::new(SmallRng::seed_from_u64(SEED*experiment_no)),
 							sim_duration: Cell::default()
 						},
 						// simulation entry point
diff --git a/benches/support/mod.rs b/benches/support/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..f38c7cd1ad9006fe54c2a3f687f526c62dd67e05
--- /dev/null
+++ b/benches/support/mod.rs
@@ -0,0 +1,79 @@
+use std::{process::Command, time::Duration, iter::once};
+use itertools::Itertools;
+
+/// Runs the SLX runtime environment once for an SLX program that measures its
+/// own duration and returns it on the standard output.
+/// 
+/// Errors during this execution are returned back to the caller.
+fn slx_run_once(program: &str, arguments: &[&str], iterations: usize) -> Result<Duration, (i32, String)> {
+	// start the SLX runtime and wait for its return
+	let rc = Command::new(program)
+		.args(arguments)
+		.arg(iterations.to_string())
+		.output()
+		.map_err(|err| (-1, format!("Failed to run the SLX program: {}", err)))?;
+	
+	if !rc.status.success() {
+		// check the error code and add a description to it
+		Err(rc.status
+		      .code()
+		      .map_or_else(
+			      || (-10000, "Unknown error code".to_string()),
+			      |code| {
+				      (code, match code {
+					      -10001 => "Unable to find a security key with SLX permission".to_string(),
+					      -10002 => "The command line includes an invalid option".to_string(),
+					      -10003 => "The source file cannot be found".to_string(),
+					      -10004 => "The specified/implied output file cannot be written".to_string(),
+					      -10005 => "The program contains compile-time errors".to_string(),
+					      -10006 => "The program has terminated with a run-time error".to_string(),
+					      -10007 => "The /genrts option failed".to_string(),
+					      _ => format!("Unknown error code: {}", code)
+				      })
+			      }
+		      )
+		)
+	} else {
+		Ok(Duration::from_secs_f64(
+			(&String::from_utf8_lossy(&rc.stdout)).trim().parse().unwrap()
+		))
+	}
+}
+
+/// Repeats runs of an SLX program for a specified number of times and collects
+/// the total (real-time) duration of those combined runs.
+/// 
+/// The SLX program in question has to report its own real-time duration using
+/// the standard output.
+pub fn slx_bench(program: &str, arguments: &[&str], iterations: usize) -> Result<Duration, String> {
+	// try to complete the iterations in a single run of the SLX program
+	slx_run_once(program, arguments, iterations)
+		.or_else(|(code, desc)| {
+			if code == -10006 {
+				// Runtime error: this happens when the free version of SLX
+				// exceeds its total instance budget, either through a
+				// complicated scenario or too many iterations in one call.
+				// We can still make this work by running SLX multiple times
+				// with lower iteration counts and combining the timings.
+				// This effectively trades benchmark speed with simulation model
+				// size.
+				(1..)
+					.map(|i| iterations >> i)
+					.take_while(|&chunk_size| chunk_size > 0)
+					// .inspect(|chunk_size| println!("reducing the chunk size to {}", chunk_size))
+					.map(|chunk_size| {
+						(0..(iterations - 1)/chunk_size)
+							.map(|_| chunk_size)
+							.chain(once((iterations - 1) % chunk_size + 1))
+							.map(|size|
+								slx_run_once(program, arguments, size)
+							)
+							.fold_ok(Duration::default(), |duration, run| duration + run)
+					})
+					.find_map(|result| result.ok())
+					.ok_or(desc)
+			} else {
+				Err(desc)
+			}
+		})
+}
diff --git a/slx/barbershop.slx b/slx/barbershop.slx
index 0b330030c6864aecc017408163fa8ef22101c52a..50aa666ae6a0a5018fc1c960d965ef3687d5ba39 100644
--- a/slx/barbershop.slx
+++ b/slx/barbershop.slx
@@ -1,7 +1,7 @@
 import <h7>
 
 // enable this macro for the benchmark
-#define BENCH
+// #define BENCH
 
 module barbershop {
 	// globally shared data
diff --git a/src/main.rs b/src/main.rs
index ba03b4f27f12cbd0a272db7feda19f6cf909d4f9..d3ab051e23915939733a8424b28545c664e5940d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,30 +1,12 @@
-use simcore_rs::{channel, simulation};
 
 fn main() {
-	simulation(
-		(),
-		|sim| sim.process(async move {
-			println!("[{}] Begin", sim.now());
-			
-			let (sx, rx) = channel();
-			sim.activate(async move {
-				for i in 0.. {
-					sim.advance(1.0).await;
-					sx.send(i).await.ok();
-				}
-			});
-			
-			sim.select(async move {
-				while let Some(i) = rx.recv().await {
-					println!("[{}] Received {}", sim.now(), i);
-					if i >= 3 { break; }
-				}
-				
-				println!("[{}] Exit Receiver Process", sim.now());
-			}, sim.advance(5.0)).await;
-			
-			sim.advance(10.0).await;
-			println!("[{}] End", sim.now());
-		})
-	);
+	let iterations = 11;
+	let chunk_size = 4;
+	
+	let res: Vec<_> = (0..(iterations - 1)/chunk_size)
+		.map(|_| chunk_size)
+		.chain(std::iter::once((iterations - 1) % chunk_size + 1))
+		.collect();
+	
+	println!("{:?}", res);
 }