#include <fstream>
#include <stdlib>
#include <thread>

#include "bench.h"

condition condA; 
condition condB;
condition condC;
condition condD;

monitor mon_t {};

mon_t mon1, mon2;

thread thrdA {};
thread thrdB {};
thread thrdC {};
thread thrdD {};

//-------------------------------------------------------------------
// 1 monitor signal cycle
void sideA( mon_t * mutex a ) {
	long long int StartTime, EndTime;

	StartTime = Time();
	for( int i = 0;; i++ ) {
		signal(&condA);
		if( i > N ) break;
		wait(&condB);
	}
	EndTime = Time();

	sout | ( EndTime - StartTime ) / N;
}

void sideB( mon_t * mutex a ) {
	for( int i = 0;; i++ ) {
		signal(&condB);
		if( i > N ) break;
		wait(&condA);
	}
}

//-------------------------------------------------------------------
// 2 monitor signal cycle
void sideC( mon_t * mutex a, mon_t * mutex b ) {
	long long int StartTime, EndTime;

	StartTime = Time();
	for( int i = 0;; i++ ) {
		signal(&condC);
		if( i > N ) break;
		wait(&condD);
	}
	EndTime = Time();

	sout | ( EndTime - StartTime ) / N | endl;
}

void sideD( mon_t * mutex a, mon_t * mutex b ) {
	for( int i = 0;; i++ ) {
		signal(&condD);
		if( i > N ) break;
		wait(&condC);
	}
}

void main( thrdA * this ) { sideA( &mon1 ); }
void main( thrdB * this ) { sideB( &mon1 ); }
void main( thrdC * this ) { sideC( &mon1, &mon2 ); }
void main( thrdD * this ) { sideD( &mon1, &mon2 ); }

int main() {
	{
		thrdA a;
		thrdB b;
	}
	{
		thrdC c;
		thrdD d;
	}
}