package edu.vt.rt.hyflow.benchmark.realtimermi;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.concurrent.atomic.AtomicBoolean;
import edu.vt.realtime.ChronosAborts;
import edu.vt.realtime.ChronosMutex;
import edu.vt.realtime.ChronosScheduler;
import edu.vt.realtime.ChronosUtil;
import edu.vt.realtime.Timespec;
import edu.vt.rt.hyflow.benchmark.Priorities;
import edu.vt.rt.hyflow.util.io.Logger;
import edu.vt.rt.hyflow.util.network.Network;
public class Lockable extends UnicastRemoteObject
implements ILockabel{
protected AtomicBoolean lock = new AtomicBoolean();
//protected ChronosMutex lock = new ChronosMutex();
private ChronosAborts aborts;
protected boolean enableTimeout = true;
private boolean destroied = false;
private String id;
public static int timouts;
protected Lockable(String id) throws RemoteException {
super();
this.id = id;
try {
UnicastRemoteObject.unexportObject(this, true);
} catch (Exception e) {
Logger.error("RMI unexporting");
}
Remote stub = UnicastRemoteObject.exportObject(this, 0);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.getRegistry(Network.getInstance().getPort());
registry.rebind(id, stub);
//this.aborts = ChronosScheduler.initAborts();
}
@Override
public void destroy() throws RemoteException {
destroied = true;
final Lockable me = this;
new Thread(){
public void run() {
// System.err.println("Destroy >--@@@@ B O O M @@@@--<");
// Wait for quiescent time
try {
Thread.sleep(edu.vt.rt.hyflow.benchmark.Benchmark.timout()*2);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
// Unbind the remote object's stub in the registry
try {
Registry registry = LocateRegistry.getRegistry(Network.getInstance().getPort());
registry.unbind(id);
} catch (RemoteException e1) {
e1.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
try {
UnicastRemoteObject.unexportObject(me, true);
} catch (Exception e) {
Logger.error("RMI unexporting");
}
}
}.start();
}
@Override
public void lock() throws RemoteException, InterruptedException {
long start = System.currentTimeMillis();
boolean timedout = false;
long timeoutPeriod = edu.vt.rt.hyflow.benchmark.Benchmark.timout();
while(!destroied && !lock.compareAndSet(false, true)){
if(enableTimeout && System.currentTimeMillis() - start > timeoutPeriod){
timedout = true;
timouts++;
break;
}
}
if(destroied || timedout)
throw new InterruptedException();
/*if(!destroied)
lock.lock();
if(destroied) //|| timedout)
throw new InterruptedException();
*/
}
@Override
public void unlock() throws RemoteException {
//lock.unlock();
lock.set(false);
}
@Override
public void lock(long deadlineSec, long deadlineNSec, long period_tsSec, long period_tsNSec) throws RemoteException, InterruptedException {
long start = System.currentTimeMillis();
boolean timedout = false;
long timeoutPeriod = edu.vt.rt.hyflow.benchmark.Benchmark.timout();
int count =0;
//this.aborts = ChronosScheduler.initAborts();
this.aborts = edu.vt.rt.hyflow.benchmark.Benchmark.getAbortHandler();
Timespec deadline = new Timespec();
deadline.setTime(deadlineSec, deadlineNSec);
Timespec period_ts = new Timespec();
period_ts.setTime(period_tsSec, period_tsNSec);
Timespec iota_time = new Timespec();
iota_time.setTime(0, 5000000); // 5 mSec
//deadline.subtract(iota_time);
//period_ts.subtract(iota_time);
Timespec currenttime = new Timespec();
currenttime.getTime();
if(currenttime.greaterThan(deadline)) {
//System.out.println("T_O AB1");
//System.out.println("Currenttime= " + currenttime.getSeconds() + " S " + currenttime.getNanoseconds() + " ns");
//System.out.println("Currenttime= " + deadline.getSeconds() + " S " + deadline.getNanoseconds() + " ns");
throw new InterruptedException();
}
ChronosScheduler.beginSegment(Priorities.TASK_RUN.getNativeId(), 2, deadline, period_ts, 0);
while(!destroied && !lock.compareAndSet(false, true)){
//if(enableTimeout && System.currentTimeMillis() - start > timeoutPeriod){
currenttime.getTime();
if(currenttime.greaterThan(deadline)) {
timedout = true;
break;
}
// timouts++;
// break;
//}
count++;
}
if(destroied || timedout)
throw new InterruptedException();
/*if(!destroied)
lock.lock();
if(destroied) //|| timedout)
throw new InterruptedException();
*/
ChronosScheduler.endSegment(Priorities.TASK_CLEANUP.getNativeId());
if(this.aborts.wasAborted(ChronosUtil.gettid())) {
System.out.println("T_O ABL");
throw new InterruptedException();
}
}
@Override
public void unlock(long deadlineSec, long deadlineNSec, long period_tsSec, long period_tsNSec) throws InterruptedException {
//this.aborts = ChronosScheduler.initAborts();
this.aborts = edu.vt.rt.hyflow.benchmark.Benchmark.getAbortHandler();
Timespec deadline = new Timespec();
deadline.setTime(deadlineSec, deadlineNSec);
Timespec period_ts = new Timespec();
period_ts.setTime(period_tsSec, period_tsNSec);
Timespec iota_time = new Timespec();
iota_time.setTime(0, 5000000); // 5 mSec
//deadline.subtract(iota_time);
//period_ts.subtract(iota_time);
ChronosScheduler.beginSegment(Priorities.TASK_RUN.getNativeId(), 0, deadline, period_ts, 0);
//lock.unlock();
lock.set(false);
ChronosScheduler.endSegment(Priorities.TASK_CLEANUP.getNativeId());
if(this.aborts.wasAborted(ChronosUtil.gettid())) {
System.out.println("T_O ABU");
throw new InterruptedException();
}
}
}