 1Content-type: application/x-Unknown; charset=UTF8package producerconsumerexample; 

import com.ajile.util.FifoQueue; 
import com.ajile.jem.rawJEM; 
import com.ajile.drivers.irq.InterruptEventListener;

/** 
 * Copyright:    Copyright (c) 2001 
 * Company:      Ajile 
 * @author       Phil Wiley 
 * @version 
 */ 

public class ConsumerThread extends Thread implements InterruptEventListener { 

  private WaitFreeQueue queue = new WaitFreeQueue(100); 

  /** 
   * public constructor. 
   */ 
  public ConsumerThread() { 
    // set the priority ceiling of this thread to interrupt level. 
    // This allows the interrupt handler to call synchronized methods 
    // within this class with out generating an illegal monitor state exception 
    rawJEM.setCeiling(this,31); 
  } 
  

  /** 
   * Method waits for data from the gpio interrupts, wakes up prints the data. 
   * It then waits for more data. 
   * 
   * The amount of time spend inside of the synchronized block should
   * be minimized.  The only statement that has to be synchronized is
   * the wait method.  The queue.dequeue is not inside of the
   * synchronized block since the queue does not require any
   * synchronization.
   */ 
  public void run() { 
    while(true) { 
      try { 
        synchronized(this) { 
          wait(); 
        } 
        while(!queue.isEmpty()) { 
          int data = queue.dequeue(); 

          //System.out.print("received "); 
          //System.out.print(data); 
          //System.out.println(" from sampling thread"); 
        } // end while 
      } catch (InterruptedException ie) { 
      } 
    } // end while 
  } // end run 

  /** 
   * this method will be called by the gpio interrupt handler. The entire 
   * method runs at interrupt level priority so there is no reason to minimize 
   * the size of the synchronize block 
   */ 
//    synchronized public void wakeUp(int data) { 
//      queue.enqueue(data); 
//      notifyAll(); 
//    } 

    private int interruptCounter = 18; 

    public void interruptEvent() {
        wakeUp();
        rawJEM.set(App.GPIOA_CLEAR_INT, SetupInfo.BITNUM);
    }

    synchronized /* public */ private void wakeUp() { 
    queue.enqueue(interruptCounter++); 
    notifyAll(); 
  } 


} // end consumerthread class 
  

//===================================================== 
// helper class 
//===================================================== 

/**
 * Setup information that the producer and consumer must agree on
 */
class SetupInfo {
    public static final int BITNUM = 5;
}

/** 
 * very simple and naive implementation of a wait free queue 
 */ 
class WaitFreeQueue { 
  private int[] buffer; 
  private int head; 
  private int tail; 
  private int bufferSize; 

  public WaitFreeQueue(int size) { 
    bufferSize = size; 
    buffer = new int[size]; 
    head = 0; 
    tail = 0; 
  } 

  public void enqueue(int data) { 
    int newHead = (head + 1) % bufferSize; 
    if (newHead == tail) { 
      System.out.println("buffer overflow"); 
      rawJEM.breakPoint("bufferoverflow"); 
    } else { 
      buffer[head]=data; 
      head = newHead; 
    } 
  } 

  public int dequeue() { 
    int data = 0; 
    if (head != tail) { 
      data = buffer[tail]; 
      int newTail = (tail+1)%bufferSize; 
      tail = newTail; 
    } 
    return data; 
  } // end dequeue 

  public boolean isEmpty() { 
    return (head == tail); 
  } 

} // end wait free queue 
