package pt.ul.jarmus;
import java.util.Collection;
import pt.ul.armus.Armus;
import pt.ul.armus.edgebuffer.TaskHandle;
/**
* Interacts with Armus. Maintains a registry of barriers and generates the
* edges for the deadlock verification.
*
* @author Tiago Cogumbreiro (cogumbreiro@di.fc.ul.pt)
*
*/
class JArmusControllerImpl implements JArmusController {
private final Armus verifier;
private final ThreadLocal<ResourceManager> resourceManager = new ThreadLocal<ResourceManager>() {
@Override
protected ResourceManager initialValue() {
ResourceManager task = new ResourceManager(verifier.getBuffer().createHandle());
task.register(Thread.currentThread(), 1);
return task;
};
};
public JArmusControllerImpl(Armus verifier) {
this.verifier = verifier;
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#start()
*/
@Override
public void start() {
verifier.start(); // launch the handler
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#stop()
*/
@Override
public void stop() {
verifier.stop();
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#deregister(java.lang.Object)
*/
@Override
public void deregister(Object synch) {
if (! resourceManager.get().deregister(synch)) {
throw new IllegalStateException("Object not registred: " + synch);
}
}
@Override
public boolean tryDeregister(Object synch) {
return resourceManager.get().deregister(synch);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#deregisterAll()
*/
@Override
public void deregisterAll() {
resourceManager.get().clear();
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#isRegistered(java.lang.Object)
*/
@Override
public boolean isRegistered(Object synch) {
return resourceManager.get().isRegistered(synch);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#ensureRegistered(java.lang.Object)
*/
@Override
public void ensureRegistered(Object synch) {
resourceManager.get().ensureRegistered(synch);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#register(java.lang.Object, int)
*/
@Override
public void register(Object synch, int phase) {
resourceManager.get().register(synch, phase);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#advance(java.lang.Object)
*/
@Override
public int advance(Object synch) {
return resourceManager.get().advance(synch);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#getPhase(java.lang.Object)
*/
@Override
public int getPhase(Object synch) {
return resourceManager.get().getPhase(synch);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#beforeAdvanceAwait(java.lang.Object)
*/
@Override
public int beforeAdvanceAwait(Object synch)
throws DeadlockIdentifiedException {
ResourceManager taskView = resourceManager.get();
int phase = taskView.advance(synch);
taskView.beforeAwait(synch, phase);
return phase;
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#beforeTask()
*/
@Override
public void beforeTask() {
ResourceManager task = resourceManager.get();
task.beginTask(verifier.getBuffer().createHandle());
task.register(Thread.currentThread(), 1); // always register the current thread as a barrier
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#afterTask()
*/
@Override
public void afterTask() {
ResourceManager task = resourceManager.get();
TaskHandle oldTask = task.endTask();
verifier.getBuffer().destroy(oldTask);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#beforeAwaitMany(java.util.Collection, int)
*/
@Override
public void beforeAwaitMany(Collection<?> synch, int phase)
throws DeadlockIdentifiedException {
ResourceManager taskView = resourceManager.get();
taskView.beforeAwaitMany(synch, phase);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#beforeAwait(java.lang.Object, int)
*/
@Override
public void beforeAwait(Object synch, int phase)
throws DeadlockIdentifiedException {
ResourceManager taskView = resourceManager.get();
taskView.beforeAwait(synch, phase);
}
/* (non-Javadoc)
* @see pt.ul.jarmus.JArmusFacade#afterAwait()
*/
@Override
public void afterAwait() {
ResourceManager taskView = resourceManager.get();
taskView.afterAwait();
}
}