/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.nativelibs4java.opencl.blas;
import com.nativelibs4java.opencl.CLEvent;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author ochafik
*/
public class CLEvents {
CLEvent lastWriteEvent;
List<CLEvent> readEvents = new ArrayList<CLEvent>();
List<Listener> listeners = new ArrayList<Listener>();
public interface Listener {
void writing(CLEvents evts);
void reading(CLEvents evts);
}
public interface Action {
CLEvent perform(CLEvent[] events);
}
public synchronized void addListener(Listener l) {
listeners.add(l);
}
public synchronized void removeListener(Listener l) {
listeners.remove(l);
}
static final CLEvent[] EMPTY_EVENTS = new CLEvent[0];
protected synchronized CLEvent clearEvents(Action action) {
int nReads = readEvents.size();
boolean hasWrite = lastWriteEvent != null;
int n = nReads + (hasWrite ? 1 : 0);
CLEvent[] evts = n == 0 ? EMPTY_EVENTS : readEvents.toArray(new CLEvent[n]);
if (hasWrite)
evts[nReads] = lastWriteEvent;
CLEvent evt = action.perform(evts);
lastWriteEvent = null;
readEvents.clear();
return evt;
}
public synchronized CLEvent performRead(Action action) {
for (Listener listener : listeners)
listener.writing(this);
CLEvent evt = action.perform(lastWriteEvent == null ? EMPTY_EVENTS : new CLEvent[] { lastWriteEvent });
if (evt != null) {
readEvents.add(evt);
lastWriteEvent = null; // read completed only if the optional write also completed
}
return evt;
}
public synchronized void performRead(Runnable action) {
for (Listener listener : listeners)
listener.reading(this);
waitForRead();
action.run();
}
public synchronized CLEvent performWrite(Action action) {
return lastWriteEvent = clearEvents(action);
}
/**
* Wait until all write operations are completed so that the data is readable.
*/
public synchronized void waitForRead() {
CLEvent.waitFor(lastWriteEvent);
lastWriteEvent = null;
}
/**
* Wait for all associated operations to complete (read or write).
*/
public synchronized void waitFor() {
clearEvents(new Action() {
public CLEvent perform(CLEvent[] evts) {
CLEvent.waitFor(evts);
return null;
}
});
}
}