//********************************************************
//
// BoundedOvertakingAllocator Class
//
package concurrency.golf;

public class BoundedOvertakingAllocator implements Allocator{

  private int available;
  private int turn = 0;
  private int next = 0;
  private int bound;
  private int overtaken =0;

  public BoundedOvertakingAllocator(int n, int b)
    { available = n; bound = b;}

  synchronized public void get(int n)
          throws InterruptedException{
    int myturn = turn; ++turn;
    boolean overtakenMe = false;
    while (n>available || (overtaken>0 && !overtakenMe)) {
      wait();
      if ((next>= (myturn + bound)) && !overtakenMe) {
        overtakenMe = true; ++overtaken;
      }
    }
    if (overtakenMe) --overtaken;
    ++next; available -= n;
    notifyAll();
  }

  synchronized public void put(int n) {
    available += n;
    notifyAll();
  }
}
//********************************************************

