Tejas/src/simulator/emulatorinterface/GlobalTable.java

244 lines
7.3 KiB
Java
Executable File

package emulatorinterface;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import memorysystem.AddressCarryingEvent;
import emulatorinterface.communication.Encoding;
import emulatorinterface.communication.IpcBase;
import emulatorinterface.communication.Packet;
import generic.Barrier;
import generic.BarrierTable;
import generic.CoreBcastBus;
import generic.RequestType;
class ResumeSleep {
ArrayList<Integer> resume=new ArrayList<Integer>();
ArrayList<Integer> sleep=new ArrayList<Integer>();
long barrierAddress;
void addSleeper(int t){
this.sleep.add(t);
}
void addResumer(int t){
this.resume.add(t);
}
int getNumResumers() {
return this.resume.size();
}
int getNumSleepers() {
return this.sleep.size();
}
public void merge(ResumeSleep other) {
for (int res : other.resume) {
this.addResumer(res);
}
for (int slp : other.sleep) {
this.addSleeper(slp);
}
}
public void setBarrierAddress(long add){
this.barrierAddress = add;
}
}
public final class GlobalTable implements Encoding {
private Hashtable<Long, SynchPrimitive> synchTable;
private Hashtable<Integer, ThreadState> stateTable;
private IpcBase ipcType;
public GlobalTable(IpcBase ipcType) {
this.ipcType = ipcType;
this.synchTable = new Hashtable<Long, SynchPrimitive>();
this.stateTable = new Hashtable<Integer, ThreadState>();
// this.coreBcastBus = coreBcastBus;
}
public Hashtable<Long, SynchPrimitive> getSynchTable() {
return synchTable;
}
public Hashtable<Integer, ThreadState> getStateTable() {
return stateTable;
}
public void setStateTable(Hashtable<Integer, ThreadState> stateTable) {
this.stateTable = stateTable;
}
// returns -2 if no thread needs to be slept/resumed.
// returns -1 if 'this' thread needs to sleep
// o/w returns otherThreadsId which will now resume
@SuppressWarnings("unused")
public ResumeSleep update(long addressSynchItem, int thread, long time,
long value) {
SynchPrimitive s;
if (synchTable.containsKey(addressSynchItem))
s = (SynchPrimitive)synchTable.get(addressSynchItem);
else {
s = new SynchPrimitive(
addressSynchItem, thread, time, value, ipcType);
synchTable.put(addressSynchItem, s);
}
ResumeSleep ret = new ResumeSleep();
switch ((int)value) {
case (BCAST):
// ret = s.broadcastEnter(thread,time,value);
break;
case (SIGNAL):
// ret = s.sigEnter(thread, time, value);
break;
case (LOCK):
// ret = s.lockEnter(thread, time, value);
break;
case (UNLOCK):
// ret = s.unlockEnter(thread, time, value);
break;
case (JOIN):
//TODO
break;
case (CONDWAIT):
// ret = s.waitEnter(thread, time, value);
break;
case (BARRIERWAIT):
Barrier bar = BarrierTable.barrierList.get(addressSynchItem);
if(bar != null){ //to track the condition that the barrier is already opened
while(bar.blockedThreadSize() == bar.getNumThreads()){ //to track re initialization of barrier
bar = BarrierTable.barrierList.get(++addressSynchItem);
if(bar == null){
addressSynchItem = BarrierTable.barrierCopy(--addressSynchItem);
bar = BarrierTable.barrierList.get(addressSynchItem);
System.out.println(thread + " bar was null");
//return ret;
}
}
while(bar.containsThread(thread)){ //to block the same thread entering barrier twice
int i = bar.getNumThreads();
//addressSynchItem = BarrierTable.barrierCopy(addressSynchItem);
System.out.println("already contains " + thread);
bar = BarrierTable.barrierList.get(++addressSynchItem);
if(bar == null){
bar = new Barrier(addressSynchItem, i);
BarrierTable.barrierList.put(addressSynchItem, bar);
break;
}
}
if(bar==null){
System.err.println("barrier not yet initialized");
System.exit(0);
}
// System.out.println(" thread " + thread + " waiting on " +bar.getBarrierAddress() +" " + addressSynchItem);
// System.out.println(BarrierTable.barrierList.get(addressSynchItem).getBlockedThreads());
bar.addThread(thread);
// System.out.println(BarrierTable.barrierList.get(addressSynchItem).getBlockedThreads());
ret.setBarrierAddress((long)addressSynchItem);
ret.addSleeper(thread);
return ret;
}
break;
case (BCAST + 1):
// TODO
break;
case (SIGNAL + 1):
// ignore
break;
case (LOCK + 1):
// ret = s.lockExit(thread, time, value);
break;
case (UNLOCK + 1):
// ignore
break;
case (JOIN + 1):
break;
case (CONDWAIT + 1):
// ret = s.waitExit(thread, time, value);
break;
case (BARRIERWAIT + 1):
break;
}
return null;
}
// ResumeSleep resumePipelineTimer(int tidToResume) {
// ResumeSleep ret = new ResumeSleep();
// int numResumes=IpcBase.glTable.getStateTable().get(tidToResume).countTimedSleep;
// IpcBase.glTable.getStateTable().get(tidToResume).countTimedSleep=0;
// for (int i=0; i<numResumes; i++) {
// //System.out.println("Resuming by timer"+tidToResume);
// //this.pipelineInterfaces[tidToResume].resumePipeline();
// ret.addResumer(tidToResume);
// }
// if (ret==null) misc.Error.shutDown("resumePipelineTimer returned null");
// return ret;
// }
//
// ResumeSleep tryResumeOnWaitingPipelines(int signaller, long time) {
// ResumeSleep ret = new ResumeSleep();
// Hashtable<Integer, ThreadState> stateTable = IpcBase.glTable.getStateTable();
// Hashtable<Long, SynchPrimitive> synchTable = IpcBase.glTable.getSynchTable();
// ThreadState signallingThread = stateTable.get(signaller);
// signallingThread.lastTimerseen = time;
//
// for (PerAddressInfoNew pai : signallingThread.addressMap.values()) {
// for (Iterator<Integer> iter = pai.probableInteractors.iterator(); iter.hasNext();) {
// int waiter = (Integer)iter.next();
// ThreadState waiterThread = stateTable.get(waiter);
// if (waiterThread.isOntimedWaitAt(pai.address)) {
// //TODO if multiple RunnableThreads then this should be synchronised
// if (time>=waiterThread.timeSlept(pai.address)) {
// //Remove dependencies from both sides.
// iter.remove();
// waiterThread.removeDep(signaller);
// if (!waiterThread.isOntimedWait()) {
// //TODOthis means waiter got released from a timedWait by a timer and not by synchPrimitive.
// //this means that in the synchTable somewhere there is a stale entry of their lockEnter/Exit
// // or unlockEnter. which needs to removed.
// // flushSynchTable();
// /* System.out.println(waiter+" pipeline is resuming by timedWait from"+signaller
// +" num of Times"+stateTable.get(waiter).countTimedSleep);
// */
// ret = resumePipelineTimer(waiter);
// PerAddressInfoNew p = waiterThread.addressMap.get(pai.address);
// if (p!=null) {
// if (p.on_broadcast) {
// ret.merge(synchTable.get(pai.address).broadcastResume(p.broadcastTime,waiter));
// p.on_broadcast = false;
// p.broadcastTime = Long.MAX_VALUE;
// }
// else if (p.on_barrier) {
// ret.merge(synchTable.get(pai.address).barrierResume());
// p.on_barrier = false;
// }
// }
// }
// }
// }
// else {
// // this means that the thread was not timedWait anymore as it got served by the synchronization
// // it was waiting for.
// iter.remove();
// }
// }
// }
// return ret;
// }
}