// Gerry Brönnimann, ib03

public class ProducerConsumerMonitor extends Monitor{

	private static int slots;
	private Object [] ringbuffer;
	private int   slotsinuse = 0;
	private int   nextslottofill = 0;
	private int   nextslottoempty = 0;
	private Condition  ringbufferhasdata = new Condition();
	private Condition  ringbufferhasspace = new Condition();

	public ProducerConsumerMonitor(int i){
		ringbuffer = new Object[i];
		slots = i;
	}

	public void fillaslot(Object slotdata) {
		  if (slotsinuse == slots)
				ringbufferhasspace.Wait();
		  ringbuffer[nextslottofill] = slotdata;
		  slotsinuse= slotsinuse+1;
		  nextslottofill= (nextslottofill + 1) % slots;
		  ringbufferhasdata.Signal();
	}

	public Object emptyaslot (){
		  Object slotdata;
		  if (slotsinuse == 0)
				ringbufferhasdata.Wait();
		  slotdata = ringbuffer[nextslottoempty];
		  slotsinuse= slotsinuse-1;
		  nextslottoempty=(nextslottoempty+1) % slots;
		  ringbufferhasspace.Signal();
		  return slotdata;
    }

}
