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

static int global12, global23, global13;

static monitor_desc m1, m2, m3;

void increment( /*mutex*/ monitor_desc * p1, /*mutex*/ monitor_desc * p2, int * value ) {
	monitor_desc * mons[] = { p1, p2 };
	monitor_guard_t g = { mons, 2 };
	*value += 1;
}

struct MyThread { 
	thread_desc t; 
	int target;
};

DECL_THREAD(MyThread);

void ?{}( MyThread * this, int target ) {
	this->target = target;
}

void main( MyThread* this ) {
	for(int i = 0; i < 1000000; i++) {
		choose(this->target) {
			case 0: increment( &m1, &m2, &global12 );
			case 1: increment( &m2, &m3, &global23 );
			case 2: increment( &m1, &m3, &global13 );
		}
	}
}

int main(int argc, char* argv[]) {
	processor p;
	{
		scoped(MyThread) * f[6];
		for(int i = 0; i < 6; i++) {
			f[i] = ((scoped(MyThread) *)malloc()){ i % 3 };
		}

		for(int i = 0; i < 6; i++) {
			delete( f[i] );
		}
	}
	sout | global12 | global23 | global13 | endl;
}