

#include <fstream>
#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 coroutine
//=======================================

struct CoroutineResume {
    int N;
    coroutine c;
};

coroutine* get_coroutine(CoroutineResume* this);
void co_main(CoroutineResume* this);

void ?{}(CoroutineResume* this, int N) {
      this->N = N;
	prime(this);
}

coroutine* get_coroutine(CoroutineResume* this) {
      return &this->c;
}

void co_main(CoroutineResume* this) {
	for ( int i = 1; i <= this->N; i += 1 ) {
		suspend();
	} // for
} // CoroutineResume::main

void resumer(CoroutineResume* this) {
	long long int StartTime, EndTime;

	StartTime = Time();
	for ( int i = 1; i <= this->N; i += 1 ) {
		resume(this);
	} // for
	EndTime = Time();
	sout | "\t " | ( EndTime - StartTime ) / this->N;
} // CoroutineResume::resumer


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\t16i/4o\t16i/4o\tresume/\tsignal/" | 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 | "coroutine";
	sout | "\t N/A\t N/A\t N/A";
	sout | "\t N/A";
	{
		CoroutineResume resumer = { NoOfTimes };
		resumer(&resumer);
	}
	sout | "\t N/A";

	sout | "\t" | endl;
}