--- /dev/null
+import java.util.Random;
+
+public class Executor {
+ int numThreads;
+ int numTrans;
+ int deltaTrans;
+ int numObjects;
+ int numAccesses;
+ int deltaAccesses;
+ int delay;
+ int deltaDelay;
+ int nonTrans;
+ int deltaNonTrans;
+ int readPercent;
+ Random r;
+ ThreadClass[] threads;
+
+ public Executor(int numThreads, int numTrans, int deltaTrans, int numObjects, int numAccesses, int deltaAccesses, int readPercent, int delay, int deltaDelay, int nonTrans, int deltaNonTrans) {
+ this.numThreads=numThreads;
+ this.numTrans=numTrans;
+ this.deltaTrans=deltaTrans;
+ this.numObjects=numObjects;
+ this.numAccesses=numAccesses;
+ this.deltaAccesses=deltaAccesses;
+ this.readPercent=readPercent;
+ this.delay=delay;
+ this.deltaDelay=deltaDelay;
+ this.nonTrans=nonTrans;
+ this.deltaNonTrans=deltaNonTrans;
+ r=new Random();
+ threads=new ThreadClass[numThreads];
+ generateThreads();
+ }
+
+ public int maxTime() {
+ int maxtime=0;
+ for(int i=0;i<numThreads;i++) {
+ int time=0;
+ for(int j=0;j<getThread(i).numTransactions();j++) {
+ Transaction trans=getThread(i).getTransaction(j);
+ time+=trans.getTime(trans.numEvents()-1);
+ }
+ if (time>maxtime)
+ maxtime=time;
+ }
+ return maxtime;
+ }
+
+ public int numObjects() {
+ return numObjects;
+ }
+
+ public int numThreads() {
+ return numThreads;
+ }
+
+ public int numEvents() {
+ int events=0;
+ for(int i=0;i<numThreads();i++) {
+ events+=getThread(i).numTransactions();
+ }
+ return events;
+ }
+
+ public int maxEvents() {
+ int events=0;
+ for(int i=0;i<numThreads();i++) {
+ if (events<getThread(i).numTransactions())
+ events=getThread(i).numTransactions();
+ }
+ return events;
+ }
+
+ public ThreadClass getThread(int i) {
+ return threads[i];
+ }
+
+ private int getRandom(int base, int delta) {
+ return base+delta-r.nextInt(2*delta+1);
+ }
+
+ public void generateThreads() {
+ for(int i=0;i<numThreads;i++) {
+ threads[i]=generateThread();
+ }
+ }
+
+ private Transaction generateTransaction() {
+ int accesses=getRandom(numAccesses, deltaAccesses);
+ Transaction t=new Transaction(accesses);
+ int time=0;
+ for(int i=0;i<accesses; i++) {
+ boolean isRead=r.nextInt(100)<readPercent;
+ time+=getRandom(delay, deltaDelay);
+ int object=r.nextInt(numObjects);
+ t.setObject(i, object);
+ t.setTime(i, time);
+ if (isRead)
+ t.setEvent(i, Transaction.READ);
+ else
+ t.setEvent(i, Transaction.WRITE);
+ }
+ return t;
+ }
+
+ private ThreadClass generateThread() {
+ int numTransactions=getRandom(numTrans, deltaTrans);
+ ThreadClass t=new ThreadClass(numTransactions*2);
+ for(int i=0;i<numTransactions;i++) {
+ Transaction trans=generateTransaction();
+ t.setTransaction(i*2, trans);
+ Transaction transdelay=new Transaction(1);
+ transdelay.setObject(0,Transaction.DELAY);
+ transdelay.setEvent(0,Transaction.DELAY);
+ transdelay.setTime(0, getRandom(nonTrans, deltaNonTrans));
+ t.setTransaction(i*2+1, transdelay);
+ }
+ return t;
+ }
+}
\ No newline at end of file
--- /dev/null
+import java.util.*;
+
+public class FlexScheduler {
+ Executor e;
+
+ public FlexScheduler(Executor e, int policy) {
+ this.e=e;
+ aborted=new boolean[e.numThreads()];
+ currentevents=new Event[e.numThreads()];
+ rdobjmap=new Hashtable();
+ wrobjmap=new Hashtable();
+ this.policy=policy;
+ r=new Random(100);
+ eq=new PriorityQueue();
+ backoff=new int[e.numThreads()];
+ for(int i=0;i<e.numThreads();i++) {
+ backoff[i]=1;
+ }
+ }
+
+ public static final int LAZY=0;
+ public static final int COMMIT=1;
+ public static final int ATTACK=2;
+ public static final int POLITE=3;
+ public static final int KARMA=4;
+
+ PriorityQueue eq;
+ int policy;
+ boolean[] aborted;
+ int shorttesttime;
+ Hashtable rdobjmap;
+ Hashtable wrobjmap;
+ int abortcount;
+ int commitcount;
+ Event[] currentevents;
+ Random r;
+ int[] backoff;
+
+ public boolean isEager() {
+ return policy==ATTACK||policy==POLITE||policy==KARMA;
+ }
+
+ public int getAborts() {
+ return abortcount;
+ }
+
+ public int getCommits() {
+ return commitcount;
+ }
+
+ public int getTime() {
+ return shorttesttime;
+ }
+
+ public void reschedule(int currthread, int time) {
+ currentevents[currthread].makeInvalid();
+ Transaction trans=currentevents[currthread].getTransaction();
+
+ //remove all events
+ for(int i=0;i<trans.numEvents();i++) {
+ int object=trans.getObject(i);
+ if (object!=-1&&rdobjmap.containsKey(new Integer(object))) {
+ ((Set)rdobjmap.get(new Integer(object))).remove(new Integer(currthread));
+ }
+ if (object!=-1&&wrobjmap.containsKey(new Integer(object))) {
+ ((Set)wrobjmap.get(new Integer(object))).remove(new Integer(currthread));
+ }
+ }
+
+ Event nev=new Event(time+trans.getTime(0), trans, 0, currthread, currentevents[currthread].getTransNum());
+ currentevents[currthread]=nev;
+ eq.add(nev);
+ }
+
+ public void startinitial() {
+ for(int i=0;i<e.numThreads();i++) {
+ Transaction trans=e.getThread(i).getTransaction(0);
+ int time=trans.getTime(0);
+ Event ev=new Event(time, trans, 0, i, 0);
+ currentevents[i]=ev;
+ eq.add(ev);
+ }
+ }
+
+ public void dosim() {
+ int lasttime=0;
+ //start first transactions
+ startinitial();
+
+ while(!eq.isEmpty()) {
+ Event ev=(Event)eq.poll();
+ if (!ev.isValid())
+ continue;
+
+ Transaction trans=ev.getTransaction();
+ int event=ev.getEvent();
+ int currtime=ev.getTime();
+ lasttime=currtime;
+
+ if (trans.numEvents()==(event+1)) {
+ tryCommit(ev, trans);
+ } else {
+ enqueueEvent(ev, trans);
+ }
+ }
+ shorttesttime=lasttime;
+ }
+
+
+ public void tryCommit(Event ev, Transaction trans) {
+ //ready to commit this one
+ int currtime=ev.getTime();
+
+ //Remove everything we put in object sets
+ for(int i=0;i<trans.numEvents();i++) {
+ int object=trans.getObject(i);
+ if (object!=-1&&rdobjmap.containsKey(new Integer(object))) {
+ ((Set)rdobjmap.get(new Integer(object))).remove(new Integer(ev.getThread()));
+ }
+ if (object!=-1&&wrobjmap.containsKey(new Integer(object))) {
+ ((Set)wrobjmap.get(new Integer(object))).remove(new Integer(ev.getThread()));
+ }
+ }
+
+ //See if we have been flagged as aborted
+ boolean abort=aborted[ev.getThread()];
+ aborted[ev.getThread()]=false;
+ if (!abort) {
+ if (trans.numEvents()>1||trans.getEvent(0)!=Transaction.DELAY) {
+ commitcount++;
+ }
+ backoff[ev.getThread()]=1;
+ //abort the other threads
+ for(int i=0;i<trans.numEvents();i++) {
+ int object=trans.getObject(i);
+ int op=trans.getEvent(i);
+ if (op==Transaction.WRITE) {
+ HashSet abortset=new HashSet();
+ if (rdobjmap.containsKey(new Integer(object))) {
+ for(Iterator it=((Set)rdobjmap.get(new Integer(object))).iterator();it.hasNext();) {
+ Integer threadid=(Integer)it.next();
+ abortset.add(threadid);
+ }
+ }
+ if (wrobjmap.containsKey(new Integer(object))) {
+ for(Iterator it=((Set)wrobjmap.get(new Integer(object))).iterator();it.hasNext();) {
+ Integer threadid=(Integer)it.next();
+ abortset.add(threadid);
+ }
+ }
+ for(Iterator abit=abortset.iterator();abit.hasNext();) {
+ Integer threadid=(Integer)abit.next();
+ if (policy==LAZY) {
+ aborted[threadid]=true;
+ } else if (policy==COMMIT) {
+ reschedule(threadid, currtime);
+ abortcount++;
+ }
+ }
+ }
+ }
+ } else {
+ abortcount++;
+ }
+
+ //add next transaction event...could be us if we aborted
+ int nexttransnum=abort?ev.getTransNum():ev.getTransNum()+1;
+ if (nexttransnum<e.getThread(ev.getThread()).numTransactions()) {
+ Transaction nexttrans=e.getThread(ev.getThread()).getTransaction(nexttransnum);
+ Event nev=new Event(currtime+nexttrans.getTime(0), nexttrans, 0, ev.getThread(), nexttransnum);
+ currentevents[ev.getThread()]=nev;
+ eq.add(nev);
+ }
+ }
+
+ public Set rdConflictSet(int thread, int object) {
+ Integer obj=new Integer(object);
+ if (!wrobjmap.containsKey(obj))
+ return null;
+ HashSet conflictset=new HashSet();
+ for(Iterator it=((Set)wrobjmap.get(obj)).iterator();it.hasNext();) {
+ Integer threadid=(Integer)it.next();
+ if (threadid.intValue()!=thread)
+ conflictset.add(threadid);
+ }
+ if (conflictset.isEmpty())
+ return null;
+ else
+ return conflictset;
+ }
+
+ public Set wrConflictSet(int thread, int object) {
+ Integer obj=new Integer(object);
+ if (!rdobjmap.containsKey(obj))
+ return null;
+ HashSet conflictset=new HashSet();
+ for(Iterator it=((Set)rdobjmap.get(obj)).iterator();it.hasNext();) {
+ Integer threadid=(Integer)it.next();
+ if (threadid.intValue()!=thread)
+ conflictset.add(threadid);
+ }
+ if (conflictset.isEmpty())
+ return null;
+ else
+ return conflictset;
+ }
+
+ //Takes as parameter -- current transaction read event ev, conflicting
+ //set of threads, and the current time
+
+ public boolean handleConflicts(Event ev, Set threadstokill, int time) {
+ if (policy==ATTACK) {
+ for(Iterator thit=threadstokill.iterator();thit.hasNext();) {
+ Integer thread=(Integer)thit.next();
+ reschedule(thread, time+r.nextInt(backoff[thread.intValue()]));
+ backoff[thread.intValue()]*=2;
+ abortcount++;
+ }
+ return true;
+ } else if (policy==POLITE) {
+ reschedule(ev.getThread(), time+r.nextInt(backoff[ev.getThread()]));
+ backoff[ev.getThread()]*=2;
+ abortcount++;
+ return false;
+ } else if (policy==KARMA) {
+ int opponenttime=0;
+
+ for(Iterator thit=threadstokill.iterator();thit.hasNext();) {
+ Integer thread=(Integer)thit.next();
+ Event other=currentevents[thread.intValue()];
+ int eventnum=other.getEvent();
+ int otime=other.getTransaction().getTime(other.getEvent());
+ if (otime>opponenttime)
+ opponenttime=otime;
+ }
+ if (opponenttime>ev.getTransaction().getTime(ev.getEvent())) {
+ //kill ourself
+ reschedule(ev.getThread(), time+r.nextInt(backoff[ev.getThread()]));
+ backoff[ev.getThread()]*=2;
+ abortcount++;
+ return false;
+ } else {
+ //kill the opponents
+ for(Iterator thit=threadstokill.iterator();thit.hasNext();) {
+ Integer thread=(Integer)thit.next();
+ reschedule(thread, time+r.nextInt(backoff[thread.intValue()]));
+ backoff[thread.intValue()]*=2;
+ abortcount++;
+ }
+ return true;
+ }
+ }
+
+ //Not eager
+ return true;
+ }
+
+ public void enqueueEvent(Event ev, Transaction trans) {
+ //just enqueue next event
+ int event=ev.getEvent();
+ int currtime=ev.getTime();
+ int object=trans.getObject(event);
+ int operation=trans.getEvent(event);
+ //process the current event
+ if (operation==Transaction.READ) {
+ Integer obj=new Integer(object);
+ if (!rdobjmap.containsKey(obj))
+ rdobjmap.put(obj,new HashSet());
+ ((Set)rdobjmap.get(obj)).add(new Integer(ev.getThread()));
+ if (isEager()) {
+ Set conflicts=rdConflictSet(ev.getThread(), object);
+ if (conflicts!=null)
+ if (!handleConflicts(ev, conflicts, currtime))
+ return;
+ }
+ } else if (operation==Transaction.WRITE) {
+ Integer obj=new Integer(object);
+ if (!wrobjmap.containsKey(obj))
+ wrobjmap.put(obj,new HashSet());
+ ((Set)wrobjmap.get(obj)).add(new Integer(ev.getThread()));
+ if (isEager()) {
+ Set conflicts=wrConflictSet(ev.getThread(), object);
+ if (conflicts!=null)
+ if (!handleConflicts(ev, conflicts, currtime))
+ return;
+ }
+ }
+
+ //enqueue the next event
+ int deltatime=trans.getTime(event+1)-trans.getTime(event);
+ Event nev=new Event(deltatime+currtime, trans, event+1, ev.getThread(), ev.getTransNum());
+ currentevents[ev.getThread()]=nev;
+ eq.add(nev);
+ }
+
+
+ class Event implements Comparable {
+ boolean valid;
+ int time;
+ int num;
+ Transaction t;
+ int threadid;
+ int transnum;
+
+ public void makeInvalid() {
+ valid=false;
+ }
+
+ public boolean isValid() {
+ return valid;
+ }
+
+ public int getTransNum() {
+ return transnum;
+ }
+
+ public Transaction getTransaction() {
+ return t;
+ }
+
+ public int getEvent() {
+ return num;
+ }
+
+ public int getTime() {
+ return time;
+ }
+
+ public int getThread() {
+ return threadid;
+ }
+
+ public Event(int time, Transaction t, int num, int threadid, int transnum) {
+ this.time=time;
+ this.t=t;
+ this.num=num;
+ this.threadid=threadid;
+ this.transnum=transnum;
+ valid=true;
+ }
+
+ public int compareTo(Object o) {
+ Event e=(Event)o;
+ return time-e.time;
+ }
+ }
+
+
+
+}
\ No newline at end of file
--- /dev/null
+import java.util.HashSet;
+
+public class Scheduler {
+ Executor e;
+
+ public Scheduler(Executor e, int time) {
+ this.e=e;
+ schedule=new int[e.numEvents()+1][e.numThreads()];
+ turn=new int[e.numEvents()];
+ //give last time an event can be scheduled
+ lasttime=new int[e.maxEvents()][e.numThreads()];
+
+ schedtime=new int[e.maxEvents()][e.numThreads()];
+ lastrd=new int[e.numEvents()+1][e.numObjects()];
+ lastwr=new int[e.numEvents()+1][e.numObjects()];
+ shorttesttime=time;
+ computeFinishing(time);
+ }
+
+ int currbest;
+ int shorttesttime;
+ int[][] schedule;
+ int[] turn;
+ int[][] lasttime;
+ int[][] schedtime;
+ int[][] lastrd;
+ int[][] lastwr;
+
+ public int getTime() {
+ return currbest;
+ }
+
+ private void computeFinishing(int totaltime) {
+ for(int threadnum=0;threadnum<e.numThreads();threadnum++) {
+ ThreadClass thread=e.getThread(threadnum);
+ int threadtime=totaltime;
+ for(int transnum=thread.numTransactions()-1;transnum>=0;transnum--) {
+ Transaction trans=thread.getTransaction(transnum);
+ int ltime=trans.getTime(trans.numEvents()-1);
+ threadtime-=ltime;
+ lasttime[transnum][threadnum]=threadtime;
+ }
+ }
+ }
+
+ private boolean scheduleTask(int step, int iturn) {
+ for(int i=0;i<e.numThreads();i++) {
+ schedule[step+1][i]=schedule[step][i];
+ }
+ schedule[step+1][iturn]--;
+ turn[step]=iturn;
+
+ //compute start time
+ ThreadClass thread=e.getThread(iturn);
+ int transnum=schedule[0][iturn]-schedule[step][iturn];
+ int starttime=0;
+ if (transnum>0) {
+ starttime=schedtime[transnum-1][iturn];
+ Transaction prevtrans=thread.getTransaction(transnum-1);
+ starttime+=prevtrans.getTime(prevtrans.numEvents()-1);
+ }
+ //Let's check for object conflicts that delay start time
+ Transaction trans=thread.getTransaction(transnum);
+ for(int ev=0;ev<trans.numEvents();ev++) {
+ int evtime=trans.getTime(ev);
+ int evobject=trans.getObject(ev);
+ switch(trans.getEvent(ev)) {
+ case Transaction.READ:
+ {
+ //just need to check write time
+ int newstart=lastwr[step][evobject]-evtime;
+ if (newstart>starttime)
+ starttime=newstart;
+ break;
+ }
+ case Transaction.WRITE:
+ {
+ //just need to check both write and read times
+ int newstart=lastwr[step][evobject]-evtime;
+ if (newstart>starttime)
+ starttime=newstart;
+ newstart=lastrd[step][evobject]-evtime;
+ if (newstart>starttime)
+ starttime=newstart;
+ break;
+ }
+ default:
+ }
+ }
+ //check to see if start time is okay
+ if (starttime>lasttime[transnum][iturn])
+ return false;
+
+ //good to update schedule
+ schedtime[transnum][iturn]=starttime;
+
+ //copy read and write times forward
+ for(int obj=0;obj<e.numObjects();obj++) {
+ lastrd[step+1][obj]=lastrd[step][obj];
+ lastwr[step+1][obj]=lastwr[step][obj];
+ }
+
+ int finishtime=starttime+trans.getTime(trans.numEvents()-1);
+
+ //Update read and write times
+ for(int ev=0;ev<trans.numEvents();ev++) {
+ int evtime=trans.getTime(ev);
+ int evobject=trans.getObject(ev);
+ switch(trans.getEvent(ev)) {
+ case Transaction.READ: {
+ //just need to check write time
+ if (finishtime>lastrd[step+1][evobject])
+ lastrd[step+1][evobject]=finishtime;
+ break;
+ }
+ case Transaction.WRITE: {
+ //just need to check both write and read times
+ if (finishtime>lastwr[step+1][evobject])
+ lastwr[step+1][evobject]=finishtime;
+ break;
+ }
+ default:
+ }
+ }
+ // System.out.println("thread="+iturn+" trans="+transnum+" stime="+starttime+" ftime="+finishtime+" transtime="+trans.getTime(trans.numEvents()-1));
+ return true;
+ }
+
+
+ public void dosim() {
+ for(int i=0;i<e.numThreads();i++) {
+ schedule[0][i]=e.getThread(i).numTransactions();
+ }
+
+ int lastEvent=e.numEvents()-1;
+
+ //go forward
+ for(int step=0;step<=lastEvent;step++) {
+ int iturn=0;
+ for(;iturn<e.numThreads();iturn++) {
+ if (schedule[step][iturn]>0)
+ break;
+ }
+
+ //force blank transactions first
+ for(int i=0;i<e.numThreads();i++) {
+ if (schedule[step][i]>0) {
+ Transaction t=e.getThread(i).getTransaction(schedule[0][i]-schedule[step][i]);
+ if ((t.numEvents()==1)&&(t.getEvent(0)==Transaction.DELAY)) {
+ iturn=i;
+ break;
+ }
+ }
+ }
+
+ boolean lgood=scheduleTask(step, iturn);
+
+ if (step==lastEvent&&lgood) {
+ int maxfinish=0;
+ for(int i=0;i<e.numThreads();i++) {
+ int numTrans=e.getThread(i).numTransactions();
+ int startt=schedtime[numTrans-1][i];
+ Transaction lasttrans=e.getThread(i).getTransaction(numTrans-1);
+ int finisht=startt+lasttrans.getTime(lasttrans.numEvents()-1);
+ if (finisht>maxfinish)
+ maxfinish=finisht;
+ }
+
+ if (maxfinish<=shorttesttime) {
+ currbest=maxfinish;
+ shorttesttime=maxfinish;
+ computeFinishing(shorttesttime);
+ }
+ }
+
+ if (!lgood||step==lastEvent) {
+ //go backwards
+ for(;step>=0;step--) {
+ //check for delay transaction...just skip them
+ Transaction oldtrans=e.getThread(turn[step]).getTransaction(schedule[0][turn[step]]-schedule[step][turn[step]]);
+ if (oldtrans.numEvents()==1&&oldtrans.getEvent(0)==Transaction.DELAY)
+ continue;
+
+ iturn=turn[step]+1;
+ for(;iturn<e.numThreads();iturn++) {
+ if (schedule[step][iturn]>0) {
+ if (step==0)
+ break;
+
+ int lastturn=turn[step-1];
+ if (iturn<lastturn) {
+ Transaction trans1=e.getThread(lastturn).getTransaction(schedule[0][iturn]-schedule[step][iturn]);
+ Transaction trans2=e.getThread(iturn).getTransaction(schedule[0][lastturn]-schedule[step-1][lastturn]);
+ if (checkConflicts(trans1, trans2))
+ break;
+ } else
+ break;
+ }
+ }
+ if (iturn<e.numThreads()) {
+ //found something to iterate
+ if (scheduleTask(step, iturn))
+ break;
+ }
+ }
+ if (step<0)
+ return;
+ }
+ }
+ }
+
+
+ public static boolean checkConflicts(Transaction t1, Transaction t2) {
+ HashSet writeset=new HashSet();
+ HashSet readset=new HashSet();
+
+ for(int i=0;i<t1.numEvents();i++) {
+ int t1obj=t1.getObject(i);
+ int t1evt=t1.getEvent(i);
+ if (t1evt==Transaction.READ) {
+ readset.add(new Integer(t1obj));
+ } else if (t1evt==Transaction.WRITE) {
+ writeset.add(new Integer(t1obj));
+ }
+ }
+
+ for(int i=0;i<t2.numEvents();i++) {
+ int t2obj=t2.getObject(i);
+ int t2evt=t2.getEvent(i);
+ if (t2evt==Transaction.READ) {
+ if (writeset.contains(new Integer(t2obj)))
+ return true;
+ } else if (t2evt==Transaction.WRITE) {
+ if (writeset.contains(new Integer(t2obj))||
+ readset.contains(new Integer(t2obj)))
+ return true;
+ }
+ }
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null
+public class ThreadClass {
+ Transaction[] trans;
+
+ public ThreadClass(int numTrans) {
+ trans=new Transaction[numTrans];
+ }
+
+ public int numTransactions() {
+ return trans.length;
+ }
+
+ public Transaction getTransaction(int i) {
+ return trans[i];
+ }
+
+ public void setTransaction(int i, Transaction t) {
+ trans[i]=t;
+ }
+}
\ No newline at end of file
--- /dev/null
+public class TransSim {
+ public static void main(String[] args) {
+ int numThreads=4;
+ int numTrans=8;
+ int deltaTrans=0;
+ int numObjects=10;
+ int numAccesses=4;
+ int deltaAccesses=2;
+ int readPercent=50;
+ //time for operation
+ int delay=20;
+ int deltaDelay=4;
+ //time between transactions
+ int nonTrans=20;
+ int deltaNonTrans=4;
+ Executor e=new Executor(numThreads, numTrans, deltaTrans, numObjects, numAccesses, deltaAccesses, readPercent, delay, deltaDelay, nonTrans, deltaNonTrans);
+ System.out.println(e.maxTime());
+ FlexScheduler ls=new FlexScheduler(e, FlexScheduler.LAZY);
+ ls.dosim();
+ System.out.println("Lazy Time="+ls.getTime());
+ System.out.println("Aborts="+ls.getAborts()+" Commit="+ls.getCommits());
+ int besttime=ls.getTime();
+
+ //Kill others at commit
+ ls=new FlexScheduler(e, FlexScheduler.COMMIT);
+ ls.dosim();
+ System.out.println("Fast Abort="+ls.getTime());
+ System.out.println("Aborts="+ls.getAborts()+" Commit="+ls.getCommits());
+ if (ls.getTime()<besttime)
+ besttime=ls.getTime();
+
+ //Eager attack
+ ls=new FlexScheduler(e, FlexScheduler.ATTACK);
+ ls.dosim();
+ System.out.println("Attack Abort="+ls.getTime());
+ System.out.println("Aborts="+ls.getAborts()+" Commit="+ls.getCommits());
+ if (ls.getTime()<besttime)
+ besttime=ls.getTime();
+
+ //Eager polite
+ ls=new FlexScheduler(e, FlexScheduler.POLITE);
+ ls.dosim();
+ System.out.println("Polite Abort="+ls.getTime());
+ System.out.println("Aborts="+ls.getAborts()+" Commit="+ls.getCommits());
+ if (ls.getTime()<besttime)
+ besttime=ls.getTime();
+
+ //Karma
+ ls=new FlexScheduler(e, FlexScheduler.KARMA);
+ ls.dosim();
+ System.out.println("Karma Abort="+ls.getTime());
+ System.out.println("Aborts="+ls.getAborts()+" Commit="+ls.getCommits());
+ if (ls.getTime()<besttime)
+ besttime=ls.getTime();
+
+ Scheduler s=new Scheduler(e, besttime);
+ s.dosim();
+ System.out.println("Optimal Time="+s.getTime());
+ }
+}
\ No newline at end of file
--- /dev/null
+public class Transaction {
+ int[] events;
+ int[] objects;
+ int[] times;
+
+ public static final int READ=0;
+ public static final int WRITE=1;
+ public static final int DELAY=-1;
+
+ public Transaction(int size) {
+ events=new int[size];
+ objects=new int[size];
+ times=new int[size];
+ }
+
+ public int numEvents() {
+ return events.length;
+ }
+
+ public int getEvent(int index) {
+ return events[index];
+ }
+
+ public int getTime(int index) {
+ return times[index];
+ }
+
+ public int getObject(int index) {
+ return objects[index];
+ }
+
+ public void setEvent(int index, int val) {
+ events[index]=val;
+ }
+
+ public void setTime(int index, int val) {
+ times[index]=val;
+ }
+
+ public void setObject(int index, int val) {
+ objects[index]=val;
+ }
+}
\ No newline at end of file