From 694e6c000619550128740c4689b1b40febcdd538 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Mon, 14 Sep 2009 05:12:03 +0000 Subject: [PATCH] Transaction simulation framework. The idea is to basically give us a way to explore possible benefits of various contention management approaches. --- Robust/TransSim/Executor.java | 120 ++++++++++ Robust/TransSim/FlexScheduler.java | 350 +++++++++++++++++++++++++++++ Robust/TransSim/Scheduler.java | 241 ++++++++++++++++++++ Robust/TransSim/ThreadClass.java | 19 ++ Robust/TransSim/TransSim.java | 60 +++++ Robust/TransSim/Transaction.java | 43 ++++ 6 files changed, 833 insertions(+) create mode 100644 Robust/TransSim/Executor.java create mode 100644 Robust/TransSim/FlexScheduler.java create mode 100644 Robust/TransSim/Scheduler.java create mode 100644 Robust/TransSim/ThreadClass.java create mode 100644 Robust/TransSim/TransSim.java create mode 100644 Robust/TransSim/Transaction.java diff --git a/Robust/TransSim/Executor.java b/Robust/TransSim/Executor.java new file mode 100644 index 00000000..ab85935b --- /dev/null +++ b/Robust/TransSim/Executor.java @@ -0,0 +1,120 @@ +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;imaxtime) + maxtime=time; + } + return maxtime; + } + + public int numObjects() { + return numObjects; + } + + public int numThreads() { + return numThreads; + } + + public int numEvents() { + int events=0; + for(int i=0;i1||trans.getEvent(0)!=Transaction.DELAY) { + commitcount++; + } + backoff[ev.getThread()]=1; + //abort the other threads + for(int i=0;iopponenttime) + 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 diff --git a/Robust/TransSim/Scheduler.java b/Robust/TransSim/Scheduler.java new file mode 100644 index 00000000..b0509130 --- /dev/null +++ b/Robust/TransSim/Scheduler.java @@ -0,0 +1,241 @@ +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=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;i0) { + 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;evstarttime) + 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;objlastrd[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;i0) + break; + } + + //force blank transactions first + for(int i=0;i0) { + 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;imaxfinish) + 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(;iturn0) { + if (step==0) + break; + + int lastturn=turn[step-1]; + if (iturn