Index: src/benchmark/bench.c
===================================================================
--- src/benchmark/bench.c	(revision ac93b2287119108108d39026a0f27c1c260ea646)
+++ src/benchmark/bench.c	(revision ac93b2287119108108d39026a0f27c1c260ea646)
@@ -0,0 +1,246 @@
+
+#include <fstream>
+#include <stdlib>
+#include <threads>
+
+#include <unistd.h>					// sysconf
+#include <sys/times.h>					// times
+#include <time.h>
+
+inline unsigned long long int Time() {
+    timespec ts;
+    clock_gettime(
+#if defined( __linux__ )
+	 CLOCK_THREAD_CPUTIME_ID,
+#elif defined( __freebsd__ )
+	 CLOCK_PROF,
+#elif defined( __solaris__ )
+	 CLOCK_HIGHRES,
+#else
+    #error uC++ : internal error, unsupported architecture
+#endif
+	 &ts );
+    return 1000000000LL * ts.tv_sec + ts.tv_nsec;
+} // Time
+
+//=======================================
+// time struct
+//=======================================
+
+// prevent dead-code removal
+struct StructDummy {
+	volatile int i;
+};
+
+void ?{}(StructDummy * this) __attribute__(( noinline )) {
+	this->i = 2;
+}
+
+int get_i(StructDummy * this) {
+	return this->i;
+}
+
+forall( dtype T | { int get_i(T*); } )
+int bidirectional( StructDummy * this ) __attribute__(( noinline )) {
+	return get_i( this );
+}
+
+void BlockStructCreateDelete( int N ) {
+    long long int StartTime, EndTime;
+
+    StartTime = Time();
+    for ( int i = 0; i < N; i += 1 ) {
+	StructDummy dummy;
+    }
+    EndTime = Time();
+    sout | "\t " | ( EndTime - StartTime ) / N;
+}
+
+void DynamicStructCreateDelete( int N ) {
+    long long int StartTime, EndTime;
+
+    StartTime = Time();
+    for ( int i = 0; i < N; i += 1 ) {
+	StructDummy *dummy = new();
+	delete(dummy);
+    }
+    EndTime = Time();
+    sout | "\t " | ( EndTime - StartTime ) / N;
+}
+
+void StructBidirectional( int N ) {
+    long long int StartTime, EndTime;
+    StructDummy dummy;
+    volatile int rv __attribute__(( unused ));
+
+    StartTime = Time();
+    for ( int i = 0; i < N; i += 1 ) {
+	rv = bidirectional( &dummy ); 
+    }
+    EndTime = Time();
+    sout | "\t " | ( EndTime - StartTime ) / N;
+}
+
+//=======================================
+// time coroutine
+//=======================================
+
+struct CoroutineDummy { coroutine c; };
+DECL_COROUTINE(CoroutineDummy);
+void main(CoroutineDummy * this) {}
+
+void ?{}(CoroutineDummy * this) {
+	prime(this);
+}
+
+void BlockCoroutineCreateDelete( int N ) {
+    long long int StartTime, EndTime;
+
+    StartTime = Time();
+    for ( int i = 0; i < N; i += 1 ) {
+	CoroutineDummy dummy;
+    }
+    EndTime = Time();
+    sout | "\t " | ( EndTime - StartTime ) / N;
+}
+
+void DynamicCoroutineCreateDelete( int N ) {
+    long long int StartTime, EndTime;
+
+    StartTime = Time();
+    for ( int i = 0; i < N; i += 1 ) {
+	CoroutineDummy * dummy = new();
+	delete(dummy);
+    }
+    EndTime = Time();
+    sout | "\t " | ( EndTime - StartTime ) / N;
+}
+
+struct CoroutineResume {
+    int N;
+    coroutine c;
+};
+
+DECL_COROUTINE(CoroutineResume);
+
+void ?{}(CoroutineResume* this, int N) {
+      this->N = N;
+	prime(this);
+}
+
+void main(CoroutineResume* this) {
+	for ( int i = 1; i <= this->N; i += 1 ) {
+		suspend();
+	}
+}
+
+void resumer(CoroutineResume* this) {
+	long long int StartTime, EndTime;
+
+	StartTime = Time();
+	for ( int i = 1; i <= this->N; i += 1 ) {
+		resume(this);
+	}
+	EndTime = Time();
+	sout | "\t " | ( EndTime - StartTime ) / this->N;
+}
+
+//=======================================
+// time task
+//=======================================
+
+struct ThreadDummy { thread t; };
+DECL_THREAD(ThreadDummy);
+void main(ThreadDummy * this) {}
+
+void BlockTaskCreateDelete( int N ) {
+    long long int StartTime, EndTime;
+
+    StartTime = Time();
+    for ( int i = 0; i < N; i += 1 ) {
+	scoped(ThreadDummy) dummy;
+    }
+    EndTime = Time();
+    sout | "\t " | ( EndTime - StartTime ) / N;
+}
+
+void DynamicTaskCreateDelete( int N ) {
+    long long int StartTime, EndTime;
+
+    StartTime = Time();
+    for ( int i = 0; i < N; i += 1 ) {
+	scoped(ThreadDummy) * dummy = new();
+	delete(dummy);
+    }
+    EndTime = Time();
+    sout | "\t " | ( EndTime - StartTime ) / N;
+}
+
+struct ContextSwitch {
+    int N;
+    long long result;
+    thread t;
+};
+
+DECL_THREAD(ContextSwitch);
+
+void main(ContextSwitch * this) {    
+	long long int StartTime, EndTime;
+
+	StartTime = Time();
+	for ( int i = 1; i <= this->N; i += 1 ) {
+	    yield();
+	} // for
+	EndTime = Time();
+	this->result = ( EndTime - StartTime ) / this->N;
+}
+
+void ?{}(ContextSwitch * this, int N) {
+	this->N = N;
+}
+
+void ^?{}(ContextSwitch * this) {
+	sout | "\t " | this->result;
+}
+
+//=======================================
+// benchmark driver
+//=======================================
+
+
+int main() {
+	const int NoOfTimes =
+#if defined( __U_DEBUG__ )				// takes longer so run fewer iterations
+	100000;
+#else
+	1000000;
+#endif // __U_DEBUG__
+
+	sout | "\t\tcreate\tcreate\tcall/" | endl;
+	sout | "(nsecs)";
+	sout | "\t\tdelete/\tdelete/\tctx" | endl;
+	sout | "\t\tblock\tdynamic\tcycle" | endl;
+
+	sout | "object\t";
+	BlockStructCreateDelete( NoOfTimes );
+	DynamicStructCreateDelete( NoOfTimes );
+	StructBidirectional( NoOfTimes );
+	sout | endl;
+
+	sout | "coroutine";
+	BlockCoroutineCreateDelete( NoOfTimes );
+	DynamicCoroutineCreateDelete( NoOfTimes );
+	{
+		CoroutineResume resumer = { NoOfTimes };
+		resumer(&resumer);
+	}
+	sout | endl;
+
+	sout | "task\t";
+	BlockTaskCreateDelete( NoOfTimes );
+	DynamicTaskCreateDelete( NoOfTimes );
+	{
+		scoped(ContextSwitch) dummy = { (int)NoOfTimes };		// context switch
+	}
+	sout | "\t" | endl;
+}
