// 
// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
// 
// prodcons.c -- 
// 
// Author           : Peter A. Buhr
// Created On       : Mon Sep 18 12:23:39 2017
// Last Modified By : Peter A. Buhr
// Last Modified On : Tue Jan  2 12:17:01 2018
// Update Count     : 47
// 

#include <fstream>
#include <coroutine>
#include <stdlib>										// random
#include <unistd.h>										// getpid

coroutine Cons;											// forward
int delivery( Cons & cons, int p1, int p2 );
void stop( Cons & cons );

coroutine Prod {
	Cons * c;
	int N, money, receipt;
};
void main( Prod & prod ) with( prod ) {					// starter ::main
	// 1st resume starts here
	for ( int i = 0; i < N; i += 1 ) {
		int p1 = random( 100 );
		int p2 = random( 100 );
		sout | p1 | " " | p2 | endl;
		int status = delivery( *c, p1, p2 );
		sout | " $" | money | endl;
		sout | status | endl;
		receipt += 1;
	}
	stop( *c );
	sout | "prod stops" | endl;
}
int payment( Prod & prod, int money ) {
	prod.money = money;
	resume( prod );										// main 1st time, then
	return prod.receipt;								// prod in delivery
}
void start( Prod & prod, int N, Cons &c ) {
	prod.N = N;
	prod.c = &c;
	prod.receipt = 0;
	resume( prod );										// activate main
}

coroutine Cons {
	Prod * p;
	int p1, p2, status;
	bool done;
};
void ?{}( Cons & cons, Prod & p ) {
	cons.p = &p;
	cons.status = 0;
	cons.done = false;
}
void ^?{}( Cons & cons ) {}
void main( Cons & cons ) with( cons ) {					// starter prod
	// 1st resume starts here
	int money = 1, receipt;
	for ( ; ! done; ) {
		sout | p1 | " " | p2 | endl;
		sout | " $" | money | endl;
		status += 1;
		receipt = payment( *p, money );
		sout | " #" | receipt | endl;
		money += 1;
	}
	sout | "cons stops" | endl;
}
int delivery( Cons & cons, int p1, int p2 ) {
	cons.p1 = p1;
	cons.p2 = p2;
	resume( cons );										// main 1st time, then
	return cons.status;									// cons in payment
}
void stop( Cons & cons ) {
	cons.done = true;
	resume( cons );										// activate payment
}
int main() {
	Prod prod;
	Cons cons = { prod };
	srandom( /* getpid() */ 103 );						// fixed seed for testing
	start( prod, 5, cons );
	sout | "main stops" | endl;
}

// Local Variables: //
// tab-width: 4 //
// compile-command: "cfa prodcons.c" //
// End: //
