#include <fstream>
#include <kernel>
#include <monitor>
#include <stdlib>
#include <thread>

#include <time.h>

static const unsigned long N = 500ul;

#ifndef PREEMPTION_RATE
#define PREEMPTION_RATE 10`ms
#endif

Duration default_preemption() {
	return PREEMPTION_RATE;
}

monitor global_t {};

global_t globalA;

thread Acceptor {};
thread Acceptee {};

volatile bool done;

//----------------------------------------------------------------------------------------------------
// Acceptor
void do_notify( global_t * mutex a );

void do_wait( global_t * mutex a ) {
	sout | "Waiting to accept" | endl;
	yield( random( 10 ) );

	sout | "Accepting" | endl;

	__acceptable_t acceptable;
	acceptable.func          = (fptr_t)do_notify;
	acceptable.count         = 1;
	acceptable.monitors      = &a;

	__waitfor_internal( 1, &acceptable );

	sout | "Accepted" | endl;
	yield( random( 10 ) );
}

void main( Acceptor* this ) {
	for( int i = 0; i < N; i++ ) {
		do_wait( &globalA );
		sout | i | endl;
	}

	done = true;
}

//----------------------------------------------------------------------------------------------------
// Acceptee
void do_notify( global_t * mutex a ) {

}

void main( Acceptee* this ) {
	while( !done ) {
		yield( random( 10 ) );
		do_notify( &globalA );
		yield( random( 10 ) );
	}
}

//----------------------------------------------------------------------------------------------------
// Main
int main(int argc, char* argv[]) {
	done = false;
	srandom( time( NULL ) );
	printf("%p\n", &globalA);
	sout | "Starting" | endl;
	{
		Acceptor r;
		Acceptee e[13];

	}
	sout | "Done" | endl;
}
