import Concurrent.*;

public class EventCounterMutex {

	private Mutex inputcounter = new Mutex();
	private Mutex outputcounter = new Mutex();
	private int slots = 0;
	private Object [] buffer;
	private int inputsequence = 0;
	private int outputsequence = 0;

	public EventCounterExample(int i){
		buffer = new Object[i];
		slots = i;
	}

	public class producer extends Thread {

		public producer(){
			start();
		}

		public void run(){
		Object item;
		while (true){
			item = produce();
			inputsequence = inputsequence+1;


			outputcounter.await(inputsequence-slots);
			buffer[(inputsequence-1) % slots]= item;
			inputcounter.advance();
			}
		}
	}

	public class consumer extends Thread{

		public consumer(){
			start();
		}
		public void run(){
			Object item;
			while (true){
				outputsequence = outputsequence+1;
				inputcounter.await(outputsequence);
				item= buffer[(outputsequence-1 % slots)];
				outputcounter.advance();
				consume(item);
			}
		}
	}
	producer my_producer = new producer();
	consumer my_consumer = new consumer();

	public static void main(String[] args ){
		EventCounterExample evct = new EventCounterExample(10);
	}
}
