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

monitor global_t {};

global_t globalB;
global_t globalA;

condition cond;

thread Signalee {};
thread Signaler {};

void signalee_action( global_t * mutex a, global_t * mutex b ) {
	sout | "Waiting All" | endl;
	wait( &cond );
	sout | "Done waiting" | endl;
}

void main( Signalee* this ) {
	signalee_action( &globalA, &globalB );
}

void signaler_action_inner( global_t * mutex a, global_t * mutex b ) {
	sout | "Entering A & B" | endl;
	sout | "Signal" | endl;
	signal( &cond );
	sout | "Leaving  A & B" | endl;
}

void signaler_action( global_t * mutex a, global_t * b ) {
	sout | "Entering A" | endl;
	signaler_action_inner( a, b );
	sout | "Leaving  A" | endl;
}

void main( Signaler* this ) {
	for(int i = 0; i < 10_000; i++) {
		asm volatile ("" : : : "memory");
	}

	signaler_action( &globalA, &globalB );
}

int main(int argc, char* argv[]) {
	processor p;
	{
		Signalee a;
		Signaler b;
	}
}