Index: src/examples/Bench.c
===================================================================
--- src/examples/Bench.c	(revision 059531a68fa2cdde9d256ef7ebd70ebcc93be6a2)
+++ src/examples/Bench.c	(revision a91dcc270d1d5243240ff73c2d041711535b0462)
@@ -1,5 +1,5 @@
-
 
 #include <fstream>
+#include <stdlib>
 #include <threads>
 
@@ -25,6 +25,95 @@
 
 //=======================================
+// 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 {
@@ -33,6 +122,5 @@
 };
 
-coroutine* get_coroutine(CoroutineResume* this);
-void co_main(CoroutineResume* this);
+DECL_COROUTINE(CoroutineResume)
 
 void ?{}(CoroutineResume* this, int N) {
@@ -41,13 +129,9 @@
 }
 
-coroutine* get_coroutine(CoroutineResume* this) {
-      return &this->c;
-}
-
-void co_main(CoroutineResume* this) {
+void main(CoroutineResume* this) {
 	for ( int i = 1; i <= this->N; i += 1 ) {
 		suspend();
-	} // for
-} // CoroutineResume::main
+	}
+}
 
 void resumer(CoroutineResume* this) {
@@ -57,8 +141,70 @@
 	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();
-	sout | "\t " | ( EndTime - StartTime ) / this->N;
-} // CoroutineResume::resumer
+	this->result = ( EndTime - StartTime ) / this->N;
+}
+
+void ?{}(ContextSwitch * this, int N) {
+	this->N = N;
+}
+
+void ^?{}(ContextSwitch * this) {
+	sout | "\t " | this->result;
+}
+
+//=======================================
+// benchmark driver
+//=======================================
 
 
@@ -71,23 +217,30 @@
 #endif // __U_DEBUG__
 
-	sout | "\t\tcreate\tcreate\t16i/4o\t16i/4o\tresume/\tsignal/" | endl;
+	sout | "\t\tcreate\tcreate\tcall/" | endl;
 	sout | "(nsecs)";
-	sout | "\t\tdelete/\tdelete/\tbytes\tbytes\tsuspend\twait" | endl;
-	sout | "\t\tblock\tdynamic\tdirect\taccept\tcycle\tcycle" | endl;
-
-	sout | "class\t";
-	sout | "\t N/A\t N/A\t N/A";
-	sout | "\t N/A\t N/A\t N/A";
-	sout | "\t" | endl;
+	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";
-	sout | "\t N/A\t N/A\t N/A";
-	sout | "\t N/A";
+	BlockCoroutineCreateDelete( NoOfTimes );
+	DynamicCoroutineCreateDelete( NoOfTimes );
 	{
 		CoroutineResume resumer = { NoOfTimes };
 		resumer(&resumer);
 	}
-	sout | "\t N/A";
-
+	sout | endl;
+
+	sout | "task\t";
+	BlockTaskCreateDelete( NoOfTimes );
+	DynamicTaskCreateDelete( NoOfTimes );
+	{
+		scoped(ContextSwitch) dummy = { (int)NoOfTimes };		// context switch
+	}
 	sout | "\t" | endl;
 }
