diff --git a/build.xml b/build.xml index f41800a..2e380b2 100644 --- a/build.xml +++ b/build.xml @@ -3,54 +3,55 @@ Any modifications will be overwritten. To include a user specific buildfile here, simply create one in the same directory with the processing instruction - as the first entry and export the buildfile again. --> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + as the first entry and export the buildfile again. --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/print.jar b/lib/print.jar deleted file mode 100644 index 693f5f4..0000000 Binary files a/lib/print.jar and /dev/null differ diff --git a/lib/printrv.jar b/lib/printrv.jar new file mode 100644 index 0000000..5630508 Binary files /dev/null and b/lib/printrv.jar differ diff --git a/src/PrintTrace.java b/src/PrintTrace.java index 0168ba1..5cbb1db 100644 --- a/src/PrintTrace.java +++ b/src/PrintTrace.java @@ -10,7 +10,7 @@ public PrintTrace() { // Prints RVPredict traces in human-readable format. public static void main(String[] args) { CmdOptions options = new GetOptions(args).parse(); - ZipTrackPrintEngine engine = new ZipTrackPrintEngine(options.path, true); + ZipTrackPrintEngine engine = new ZipTrackPrintEngine(options.parserType, options.path, options.map_file, true); engine.analyzeTrace(); } } diff --git a/src/print/cmd/CmdOptions.java b/src/print/cmd/CmdOptions.java new file mode 100644 index 0000000..aa81d69 --- /dev/null +++ b/src/print/cmd/CmdOptions.java @@ -0,0 +1,24 @@ +package print.cmd; + +import print.parse.ParserType; + +public class CmdOptions { + public String path; + public ParserType parserType; + public String map_file; + + public CmdOptions() { + this.path = null; + this.map_file = null; + this.parserType = ParserType.RR; + } + + public String toString(){ + String str = ""; + str += "path " + " = " + this.path + "\n"; + str += "path to map file" + " = " + this.map_file + "\n"; + str += "parserType " + " = " + this.parserType.toString() + "\n"; + return str; + } + +} diff --git a/src/print/cmd/GetOptions.java b/src/print/cmd/GetOptions.java new file mode 100644 index 0000000..9a79dcc --- /dev/null +++ b/src/print/cmd/GetOptions.java @@ -0,0 +1,79 @@ +package print.cmd; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +import print.parse.ParserType; + +public class GetOptions { + + private static final Logger log = Logger.getLogger(GetOptions.class.getName()); + private String[] args = null; + private Options options = new Options(); + + public GetOptions(String[] args) { + this.args = args; + options.addOption("h", "help", false, "generate this message"); + options.addOption("f", "format", true, "format of the trace. Possible choices include rv, rr, std (Default : rr) "); + options.addOption("p", "path", true, "the path to the trace file/folder (Required)"); + options.addOption("m", "map", true, "file path to dump the map file [mapping event ids to their descriptions] (Required)"); + + } + + public CmdOptions parse() { + CommandLineParser parser = new DefaultParser(); + CommandLine cmd = null; + CmdOptions cmdOpt = new CmdOptions();; + + try { + cmd = parser.parse(options, args); + if (cmd.hasOption("h")) + help(); + + if (cmd.hasOption("f")) { + cmdOpt.parserType = ParserType.getType(cmd.getOptionValue("f")) ; + if (cmdOpt.parserType.isRV()) { + System.err.println("**Warning** - Provided file format is RV. RVPredict support is getting obsolete day-by-day. \nConsider using some other logger.\n"); + } + } + + if (cmd.hasOption("p")) { + cmdOpt.path = cmd.getOptionValue("p") ; + } + else { + log.log(Level.INFO, "MIssing path to trace file/folder"); + help(); + } + + if (cmd.hasOption("m")) { + cmdOpt.map_file = cmd.getOptionValue("m") ; + } + else { + log.log(Level.INFO, "MIssing path to map file"); + help(); + } + + } catch (ParseException e) { + help(); + } + + return cmdOpt; + } + + private void help() { + HelpFormatter formater = new HelpFormatter(); + formater.printHelp("Ziptrack-Print", options); + System.exit(0); + } + + public static void main(String[] args) { + new GetOptions(args).parse(); + } +} diff --git a/src/print/engine/Engine.java b/src/print/engine/Engine.java new file mode 100644 index 0000000..bcd99b1 --- /dev/null +++ b/src/print/engine/Engine.java @@ -0,0 +1,43 @@ +package print.engine; + +import print.parse.rr.ParseRoadRunner; +import print.parse.rv.parserv.ParseRVPredict; +import print.parse.std.ParseStandard; +import print.parse.ParserType; +import print.event.Event; + +public abstract class Engine { + protected ParserType parserType; + protected ParseRVPredict rvParser;//RV + protected ParseStandard stdParser; //STD + protected ParseRoadRunner rrParser; //RR + protected E handlerEvent; + + public Engine(ParserType pType){ + this.parserType = pType; + } + + protected void initializeReader(String trace_folder) { + if(this.parserType.isRV()){ + initializeReaderRV(trace_folder); + } + else if(this.parserType.isSTD()){ + initializeReaderSTD(trace_folder); + } + else if(this.parserType.isRR()){ + initializeReaderRR(trace_folder); + } + } + + protected void initializeReaderRV(String trace_folder){ + rvParser = new ParseRVPredict(trace_folder, null); + } + + protected void initializeReaderSTD(String trace_file) { + stdParser = new ParseStandard(trace_file); + } + + protected void initializeReaderRR(String trace_file) { + rrParser = new ParseRoadRunner(trace_file); + } +} diff --git a/src/print/engine/RefinedAccessTimesEngine.java b/src/print/engine/RefinedAccessTimesEngine.java new file mode 100644 index 0000000..dc55e90 --- /dev/null +++ b/src/print/engine/RefinedAccessTimesEngine.java @@ -0,0 +1,400 @@ +package print.engine; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Stack; + +import print.parse.ParserType; +import print.engine.Engine; +import print.event.Event; + +public class RefinedAccessTimesEngine extends Engine { + + public HashMap lockLast; + public HashMap variableLast; + public HashMap> lockThreadLast; + + private HashMap>> threadStackReadVariables; + private HashMap>> threadStackWriteVariables; + private HashMap>> readVariableToLockToThreadSet; + private HashMap>> writeVariableToLockToThreadSet; + //public HashMap> lockReadVariables; + //public HashMap> lockWriteVariables; + public HashMap>> existsLockReadVariableThreads; + public HashMap>> existsLockWriteVariableThreads; + + private long freshReadIndex; + private long freshWriteIndex; + private boolean newReadVariableSeen; + private boolean newWriteVariableSeen; + private Long indexOfNewlySeenReadVariable; + private Long indexOfNewlySeenWriteVariable; + private Long tempOldIndex; + private Long tempNewIndex; + public HashMap variableToReadEquivalenceClass; + public HashMap variableToWriteEquivalenceClass; + + public HashMap> variableToThreadSet; + public HashMap> lockToThreadSet; + public HashSet threadSet; + public HashSet variablesWritten; + private HashMap parentMap; + + //private HashMap> threadToActiveLocks; + //public HashMap> variableToAccessdLocks; + + public RefinedAccessTimesEngine(ParserType pType, String trace_folder) { + super(pType); + initializeReader(trace_folder); + + handlerEvent = new Event(); + lockLast = new HashMap () ; + variableLast = new HashMap () ; + lockThreadLast = new HashMap >(); + + threadStackReadVariables = new HashMap>>(); + threadStackWriteVariables = new HashMap>>(); + readVariableToLockToThreadSet = new HashMap>>(); + writeVariableToLockToThreadSet = new HashMap>>(); + //lockReadVariables = new HashMap>(); + //lockWriteVariables = new HashMap>(); + existsLockReadVariableThreads = new HashMap>>(); + existsLockWriteVariableThreads = new HashMap>>(); + + //threadToActiveLocks = new HashMap> (); + //variableToAccessdLocks = new HashMap>(); + + freshReadIndex = (long) 0; + freshWriteIndex = (long) 0; + newReadVariableSeen = false; + newWriteVariableSeen = false; + indexOfNewlySeenReadVariable = (long) 0; + indexOfNewlySeenWriteVariable = (long) 0; + tempOldIndex = (long) 0; + tempNewIndex = (long) 0; + variableToReadEquivalenceClass = new HashMap(); + variableToWriteEquivalenceClass = new HashMap(); + + variableToThreadSet = new HashMap>(); + lockToThreadSet = new HashMap>(); + threadSet = new HashSet (); + variablesWritten = new HashSet (); + + parentMap = new HashMap (); + } + + private void deleteObseleteThreads(){ + HashMap threadAccessCount = new HashMap (); + for(String tstr : threadSet){ + threadAccessCount.put(tstr, 0); + } + + for(String vstr : variableToThreadSet.keySet()){ + if(variablesWritten.contains(vstr)){ + HashSet threads = variableToThreadSet.get(vstr); + for(String tstr : threads){ + int cnt = threadAccessCount.get(tstr); + threadAccessCount.put(tstr, cnt+1); + } + } + else{ + // System.out.println("Read only " + vstr); + // System.out.println("Threads " + variableToThreadSet.get(vstr)); + } + } + + for(String lstr : lockToThreadSet.keySet()){ + HashSet threads = lockToThreadSet.get(lstr); + for(String tstr : threads){ + int cnt = threadAccessCount.get(tstr); + threadAccessCount.put(tstr, cnt+1); + } + } + + for(String tstr : parentMap.keySet()){ + String p_tstr = parentMap.get(tstr); + int cnt = threadAccessCount.get(p_tstr); + threadAccessCount.put(p_tstr, cnt+1); + } + + boolean change = true; + while(change){ + change = false; + HashSet removedToBe = new HashSet (); + for(String tstr : threadSet){ + if(threadAccessCount.get(tstr) == 0){ + change = true; + removedToBe.add(tstr); + String p_str = parentMap.get(tstr); + int new_parent_cnt = threadAccessCount.get(p_str) - 1; + threadAccessCount.put(p_str, new_parent_cnt); + } + } + + for(String rem : removedToBe){ + threadSet.remove(rem); + } + } + } + + public void computeLastAccessTimes(){ + if(this.parserType.isRV()){ + computeLastAccessTimesRV(); + } + else if(this.parserType.isSTD()){ + computeLastAccessTimesSTD(); + } + else if(this.parserType.isRR()){ + computeLastAccessTimesRR(); + } + deleteObseleteThreads(); + } + + public void computeLastAccessTimesRV() { + if(rvParser.pathListNotNull()){ + while(rvParser.hasNext()){ + rvParser.getNextEvent(handlerEvent); + processEvent(); + } + } + } + + public void computeLastAccessTimesSTD() { + while(stdParser.hasNext()){ + stdParser.getNextEvent(handlerEvent); + processEvent(); + } + } + + public void computeLastAccessTimesRR() { + while(rrParser.checkAndGetNext(handlerEvent)){ + processEvent(); + } + } + + private void processEvent(){ + threadSet.add(handlerEvent.getThread().getName()); + + long eventIndex = handlerEvent.getAuxId(); + + if(!threadStackReadVariables.containsKey( handlerEvent.getThread().getName() )){ + threadStackReadVariables.put(handlerEvent.getThread().getName(), new Stack>()); + threadStackWriteVariables.put(handlerEvent.getThread().getName(), new Stack>()); + /* + threadToActiveLocks.put(handlerEvent.getThread().getName(), new Stack ()); + */ + } + + if(handlerEvent.getType().isLockType()){ + if(!lockToThreadSet.containsKey(handlerEvent.getLock().getName())){ + lockToThreadSet.put(handlerEvent.getLock().getName(), new HashSet()); + } + lockToThreadSet.get(handlerEvent.getLock().getName()).add(handlerEvent.getThread().getName()); + + lockLast.put(handlerEvent.getLock().getName(), eventIndex); + + if(! (lockThreadLast.containsKey(handlerEvent.getLock().getName()))){ + lockThreadLast.put(handlerEvent.getLock().getName(), new HashMap()); + /* + lockReadVariables.put(handlerEvent.getLock().getName(), new HashSet()); + lockWriteVariables.put(handlerEvent.getLock().getName(), new HashSet()); + */ + existsLockReadVariableThreads.put(handlerEvent.getLock().getName(), new HashMap>()); + existsLockWriteVariableThreads.put(handlerEvent.getLock().getName(), new HashMap>()); + } + lockThreadLast.get(handlerEvent.getLock().getName()).put(handlerEvent.getThread().getName(), eventIndex); + + if(handlerEvent.getType().isAcquire()){ + threadStackReadVariables.get(handlerEvent.getThread().getName()).push(new HashSet()); + threadStackWriteVariables.get(handlerEvent.getThread().getName()).push(new HashSet()); + + /* + threadToActiveLocks.get(handlerEvent.getThread().getName()).push(handlerEvent.getLock().getName()); + */ + } + else if(handlerEvent.getType().isRelease()){ + HashSet readVarSet = threadStackReadVariables.get(handlerEvent.getThread().getName()).pop(); + HashSet writeVarSet = threadStackWriteVariables.get(handlerEvent.getThread().getName()).pop(); + if (!(threadStackReadVariables.get(handlerEvent.getThread().getName()).isEmpty())){ + threadStackReadVariables.get(handlerEvent.getThread().getName()).peek().addAll(readVarSet); + threadStackWriteVariables.get(handlerEvent.getThread().getName()).peek().addAll(writeVarSet); + } + /* + lockReadVariables.get(handlerEvent.getLock().getName()).addAll(readVarSet); + lockWriteVariables.get(handlerEvent.getLock().getName()).addAll(writeVarSet); + */ + + for(String rVar: readVarSet){ + if(!readVariableToLockToThreadSet.containsKey(rVar)){ + readVariableToLockToThreadSet.put(rVar, new HashMap>()); + } + if(!readVariableToLockToThreadSet.get(rVar).containsKey(handlerEvent.getLock().getName())){ + readVariableToLockToThreadSet.get(rVar).put(handlerEvent.getLock().getName(), new HashSet()); + } + readVariableToLockToThreadSet.get(rVar).get(handlerEvent.getLock().getName()).add(handlerEvent.getThread().getName()); + + //Check if there was a critical section before this on the same lock in some other thread in which rVar was written. If so, add rVar to lockWriteVariables + if(writeVariableToLockToThreadSet.containsKey(rVar)){ + if(writeVariableToLockToThreadSet.get(rVar).containsKey(handlerEvent.getLock().getName())){ + boolean anyOtherThread = false; + if(writeVariableToLockToThreadSet.get(rVar).get(handlerEvent.getLock().getName()).contains(handlerEvent.getThread().getName())) { + if( writeVariableToLockToThreadSet.get(rVar).get(handlerEvent.getLock().getName()).size() > 1 ){ + anyOtherThread = true; + } + } + else{ + if( writeVariableToLockToThreadSet.get(rVar).get(handlerEvent.getLock().getName()).size() > 0 ){ + anyOtherThread = true; + } + } + if (anyOtherThread){ + if(! existsLockWriteVariableThreads.get(handlerEvent.getLock().getName()).containsKey(rVar)){ + existsLockWriteVariableThreads.get(handlerEvent.getLock().getName()).put(rVar, new HashSet()); + } + existsLockWriteVariableThreads.get(handlerEvent.getLock().getName()).get(rVar).add(handlerEvent.getThread().getName()); + } + } + } + + } + for(String wVar: writeVarSet){ + if(!writeVariableToLockToThreadSet.containsKey(wVar)){ + writeVariableToLockToThreadSet.put(wVar, new HashMap>()); + } + if(!writeVariableToLockToThreadSet.get(wVar).containsKey(handlerEvent.getLock().getName())){ + writeVariableToLockToThreadSet.get(wVar).put(handlerEvent.getLock().getName(), new HashSet()); + } + writeVariableToLockToThreadSet.get(wVar).get(handlerEvent.getLock().getName()).add(handlerEvent.getThread().getName()); + + //Check if there was a critical section before this on the same lock in some other thread in which wVar was read. If so, add wVar to lockReadVariables + if(readVariableToLockToThreadSet.containsKey(wVar)){ + if(readVariableToLockToThreadSet.get(wVar).containsKey(handlerEvent.getLock().getName())){ + boolean anyOtherThread = false; + if(readVariableToLockToThreadSet.get(wVar).get(handlerEvent.getLock().getName()).contains(handlerEvent.getThread().getName())) { + if( readVariableToLockToThreadSet.get(wVar).get(handlerEvent.getLock().getName()).size() > 1 ){ + anyOtherThread = true; + } + } + else{ + if( readVariableToLockToThreadSet.get(wVar).get(handlerEvent.getLock().getName()).size() > 0 ){ + anyOtherThread = true; + } + } + if (anyOtherThread){ + + if(! existsLockReadVariableThreads.get(handlerEvent.getLock().getName()).containsKey(wVar)){ + existsLockReadVariableThreads.get(handlerEvent.getLock().getName()).put(wVar, new HashSet()); + } + existsLockReadVariableThreads.get(handlerEvent.getLock().getName()).get(wVar).add(handlerEvent.getThread().getName()); + } + } + } + + + //Check if there was a critical section before this on the same lock in some other thread in which wVar was written. If so, add wVar to lockWriteVariables + if(writeVariableToLockToThreadSet.containsKey(wVar)){ + if(writeVariableToLockToThreadSet.get(wVar).containsKey(handlerEvent.getLock().getName())){ + boolean anyOtherThread = false; + if(writeVariableToLockToThreadSet.get(wVar).get(handlerEvent.getLock().getName()).contains(handlerEvent.getThread().getName())) { + if( writeVariableToLockToThreadSet.get(wVar).get(handlerEvent.getLock().getName()).size() > 1 ){ + anyOtherThread = true; + } + } + else{ + if( writeVariableToLockToThreadSet.get(wVar).get(handlerEvent.getLock().getName()).size() > 0 ){ + anyOtherThread = true; + } + } + if (anyOtherThread){ + + if(! existsLockWriteVariableThreads.get(handlerEvent.getLock().getName()).containsKey(wVar)){ + existsLockWriteVariableThreads.get(handlerEvent.getLock().getName()).put(wVar, new HashSet()); + } + existsLockWriteVariableThreads.get(handlerEvent.getLock().getName()).get(wVar).add(handlerEvent.getThread().getName()); + } + } + } + + } + + HashMap readOldIndexToNewIndex = new HashMap(); + newReadVariableSeen = false; + for (String rVar : readVarSet){ + if(!variableToReadEquivalenceClass.containsKey(rVar)){ + if(! newReadVariableSeen){ + indexOfNewlySeenReadVariable = freshReadIndex; + freshReadIndex = freshReadIndex + 1; + newReadVariableSeen = true; + } + variableToReadEquivalenceClass.put(rVar, indexOfNewlySeenReadVariable); + } + else{ + if(!readOldIndexToNewIndex.containsKey(variableToReadEquivalenceClass.get(rVar))){ + readOldIndexToNewIndex.put(variableToReadEquivalenceClass.get(rVar), freshReadIndex); + freshReadIndex = freshReadIndex + 1; + } + tempOldIndex = variableToReadEquivalenceClass.get(rVar); + tempNewIndex = readOldIndexToNewIndex.get(tempOldIndex); + variableToReadEquivalenceClass.put(rVar, tempNewIndex); + } + } + + HashMap writeOldIndexToNewIndex = new HashMap(); + newWriteVariableSeen = false; + for (String wVar : writeVarSet){ + if(!variableToWriteEquivalenceClass.containsKey(wVar)){ + if(! newWriteVariableSeen){ + indexOfNewlySeenWriteVariable = freshWriteIndex; + freshWriteIndex = freshWriteIndex + 1; + newWriteVariableSeen = true; + } + variableToWriteEquivalenceClass.put(wVar, indexOfNewlySeenWriteVariable); + } + else{ + if(!writeOldIndexToNewIndex.containsKey(variableToWriteEquivalenceClass.get(wVar))){ + writeOldIndexToNewIndex.put(variableToWriteEquivalenceClass.get(wVar), freshWriteIndex); + freshWriteIndex = freshWriteIndex + 1; + } + tempOldIndex = variableToWriteEquivalenceClass.get(wVar); + tempNewIndex = writeOldIndexToNewIndex.get(tempOldIndex); + variableToWriteEquivalenceClass.put(wVar, tempNewIndex); + } + } + + /* + threadToActiveLocks.get(handlerEvent.getThread().getName()).pop(); + for (String rVar : readVarSet){ + variableToAccessdLocks.get(rVar).add(handlerEvent.getLock().getName()); + } + for (String wVar : writeVarSet){ + variableToAccessdLocks.get(wVar).add(handlerEvent.getLock().getName()); + } + */ + } + } + + if(handlerEvent.getType().isAccessType()){ + if(!variableToThreadSet.containsKey(handlerEvent.getVariable().getName())){ + variableToThreadSet.put(handlerEvent.getVariable().getName(), new HashSet()); + } + variableToThreadSet.get(handlerEvent.getVariable().getName()).add(handlerEvent.getThread().getName()); + + variableLast.put(handlerEvent.getVariable().getName(), eventIndex); + if(handlerEvent.getType().isRead()){ + if (!(threadStackReadVariables.get(handlerEvent.getThread().getName()).isEmpty())){ + threadStackReadVariables.get(handlerEvent.getThread().getName()).peek().add(handlerEvent.getVariable().getName()); + } + } + else if(handlerEvent.getType().isWrite()){ + if (!(threadStackWriteVariables.get(handlerEvent.getThread().getName()).isEmpty())){ + threadStackWriteVariables.get(handlerEvent.getThread().getName()).peek().add(handlerEvent.getVariable().getName()); + } + variablesWritten.add(handlerEvent.getVariable().getName()); + } + } + + if(handlerEvent.getType().isExtremeType()){ + parentMap.put(handlerEvent.getTarget().getName(), handlerEvent.getThread().getName()); + } + } +} diff --git a/src/print/engine/ZipTrackPrintEngine.java b/src/print/engine/ZipTrackPrintEngine.java new file mode 100644 index 0000000..88629f9 --- /dev/null +++ b/src/print/engine/ZipTrackPrintEngine.java @@ -0,0 +1,295 @@ +package print.engine; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; + +import print.parse.ParserType; +import print.engine.Engine; +import print.engine.RefinedAccessTimesEngine; +import print.event.Event; +import print.event.Thread; +import print.event.Lock; +import print.event.Variable; + +public class ZipTrackPrintEngine extends Engine { + + long event_index; + HashMap> readMap; + HashMap> writeMap; + HashMap> acquireMap; + HashMap> releaseMap; + HashMap> forkMap; + HashMap> joinMap; + ArrayList eventStrings; + + private HashMap> variableToThreadSet; + private HashMap> lockToThreadSet; + private HashSet threadSet; + private HashSet variablesWritten; + + private boolean removeThreadLocalEvents; + + private String path_to_map_file; + + public ZipTrackPrintEngine(ParserType pType, String trace_folder, String path_to_map_file, boolean th) { + super(pType); + initializeReader(trace_folder); + handlerEvent = new Event(); + event_index = 0; + + this.removeThreadLocalEvents = th; + + readMap = new HashMap> (); + writeMap = new HashMap> (); + acquireMap = new HashMap> (); + releaseMap = new HashMap> (); + forkMap = new HashMap> (); + joinMap = new HashMap> (); + eventStrings = new ArrayList (); + + RefinedAccessTimesEngine accessTimesEngine = new RefinedAccessTimesEngine(pType, trace_folder); + accessTimesEngine.computeLastAccessTimes(); + + this.variableToThreadSet = accessTimesEngine.variableToThreadSet; + this.lockToThreadSet = accessTimesEngine.lockToThreadSet; + this.threadSet = accessTimesEngine.threadSet; + this.variablesWritten = accessTimesEngine.variablesWritten; + + this.path_to_map_file = path_to_map_file; + } + + public void analyzeTrace() { + if(this.parserType.isRV()){ + analyzeTraceRV(); + } + else if(this.parserType.isSTD()){ + analyzeTraceSTD(); + } + else if(this.parserType.isRR()){ + analyzeTraceRR(); + } + dumpMap(); + } + + private void analyzeTraceRV() { + if(rvParser.pathListNotNull()){ + while(rvParser.hasNext()){ + rvParser.getNextEvent(handlerEvent); + if(! skipEvent(handlerEvent)){ + processEvent(); + } + } + } + } + + public void analyzeTraceSTD() { + while(stdParser.hasNext()){ + stdParser.getNextEvent(handlerEvent); + if(! skipEvent(handlerEvent)){ + processEvent(); + } + } + } + + public void analyzeTraceRR() { + while(rrParser.checkAndGetNext(handlerEvent)){ + if(! skipEvent(handlerEvent)){ + processEvent(); + } + } + } + + private boolean skipEvent(Event handlerEvent){ + boolean skip = false; + if(this.removeThreadLocalEvents){ + if(!threadSet.contains(handlerEvent.getThread().getName())){ + skip = true; + } + if(handlerEvent.getType().isExtremeType()){ + if(!threadSet.contains(handlerEvent.getTarget().getName())){ + skip = true; + } + } + if(handlerEvent.getType().isAccessType()){ + if(!variablesWritten.contains(handlerEvent.getVariable().getName())){ + skip = true; + // System.out.println("Read only " + handlerEvent.getVariable().getName()); + // System.out.println("Threads " + variableToThreadSet.get(handlerEvent.getVariable().getName())); + } + if(variableToThreadSet.get(handlerEvent.getVariable().getName()).size() <= 1 ){ + skip = true; + } + } + if(handlerEvent.getType().isLockType()){ + if(lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1 ){ + skip = true; + } + } + } + return skip; + } + + private void dumpMap(){ + String filename = this.path_to_map_file; +// if(this.removeThreadLocalEvents){ +// filename = filename + ".shared.txt"; +// } +// else{ +// filename = filename + ".all.txt"; +// } + try{ + FileWriter fw = new FileWriter(filename); + for(int eidx = 0; eidx < event_index; eidx ++ ){ + fw.write(Integer.toString(eidx) + "|" + eventStrings.get(eidx) + "\n"); + } + fw.close(); + } + catch(IOException e){ + e.printStackTrace(); + } + } + + private void processEvent(){ + // System.out.println(handlerEvent.toString()); + + Thread t = handlerEvent.getThread(); + Long this_index = 0L; + + if(handlerEvent.getType().isRead()){ + Variable v = handlerEvent.getVariable(); + if(readMap.containsKey(t)){ + if(readMap.get(t).containsKey(v)){ + this_index = readMap.get(t).get(v); + } + else{ + this_index = event_index; + readMap.get(t).put(v, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + + } + } + else{ + readMap.put(t, new HashMap ()); + this_index = event_index; + readMap.get(t).put(v, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + + if(handlerEvent.getType().isWrite()){ + Variable v = handlerEvent.getVariable(); + if(writeMap.containsKey(t)){ + if(writeMap.get(t).containsKey(v)){ + this_index = writeMap.get(t).get(v); + } + else{ + this_index = event_index; + writeMap.get(t).put(v, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + else{ + writeMap.put(t, new HashMap ()); + this_index = event_index; + writeMap.get(t).put(v, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + + if(handlerEvent.getType().isAcquire()){ + Lock l = handlerEvent.getLock(); + if(acquireMap.containsKey(t)){ + if(acquireMap.get(t).containsKey(l)){ + this_index = acquireMap.get(t).get(l); + } + else{ + this_index = event_index; + acquireMap.get(t).put(l, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + else{ + acquireMap.put(t, new HashMap ()); + this_index = event_index; + acquireMap.get(t).put(l, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + + if(handlerEvent.getType().isRelease()){ + Lock l = handlerEvent.getLock(); + if(releaseMap.containsKey(t)){ + if(releaseMap.get(t).containsKey(l)){ + this_index = releaseMap.get(t).get(l); + } + else{ + this_index = event_index; + releaseMap.get(t).put(l, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + else{ + releaseMap.put(t, new HashMap ()); + this_index = event_index; + releaseMap.get(t).put(l, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + + if(handlerEvent.getType().isFork()){ + Thread tar = handlerEvent.getTarget(); + if(forkMap.containsKey(t)){ + if(forkMap.get(t).containsKey(tar)){ + this_index = forkMap.get(t).get(tar); + } + else{ + this_index = event_index; + forkMap.get(t).put(tar, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + else{ + forkMap.put(t, new HashMap ()); + this_index = event_index; + forkMap.get(t).put(tar, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + if(handlerEvent.getType().isJoin()){ + Thread tar = handlerEvent.getTarget(); + if(joinMap.containsKey(t)){ + if(joinMap.get(t).containsKey(tar)){ + this_index = joinMap.get(t).get(tar); + } + else{ + this_index = event_index; + joinMap.get(t).put(tar, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + else{ + joinMap.put(t, new HashMap ()); + this_index = event_index; + joinMap.get(t).put(tar, this_index); + eventStrings.add(handlerEvent.toCompactString()); + event_index = event_index + 1; + } + } + + System.out.print(this_index + " "); + } +} diff --git a/src/print/event/Decoration.java b/src/print/event/Decoration.java new file mode 100644 index 0000000..36ea5c5 --- /dev/null +++ b/src/print/event/Decoration.java @@ -0,0 +1,20 @@ +package print.event; + +public abstract class Decoration { + protected int id; + protected String name; + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String toString() { + return getName(); + //return "[Variable-" + Integer.toString(this.id) + "-" + this.name + "]"; + } + +} diff --git a/src/print/event/Event.java b/src/print/event/Event.java new file mode 100644 index 0000000..7f2a4db --- /dev/null +++ b/src/print/event/Event.java @@ -0,0 +1,310 @@ +package print.event; + +import java.util.HashSet; + +public class Event { + //Data for Event + public static Long eventCountTracker = (long) 0; + protected Long id; + protected Long auxId; // RV event identifier + protected int locId; // location Id given by RV + protected String name; + protected EventType type; + protected Thread thread; + + //Data for Acquire/Release + protected Lock lock; + protected HashSet readVarSet; + protected HashSet writeVarSet; + + //Data for Read/Write + protected Variable variable; + private HashSet lockSet; + + //Data for Fork/Join + protected Thread target; + + public void updateEventLockType(Lock l){ + if(this.getType().isLockType()){ + this.readVarSet = new HashSet(); + this.writeVarSet = new HashSet(); + if(l == null) throw new IllegalArgumentException("Lock is null : EventType - " + this.getType().toString()); + this.lock = l; + } + } + + public void updateEventAccessType(Variable var){ + if(this.getType().isAccessType()){ + lockSet = new HashSet(); + if(var == null) throw new IllegalArgumentException("Var is null : EventType - " + this.getType().toString()); + this.variable = var; + } + } + + public void updateEventExtremeType(Thread tar){ + if(this.getType().isExtremeType()){ + if(tar == null) throw new IllegalArgumentException("Target is null : EventType - " + this.getType().toString()); + this.target = tar; + } + } + + public void updateEvent(Long aux_id, int loc_id, String sname, EventType tp, Thread th) { + this.id = eventCountTracker; + eventCountTracker++; + this.auxId = aux_id; + this.locId = loc_id; + this.name = "__event::" + sname + "__"; + this.type = tp; + this.thread = th; + } + + public void updateEvent(Long aux_id, int loc_id, String sname, EventType tp, Thread th, Lock l, Variable var, Thread tar) { + this.updateEvent(aux_id, loc_id, sname, tp, th); + + //Acquire/Release + this.updateEventLockType(l); + + //Read/Write + this.updateEventAccessType(var); + + //Fork/Join + this.updateEventExtremeType(tar); + } + + public void updateEvent(){ + this.updateEvent(0L, 0, "dummy", EventType.DUMMY, null); + } + + public Event() { + this.updateEvent(); + } + + public Event(Long aux_id, int loc_id, EventType tp, Thread th, Lock l, Variable var, Thread tar) { + this.updateEvent(aux_id, loc_id, Long.toString(eventCountTracker), tp, th, l, var, tar); + } + + public Event(Long aux_id, int loc_id, String sname, EventType tp, Thread th, Lock l, Variable var, Thread tar) { + this.updateEvent(aux_id, loc_id, sname, tp, th, l, var, tar); + } + + public void copyFrom(Event fromEvent){ + this.id = fromEvent.getId(); + this.auxId = fromEvent.getAuxId(); + this.locId = fromEvent.getLocId(); + this.name = fromEvent.getName(); + this.type = fromEvent.getType(); + this.thread = fromEvent.getThread(); + + //Data for Acquire/Release + if(this.getType().isLockType()){ + this.lock = fromEvent.getLock(); + this.setReadVarSet(fromEvent.getReadVarSet()); + this.setWriteVarSet(fromEvent.getWriteVarSet()); + } + + //Data for Read/Write + if(this.getType().isAccessType()){ + this.variable = fromEvent.getVariable(); + this.setLockSet(fromEvent.getLockSet()); + } + + //Data for Fork/Join + if(this.getType().isExtremeType()){ + this.target = fromEvent.getTarget(); + } + } + + public Long getId() { + return this.id; + } + + public Long getAuxId() { + return this.auxId; + } + + public int getLocId() { + return this.locId; + } + + public String getName() { + return this.name; + } + + public EventType getType() { + return type; + } + + public void setType(EventType tp) { + this.type = tp; + } + + public Thread getThread() { + return thread; + } + + public String toString() { + return "(Event" + "-" + Long.toString(this.id) + "-AUX:" + Long.toString(this.auxId) + "-L" + Integer.toString(this.locId) + "-" + this.name + "-" + + this.type.toString() + " -" + this.thread.toString() + ")"; + } + + public String toFullStringForChildren() { + return "(Event" + "-" + Long.toString(this.id) + "-AUX:" + Long.toString(this.auxId) + "-L" + Integer.toString(this.locId) + "-" + this.name + "-" + + this.type.toString() + " -" + this.thread.toString(); + } + + public String toFullString(){ + String str = ""; + + if(this.getType().isLockType()) str = this.toFullStringLockType(); + if(this.getType().isAccessType()) str = this.toFullStringAccessType(); + if(this.getType().isExtremeType()) str = this.toFullStringExtremeType(); + + return str; + } + + public String toPrototypeString(){ + String str = ""; + + if(this.getType().isLockType()) str = this.toPrototypeStringLockType(); + if(this.getType().isAccessType()) str = this.toPrototypeStringAccessType(); + if(this.getType().isExtremeType()) str = this.toPrototypeStringExtremeType(); + + return str; + } + + public String toCompactString(){ + String str = ""; + str = str + this.getThread().getName(); + str = str + ","; + + if(this.getType().isAccessType()){ + if(this.getType().isRead()){ + str = str + "R"; + } + else if(this.getType().isWrite()){ + str = str + "W"; + } + str = str + ","; + str = str + this.getVariable().getName(); + } + + else if(this.getType().isLockType()){ + if(this.getType().isAcquire()){ + str = str + "L"; + } + else if(this.getType().isRelease()){ + str = str + "U"; + } + str = str + ","; + str = str + this.getLock().getName(); + } + + else if(this.getType().isExtremeType()){ + if(this.getType().isFork()){ + str = str + "F"; + } + else if(this.getType().isJoin()){ + str = str + "J"; + } + str = str + ","; + str = str + this.getTarget().getName(); + } + + return str; + } + + /**************Acquire/Release*******************/ + public Lock getLock() { + if (! this.getType().isLockType()) throw new IllegalArgumentException("Illegal operation getLock() for EventType " + this.getType().toString()); + return this.lock; + } + + public HashSet getReadVarSet() { + if (! this.getType().isLockType()) throw new IllegalArgumentException("Illegal operation getReadVarSet() for EventType " + this.getType().toString()); + return readVarSet; + } + + public HashSet getWriteVarSet() { + if (! this.getType().isLockType()) throw new IllegalArgumentException("Illegal operation getWriteVarSet() for EventType " + this.getType().toString()); + return writeVarSet; + } + + public void setReadVarSet(HashSet rSet) { + if (! this.getType().isLockType()) throw new IllegalArgumentException("Illegal operation setReadVarSet() for EventType " + this.getType().toString()); + // You have to do a deep copy here + this.readVarSet = new HashSet(rSet); + } + + public void setWriteVarSet(HashSet wSet) { + if (! this.getType().isLockType()) throw new IllegalArgumentException("Illegal operation setWriteVarSet() for EventType " + this.getType().toString()); + // You have to do a deep copy here + this.writeVarSet = new HashSet(wSet); + } + + public void addReadVariable(Variable v) { + if (! this.getType().isLockType()) throw new IllegalArgumentException("Illegal operation addReadVariable() for EventType " + this.getType().toString()); + readVarSet.add(v); + } + + public void addWriteVariable(Variable v) { + if (! this.getType().isLockType()) throw new IllegalArgumentException("Illegal operation addWriteVariable() for EventType " + this.getType().toString()); + writeVarSet.add(v); + } + + public String toFullStringLockType() { + return toFullStringForChildren() + "-" + this.getLock().toString() + "-" + "readVars=" + + this.getReadVarSet().toString() + "-" + "writeVars=" + this.getWriteVarSet().toString() + ")"; + } + + public String toPrototypeStringLockType() { + return "@ Acquire(T" + Integer.toString(this.getThread().getId()) + ",L" + + Integer.toString(this.getLock().getId()) + ")"; + } + /************************************************/ + + /****************Read/Write**********************/ + public Variable getVariable() { + if (! this.getType().isAccessType()) throw new IllegalArgumentException("Illegal operation getVariable() for EventType " + this.getType().toString()); + return this.variable; + } + + public HashSet getLockSet() { + if (! this.getType().isAccessType()) throw new IllegalArgumentException("Illegal operation getLockSet() for EventType " + this.getType().toString()); + return this.lockSet; + } + + public void setLockSet(HashSet lSet) { + if (! this.getType().isAccessType()) throw new IllegalArgumentException("Illegal operation setLockSet() for EventType " + this.getType().toString()); + //Do a deep copy here + this.lockSet = new HashSet(lSet); + } + + public String toFullStringAccessType() { + return toFullStringForChildren() + + "-" + this.getVariable().toString() + + "-" + "lockSet=" + this.getLockSet() + + ")"; + } + + public String toPrototypeStringAccessType() { + return "@ Rd(T" + Integer.toString(this.getThread().getId()) + ",V" + + Integer.toString(this.getVariable().getId()) + ")"; + } + /************************************************/ + + /*****************Fork/Join**********************/ + public Thread getTarget() { + if (! this.getType().isExtremeType()) throw new IllegalArgumentException("Illegal operation getTarget() for EventType " + this.getType().toString()); + return this.target; + } + + public String toFullStringExtremeType() { + return toFullStringForChildren() + "-" + this.getTarget().toString() + ")"; + } + + public String toPrototypeStringExtremeType() { + return "@ Start(T" + Integer.toString(this.getThread().getId()) + ",T" + + Integer.toString(this.getTarget().getId()) + ")"; + } + /************************************************/ +} \ No newline at end of file diff --git a/src/print/event/EventType.java b/src/print/event/EventType.java new file mode 100644 index 0000000..023db55 --- /dev/null +++ b/src/print/event/EventType.java @@ -0,0 +1,74 @@ +package print.event; + +public enum EventType { + ACQUIRE, RELEASE, READ, WRITE, FORK, JOIN, BEGIN, END, DUMMY; + + public boolean isAcquire(){ + return this.ordinal() == ACQUIRE.ordinal(); + } + + public boolean isRelease(){ + return this.ordinal() == RELEASE.ordinal(); + } + + public boolean isRead(){ + return this.ordinal() == READ.ordinal(); + } + + public boolean isWrite(){ + return this.ordinal() == WRITE.ordinal(); + } + + public boolean isFork(){ + return this.ordinal() == FORK.ordinal(); + } + + public boolean isJoin(){ + return this.ordinal() == JOIN.ordinal(); + } + + public boolean isBegin(){ + return this.ordinal() == BEGIN.ordinal(); + } + + public boolean isEnd(){ + return this.ordinal() == END.ordinal(); + } + + public boolean isLockType() { + return this.isAcquire() || this.isRelease(); + } + + public boolean isAccessType() { + return this.isRead() || this.isWrite(); + } + + public boolean isExtremeType() { + return this.isFork() || this.isJoin(); + } + + /* public boolean isSyncType() { + return isLockType() || isExtremeType(); + } */ + + public boolean isTransactionType(){ + return isBegin() || isEnd() ; + } + + public boolean isDummyType(){ + return this.ordinal() == DUMMY.ordinal(); + } + + public String toString(){ + String str = ""; + if(this.isAcquire()) str = "ACQUIRE"; + if(this.isRelease()) str = "RELEASE"; + if(this.isRead()) str = "READ"; + if(this.isWrite()) str = "WRITE"; + if(this.isFork()) str = "FORK"; + if(this.isJoin()) str = "JOIN"; + if(this.isBegin()) str = "BEGIN"; + if(this.isEnd()) str = "END"; + return str; + } +} diff --git a/src/print/event/Lock.java b/src/print/event/Lock.java new file mode 100644 index 0000000..92ff4f5 --- /dev/null +++ b/src/print/event/Lock.java @@ -0,0 +1,19 @@ +package print.event; + +public class Lock extends Decoration { + + public static int lockCountTracker = 0; + + public Lock() { + this.id = lockCountTracker; + lockCountTracker++; + this.name = "__lock::" + Integer.toString(this.id) + "__"; + } + + public Lock(String sname) { + this.id = lockCountTracker; + lockCountTracker++; + this.name = sname; + } + +} diff --git a/src/print/event/Thread.java b/src/print/event/Thread.java new file mode 100644 index 0000000..c3d48ba --- /dev/null +++ b/src/print/event/Thread.java @@ -0,0 +1,19 @@ +package print.event; + +public class Thread extends Decoration { + + public static int threadCountTracker = 0; + + public Thread() { + this.id = threadCountTracker; + threadCountTracker++; + this.name = "__thread::" + Integer.toString(this.id) + "__"; + } + + public Thread(String sname) { + this.id = threadCountTracker; + threadCountTracker++; + this.name = sname; + } + +} diff --git a/src/print/event/Variable.java b/src/print/event/Variable.java new file mode 100644 index 0000000..db4bc11 --- /dev/null +++ b/src/print/event/Variable.java @@ -0,0 +1,19 @@ +package print.event; + +public class Variable extends Decoration { + + public static int variableCountTracker = 0; + + public Variable() { + this.id = variableCountTracker; + variableCountTracker++; + this.name = "__variable::" + Integer.toString(this.id) + "__"; + } + + public Variable(String sname) { + this.id = variableCountTracker; + variableCountTracker++; + this.name = sname; + } + +} diff --git a/src/print/parse/ParserType.java b/src/print/parse/ParserType.java new file mode 100644 index 0000000..2f64e94 --- /dev/null +++ b/src/print/parse/ParserType.java @@ -0,0 +1,39 @@ +package print.parse; + +public enum ParserType { + RV, RR, STD; + + public boolean isRV(){ + return this.ordinal() == RV.ordinal(); + } + + public boolean isRR(){ + return this.ordinal() == RR.ordinal(); + } + + public boolean isSTD(){ + return this.ordinal() == STD.ordinal(); + } + + public boolean isLogType() { + return this.isRR() || this.isSTD(); + } + + public boolean isBinType() { + return this.isRV(); + } + + public String toString(){ + String str = ""; + if(isRV()) str = "RV"; + else if (isRR()) str = "RR"; + else if (isSTD()) str = "STD"; + return str; + } + + public static ParserType getType(String str){ + if (str.equals("rr")) return RR; + else if (str.equals("std")) return STD; + else return RV; + } +} diff --git a/src/print/parse/rr/Parse.java b/src/print/parse/rr/Parse.java new file mode 100644 index 0000000..0354b10 --- /dev/null +++ b/src/print/parse/rr/Parse.java @@ -0,0 +1,73 @@ +package print.parse.rr; + +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import print.event.EventType; +import print.parse.util.CannotParseException; +import print.parse.util.EventInfo; + +public class Parse { + // ACQUIRE, RELEASE, READ, WRITE, FORK, JOIN, BEGIN, END; + public static String matchStr[] = { "Acquire", "Release", "[A]?Rd", "[A]?Wr", "Start", "Join", "Enter", "Exit", "Dummy" }; + public static String prefixPattern = "^@[\\s]+("; + public static String suffixPattern = ")[(]([^,\\s]+)[,]([^,\\s]+)[)]([\\s]+)?([^,\\s]+)?([\\s]+)?([^,\\s]+)?"; + public static String stringEventPattern = prefixPattern + String.join("|", matchStr) + suffixPattern; + public static Pattern eventPattern = Pattern.compile(stringEventPattern); + public HashMap mapMatchType; + + public Parse() { + mapMatchType = new HashMap(); + for (EventType type : EventType.values()) { + String tp_str = matchStr[type.ordinal()]; + if(tp_str.equals("[A]?Rd") || tp_str.equals("[A]?Wr")){ + tp_str = tp_str.substring(4); + } + mapMatchType.put(tp_str, type); + } + } + + public static void example() { + String line = "@ ARd(2,null.test/Deadlock.value_I) Final Deadlock.java:50:7"; +// String line = "@ Acquire(2,@03)"; +// String line = "@ Exit(1,test/Deadlock.doSomething()V)"; + Parse parse = new Parse(); + EventInfo eInfo = new EventInfo(); + try{ + parse.getInfo(eInfo, line); + } + catch(CannotParseException e){ + System.out.println("Could not parse !"); + } + System.out.println(eInfo); + } + + public void getInfo(EventInfo eInfo, String line) throws CannotParseException { + Matcher matcher = eventPattern.matcher(line); + if (matcher.find()) { + + String tp_str = matcher.group(1); + if(tp_str.equals("ARd") || tp_str.equals("AWr")){ + tp_str = tp_str.substring(1); + } + EventType tp = mapMatchType.get(tp_str); + String thId = matcher.group(2); + String aux = matcher.group(3); + String locId = ""; + if(tp.isAccessType()){ + locId = matcher.group(7); + if(locId == null){ + throw new CannotParseException(line); + } + } + eInfo.updateEventInfo(tp, thId, aux, locId); + } else { + throw new CannotParseException(line); + } + } + + public static void main(String args[]){ + example(); + } +} diff --git a/src/print/parse/rr/ParseRoadRunner.java b/src/print/parse/rr/ParseRoadRunner.java new file mode 100644 index 0000000..8d37c82 --- /dev/null +++ b/src/print/parse/rr/ParseRoadRunner.java @@ -0,0 +1,212 @@ +package print.parse.rr; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.HashMap; +import java.util.HashSet; + +import print.event.Event; +import print.event.Lock; +import print.event.Thread; +import print.event.Variable; +import print.parse.util.CannotParseException; +import print.parse.util.EventInfo; + +public class ParseRoadRunner { + private HashMap threadMap; + private HashMap lockMap; + private HashMap variableMap; + int totThreads; + BufferedReader bufferedReader; + String line; + Parse parser; + EventInfo eInfo; + long totEvents; + + private int locIdIndex; + public HashMap locationToIdMap; + + public ParseRoadRunner(String traceFile){ + threadMap = new HashMap(); + lockMap = new HashMap(); + variableMap = new HashMap(); + totThreads = 0; + totEvents = 0; + + locIdIndex = 0; + locationToIdMap = new HashMap (); + + bufferedReader = null; + try{ + bufferedReader = new BufferedReader(new FileReader(traceFile)); + } + catch (FileNotFoundException ex) { + System.out.println("Unable to open file '" + traceFile + "'"); + } + + parser = new Parse(); + eInfo = new EventInfo(); + line = null; + } + + public ParseRoadRunner(String traceFile, boolean computeThreadSetAPriori){ + this(traceFile); + if(computeThreadSetAPriori){ + Event e = new Event (); + while(this.checkAndGetNext(e)){} //Read this trace to calculate threadSet + this.totEvents = 0; //Reset total number of events. This is needed so that AuxId is set correctly. + try{ + bufferedReader = new BufferedReader(new FileReader(traceFile)); + } + catch (FileNotFoundException ex) { + System.out.println("Unable to open file '" + traceFile + "'"); + } + } + } + + public HashSet getThreadSet(){ + return new HashSet (this.threadMap.values()); + } + + public void eInfo2Event(Event e) { + String tname = eInfo.thread; + if (!(threadMap.containsKey(tname))) { + threadMap.put(tname, new Thread(tname)); + totThreads = totThreads + 1; + } + Thread t = threadMap.get(tname); + + + if(!locationToIdMap.containsKey(eInfo.locId)){ + locationToIdMap.put(eInfo.locId, locIdIndex); + locIdIndex = locIdIndex + 1; + } + int LID = locationToIdMap.get(eInfo.locId); + String ename = "E" + Long.toString(totEvents); + + if (eInfo.type.isRead()) { + String vname = eInfo.decor; + if (!(variableMap.containsKey(vname))) { + variableMap.put(vname, new Variable(vname)); + } + Variable v = variableMap.get(vname); + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, v, null); + } + + else if (eInfo.type.isWrite()) { + String vname = eInfo.decor; + if (!(variableMap.containsKey(vname))) { + variableMap.put(vname, new Variable(vname)); + } + Variable v = variableMap.get(vname); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, v, null); + } + + else if (eInfo.type.isAcquire()) { + String lname = eInfo.decor; + if (!(lockMap.containsKey(lname))) { + lockMap.put(lname, new Lock(lname)); + } + Lock l = lockMap.get(lname); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, l, null, null); + } + + else if (eInfo.type.isRelease()) { + String lname = eInfo.decor; + if (!(lockMap.containsKey(lname))) { + lockMap.put(lname, new Lock(lname)); + } + Lock l = lockMap.get(lname); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, l, null, null); + } + + else if (eInfo.type.isFork()) { + String target_name = eInfo.decor; + if (!(threadMap.containsKey(target_name))) { + threadMap.put(target_name, new Thread(target_name)); + } + Thread target = threadMap.get(target_name); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, target); + } + + else if (eInfo.type.isJoin()) { + String target_name = eInfo.decor; + if (!(threadMap.containsKey(target_name))) { + threadMap.put(target_name, new Thread(target_name)); + } + Thread target = threadMap.get(target_name); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, target); + } + + else if (eInfo.type.isBegin()) { + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, null); + } + + else if (eInfo.type.isEnd()) { + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, null); + } + + else { + throw new IllegalArgumentException("Illegal type of event " + eInfo.type.toString()); + } + + totEvents = totEvents + 1; + } + + /* + private void getNextEvent(Event e){ //e is supposed to be over-written (deep copy) by the event-generated from the line read + try { + parser.getInfo(eInfo, line); + } catch (CannotParseException ex) { + System.err.println("Canot parse line -> " + line); + } + eInfo2Event(e); + } + */ + + private boolean hasNext(){ + try { + line = bufferedReader.readLine() ; + } catch (IOException ex) { + System.err.println("Error reading buffered reader"); + } + + boolean endOfFile = (line == null); + if(endOfFile){ + try { + bufferedReader.close(); + } catch (IOException e) { + System.err.println("Error closing buffered reader"); + } + } + return !endOfFile; + } + + public boolean checkAndGetNext(Event e){ + boolean EOF = !hasNext(); + boolean validEvent = false; + while(!EOF){ + try { + parser.getInfo(eInfo, line); + validEvent = true; + } catch (CannotParseException ex) {} + if(validEvent) break; + else{ + EOF = !hasNext(); + } + } + eInfo2Event(e); + return !EOF; + } + + public int getTotalThreads(){ + return totThreads; + } +} diff --git a/src/print/parse/std/Parse.java b/src/print/parse/std/Parse.java new file mode 100644 index 0000000..9ad0d31 --- /dev/null +++ b/src/print/parse/std/Parse.java @@ -0,0 +1,83 @@ +package print.parse.std; + +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import print.event.EventType; +import print.parse.util.CannotParseException; +import print.parse.util.EventInfo; + +public class Parse { + // ACQUIRE, RELEASE, READ, WRITE, FORK, JOIN; + public static String matchStr[] = { "acq", "rel", "r", "w", "fork", "join", "enter", "exit", "dummy" }; + + public static String prefixPattern = "^("; + public static String midFixPattern = String.join("|", matchStr); + public static String suffixPattern = ")[(]([^\\s]+)[)]$"; + public static String stringEventPattern = prefixPattern + midFixPattern + suffixPattern; + public static Pattern primitiveEventPattern = Pattern.compile(stringEventPattern); + public HashMap mapMatchType; + + public static String splitBy = "\\|"; + public static String stringGenericEventPattern = prefixPattern + midFixPattern + "|sync" + suffixPattern; + public static Pattern genericEventPattern = Pattern.compile(stringGenericEventPattern); + + //public EventInfo eInfo; + + public Parse() { + mapMatchType = new HashMap(); + for (EventType type : EventType.values()) { + mapMatchType.put(matchStr[type.ordinal()], type); + } + } + + public static void example() { +// String line = "345|T20|sync(z)"; + String line = "345|T20|join(T1)"; + Parse parse = new Parse(); + EventInfo eInfo = new EventInfo(); + try{ + parse.getInfo(eInfo, line); + System.out.println(eInfo); + } + catch(CannotParseException e){ + System.out.println("Could not parse !"); + } + } + + public void getInfoOp(EventInfo eInfo, String th, String loc, Matcher matcher) { + String strType = matcher.group(1); + EventType tp = mapMatchType.get(strType); + String aux = matcher.group(2); + eInfo.updateEventInfo(tp, th, aux, loc); + } + + public void getInfo(EventInfo eInfo, String line) throws CannotParseException { + String[] eArray = line.split(splitBy, -1); + if(eArray.length < 3 || eArray.length > 3){ + throw new CannotParseException(line); + } + else{ + String thId = eArray[0]; + String op = eArray[1]; + String locId = eArray[2]; + Matcher matcher = genericEventPattern.matcher(op); + if (matcher.find()) { + Matcher primitiveMatcher = primitiveEventPattern.matcher(op); + if(primitiveMatcher.find()){ + getInfoOp(eInfo, thId, locId, primitiveMatcher); + } + else{ + throw new CannotParseException(line); + } + } else { + throw new CannotParseException(line); + } + } + } + + public static void main(String args[]){ + example(); + } +} diff --git a/src/print/parse/std/ParseStandard.java b/src/print/parse/std/ParseStandard.java new file mode 100644 index 0000000..331e323 --- /dev/null +++ b/src/print/parse/std/ParseStandard.java @@ -0,0 +1,176 @@ +package print.parse.std; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.HashMap; +import java.util.HashSet; + +import print.event.Event; +import print.event.Lock; +import print.event.Thread; +import print.event.Variable; +import print.parse.util.CannotParseException; +import print.parse.util.EventInfo; + +public class ParseStandard { + private HashMap threadMap; + private HashMap lockMap; + private HashMap variableMap; + int totThreads; + BufferedReader bufferedReader; + String line; + Parse parser; + EventInfo eInfo; + long totEvents; + + public ParseStandard(String traceFile){ + threadMap = new HashMap(); + lockMap = new HashMap(); + variableMap = new HashMap(); + totThreads = 0; + totEvents = 0; + + bufferedReader = null; + try{ + bufferedReader = new BufferedReader(new FileReader(traceFile)); + } + catch (FileNotFoundException ex) { + System.out.println("Unable to open file '" + traceFile + "'"); + } + + parser = new Parse(); + eInfo = new EventInfo(); + line = null; + } + + public ParseStandard(String traceFile, boolean computeThreadSetAPriori){ + this(traceFile); + if(computeThreadSetAPriori){ + Event e = new Event (); + while(this.hasNext()){ + getNextEvent(e); + } + this.totEvents = 0; //Resetting totEvents is required to ensure correct AuxId + try{ + bufferedReader = new BufferedReader(new FileReader(traceFile)); + } + catch (FileNotFoundException ex) { + System.out.println("Unable to open file '" + traceFile + "'"); + } + } + } + + public HashSet getThreadSet(){ + return new HashSet (this.threadMap.values()); + } + + public void eInfo2Event(Event e) { + String tname = eInfo.thread; + if (!(threadMap.containsKey(tname))) { + threadMap.put(tname, new Thread(tname)); + totThreads = totThreads + 1; + } + Thread t = threadMap.get(tname); + + int LID = Integer.parseInt(eInfo.locId); + String ename = "E" + Long.toString(totEvents); + + if (eInfo.type.isRead()) { + String vname = eInfo.decor; + if (!(variableMap.containsKey(vname))) { + variableMap.put(vname, new Variable(vname)); + } + Variable v = variableMap.get(vname); + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, v, null); + } + + else if (eInfo.type.isWrite()) { + String vname = eInfo.decor; + if (!(variableMap.containsKey(vname))) { + variableMap.put(vname, new Variable(vname)); + } + Variable v = variableMap.get(vname); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, v, null); + } + + else if (eInfo.type.isAcquire()) { + String lname = eInfo.decor; + if (!(lockMap.containsKey(lname))) { + lockMap.put(lname, new Lock(lname)); + } + Lock l = lockMap.get(lname); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, l, null, null); + } + + else if (eInfo.type.isRelease()) { + String lname = eInfo.decor; + if (!(lockMap.containsKey(lname))) { + lockMap.put(lname, new Lock(lname)); + } + Lock l = lockMap.get(lname); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, l, null, null); + } + + else if (eInfo.type.isFork()) { + String target_name = eInfo.decor; + if (!(threadMap.containsKey(target_name))) { + threadMap.put(target_name, new Thread(target_name)); + } + Thread target = threadMap.get(target_name); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, target); + } + + else if (eInfo.type.isJoin()) { + String target_name = eInfo.decor; + if (!(threadMap.containsKey(target_name))) { + threadMap.put(target_name, new Thread(target_name)); + } + Thread target = threadMap.get(target_name); + + e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, target); + } + + else { + throw new IllegalArgumentException("Illegal type of event " + eInfo.type.toString()); + } + + totEvents = totEvents + 1; + } + + public void getNextEvent(Event e){ //e is supposed to be over-written (deep copy) by the event-generated from the line read + try { + parser.getInfo(eInfo, line); + } catch (CannotParseException ex) { +// System.err.println("Canot parse line -> " + line); + } + eInfo2Event(e); + } + + public boolean hasNext(){ + try { + line = bufferedReader.readLine() ; + } catch (IOException ex) { + System.err.println("Error reading buffered reader"); + } + + boolean endOfFile = (line == null); + if(endOfFile){ + try { + bufferedReader.close(); + } catch (IOException e) { + System.err.println("Error closing buffered reader"); + } + } + return !endOfFile; + } + + public int getTotalThreads(){ + return totThreads; + } +} diff --git a/src/print/parse/util/CannotParseException.java b/src/print/parse/util/CannotParseException.java new file mode 100644 index 0000000..8021947 --- /dev/null +++ b/src/print/parse/util/CannotParseException.java @@ -0,0 +1,16 @@ +package print.parse.util; + +public class CannotParseException extends Exception { + + private static final long serialVersionUID = -2061251787621673954L; + //private static final long serialVersionUID = 1L; + private String line; + + public CannotParseException(String str) { + this.line = str; + } + + public String getLine() { + return this.line; + } +} \ No newline at end of file diff --git a/src/print/parse/util/EventInfo.java b/src/print/parse/util/EventInfo.java new file mode 100644 index 0000000..681aa53 --- /dev/null +++ b/src/print/parse/util/EventInfo.java @@ -0,0 +1,35 @@ +package print.parse.util; + +import print.event.EventType; + +public class EventInfo { + public EventType type; + public String thread; + public String decor; + public String locId; + + public EventInfo(){} + + public EventInfo(EventType tp, String th, String dec, String l) { + this.type = tp; + this.thread = th; + this.decor = dec; + this.locId = l; + } + + public void updateEventInfo(EventType tp, String th, String dec, String l){ + this.type = tp; + this.thread = th; + this.decor = dec; + this.locId = l; + } + + public String toString(){ + if (this.locId == ""){ + return this.thread + "|" + this.type.toString() + "|" + this.decor ; + } + else{ + return this.locId + "|" + this.thread + "|" + this.type.toString() + "|" + this.decor ; + } + } +} diff --git a/src/ziptrack/ziphb/ParseZipHB.java b/src/ziptrack/ziphb/ParseZipHB.java index e1fb1f9..8f25581 100644 --- a/src/ziptrack/ziphb/ParseZipHB.java +++ b/src/ziptrack/ziphb/ParseZipHB.java @@ -151,8 +151,8 @@ public void buildMap(String mapFile){ } public static boolean isRule(String line){ - return line.matches("^[0-9]+ -> ((([\\[][0-9]+[\\]])|([0-9]+))\\s).*"); -// return line.matches("^[0-9]+ -> ([\\&]?[0-9]+\\s).*"); +// return line.matches("^[0-9]+ -> ((([\\[][0-9]+[\\]])|([0-9]+))\\s).*"); + return line.matches("^[0-9]+ -> ([\\&]?[0-9]+\\s).*"); } public NonTerminalZipHB processRule(String line){ @@ -189,10 +189,10 @@ public NonTerminalZipHB processRule(String line){ nonTerminalMap.put(symb_str, (NonTerminalZipHB) symb); } } -// else if(symb_str.matches("^[&]\\d+$")){ - else if(symb_str.matches("^[\\[]\\d+[\\]]$")){ -// symb_str = symb_str.substring(1); - symb_str = symb_str.substring(1, symb_str.length()-1); + else if(symb_str.matches("^[&]\\d+$")){ +// else if(symb_str.matches("^[\\[]\\d+[\\]]$")){ + symb_str = symb_str.substring(1); +// symb_str = symb_str.substring(1, symb_str.length()-1); if(!terminalMap.containsKey(symb_str)){ throw new IllegalArgumentException("Terminal symbol not found : " + symb_str); }