├── .gitignore ├── ASPLOS20-README.md ├── LICENSE ├── README.md ├── build.xml ├── lib ├── commons-cli-1.3.1.jar ├── commons-io-2.13.0.jar ├── jgrapht │ ├── antlr4-runtime-4.7.1.jar │ ├── commons-lang3-3.8.1.jar │ ├── commons-text-1.5.jar │ ├── fastutil-8.2.2.jar │ ├── guava-26.0-jre.jar │ ├── jgrapht-bundle-1.3.0.jar │ ├── jgrapht-core-1.3.0.jar │ ├── jgrapht-demo-1.3.0.jar │ ├── jgrapht-ext-1.3.0.jar │ ├── jgrapht-guava-1.3.0.jar │ ├── jgrapht-io-1.3.0.jar │ ├── jgrapht-opt-1.3.0.jar │ ├── jgraphx-3.4.1.3.jar │ └── jheaps-0.9.jar ├── lz4-1.3-SNAPSHOT.jar ├── parserv.jar └── rvparse.jar ├── notes ├── Generate_RoadRunner_traces.md └── PrintSubsetTool.java.txt ├── rapid.png └── src ├── Aerodrome.java ├── AerodromeBasic.java ├── ExcludeMethods.java ├── FHB.java ├── Goldilocks.java ├── HB.java ├── HBEpoch.java ├── LockSet.java ├── META-INF └── MANIFEST.MF ├── MetaInfo.java ├── OSR.java ├── PrintCSV.java ├── PrintSTD.java ├── PrintSTDFilter.java ├── SHB.java ├── SHBEpoch.java ├── SyncPreserving.java ├── Velodrome.java ├── WCP.java ├── cmd ├── CmdOptions.java └── GetOptions.java ├── engine ├── Engine.java ├── accesstimes │ ├── AccessTimesEngine.java │ ├── RefinedAccessTimesEngine.java │ └── orderedvars │ │ ├── OrderedVarsEngine.java │ │ ├── OrderedVarsEvent.java │ │ └── OrderedVarsState.java ├── atomicity │ ├── AtomicityEngine.java │ ├── AtomicityEvent.java │ ├── State.java │ └── conflictserializability │ │ ├── aerodrome │ │ ├── AerodromeEngine.java │ │ ├── AerodromeEvent.java │ │ └── AerodromeState.java │ │ ├── aerodrome_basic │ │ ├── AerodromeEngine.java │ │ ├── AerodromeEvent.java │ │ └── AerodromeState.java │ │ └── velodome │ │ ├── VelodromeEngine.java │ │ ├── VelodromeEvent.java │ │ └── VelodromeState.java ├── metainfo │ └── MetaInfoEngine.java ├── print │ ├── PrintEngine.java │ └── PrintFilterEngine.java └── racedetectionengine │ ├── OSR │ ├── AccessEventInfo.java │ ├── AcqEventInfo.java │ ├── EventInfo.java │ ├── OSREngine.java │ ├── OSREvent.java │ ├── OSRState.java │ ├── POBuild │ │ ├── NumArrayMin.java │ │ ├── POBuildReverse.java │ │ ├── PartialOrder.java │ │ ├── RangeMinima.java │ │ └── RangeMinimaQuery.java │ └── RelEventInfo.java │ ├── RaceDetectionEngine.java │ ├── RaceDetectionEvent.java │ ├── State.java │ ├── fhb │ ├── FHBEngine.java │ ├── FHBEvent.java │ └── FHBState.java │ ├── goldilocks │ ├── GoldilocksEngine.java │ ├── GoldilocksEvent.java │ ├── GoldilocksOfflineEngine.java │ └── GoldilocksState.java │ ├── hb │ ├── HBEngine.java │ ├── HBEvent.java │ └── HBState.java │ ├── hb_epoch │ ├── HBEpochEngine.java │ ├── HBEpochEvent.java │ └── HBEpochState.java │ ├── lockset │ ├── LockSetEngine.java │ ├── LockSetEvent.java │ ├── LockSetOfflineEngine.java │ └── LockSetState.java │ ├── shb │ ├── SHBEngine.java │ ├── SHBEvent.java │ ├── SHBOfflineEngine.java │ ├── SHBState.java │ └── distance │ │ ├── SHBEngine.java │ │ ├── SHBEvent.java │ │ ├── SHBOfflineEngine.java │ │ └── SHBState.java │ ├── shb_epoch │ ├── SHBEpochEngine.java │ ├── SHBEpochEvent.java │ └── SHBEpochState.java │ ├── syncpreserving │ ├── SyncPreservingRaceEngine.java │ ├── SyncPreservingRaceEvent.java │ ├── SyncPreservingRaceOfflineEngine.java │ ├── SyncPreservingRaceState.java │ └── distance │ │ ├── SyncPreservingRaceEngine.java │ │ ├── SyncPreservingRaceEvent.java │ │ ├── SyncPreservingRaceOfflineEngine.java │ │ └── SyncPreservingRaceState.java │ └── wcp │ ├── WCPEngine.java │ ├── WCPEvent.java │ ├── WCPState.java │ ├── WCPView.java │ └── distance │ ├── WCPAnnotationEngine.java │ ├── WCPEngine.java │ ├── WCPEvent.java │ ├── WCPState.java │ └── WCPView.java ├── event ├── Decoration.java ├── Event.java ├── EventType.java ├── Lock.java ├── Thread.java └── Variable.java ├── notes ├── Generate_RoadRunner_traces.md └── PrintSubsetTool.java.txt ├── parse ├── ParserType.java ├── csv │ ├── Parse.java │ └── ParseCSV.java ├── rr │ ├── Parse.java │ └── ParseRoadRunner.java ├── std │ ├── Parse.java │ └── ParseStandard.java └── util │ ├── CannotParseException.java │ └── EventInfo.java └── util ├── NeibhorsHardCodeWordTricks.java ├── Pair.java ├── PairComparators.java ├── PairHardCodeWordTricks.java ├── Quintet.java ├── Transaction.java ├── Triplet.java ├── TripletComparators.java ├── ll ├── EfficientLLView.java ├── EfficientLinkedList.java └── EfficientNode.java ├── trace ├── Trace.java └── TraceAndDataSets.java ├── treeclock └── TreeClock.java └── vectorclock ├── AdaptiveVC.java ├── ClockPair.java ├── Epoch.java ├── FullAdaptiveVC.java ├── SemiAdaptiveVC.java ├── VectorClock.java └── VectorClockOpt.java /.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | .idea/ 3 | OSR-sync-github.iml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Umang Mathur 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /lib/commons-cli-1.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/commons-cli-1.3.1.jar -------------------------------------------------------------------------------- /lib/commons-io-2.13.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/commons-io-2.13.0.jar -------------------------------------------------------------------------------- /lib/jgrapht/antlr4-runtime-4.7.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/antlr4-runtime-4.7.1.jar -------------------------------------------------------------------------------- /lib/jgrapht/commons-lang3-3.8.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/commons-lang3-3.8.1.jar -------------------------------------------------------------------------------- /lib/jgrapht/commons-text-1.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/commons-text-1.5.jar -------------------------------------------------------------------------------- /lib/jgrapht/fastutil-8.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/fastutil-8.2.2.jar -------------------------------------------------------------------------------- /lib/jgrapht/guava-26.0-jre.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/guava-26.0-jre.jar -------------------------------------------------------------------------------- /lib/jgrapht/jgrapht-bundle-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jgrapht-bundle-1.3.0.jar -------------------------------------------------------------------------------- /lib/jgrapht/jgrapht-core-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jgrapht-core-1.3.0.jar -------------------------------------------------------------------------------- /lib/jgrapht/jgrapht-demo-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jgrapht-demo-1.3.0.jar -------------------------------------------------------------------------------- /lib/jgrapht/jgrapht-ext-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jgrapht-ext-1.3.0.jar -------------------------------------------------------------------------------- /lib/jgrapht/jgrapht-guava-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jgrapht-guava-1.3.0.jar -------------------------------------------------------------------------------- /lib/jgrapht/jgrapht-io-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jgrapht-io-1.3.0.jar -------------------------------------------------------------------------------- /lib/jgrapht/jgrapht-opt-1.3.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jgrapht-opt-1.3.0.jar -------------------------------------------------------------------------------- /lib/jgrapht/jgraphx-3.4.1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jgraphx-3.4.1.3.jar -------------------------------------------------------------------------------- /lib/jgrapht/jheaps-0.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/jgrapht/jheaps-0.9.jar -------------------------------------------------------------------------------- /lib/lz4-1.3-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/lz4-1.3-SNAPSHOT.jar -------------------------------------------------------------------------------- /lib/parserv.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/parserv.jar -------------------------------------------------------------------------------- /lib/rvparse.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/lib/rvparse.jar -------------------------------------------------------------------------------- /notes/Generate_RoadRunner_traces.md: -------------------------------------------------------------------------------- 1 | In order to support RoadRunner traces, I have added a custom printing tool (that only prints a small subset of events, unlike the pre-existing PrintTool [abbreviated `P`] ). 2 | This tool is called PrintSubsetTool and the supplied file `PrintSubsetTool.java` in this folder is the file that you have to put in the appropriate place. 3 | 4 | ## Instructions for generating RoadRunner files : 5 | 6 | 1. Download RoadRunner tool [here](https://github.com/stephenfreund/RoadRunner). 7 | Let us say that RoadRunner sits in ${RoadRunnerRoot} directory. 8 | 9 | 2. Move the file [`PrintSubsetTool.java`](PrintSubsetTool.java.txt) to the folder ${RoadRunner}/src/rr/simple . 10 | That's it! RoadRunner is so designed as to automatically take care of all the book-keeping when you write a new tool. 11 | 12 | 3. Compile Roadrunner as you normally would (see `INSTALL.txt`) in ${RoadRunnerRoot} . 13 | Most likely, a simple `ant` (in ${RoadRunnerRoot} ) will do the job. 14 | 15 | 4. Once RoadRunner is compiled, we can run our tool. 16 | Let us say we want to print the events of the class `/path/to/class` . 17 | Then, the command you should run is 18 | ``` 19 | rrrun -noFP -noxml -quiet -noTidGC -tool=PS /path/to/class > /path/to/test.rr 20 | ``` 21 | `/path/to/test.rr` is the log file that is generated. 22 | This file is quite readable and you can open it to see the events for yourself. 23 | This is how the file would look like: 24 | ``` 25 | [main: RoadRunner Agent Loaded.] 26 | [main: Running in FAST Mode] 27 | [RR: Creating Fresh Meta Data] 28 | [main: ----- ----- ----- ----- Meep Meep. ----- ----- ----- -----] 29 | [main: ] 30 | @ main[tid = 0] started . 31 | @ Enter(0,test/Test.main([Ljava/lang/String;)V) from null 32 | @ Thread-0[tid = 1] started by main[tid = 0]. 33 | @ Start(0,1) 34 | . 35 | . 36 | . 37 | ``` 38 | 39 | The option `-noFP` disallows any fast-path optimization that RoadRunner would normally employ. In the absence of this flag, some of the access events are not printed. 40 | The options `-noxml` and `-quiet` reduce the clutter that RoadRunner normally produces. 41 | The option `-noTidGC` is (as of now) an unstable/experimental feature. In the absence of this flag, RoadRunner allows thread-id's of dead threads to be re-used. I did not explicitly handle such traces where you would reuse thread ids. Hence, this flag. 42 | -------------------------------------------------------------------------------- /rapid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/focs-lab/rapid/109435809b567dab44431e44fb3f690ce0f58c5f/rapid.png -------------------------------------------------------------------------------- /src/Aerodrome.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.atomicity.conflictserializability.aerodrome.AerodromeEngine; 4 | 5 | public class Aerodrome { 6 | 7 | public Aerodrome() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | AerodromeEngine engine = new AerodromeEngine(options.parserType, options.path, options.verbosity); 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if(time_reporting){ 17 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 18 | } 19 | engine.analyzeTrace(false); 20 | if(time_reporting){ 21 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 22 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 23 | System.out.println("Time for full analysis = " + timeAnalysis + " milliseconds"); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/AerodromeBasic.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.atomicity.conflictserializability.aerodrome_basic.AerodromeEngine; 4 | 5 | public class AerodromeBasic { 6 | 7 | public AerodromeBasic() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if(time_reporting){ 17 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 18 | } 19 | 20 | AerodromeEngine engine = new AerodromeEngine(options.parserType, options.path, options.verbosity); 21 | engine.analyzeTrace(false); 22 | 23 | if(time_reporting){ 24 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 25 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 26 | System.out.println("Time for full analysis = " + timeAnalysis + " milliseconds"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/ExcludeMethods.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import event.Event; 4 | import parse.rr.ParseRoadRunner; 5 | 6 | public class ExcludeMethods { 7 | 8 | public ExcludeMethods() { 9 | 10 | } 11 | 12 | public static void main(String[] args) { 13 | CmdOptions options = new GetOptions(args).parse(); 14 | String traceFile = options.path; 15 | String excludeFile = options.excludeList; 16 | Event e = new Event(); 17 | ParseRoadRunner parser; 18 | if(!(excludeFile == null)) { 19 | parser = new ParseRoadRunner(traceFile, excludeFile); 20 | } 21 | else { 22 | parser = new ParseRoadRunner(traceFile); 23 | } 24 | while(parser.checkAndGetNext(e)){ 25 | System.out.println(e.toStandardFormat()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/FHB.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.fhb.FHBEngine; 4 | 5 | public class FHB { 6 | 7 | public FHB() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | FHBEngine engine = new FHBEngine(options.parserType, options.path); 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if (time_reporting) { 17 | startTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 18 | } 19 | engine.analyzeTrace(options.multipleRace, options.verbosity); 20 | 21 | if (time_reporting) { 22 | long stopTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 23 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 24 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Goldilocks.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.goldilocks.GoldilocksEngine; 4 | 5 | public class Goldilocks { 6 | 7 | public Goldilocks() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if(time_reporting){ 17 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 18 | } 19 | 20 | GoldilocksEngine engine = new GoldilocksEngine(options.parserType, options.path, options.verbosity); 21 | engine.analyzeTrace(options.multipleRace, options.verbosity); 22 | 23 | if(time_reporting){ 24 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 25 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 26 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/HB.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.hb.HBEngine; 4 | 5 | public class HB { 6 | 7 | public HB() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | long startTimeAnalysis = System.currentTimeMillis(); 14 | HBEngine engine = new HBEngine(options.parserType, options.path); 15 | engine.analyzeTrace(options.multipleRace, options.verbosity); 16 | long stopTimeAnalysis = System.currentTimeMillis(); 17 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 18 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/HBEpoch.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.hb_epoch.HBEpochEngine; 4 | 5 | public class HBEpoch { 6 | 7 | public HBEpoch() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if(time_reporting){ 17 | startTimeAnalysis = System.currentTimeMillis(); 18 | } 19 | 20 | HBEpochEngine engine = new HBEpochEngine(options.parserType, options.path); 21 | engine.analyzeTrace(options.multipleRace, options.verbosity); 22 | 23 | if(time_reporting){ 24 | long stopTimeAnalysis = System.currentTimeMillis(); 25 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 26 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/LockSet.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.lockset.LockSetEngine; 4 | 5 | public class LockSet { 6 | 7 | public LockSet() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if(time_reporting){ 17 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 18 | } 19 | 20 | LockSetEngine engine = new LockSetEngine(options.parserType, options.path, options.verbosity); 21 | engine.analyzeTrace(options.multipleRace, options.verbosity); 22 | 23 | if(time_reporting){ 24 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 25 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 26 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: OSR 3 | 4 | -------------------------------------------------------------------------------- /src/MetaInfo.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.metainfo.MetaInfoEngine; 4 | 5 | public class MetaInfo { 6 | 7 | public MetaInfo() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | MetaInfoEngine engine = new MetaInfoEngine(options.parserType, options.path); 14 | engine.analyzeTrace(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/OSR.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.OSR.OSREngine; 4 | import engine.racedetectionengine.OSR.POBuild.POBuildReverse; 5 | import engine.racedetectionengine.hb.HBEngine; 6 | import event.Event; 7 | import event.Lock; 8 | import event.Thread; 9 | import event.Variable; 10 | import parse.ParserType; 11 | 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | public class OSR { 19 | public static void main(String[] args) throws IOException { 20 | CmdOptions options = new GetOptions(args).parse(); 21 | long startTimeAnalysis = System.currentTimeMillis(); 22 | 23 | OSREngine engine = new OSREngine(options.parserType, options.path); 24 | engine.analyzeTrace(options.multipleRace, options.verbosity); 25 | 26 | long stopTimeAnalysis = System.currentTimeMillis(); 27 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 28 | double timeInSeconds = timeAnalysis * 1.0 / 1000; 29 | double timeInMin = timeAnalysis * 1.0 / 60000; 30 | ArrayList racyEvents = new ArrayList<>(engine.state.racyEvents); 31 | racyEvents.sort((a, b) -> Math.toIntExact(a - b)); 32 | System.out.println("======================================================"); 33 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 34 | System.out.println("Time for analysis in seconds = " + String.format("%.3f", timeInSeconds)); 35 | System.out.println("Time for analysis in mins = " + String.format("%.1f", timeInMin)); 36 | System.out.println("Number of racy events: " + engine.state.racyEvents.size()); 37 | System.out.println("Racy events: " + racyEvents); 38 | System.out.println("Number of racy locations: " + engine.state.racyLocations.size()); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/PrintCSV.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.print.PrintEngine; 4 | import parse.ParserType; 5 | 6 | public class PrintCSV { 7 | 8 | public PrintCSV() { 9 | 10 | } 11 | 12 | public static void main(String[] args) { 13 | CmdOptions options = new GetOptions(args).parse(); 14 | PrintEngine engine = new PrintEngine(options.parserType, options.path); 15 | engine.analyzeTrace(ParserType.CSV); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PrintSTD.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.print.PrintEngine; 4 | import parse.ParserType; 5 | 6 | public class PrintSTD { 7 | 8 | public PrintSTD() { 9 | 10 | } 11 | 12 | public static void main(String[] args) { 13 | CmdOptions options = new GetOptions(args).parse(); 14 | PrintEngine engine = new PrintEngine(options.parserType, options.path); 15 | engine.analyzeTrace(ParserType.STD); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/PrintSTDFilter.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.print.PrintFilterEngine; 4 | import parse.ParserType; 5 | 6 | public class PrintSTDFilter { 7 | 8 | public PrintSTDFilter() { 9 | 10 | } 11 | 12 | public static void main(String[] args) { 13 | CmdOptions options = new GetOptions(args).parse(); 14 | PrintFilterEngine engine = new PrintFilterEngine(options.parserType, options.path); 15 | engine.analyzeTrace(ParserType.STD); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SHB.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.shb.SHBEngine; 4 | 5 | public class SHB { 6 | 7 | public SHB() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if (time_reporting) { 17 | startTimeAnalysis = System.currentTimeMillis(); 18 | } 19 | 20 | SHBEngine engine = new SHBEngine(options.parserType, options.path); 21 | engine.analyzeTrace(options.multipleRace, options.verbosity); 22 | 23 | if (time_reporting) { 24 | long stopTimeAnalysis = System.currentTimeMillis(); 25 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 26 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SHBEpoch.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.shb_epoch.SHBEpochEngine; 4 | 5 | public class SHBEpoch { 6 | 7 | public SHBEpoch() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if(time_reporting){ 17 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 18 | } 19 | 20 | SHBEpochEngine engine = new SHBEpochEngine(options.parserType, options.path); 21 | engine.analyzeTrace(options.multipleRace, options.verbosity); 22 | 23 | if(time_reporting){ 24 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 25 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 26 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SyncPreserving.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.syncpreserving.SyncPreservingRaceOfflineEngine; 4 | 5 | public class SyncPreserving { 6 | 7 | public SyncPreserving() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if (time_reporting) { 17 | startTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 18 | } 19 | 20 | SyncPreservingRaceOfflineEngine engine = new SyncPreservingRaceOfflineEngine( 21 | options.parserType, options.path); 22 | engine.analyzeTrace(options.multipleRace, options.verbosity); 23 | 24 | if (time_reporting) { 25 | long stopTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 26 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 27 | System.out.println("Time for analysis = " + timeAnalysis + " milliseconds"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Velodrome.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.atomicity.conflictserializability.velodome.VelodromeEngine; 4 | 5 | public class Velodrome { 6 | 7 | public Velodrome() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | VelodromeEngine engine = new VelodromeEngine(options.parserType, options.path, options.verbosity); 14 | 15 | boolean time_reporting = true; 16 | long startTimeAnalysis = 0; 17 | if(time_reporting){ 18 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 19 | } 20 | 21 | engine.analyzeTrace(false); 22 | 23 | System.out.println("Number of transactions remaining = " + engine.numTransactionsActive()); 24 | 25 | if(time_reporting){ 26 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 27 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 28 | System.out.println("Time for full analysis = " + timeAnalysis + " milliseconds"); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WCP.java: -------------------------------------------------------------------------------- 1 | import cmd.CmdOptions; 2 | import cmd.GetOptions; 3 | import engine.racedetectionengine.wcp.WCPEngine; 4 | 5 | public class WCP { 6 | 7 | public WCP() { 8 | 9 | } 10 | 11 | public static void main(String[] args) { 12 | CmdOptions options = new GetOptions(args).parse(); 13 | 14 | boolean time_reporting = true; 15 | long startTimeAnalysis = 0; 16 | if (time_reporting) { 17 | startTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 18 | } 19 | 20 | WCPEngine engine = new WCPEngine(options.parserType, options.path); 21 | engine.analyzeTrace(options.multipleRace, options.verbosity); 22 | 23 | if (time_reporting) { 24 | long stopTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 25 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 26 | System.out.println( 27 | "Time for full analysis = " + timeAnalysis + " milliseconds"); 28 | } 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/cmd/CmdOptions.java: -------------------------------------------------------------------------------- 1 | package cmd; 2 | 3 | import parse.ParserType; 4 | 5 | public class CmdOptions { 6 | 7 | public ParserType parserType; 8 | public boolean online; 9 | public boolean multipleRace; 10 | public String path; 11 | public int verbosity; 12 | public String excludeList; 13 | 14 | public CmdOptions() { 15 | this.parserType = ParserType.CSV; 16 | this.online = true; 17 | this.multipleRace = true; 18 | this.path = null; 19 | this.verbosity = 0; 20 | this.excludeList = null; 21 | } 22 | 23 | public String toString(){ 24 | String str = ""; 25 | str += "parserType " + " = " + this.parserType.toString() + "\n"; 26 | str += "online " + " = " + this.online + "\n"; 27 | str += "multipleRace " + " = " + this.multipleRace + "\n"; 28 | str += "path " + " = " + this.path + "\n"; 29 | str += "verbosity " + " = " + this.verbosity + "\n"; 30 | str += "excludeList " + " = " + this.excludeList + "\n"; 31 | return str; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/cmd/GetOptions.java: -------------------------------------------------------------------------------- 1 | package cmd; 2 | 3 | import java.util.logging.Level; 4 | import java.util.logging.Logger; 5 | 6 | import org.apache.commons.cli.DefaultParser; 7 | import org.apache.commons.cli.CommandLine; 8 | import org.apache.commons.cli.CommandLineParser; 9 | import org.apache.commons.cli.HelpFormatter; 10 | import org.apache.commons.cli.Options; 11 | import org.apache.commons.cli.ParseException; 12 | 13 | import parse.ParserType; 14 | 15 | public class GetOptions { 16 | 17 | private static final Logger log = Logger.getLogger(GetOptions.class.getName()); 18 | private String[] args = null; 19 | private Options options = new Options(); 20 | 21 | public GetOptions(String[] args) { 22 | this.args = args; 23 | options.addOption("h", "help", false, "generate this message"); 24 | options.addOption("f", "format", true, "format of the trace. Possible choices include rv, csv, rr, std (Default : csv) "); 25 | options.addOption("s", "single", false, "force the algorithm to terminate after the first race is detected"); 26 | options.addOption("p", "path", true, "the path to the trace file/folder (Required)"); 27 | options.addOption("v", "verbosity", true, "for setting verbosity: Allowed levels = 0, 1, 2 (Default : 0)"); 28 | options.addOption("m", "excluded-methods", true, "path to file that lists methods to be excluded"); 29 | } 30 | 31 | public CmdOptions parse() { 32 | CommandLineParser parser = new DefaultParser(); 33 | CommandLine cmd = null; 34 | CmdOptions cmdOpt = new CmdOptions();; 35 | 36 | try { 37 | cmd = parser.parse(options, args); 38 | if (cmd.hasOption("h")) 39 | help(); 40 | 41 | if (cmd.hasOption("f")) { 42 | cmdOpt.parserType = ParserType.getType(cmd.getOptionValue("f")) ; 43 | } 44 | 45 | if (cmd.hasOption("s")) { 46 | cmdOpt.multipleRace = false; 47 | } 48 | 49 | if (cmd.hasOption("v")) { 50 | try{ 51 | cmdOpt.verbosity = Integer.parseInt(cmd.getOptionValue("v")); 52 | if(cmdOpt.verbosity < 0 || cmdOpt.verbosity > 3){ 53 | log.log(Level.INFO, "Invalid verbosity level : " + cmdOpt.verbosity); 54 | } 55 | } 56 | catch (NumberFormatException nfe){ 57 | log.log(Level.INFO, "Invalid verbosity option : " + cmd.getOptionValue("v")); 58 | } 59 | } 60 | 61 | if (cmd.hasOption("p")) { 62 | cmdOpt.path = cmd.getOptionValue("p") ; 63 | } 64 | else { 65 | log.log(Level.INFO, "MIssing path to file/folder"); 66 | help(); 67 | } 68 | 69 | if (cmd.hasOption("m")) { 70 | cmdOpt.excludeList = cmd.getOptionValue("m") ; 71 | } 72 | 73 | } catch (ParseException e) { 74 | help(); 75 | } 76 | 77 | return cmdOpt; 78 | } 79 | 80 | private void help() { 81 | HelpFormatter formater = new HelpFormatter(); 82 | formater.printHelp("RAPID", options); 83 | System.exit(0); 84 | } 85 | 86 | public static void main(String[] args) { 87 | new GetOptions(args).parse(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/engine/Engine.java: -------------------------------------------------------------------------------- 1 | package engine; 2 | 3 | import event.Event; 4 | import parse.ParserType; 5 | import parse.rr.ParseRoadRunner; 6 | import parse.rv.ParseRVPredict; 7 | import parse.std.ParseStandard; 8 | import util.trace.Trace; 9 | 10 | public abstract class Engine { 11 | protected ParserType parserType; 12 | protected Trace trace; // CSV 13 | protected ParseRVPredict rvParser;// RV 14 | protected ParseStandard stdParser; // STD 15 | protected ParseRoadRunner rrParser; // RR 16 | protected E handlerEvent; 17 | 18 | public Engine(ParserType pType) { 19 | this.parserType = pType; 20 | } 21 | 22 | protected void initializeReader(String trace_folder) { 23 | if (this.parserType.isRV()) { 24 | initializeReaderRV(trace_folder); 25 | } else if (this.parserType.isCSV()) { 26 | initializeReaderCSV(trace_folder); 27 | } else if (this.parserType.isSTD()) { 28 | initializeReaderSTD(trace_folder); 29 | } else if (this.parserType.isRR()) { 30 | initializeReaderRR(trace_folder); 31 | } 32 | } 33 | 34 | protected abstract void initializeReaderRV(String trace_folder); 35 | 36 | protected abstract void initializeReaderCSV(String trace_file); 37 | 38 | protected abstract void initializeReaderSTD(String trace_file); 39 | 40 | protected abstract void initializeReaderRR(String trace_file); 41 | 42 | protected void printCompletionStatus() { 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/engine/accesstimes/orderedvars/OrderedVarsEngine.java: -------------------------------------------------------------------------------- 1 | package engine.accesstimes.orderedvars; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.racedetectionengine.RaceDetectionEngine; 7 | import event.Thread; 8 | import parse.ParserType; 9 | 10 | public class OrderedVarsEngine extends RaceDetectionEngine{ 11 | 12 | public OrderedVarsEngine(ParserType pType, String trace_folder, int verbosity) { 13 | super(pType); 14 | this.threadSet = new HashSet (); 15 | initializeReader(trace_folder); 16 | this.state = new OrderedVarsState(this.threadSet, verbosity); 17 | handlerEvent = new OrderedVarsEvent(); 18 | this.enablePrintStatus = false; 19 | } 20 | 21 | @Override 22 | protected boolean skipEvent(OrderedVarsEvent handlerEvent) { 23 | return false; 24 | } 25 | 26 | @Override 27 | protected void postHandleEvent(OrderedVarsEvent handlerEvent) { 28 | } 29 | 30 | public HashSet getOrdredVars(){ 31 | return this.state.orderedVariables; 32 | } 33 | 34 | public HashMap> getVariableToThreadSet(){ 35 | return this.state.variableToThreadSet; 36 | } 37 | 38 | public HashMap> getLockToThreadSet(){ 39 | return this.state.lockToThreadSet; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/engine/accesstimes/orderedvars/OrderedVarsState.java: -------------------------------------------------------------------------------- 1 | package engine.accesstimes.orderedvars; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.Iterator; 7 | 8 | import engine.racedetectionengine.State; 9 | import event.Thread; 10 | import event.Variable; 11 | import util.vectorclock.VectorClock; 12 | 13 | public class OrderedVarsState extends State { 14 | 15 | // ==== Internal data ==== 16 | public HashMap threadToIndex; 17 | private HashMap variableToIndex; 18 | private int numThreads; 19 | private int numVariables; 20 | 21 | // ==== Data used for algorithm ==== 22 | 23 | // Data for maintaining the partial order 24 | public ArrayList clockThread; 25 | public ArrayList lastWriteVariable; 26 | public HashMap thread_lastWriteAccessForVariable; // VarName -> threadId. thread_lastWriteAccessForVariable(x) = thread that performed the last write on x 27 | public HashSet readVars; // Set of vars x such that the last access on x was a read. 28 | public ArrayList lastVariable_read; 29 | 30 | public HashSet orderedVariables; 31 | public HashMap> lockToThreadSet; 32 | public HashMap> variableToThreadSet; 33 | public HashSet variablesWritten; 34 | 35 | 36 | // ==== parameter flags ==== 37 | public boolean tickClockOnAccess; 38 | public int verbosity; 39 | 40 | public OrderedVarsState(HashSet tSet, int verbosity) { 41 | this.verbosity = verbosity; 42 | initInternalData(tSet); 43 | initData(tSet); 44 | } 45 | 46 | private void initInternalData(HashSet tSet) { 47 | this.threadToIndex = new HashMap(); 48 | this.numThreads = 0; 49 | Iterator tIter = tSet.iterator(); 50 | while (tIter.hasNext()) { 51 | int threadId = tIter.next().getId(); 52 | this.threadToIndex.put(threadId, (Integer) this.numThreads); 53 | this.numThreads++; 54 | } 55 | 56 | this.variableToIndex = new HashMap(); 57 | this.numVariables = 0; 58 | } 59 | 60 | private void initialize1DArrayOfVectorClocksWithBottom( 61 | ArrayList arr, int len) { 62 | for (int i = 0; i < len; i++) { 63 | arr.add(new VectorClock(this.numThreads)); 64 | } 65 | } 66 | 67 | public void initData(HashSet tSet) { 68 | 69 | // initialize clockThread 70 | this.clockThread = new ArrayList(); 71 | initialize1DArrayOfVectorClocksWithBottom(this.clockThread, this.numThreads); 72 | for (int i = 0; i < this.numThreads; i++) { 73 | VectorClock C_t = this.clockThread.get(i); 74 | C_t.setClockIndex(i, 1); 75 | } 76 | 77 | // initialize lastWriteVariable 78 | this.lastWriteVariable = new ArrayList(); 79 | 80 | // initialize lastWriteVariable 81 | this.lastVariable_read = new ArrayList(); 82 | this.thread_lastWriteAccessForVariable = new HashMap (); 83 | this.readVars = new HashSet (); 84 | 85 | // initialize orderedVariables 86 | this.orderedVariables = new HashSet (); 87 | 88 | this.lockToThreadSet = new HashMap>(); 89 | this.variableToThreadSet = new HashMap>(); 90 | this.variablesWritten = new HashSet (); 91 | } 92 | 93 | // Access methods 94 | private VectorClock getVectorClockFrom1DArray(ArrayList arr, 95 | int index) { 96 | if (index < 0 || index >= arr.size()) { 97 | throw new IllegalArgumentException("Illegal Out of Bound access"); 98 | } 99 | return arr.get(index); 100 | } 101 | 102 | public int checkAndAddVariable(Variable v) { 103 | if (!variableToIndex.containsKey(v.getName())) { 104 | variableToIndex.put(v.getName(), this.numVariables); 105 | this.numVariables++; 106 | this.lastWriteVariable.add(new VectorClock(this.numThreads)); 107 | this.lastVariable_read.add(new VectorClock(this.numThreads)); 108 | this.orderedVariables.add(v.getName()); 109 | } 110 | return variableToIndex.get(v.getName()); 111 | } 112 | 113 | public void incClockThread(Thread t) { 114 | int tIndex = threadToIndex.get(t.getId()); 115 | VectorClock C_t = getVectorClock(clockThread, t); 116 | int origVal = C_t.getClockIndex(tIndex); 117 | C_t.setClockIndex(tIndex, origVal + 1); 118 | } 119 | 120 | public VectorClock getVectorClock(ArrayList arr, Thread t) { 121 | int tIndex = threadToIndex.get(t.getId()); 122 | return getVectorClockFrom1DArray(arr, tIndex); 123 | } 124 | 125 | public VectorClock getVectorClock(ArrayList arr, Variable v) { 126 | int vIndex = checkAndAddVariable(v); 127 | return getVectorClockFrom1DArray(arr, vIndex); 128 | } 129 | 130 | public void setClockIndex(VectorClock vc, int tId, int val) { 131 | int tIndex = threadToIndex.get(tId); 132 | vc.setClockIndex(tIndex, val); 133 | } 134 | 135 | public int getClockIndex(VectorClock vc, int tId) { 136 | int tIndex = threadToIndex.get(tId); 137 | return vc.getClockIndex(tIndex); 138 | } 139 | 140 | public boolean isThreadRelevant(Thread t) { 141 | return this.threadToIndex.containsKey(t.getId()); 142 | } 143 | 144 | public void printMemory() { 145 | System.err.println("Number of threads = " + Integer.toString(this.numThreads)); 146 | System.err 147 | .println("Number of variables = " + Integer.toString(this.numVariables)); 148 | } 149 | } -------------------------------------------------------------------------------- /src/engine/atomicity/AtomicityEngine.java: -------------------------------------------------------------------------------- 1 | package engine.atomicity; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.Engine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | import parse.csv.ParseCSV; 9 | import parse.rr.ParseRoadRunner; 10 | import parse.rv.ParseRVPredict; 11 | import parse.std.ParseStandard; 12 | import util.trace.TraceAndDataSets; 13 | 14 | public abstract class AtomicityEngine> extends Engine { 15 | 16 | public St state; 17 | protected HashSet threadSet; 18 | 19 | protected long eventCount; 20 | protected Long violationCount; 21 | protected Long totalSkippedEvents; 22 | 23 | public AtomicityEngine(ParserType pType) { 24 | super(pType); 25 | } 26 | 27 | protected void initializeReaderRV(String trace_folder){ 28 | rvParser = new ParseRVPredict(trace_folder, this.threadSet); 29 | } 30 | 31 | protected void initializeReaderCSV(String trace_file){ 32 | TraceAndDataSets traceAndDataSets = ParseCSV.parse(true, trace_file); 33 | this.threadSet = traceAndDataSets.getThreadSet(); 34 | this.trace = traceAndDataSets.getTrace(); 35 | } 36 | 37 | protected void initializeReaderSTD(String trace_folder){ 38 | stdParser = new ParseStandard(trace_folder, true); 39 | threadSet = stdParser.getThreadSet(); 40 | } 41 | 42 | protected void initializeReaderRR(String trace_folder){ 43 | rrParser = new ParseRoadRunner(trace_folder, true); 44 | threadSet = rrParser.getThreadSet(); 45 | } 46 | 47 | protected boolean analyzeEvent(RDE handlerEvent, Long eventCount){ 48 | boolean violationDetected = false; 49 | try{ 50 | violationDetected = handlerEvent.Handle(state); 51 | } 52 | catch(OutOfMemoryError oome){ 53 | oome.printStackTrace(); 54 | System.err.println("Number of events = " + Long.toString(eventCount)); 55 | state.printMemory(); 56 | } 57 | if(state.verbosity==3 && handlerEvent.getType().isAccessType() ){ 58 | System.out.println("|"+Long.toString(eventCount)); 59 | } 60 | 61 | // if (violationDetected) { 62 | // System.out.println(handlerEvent.getLocId()); 63 | // } 64 | return violationDetected; 65 | } 66 | 67 | public void analyzeTrace(boolean multipleRace){ 68 | eventCount = (long) 0; 69 | violationCount = (long) 0; 70 | totalSkippedEvents = (long) 0; 71 | if(this.parserType.isRV()){ 72 | analyzeTraceRV(multipleRace); 73 | } 74 | else if(this.parserType.isCSV()){ 75 | analyzeTraceCSV(multipleRace); 76 | } 77 | else if(this.parserType.isSTD()){ 78 | analyzeTraceSTD(multipleRace); 79 | } 80 | else if(this.parserType.isRR()){ 81 | analyzeTraceRR(multipleRace); 82 | } 83 | 84 | System.out.println("Analysis complete"); 85 | if(violationCount > 0) { 86 | System.out.println("Atomicity violation detected"); 87 | } 88 | else { 89 | System.out.println("No atomicity violation detected"); 90 | } 91 | System.out.println("Number of events analyzed = " + Long.toString(eventCount)); 92 | } 93 | 94 | protected void analyzeTraceCSV(boolean multipleRace) { 95 | for(eventCount = 0; eventCount < trace.getSize(); eventCount ++){ 96 | handlerEvent.copyFrom(trace.getEventAt((int)eventCount)); 97 | if(skipEvent(handlerEvent)){ 98 | totalSkippedEvents = totalSkippedEvents + 1; 99 | } 100 | else{ 101 | boolean raceDetected = analyzeEvent(handlerEvent, eventCount); 102 | if(raceDetected){ 103 | violationCount ++; 104 | if (!multipleRace){ 105 | break; 106 | } 107 | } 108 | postHandleEvent(handlerEvent); 109 | } 110 | } 111 | } 112 | 113 | protected void analyzeTraceRV(boolean multipleRace) { 114 | if(rvParser.pathListNotNull()){ 115 | while(rvParser.hasNext()){ 116 | eventCount = eventCount + 1; 117 | rvParser.getNextEvent(handlerEvent); 118 | 119 | if(skipEvent(handlerEvent)){ 120 | totalSkippedEvents = totalSkippedEvents + 1; 121 | } 122 | else{ 123 | boolean raceDetected = analyzeEvent(handlerEvent, (long) eventCount); 124 | if(raceDetected){ 125 | violationCount ++; 126 | if (!multipleRace){ 127 | break; 128 | } 129 | } 130 | postHandleEvent(handlerEvent); 131 | } 132 | } 133 | } 134 | } 135 | 136 | protected void analyzeTraceSTD(boolean multipleRace) { 137 | while(stdParser.hasNext()){ 138 | eventCount = eventCount + 1; 139 | stdParser.getNextEvent(handlerEvent); 140 | 141 | if(skipEvent(handlerEvent)){ 142 | totalSkippedEvents = totalSkippedEvents + 1; 143 | } 144 | else{ 145 | boolean violationDetected = analyzeEvent(handlerEvent, (long) eventCount); 146 | if(violationDetected){ 147 | violationCount ++; 148 | if (!multipleRace){ 149 | break; 150 | } 151 | } 152 | postHandleEvent(handlerEvent); 153 | } 154 | } 155 | } 156 | 157 | protected void analyzeTraceRR(boolean multipleRace) { 158 | while(rrParser.checkAndGetNext(handlerEvent)){ 159 | eventCount = eventCount + 1; 160 | 161 | if(skipEvent(handlerEvent)){ 162 | totalSkippedEvents = totalSkippedEvents + 1; 163 | } 164 | else{ 165 | boolean violationDetected = analyzeEvent(handlerEvent, (long) eventCount); 166 | if(violationDetected){ 167 | violationCount ++; 168 | if (!multipleRace){ 169 | break; 170 | } 171 | } 172 | postHandleEvent(handlerEvent); 173 | } 174 | } 175 | } 176 | 177 | protected abstract boolean skipEvent(RDE handlerEvent); 178 | 179 | protected abstract void postHandleEvent(RDE handlerEvent); 180 | 181 | } 182 | -------------------------------------------------------------------------------- /src/engine/atomicity/AtomicityEvent.java: -------------------------------------------------------------------------------- 1 | package engine.atomicity; 2 | 3 | import event.Event; 4 | 5 | public abstract class AtomicityEvent extends Event { 6 | public AtomicityEvent(){ 7 | super(); 8 | } 9 | 10 | public void copyFrom(Event fromEvent){ 11 | super.copyFrom(fromEvent); 12 | } 13 | 14 | public void printRaceInfo(S state){ 15 | if(this.getType().isLockType()) this.printRaceInfoLockType(state); 16 | if(this.getType().isAccessType()) this.printRaceInfoAccessType(state); 17 | if(this.getType().isExtremeType()) this.printRaceInfoExtremeType(state); 18 | if(this.getType().isTransactionType()) this.printRaceInfoTransactionType(state); 19 | } 20 | 21 | public boolean Handle(S state) { 22 | return this.HandleSub(state); 23 | } 24 | 25 | public boolean HandleSub(S state){ 26 | boolean violationDetected = false; 27 | 28 | if(this.getType().isAcquire()) violationDetected = this.HandleSubAcquire(state); 29 | if(this.getType().isRelease()) violationDetected = this.HandleSubRelease(state); 30 | if(this.getType().isRead()) violationDetected = this.HandleSubRead(state); 31 | if(this.getType().isWrite()) violationDetected = this.HandleSubWrite(state); 32 | if(this.getType().isFork()) violationDetected = this.HandleSubFork(state); 33 | if(this.getType().isJoin()) violationDetected = this.HandleSubJoin(state); 34 | if(this.getType().isBegin()) violationDetected = this.HandleSubBegin(state); 35 | if(this.getType().isEnd()) violationDetected = this.HandleSubEnd(state); 36 | 37 | return violationDetected; 38 | } 39 | 40 | public abstract void printRaceInfoLockType(S state); 41 | public abstract void printRaceInfoAccessType(S state); 42 | public abstract void printRaceInfoExtremeType(S state); 43 | public abstract void printRaceInfoTransactionType(S state); 44 | 45 | public abstract boolean HandleSubAcquire(S state); 46 | public abstract boolean HandleSubRelease(S state); 47 | public abstract boolean HandleSubRead(S state); 48 | public abstract boolean HandleSubWrite(S state); 49 | public abstract boolean HandleSubFork(S state); 50 | public abstract boolean HandleSubJoin(S state); 51 | public abstract boolean HandleSubBegin(S state); 52 | public abstract boolean HandleSubEnd(S state); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/engine/atomicity/State.java: -------------------------------------------------------------------------------- 1 | package engine.atomicity; 2 | 3 | public abstract class State { 4 | 5 | //parameter flags 6 | public boolean forceOrder; 7 | public boolean tickClockOnAccess; 8 | public int verbosity; 9 | 10 | public abstract void printMemory(); 11 | } 12 | -------------------------------------------------------------------------------- /src/engine/atomicity/conflictserializability/aerodrome/AerodromeEngine.java: -------------------------------------------------------------------------------- 1 | package engine.atomicity.conflictserializability.aerodrome; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.atomicity.AtomicityEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class AerodromeEngine extends AtomicityEngine{ 10 | 11 | public AerodromeEngine(ParserType pType, String trace_folder, int verbosity) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new AerodromeState(this.threadSet, verbosity); 16 | handlerEvent = new AerodromeEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(AerodromeEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(AerodromeEvent handlerEvent) { 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/engine/atomicity/conflictserializability/aerodrome_basic/AerodromeEngine.java: -------------------------------------------------------------------------------- 1 | package engine.atomicity.conflictserializability.aerodrome_basic; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.atomicity.AtomicityEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class AerodromeEngine extends AtomicityEngine{ 10 | 11 | public AerodromeEngine(ParserType pType, String trace_folder, int verbosity) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new AerodromeState(this.threadSet, verbosity); 16 | handlerEvent = new AerodromeEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(AerodromeEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(AerodromeEvent handlerEvent) { 26 | // if(handlerEvent.getType().isAccessType()){ 27 | // if(state.verbosity == 1 || state.verbosity == 2){ 28 | // System.out.println(); 29 | // } 30 | // } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/engine/atomicity/conflictserializability/velodome/VelodromeEngine.java: -------------------------------------------------------------------------------- 1 | package engine.atomicity.conflictserializability.velodome; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.atomicity.AtomicityEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class VelodromeEngine extends AtomicityEngine{ 10 | 11 | public VelodromeEngine(ParserType pType, String trace_folder, int verbosity) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new VelodromeState(this.threadSet, verbosity); 16 | handlerEvent = new VelodromeEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(VelodromeEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(VelodromeEvent handlerEvent) { 26 | } 27 | 28 | public int numTransactionsActive() { 29 | return this.state.numTransactionsActive(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/engine/print/PrintEngine.java: -------------------------------------------------------------------------------- 1 | package engine.print; 2 | import java.util.HashMap; 3 | 4 | import engine.Engine; 5 | import event.Event; 6 | import event.EventType; 7 | import event.Thread; 8 | import parse.ParserType; 9 | import parse.csv.ParseCSV; 10 | import parse.rr.ParseRoadRunner; 11 | import parse.rv.ParseRVPredict; 12 | import parse.std.ParseStandard; 13 | import util.trace.TraceAndDataSets; 14 | 15 | public class PrintEngine extends Engine { 16 | 17 | int totThreads; 18 | int currentThreadIdx; 19 | HashMap tIndexMap; 20 | static HashMap type2String; 21 | 22 | private static void initType2String(){ 23 | type2String = new HashMap (); 24 | type2String.put(EventType.ACQUIRE, "acq"); 25 | type2String.put(EventType.RELEASE, "rel"); 26 | type2String.put(EventType.READ, "r"); 27 | type2String.put(EventType.WRITE, "w"); 28 | type2String.put(EventType.FORK, "fork"); 29 | type2String.put(EventType.JOIN, "join"); 30 | } 31 | 32 | public PrintEngine(ParserType pType, String trace_folder) { 33 | super(pType); 34 | initializeReader(trace_folder); 35 | initType2String(); 36 | handlerEvent = new Event(); 37 | tIndexMap = new HashMap (); 38 | currentThreadIdx = 0; 39 | } 40 | 41 | public void analyzeTrace(ParserType outputType) { 42 | if(this.parserType.isRV()){ 43 | analyzeTraceRV(outputType); 44 | } 45 | else if(this.parserType.isCSV()){ 46 | analyzeTraceCSV(outputType); 47 | } 48 | else if(this.parserType.isSTD()){ 49 | analyzeTraceSTD(outputType); 50 | } 51 | else if(this.parserType.isRR()){ 52 | analyzeTraceRR(outputType); 53 | } 54 | } 55 | 56 | private void analyzeTraceRV(ParserType outputType) { 57 | if(rvParser.pathListNotNull()){ 58 | while(rvParser.hasNext()){ 59 | rvParser.getNextEvent(handlerEvent); 60 | if(! skipEvent(handlerEvent)){ 61 | processEvent(outputType); 62 | } 63 | } 64 | } 65 | } 66 | 67 | private void analyzeTraceSTD(ParserType outputType) { 68 | while(stdParser.hasNext()){ 69 | stdParser.getNextEvent(handlerEvent); 70 | if(! skipEvent(handlerEvent)){ 71 | processEvent(outputType); 72 | } 73 | } 74 | } 75 | 76 | private void analyzeTraceCSV(ParserType outputType) { 77 | for(int eCount = 0; eCount < trace.getSize(); eCount ++){ 78 | handlerEvent = trace.getEventAt(eCount); 79 | if(! skipEvent(handlerEvent)){ 80 | processEvent(outputType); 81 | } 82 | } 83 | } 84 | 85 | private void analyzeTraceRR(ParserType outputType) { 86 | while(rrParser.checkAndGetNext(handlerEvent)){ 87 | if(! skipEvent(handlerEvent)){ 88 | processEvent(outputType); 89 | } 90 | } 91 | } 92 | 93 | private boolean skipEvent(Event handlerEvent){ 94 | boolean skip = false; 95 | return skip; 96 | } 97 | 98 | private String toCSV(Event e, int tIdx, int totThreads){ 99 | String csvStr = ""; 100 | String decor_name = ""; 101 | if(e.getType().isAccessType()){ 102 | decor_name = e.getVariable().getName(); 103 | } 104 | else if(e.getType().isLockType()){ 105 | decor_name = e.getLock().getName(); 106 | } 107 | else if(e.getType().isExtremeType()){ 108 | Integer target_index = this.tIndexMap.get(e.getTarget()); 109 | if(target_index == null){ 110 | decor_name = "-unknown-thread-"; 111 | } 112 | else{ 113 | decor_name = "T" + target_index; 114 | } 115 | } 116 | for(int i = 0; i { 17 | 18 | int totThreads; 19 | int currentThreadIdx; 20 | HashMap tIndexMap; 21 | static HashMap type2String; 22 | 23 | private static void initType2String(){ 24 | type2String = new HashMap (); 25 | type2String.put(EventType.ACQUIRE, "acq"); 26 | type2String.put(EventType.RELEASE, "rel"); 27 | type2String.put(EventType.READ, "r"); 28 | type2String.put(EventType.WRITE, "w"); 29 | type2String.put(EventType.FORK, "fork"); 30 | type2String.put(EventType.JOIN, "join"); 31 | } 32 | 33 | public PrintFilterEngine(ParserType pType, String trace_folder) { 34 | super(pType); 35 | initializeReader(trace_folder); 36 | initType2String(); 37 | handlerEvent = new Event(); 38 | tIndexMap = new HashMap (); 39 | currentThreadIdx = 0; 40 | 41 | boolean time_reporting = true; 42 | long startTimeAnalysis = 0; 43 | if(time_reporting){ 44 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 45 | } 46 | AccessTimesEngine accessTimesEngine = new AccessTimesEngine(pType, trace_folder); 47 | accessTimesEngine.computeLastAccessTimes(); 48 | if(time_reporting){ 49 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 50 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 51 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 52 | } 53 | } 54 | 55 | public void analyzeTrace(ParserType outputType) { 56 | if(this.parserType.isRV()){ 57 | analyzeTraceRV(outputType); 58 | } 59 | else if(this.parserType.isCSV()){ 60 | analyzeTraceCSV(outputType); 61 | } 62 | else if(this.parserType.isSTD()){ 63 | analyzeTraceSTD(outputType); 64 | } 65 | else if(this.parserType.isRR()){ 66 | analyzeTraceRR(outputType); 67 | } 68 | } 69 | 70 | private void analyzeTraceRV(ParserType outputType) { 71 | if(rvParser.pathListNotNull()){ 72 | while(rvParser.hasNext()){ 73 | rvParser.getNextEvent(handlerEvent); 74 | if(! skipEvent(handlerEvent)){ 75 | processEvent(outputType); 76 | } 77 | } 78 | } 79 | } 80 | 81 | private void analyzeTraceSTD(ParserType outputType) { 82 | while(stdParser.hasNext()){ 83 | stdParser.getNextEvent(handlerEvent); 84 | if(! skipEvent(handlerEvent)){ 85 | processEvent(outputType); 86 | } 87 | } 88 | } 89 | 90 | private void analyzeTraceCSV(ParserType outputType) { 91 | for(int eCount = 0; eCount < trace.getSize(); eCount ++){ 92 | handlerEvent = trace.getEventAt(eCount); 93 | if(! skipEvent(handlerEvent)){ 94 | processEvent(outputType); 95 | } 96 | } 97 | } 98 | 99 | private void analyzeTraceRR(ParserType outputType) { 100 | while(rrParser.checkAndGetNext(handlerEvent)){ 101 | if(! skipEvent(handlerEvent)){ 102 | processEvent(outputType); 103 | } 104 | } 105 | } 106 | 107 | private boolean skipEvent(Event handlerEvent){ 108 | boolean skip = false; 109 | return skip; 110 | } 111 | 112 | private String toCSV(Event e, int tIdx, int totThreads){ 113 | String csvStr = ""; 114 | String decor_name = ""; 115 | if(e.getType().isAccessType()){ 116 | decor_name = e.getVariable().getName(); 117 | } 118 | else if(e.getType().isLockType()){ 119 | decor_name = e.getLock().getName(); 120 | } 121 | else if(e.getType().isExtremeType()){ 122 | Integer target_index = this.tIndexMap.get(e.getTarget()); 123 | if(target_index == null){ 124 | decor_name = "-unknown-thread-"; 125 | } 126 | else{ 127 | decor_name = "T" + target_index; 128 | } 129 | } 130 | for(int i = 0; i = mid+1) { 185 | return sumRange(root.right, start, end); 186 | } else { 187 | int l = sumRange(root.left, start, mid); 188 | int r = sumRange(root.right, mid+1, end); 189 | 190 | return l < r ? l : r ; 191 | } 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /src/engine/racedetectionengine/OSR/POBuild/PartialOrder.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.OSR.POBuild; 2 | 3 | import util.Triplet; 4 | import util.vectorclock.VectorClock; 5 | 6 | import java.util.*; 7 | 8 | // This class exposes the method for abstract graph building 9 | 10 | public class PartialOrder { 11 | public int width; // number of threads 12 | public List> successors; 13 | 14 | public PartialOrder(Map>> succFromNode, 15 | Map>> succToNode, int numThreads) { 16 | this.width = numThreads; 17 | this.successors = new ArrayList<>(); 18 | 19 | for(int i=0; i< this.width; i++) { 20 | this.successors.add(new HashMap<>()); 21 | for(int j=0; j fromNodes = succFromNode.get(i).get(j); 24 | ArrayList toNodes = succToNode.get(i).get(j); 25 | this.successors.get(i).put(j, new RangeMinimaQuery(fromNodes, toNodes)); 26 | toNodes = null; 27 | succFromNode.get(i).remove(j); 28 | succToNode.get(i).remove(j); 29 | } 30 | } 31 | succFromNode.remove(i); 32 | succToNode.remove(i); 33 | } 34 | } 35 | 36 | public void pause() { 37 | try {System.in.read();} catch(Exception e) {} 38 | } 39 | 40 | 41 | // Given an event e1 and osr set, return the earliest events e2 in every thread, 42 | // s.t. there is a forward path from e1 to e2 43 | public VectorClock queryForEvent(Triplet event, VectorClock osr, 44 | ArrayList[] inThreadIdToAuxId){ 45 | // event = 46 | VectorClock ret = new VectorClock(osr.getDim()); 47 | int threadId = event.first; 48 | int inThreadId = event.second; 49 | int numThreads = ret.getDim(); 50 | int limit = osr.getClockIndex(threadId); 51 | 52 | // init with direct edges 53 | for(int i=0; i unvisited = new HashSet<>(); 92 | for(int i=0; i map = inThreadIdToAuxId[i]; 103 | int localId = ret.getClockIndex(i) - 1; 104 | long curAuxId; 105 | 106 | // localId = -2 => not reachable for now 107 | if (localId != -2) { 108 | curAuxId = map.get(localId); 109 | } else { 110 | curAuxId = Long.MAX_VALUE; 111 | } 112 | 113 | if (curTh == -1 || minAuxId > curAuxId) { 114 | curTh = i; 115 | minAuxId = curAuxId; 116 | } 117 | } 118 | 119 | // pick curTh to update the rest threads 120 | unvisited.remove(curTh); 121 | int left = ret.getClockIndex(curTh); 122 | int right = osr.getClockIndex(curTh); 123 | 124 | for(Integer to : unvisited) { 125 | int curVal = this.successors.get(curTh).get(to).getMinWithRange(left, right); 126 | if(curVal != -1 && curVal < ret.getClockIndex(to)) { 127 | ret.setClockIndex(to, curVal); 128 | } 129 | } 130 | } 131 | 132 | return ret; 133 | } 134 | 135 | // This is the entry method for building the abstract graph. 136 | // Given a list of events (events) and current OLClosure (osr), 137 | // returns a vector clock vc for each event e in events, 138 | // where vc[i] = e's first successor in thread i 139 | public List queryForEventLists(List> events, VectorClock osr, 140 | ArrayList[] inThreadIdToAuxId){ 141 | // input = list( ) 142 | // 143 | 144 | List ret = new ArrayList<>(); 145 | 146 | for(Triplet cur : events) { 147 | ret.add(this.queryForEvent(cur, osr, inThreadIdToAuxId)); 148 | } 149 | 150 | return ret; 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/OSR/POBuild/RangeMinima.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.OSR.POBuild; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class RangeMinima { 6 | 7 | public NumArrayMin numArray; 8 | 9 | public RangeMinima(ArrayList nums) { 10 | this.numArray = new NumArrayMin(nums); 11 | } 12 | 13 | public RangeMinima(RangeMinima other) { 14 | this.numArray = new NumArrayMin(other.numArray); 15 | } 16 | 17 | public int getMinWithRange(int leftInThId, int rightInThId){ 18 | return this.numArray.sumRange(leftInThId, rightInThId); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/OSR/POBuild/RangeMinimaQuery.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.OSR.POBuild; 2 | 3 | import java.util.ArrayList; 4 | 5 | // This class solves Range Minima Query using segment tree 6 | public class RangeMinimaQuery { 7 | public ArrayList inThreadIdArray; 8 | public int[] segmentTree; // tree node = [left idx of nums, right idx of nums, minVal] 9 | int numsSize; 10 | 11 | public RangeMinimaQuery(){} 12 | 13 | // Given the partial order built in POBuildReverse, initialize the segment tree 14 | // There is an edge from fromNodes[i] to toNodes[i]. 15 | public RangeMinimaQuery(ArrayList fromNodes, ArrayList toNodes){ 16 | // this.nums = nums; 17 | this.inThreadIdArray = fromNodes; 18 | this.buildTree(toNodes); 19 | } 20 | 21 | // Compute the size of segment tree 22 | public void buildUpArray(ArrayList nums){ 23 | this.numsSize = nums.size(); 24 | 25 | int exp = 1, limit = 2 * this.numsSize - 1; 26 | 27 | while(limit > exp - 1){ 28 | exp = exp * 2; 29 | } 30 | int treeSize = exp - 1; 31 | 32 | this.segmentTree = new int[treeSize]; 33 | } 34 | 35 | // Entry method for building segment tree 36 | public void buildTree(ArrayList nums){ 37 | if(nums.size() > 0) { 38 | this.buildUpArray(nums); 39 | this.buildTree(0, 0, this.numsSize - 1, nums); 40 | } 41 | } 42 | 43 | // Build the tree for segment [numsLeft, numsRight] in nums array. 44 | // This method returns the value we should save in this.segmentTree[treeLoc]. 45 | public int buildTree(int treeLoc, int numsLeft, int numsRight, ArrayList nums){ 46 | int val; 47 | if(numsLeft == numsRight){ 48 | val = nums.get(numsLeft); 49 | this.segmentTree[treeLoc] = val; 50 | return val; 51 | } 52 | 53 | int mid = (numsLeft + numsRight) / 2; 54 | 55 | int left = this.buildTree(2 * treeLoc + 1, numsLeft, mid, nums); 56 | int right = this.buildTree(2 * treeLoc + 2, mid + 1, numsRight, nums); 57 | 58 | val = Math.min(left, right); 59 | this.segmentTree[treeLoc] = val; 60 | return val; 61 | } 62 | 63 | // Given a query [left, right], return the min value in this range 64 | public int rangeQueryMin(int left, int right){ 65 | if(left < 0 || right >= this.numsSize || left > right) return -1; 66 | else return rangeQueryMin(0, 0, this.numsSize - 1, left, right); 67 | } 68 | 69 | 70 | // recursive query method 71 | public int rangeQueryMin(int treeLoc, int curNodeLeft, int curNodeRight, int queryLeft, int queryRight){ 72 | if(queryLeft <= curNodeLeft && queryRight >= curNodeRight) { 73 | // curNode is in query range, return node value 74 | return this.segmentTree[treeLoc]; 75 | } 76 | else if(queryLeft > curNodeRight || queryRight < curNodeLeft) return Integer.MAX_VALUE; // out of range 77 | else { 78 | int nodeMid = (curNodeLeft + curNodeRight) / 2; 79 | int leftVal = rangeQueryMin(2 * treeLoc + 1, curNodeLeft, nodeMid, queryLeft, queryRight); 80 | int rightVal = rangeQueryMin(2 * treeLoc + 2, nodeMid + 1, curNodeRight, queryLeft, queryRight); 81 | return Math.min(leftVal, rightVal); 82 | } 83 | } 84 | 85 | // find the largest index idx in nums, s.t. nums[idx] >= val 86 | public int searchIndexLeft(int val){ 87 | if(this.inThreadIdArray.get(0) < val) return -1; 88 | int size = this.inThreadIdArray.size(); 89 | int left = 0, right = size - 1; 90 | int mid = -1; 91 | 92 | while(left < right){ 93 | mid = (left + right) / 2; 94 | int midVal = this.inThreadIdArray.get(mid); 95 | 96 | if(midVal == val) return mid; 97 | else if(midVal > val){ 98 | if(mid + 1 < size){ 99 | if(this.inThreadIdArray.get(mid + 1) >= val){ 100 | left = mid + 1; 101 | } else { 102 | return mid; 103 | } 104 | } else { 105 | return size - 1; 106 | } 107 | } else { 108 | right = mid - 1; 109 | } 110 | } 111 | 112 | return left; 113 | } 114 | 115 | // find the smallest index idx in nums, s.t. nums[idx] <= val 116 | public int searchIndexRight(int val){ 117 | if(this.inThreadIdArray.get(this.inThreadIdArray.size()-1) > val) return this.inThreadIdArray.size(); 118 | 119 | int left = 0, right = this.inThreadIdArray.size() - 1; 120 | int mid = -1; 121 | 122 | while(left < right){ 123 | mid = (left + right) / 2; 124 | int midVal = inThreadIdArray.get(mid); 125 | 126 | if(midVal == val) return mid; 127 | else if(midVal > val){ 128 | left = mid + 1; 129 | } else { 130 | if(mid - 1 >= 0){ 131 | if(this.inThreadIdArray.get(mid - 1) <= val){ 132 | right = mid - 1; 133 | } else { 134 | return mid; 135 | } 136 | } else { 137 | return 0; 138 | } 139 | } 140 | } 141 | 142 | return left; 143 | } 144 | 145 | // Note that the input leftInThId, rightInThId are different from the index 146 | // of this.segmentTree index. 147 | // This methods maps a query on in-thread Id into segmentTree index and performs the query. 148 | public int getMinWithRange(int leftInThId, int rightInThId) { 149 | if(this.inThreadIdArray.size() == 0) return -1; 150 | 151 | int right = searchIndexLeft(leftInThId); 152 | int left = searchIndexRight(rightInThId); 153 | 154 | if(left < 0 || right >= this.inThreadIdArray.size() || left > right) return -1; 155 | 156 | return this.rangeQueryMin(left, right); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/OSR/RelEventInfo.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.OSR; 2 | 3 | import util.vectorclock.VectorClock; 4 | 5 | public class RelEventInfo extends EventInfo { 6 | 7 | public VectorClock TLClosure; 8 | 9 | public long auxId; 10 | 11 | public RelEventInfo(){} 12 | 13 | @Override 14 | public String toString() { 15 | return "RelEventInfo{" + 16 | ", TLClosure=" + TLClosure + 17 | ", auxId=" + auxId + 18 | ", inThreadId=" + inThreadId + 19 | '}'; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/RaceDetectionEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.Engine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | import parse.csv.ParseCSV; 9 | import parse.rr.ParseRoadRunner; 10 | import parse.rv.ParseRVPredict; 11 | import parse.std.ParseStandard; 12 | import util.trace.TraceAndDataSets; 13 | 14 | public abstract class RaceDetectionEngine> 15 | extends Engine { 16 | 17 | public St state; 18 | protected HashSet threadSet; 19 | 20 | protected long eventCount; 21 | protected Long raceCount; 22 | protected HashSet locIdsOfRacyEvents; 23 | protected Long totalSkippedEvents; 24 | 25 | protected boolean enablePrintStatus; 26 | 27 | public RaceDetectionEngine(ParserType pType) { 28 | super(pType); 29 | enablePrintStatus = true; 30 | } 31 | 32 | @Override 33 | protected void initializeReaderRV(String trace_folder) { 34 | rvParser = new ParseRVPredict(trace_folder, this.threadSet); 35 | } 36 | 37 | @Override 38 | protected void initializeReaderCSV(String trace_file) { 39 | TraceAndDataSets traceAndDataSets = ParseCSV.parse(true, trace_file); 40 | this.threadSet = traceAndDataSets.getThreadSet(); 41 | this.trace = traceAndDataSets.getTrace(); 42 | } 43 | 44 | @Override 45 | protected void initializeReaderSTD(String trace_file) { 46 | stdParser = new ParseStandard(trace_file, true); 47 | threadSet = stdParser.getThreadSet(); 48 | } 49 | 50 | @Override 51 | protected void initializeReaderRR(String trace_file) { 52 | rrParser = new ParseRoadRunner(trace_file, true); 53 | threadSet = rrParser.getThreadSet(); 54 | } 55 | 56 | protected abstract boolean skipEvent(RDE handlerEvent); 57 | 58 | protected abstract void postHandleEvent(RDE handlerEvent); 59 | 60 | protected boolean analyzeEvent(RDE handlerEvent, int verbosity, Long eventCount) { 61 | boolean raceDetected = false; 62 | try { 63 | raceDetected = handlerEvent.Handle(state, verbosity); 64 | } catch (OutOfMemoryError oome) { 65 | oome.printStackTrace(); 66 | System.err.println("Number of events = " + Long.toString(eventCount)); 67 | state.printMemory(); 68 | } 69 | if (verbosity == 3 && handlerEvent.getType().isAccessType()) { 70 | System.out.println("|" + Long.toString(eventCount)); 71 | } 72 | 73 | if (raceDetected) { 74 | // raceCount ++; 75 | 76 | if (verbosity >= 1) { 77 | System.out.println("Race detected at event " + eventCount + " : " 78 | + handlerEvent.toStandardFormat()); 79 | } else { 80 | // System.out.println(handlerEvent.getLocId()); 81 | } 82 | this.locIdsOfRacyEvents.add(handlerEvent.getLocId()); 83 | } 84 | return raceDetected; 85 | } 86 | 87 | public void analyzeTrace(boolean multipleRace, int verbosity) { 88 | eventCount = (long) 0; 89 | raceCount = (long) 0; 90 | locIdsOfRacyEvents = new HashSet(); 91 | totalSkippedEvents = (long) 0; 92 | if (this.parserType.isRV()) { 93 | analyzeTraceRV(multipleRace, verbosity); 94 | } else if (this.parserType.isCSV()) { 95 | analyzeTraceCSV(multipleRace, verbosity); 96 | } else if (this.parserType.isSTD()) { 97 | analyzeTraceSTD(multipleRace, verbosity); 98 | } else if (this.parserType.isRR()) { 99 | analyzeTraceRR(multipleRace, verbosity); 100 | } 101 | printCompletionStatus(); 102 | postAnalysis(); 103 | } 104 | 105 | protected void postAnalysis() { 106 | } 107 | 108 | public void analyzeTraceCSV(boolean multipleRace, int verbosity) { 109 | for (eventCount = 0; eventCount < trace.getSize(); eventCount++) { 110 | handlerEvent.copyFrom(trace.getEventAt((int) eventCount)); 111 | if (skipEvent(handlerEvent)) { 112 | totalSkippedEvents = totalSkippedEvents + 1; 113 | } else { 114 | boolean raceDetected = analyzeEvent(handlerEvent, verbosity, eventCount); 115 | if (raceDetected) { 116 | raceCount++; 117 | if (!multipleRace) { 118 | break; 119 | } 120 | } 121 | postHandleEvent(handlerEvent); 122 | } 123 | } 124 | } 125 | 126 | public void analyzeTraceRV(boolean multipleRace, int verbosity) { 127 | if (rvParser.pathListNotNull()) { 128 | while (rvParser.hasNext()) { 129 | eventCount = eventCount + 1; 130 | rvParser.getNextEvent(handlerEvent); 131 | 132 | if (skipEvent(handlerEvent)) { 133 | totalSkippedEvents = totalSkippedEvents + 1; 134 | } else { 135 | boolean raceDetected = analyzeEvent(handlerEvent, verbosity, 136 | (long) eventCount); 137 | if (raceDetected) { 138 | raceCount++; 139 | if (!multipleRace) { 140 | break; 141 | } 142 | } 143 | postHandleEvent(handlerEvent); 144 | } 145 | } 146 | } 147 | } 148 | 149 | public void analyzeTraceSTD(boolean multipleRace, int verbosity) { 150 | while (stdParser.hasNext()) { 151 | eventCount = eventCount + 1; 152 | stdParser.getNextEvent(handlerEvent); 153 | 154 | if (skipEvent(handlerEvent)) { 155 | totalSkippedEvents = totalSkippedEvents + 1; 156 | } else { 157 | boolean raceDetected = analyzeEvent(handlerEvent, verbosity, eventCount); 158 | if (raceDetected) { 159 | raceCount++; 160 | if (!multipleRace) { 161 | break; 162 | } 163 | } 164 | postHandleEvent(handlerEvent); 165 | } 166 | } 167 | } 168 | 169 | public void analyzeTraceRR(boolean multipleRace, int verbosity) { 170 | while (rrParser.checkAndGetNext(handlerEvent)) { 171 | eventCount = eventCount + 1; 172 | if (skipEvent(handlerEvent)) { 173 | totalSkippedEvents = totalSkippedEvents + 1; 174 | } else { 175 | boolean raceDetected = analyzeEvent(handlerEvent, verbosity, 176 | (long) eventCount); 177 | if (raceDetected) { 178 | raceCount++; 179 | if (!multipleRace) { 180 | break; 181 | } 182 | } 183 | postHandleEvent(handlerEvent); 184 | } 185 | } 186 | } 187 | 188 | @Override 189 | protected void printCompletionStatus() { 190 | if (enablePrintStatus) { 191 | System.out.println("Analysis complete"); 192 | System.out.println( 193 | "Number of 'racy' events found = " + Long.toString(raceCount)); 194 | System.out.println( 195 | "Number of 'racy' lines found = " + this.locIdsOfRacyEvents.size()); 196 | } 197 | } 198 | 199 | } 200 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/RaceDetectionEvent.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine; 2 | 3 | import event.Event; 4 | 5 | public abstract class RaceDetectionEvent extends Event { 6 | public RaceDetectionEvent(){ 7 | super(); 8 | } 9 | 10 | public void copyFrom(Event fromEvent){ 11 | super.copyFrom(fromEvent); 12 | } 13 | 14 | public void printRaceInfo(S state, int verbosity){ 15 | if(this.getType().isLockType()) this.printRaceInfoLockType(state, verbosity); 16 | if(this.getType().isAccessType()) this.printRaceInfoAccessType(state, verbosity); 17 | if(this.getType().isExtremeType()) this.printRaceInfoExtremeType(state, verbosity); 18 | } 19 | 20 | public abstract boolean Handle(S state, int verbosity); 21 | 22 | public boolean HandleSub(S state, int verbosity){ 23 | boolean raceDetected = false; 24 | 25 | if(this.getType().isAcquire()) raceDetected = this.HandleSubAcquire(state, verbosity); 26 | if(this.getType().isRelease()) raceDetected = this.HandleSubRelease(state, verbosity); 27 | if(this.getType().isRead()) raceDetected = this.HandleSubRead(state, verbosity); 28 | if(this.getType().isWrite()) raceDetected = this.HandleSubWrite(state, verbosity); 29 | if(this.getType().isFork()) raceDetected = this.HandleSubFork(state, verbosity); 30 | if(this.getType().isJoin()) raceDetected = this.HandleSubJoin(state, verbosity); 31 | if(this.getType().isBegin()) raceDetected = this.HandleSubBegin(state, verbosity); 32 | if(this.getType().isEnd()) raceDetected = this.HandleSubEnd(state, verbosity); 33 | 34 | return raceDetected; 35 | } 36 | 37 | public abstract void printRaceInfoLockType(S state, int verbosity); 38 | public abstract void printRaceInfoAccessType(S state, int verbosity); 39 | public abstract void printRaceInfoExtremeType(S state, int verbosity); 40 | public abstract void printRaceInfoTransactionType(S state, int verbosity); 41 | 42 | public abstract boolean HandleSubAcquire(S state, int verbosity); 43 | public abstract boolean HandleSubRelease(S state, int verbosity); 44 | public abstract boolean HandleSubRead(S state, int verbosity); 45 | public abstract boolean HandleSubWrite(S state, int verbosity); 46 | public abstract boolean HandleSubFork(S state, int verbosity); 47 | public abstract boolean HandleSubJoin(S state, int verbosity); 48 | public abstract boolean HandleSubBegin(S state, int verbosity); 49 | public abstract boolean HandleSubEnd(S state, int verbosity); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/State.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine; 2 | 3 | public abstract class State { 4 | 5 | public abstract void printMemory(); 6 | } 7 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/fhb/FHBEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.fhb; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class FHBEngine extends RaceDetectionEngine{ 10 | 11 | public FHBEngine(ParserType pType, String trace_folder) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new FHBState(this.threadSet); 16 | handlerEvent = new FHBEvent(); 17 | } 18 | 19 | public void postAnalysis(){ 20 | // System.out.println("Number of race pc pairs = " + Integer.toString(state.getLocPairs().size())); 21 | } 22 | 23 | @Override 24 | protected boolean skipEvent(FHBEvent handlerEvent) { 25 | return false; 26 | } 27 | 28 | @Override 29 | protected void postHandleEvent(FHBEvent handlerEvent) { 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/goldilocks/GoldilocksEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.goldilocks; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class GoldilocksEngine extends RaceDetectionEngine{ 10 | 11 | public GoldilocksEngine(ParserType pType, String trace_folder, int verbosity) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new GoldilocksState(this.threadSet, verbosity); 16 | handlerEvent = new GoldilocksEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(GoldilocksEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(GoldilocksEvent handlerEvent) { 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/goldilocks/GoldilocksOfflineEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.goldilocks; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.accesstimes.AccessTimesEngine; 7 | import engine.racedetectionengine.RaceDetectionEngine; 8 | import event.Thread; 9 | import parse.ParserType; 10 | 11 | 12 | public class GoldilocksOfflineEngine extends RaceDetectionEngine { 13 | 14 | private HashMap> variableToThreadSet; 15 | private HashMap> lockToThreadSet; 16 | 17 | 18 | public GoldilocksOfflineEngine(ParserType pType, String trace_folder, int verbosity) { 19 | super(pType); 20 | this.threadSet = new HashSet (); 21 | initializeReader(trace_folder); 22 | this.state = new GoldilocksState(this.threadSet, verbosity); 23 | handlerEvent = new GoldilocksEvent(); 24 | 25 | boolean time_reporting = true; 26 | long startTimeAnalysis = 0; 27 | if(time_reporting){ 28 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 29 | } 30 | AccessTimesEngine accessTimesEngine = new AccessTimesEngine(pType, trace_folder); 31 | accessTimesEngine.computeLastAccessTimes(); 32 | if(time_reporting){ 33 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 34 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 35 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 36 | } 37 | 38 | this.variableToThreadSet = accessTimesEngine.variableToThreadSet; 39 | this.lockToThreadSet = accessTimesEngine.lockToThreadSet; 40 | } 41 | 42 | @Override 43 | protected boolean skipEvent(GoldilocksEvent handlerEvent){ 44 | boolean skip = false; 45 | if(handlerEvent.getType().isAccessType()){ 46 | if(variableToThreadSet.get(handlerEvent.getVariable().getName()).size() <= 1 ){ 47 | skip = true; 48 | } 49 | } 50 | if(handlerEvent.getType().isLockType()){ 51 | if(lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1 ){ 52 | skip = true; 53 | } 54 | } 55 | return skip; 56 | } 57 | 58 | @Override 59 | protected void postHandleEvent(GoldilocksEvent handlerEvent) { 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/goldilocks/GoldilocksState.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.goldilocks; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.racedetectionengine.State; 7 | import event.Lock; 8 | import event.Thread; 9 | import event.Variable; 10 | 11 | public class GoldilocksState extends State { 12 | 13 | // Data for the algorithm data 14 | public HashMap> writeLockSet; 15 | // public HashMap> writeThreadSet; 16 | 17 | public HashMap>> readLockSet; 18 | // public HashMap>> readThreadSet; 19 | 20 | public HashMap threadLocks; 21 | 22 | public int verbosity; 23 | 24 | public GoldilocksState(HashSet tSet, int verbosity) { 25 | this.verbosity = verbosity; 26 | initData(tSet); 27 | } 28 | 29 | public void initData(HashSet tSet) { 30 | writeLockSet = new HashMap> (); 31 | // writeThreadSet = new HashMap> (); 32 | readLockSet = new HashMap>> (); 33 | // readThreadSet = new HashMap>> (); 34 | 35 | this.threadLocks = new HashMap (); 36 | for(Thread t: tSet){ 37 | Lock tLock = new Lock("ThreadLock-" + t.getName()); 38 | this.threadLocks.put(t, tLock); 39 | } 40 | } 41 | 42 | @Override 43 | public void printMemory() { 44 | System.out.println("Dummy method called"); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /src/engine/racedetectionengine/hb/HBEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.hb; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class HBEngine extends RaceDetectionEngine { 10 | 11 | public HBEngine(ParserType pType, String trace_folder) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new HBState(this.threadSet); 16 | this.handlerEvent = new HBEvent(); 17 | } 18 | 19 | protected boolean skipEvent(HBEvent handlerEvent){ 20 | return false; 21 | } 22 | 23 | protected void postHandleEvent(HBEvent handlerEvent){} 24 | } 25 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/hb/HBEvent.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.hb; 2 | 3 | import engine.racedetectionengine.RaceDetectionEvent; 4 | import util.vectorclock.VectorClock; 5 | 6 | public class HBEvent extends RaceDetectionEvent { 7 | public HBEvent() { 8 | super(); 9 | } 10 | 11 | public boolean Handle(HBState state, int verbosity){ 12 | return this.HandleSub(state, verbosity); 13 | } 14 | 15 | /**************Pretty Printing*******************/ 16 | @Override 17 | public void printRaceInfoLockType(HBState state, int verbosity){ 18 | if(verbosity >= 2){ 19 | String str = "#"; 20 | str += Integer.toString(getLocId()); 21 | str += "|"; 22 | str += this.getType().toString(); 23 | str += "|"; 24 | str += this.getLock().toString(); 25 | str += "|"; 26 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 27 | str += C_t.toString(); 28 | str += "|"; 29 | str += this.getThread().getName(); 30 | System.out.println(str); 31 | } 32 | } 33 | 34 | @Override 35 | public void printRaceInfoAccessType(HBState state, int verbosity){ 36 | if(verbosity >= 2){ 37 | String str = "#"; 38 | str += Integer.toString(getLocId()); 39 | str += "|"; 40 | str += this.getType().toString(); 41 | str += "|"; 42 | str += this.getVariable().getName(); 43 | str += "|"; 44 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 45 | str += C_t.toString(); 46 | str += "|"; 47 | str += this.getThread().getName(); 48 | System.out.println(str); 49 | } 50 | } 51 | 52 | @Override 53 | public void printRaceInfoExtremeType(HBState state, int verbosity){ 54 | if(verbosity >= 2){ 55 | String str = "#"; 56 | str += Integer.toString(getLocId()); 57 | str += "|"; 58 | str += this.getType().toString(); 59 | str += "|"; 60 | str += this.getTarget().toString(); 61 | str += "|"; 62 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 63 | str += C_t.toString(); 64 | str += "|"; 65 | str += this.getThread().getName(); 66 | System.out.println(str); 67 | } 68 | } 69 | /************************************************/ 70 | 71 | /**************Acquire/Release*******************/ 72 | @Override 73 | public boolean HandleSubAcquire(HBState state, int verbosity){ 74 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 75 | VectorClock L_l = state.getVectorClock(state.lastReleaseLock, this.getLock()); 76 | C_t.updateWithMax(C_t, L_l); 77 | this.printRaceInfo(state, verbosity); 78 | return false; 79 | } 80 | 81 | @Override 82 | public boolean HandleSubRelease(HBState state, int verbosity) { 83 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 84 | VectorClock L_l = state.getVectorClock(state.lastReleaseLock, this.getLock()); 85 | L_l.copyFrom(C_t); 86 | state.incClockThread(getThread()); 87 | this.printRaceInfo(state, verbosity); 88 | return false; 89 | } 90 | /************************************************/ 91 | 92 | /****************Read/Write**********************/ 93 | @Override 94 | public boolean HandleSubRead(HBState state, int verbosity) { 95 | 96 | boolean raceDetected = false; 97 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 98 | VectorClock R_v = state.getVectorClock(state.readVariable, getVariable()); 99 | VectorClock W_v = state.getVectorClock(state.writeVariable, getVariable()); 100 | 101 | this.printRaceInfo(state, verbosity); 102 | 103 | if (!(W_v.isLessThanOrEqual(C_t))) { 104 | raceDetected = true; 105 | } 106 | 107 | R_v.updateWithMax(R_v, C_t); 108 | 109 | return raceDetected; 110 | } 111 | 112 | @Override 113 | public boolean HandleSubWrite(HBState state, int verbosity) { 114 | 115 | boolean raceDetected = false; 116 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 117 | VectorClock R_v = state.getVectorClock(state.readVariable, getVariable()); 118 | VectorClock W_v = state.getVectorClock(state.writeVariable, getVariable()); 119 | 120 | this.printRaceInfo(state, verbosity); 121 | 122 | if (!(R_v.isLessThanOrEqual(C_t))) { 123 | raceDetected = true; 124 | } 125 | if (!(W_v.isLessThanOrEqual(C_t))) { 126 | raceDetected = true; 127 | } 128 | 129 | W_v.updateWithMax(W_v, C_t); 130 | 131 | return raceDetected; 132 | } 133 | /************************************************/ 134 | 135 | /*****************Fork/Join**********************/ 136 | @Override 137 | public boolean HandleSubFork(HBState state,int verbosity) { 138 | if (state.isThreadRelevant(this.getTarget())) { 139 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 140 | VectorClock C_tc = state.getVectorClock(state.HBThread, this.getTarget()); 141 | C_tc.updateWithMax(C_tc, C_t); 142 | state.incClockThread(this.getThread()); 143 | this.printRaceInfo(state, verbosity); 144 | } 145 | return false; 146 | } 147 | 148 | @Override 149 | public boolean HandleSubJoin(HBState state,int verbosity) { 150 | if (state.isThreadRelevant(this.getTarget())) { 151 | VectorClock C_t = state.getVectorClock(state.HBThread, this.getThread()); 152 | VectorClock C_tc = state.getVectorClock(state.HBThread, this.getTarget()); 153 | C_t.updateWithMax(C_t, C_tc); 154 | this.printRaceInfo(state, verbosity); 155 | } 156 | return false; 157 | } 158 | /************************************************/ 159 | 160 | @Override 161 | public void printRaceInfoTransactionType(HBState state, int verbosity) { 162 | // TODO Auto-generated method stub 163 | 164 | } 165 | 166 | @Override 167 | public boolean HandleSubBegin(HBState state, int verbosity) { 168 | // TODO Auto-generated method stub 169 | return false; 170 | } 171 | 172 | @Override 173 | public boolean HandleSubEnd(HBState state, int verbosity) { 174 | // TODO Auto-generated method stub 175 | return false; 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/hb/HBState.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.hb; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.Iterator; 7 | 8 | import engine.racedetectionengine.State; 9 | import event.Lock; 10 | import event.Thread; 11 | import event.Variable; 12 | import util.vectorclock.VectorClock; 13 | 14 | public class HBState extends State{ 15 | 16 | // Internal data 17 | private HashMap threadToIndex; 18 | private HashMap lockToIndex; 19 | private HashMap variableToIndex; 20 | private int numThreads; 21 | private int numLocks; 22 | private int numVariables; 23 | 24 | // Data used for algorithm 25 | public ArrayList HBThread; 26 | public ArrayList lastReleaseLock; 27 | public ArrayList readVariable; 28 | public ArrayList writeVariable; 29 | 30 | public HBState(HashSet tSet) { 31 | initInternalData(tSet); 32 | initData(tSet); 33 | } 34 | 35 | private void initInternalData(HashSet tSet) { 36 | this.threadToIndex = new HashMap(); 37 | this.numThreads = 0; 38 | Iterator tIter = tSet.iterator(); 39 | while (tIter.hasNext()) { 40 | Thread thread = tIter.next(); 41 | this.threadToIndex.put(thread, (Integer)this.numThreads); 42 | this.numThreads ++; 43 | } 44 | 45 | this.lockToIndex = new HashMap(); 46 | this.numLocks = 0; 47 | this.variableToIndex = new HashMap(); 48 | this.numVariables = 0; 49 | } 50 | 51 | public void initData(HashSet tSet) { 52 | // initialize HBThread 53 | this.HBThread = new ArrayList(); 54 | initialize1DArrayOfVectorClocksWithBottom(this.HBThread, this.numThreads, this.numThreads); 55 | for(int i=0; i < this.numThreads; i++){ 56 | this.HBThread.get(i).setClockIndex(i, 1); 57 | } 58 | 59 | // initialize lastReleaseLock 60 | this.lastReleaseLock = new ArrayList(); 61 | 62 | // initialize readVariable 63 | this.readVariable = new ArrayList(); 64 | 65 | // initialize writeVariable 66 | this.writeVariable = new ArrayList(); 67 | } 68 | 69 | //Access Methods 70 | void initialize1DArrayOfVectorClocksWithBottom(ArrayList arr, int len, int dim) { 71 | for (int i = 0; i < len; i++) { 72 | arr.add(new VectorClock(dim)); 73 | } 74 | } 75 | 76 | private int checkAndAddLock(Lock l){ 77 | if(!lockToIndex.containsKey(l)){ 78 | lockToIndex.put(l, this.numLocks); 79 | this.numLocks ++; 80 | 81 | lastReleaseLock.add(new VectorClock(this.numThreads)); 82 | } 83 | return lockToIndex.get(l); 84 | } 85 | 86 | private int checkAndAddVariable(Variable v){ 87 | if(!variableToIndex.containsKey(v)){ 88 | variableToIndex.put(v, this.numVariables); 89 | this.numVariables ++; 90 | readVariable .add(new VectorClock(this.numThreads)); 91 | writeVariable .add(new VectorClock(this.numThreads)); 92 | } 93 | return variableToIndex.get(v); 94 | } 95 | 96 | public int getClockThread(Thread t) { 97 | int tIndex = threadToIndex.get(t); 98 | return this.HBThread.get(tIndex).getClockIndex(tIndex); 99 | } 100 | 101 | public VectorClock getVectorClockFrom1DArray(ArrayList arr, int index) { 102 | if (index < 0 || index >= arr.size()) { 103 | throw new IllegalArgumentException("Illegal Out of Bound access"); 104 | } 105 | return arr.get(index); 106 | } 107 | 108 | public void incClockThread(Thread t) { 109 | int tIndex = threadToIndex.get(t); 110 | int origVal = this.HBThread.get(tIndex).getClockIndex(tIndex); 111 | this.HBThread.get(tIndex).setClockIndex(tIndex, (Integer)(origVal + 1)); 112 | } 113 | 114 | public VectorClock getVectorClock(ArrayList arr, Thread t) { 115 | int tIndex = threadToIndex.get(t); 116 | return getVectorClockFrom1DArray(arr, tIndex); 117 | } 118 | 119 | public VectorClock getVectorClock(ArrayList arr, Lock l) { 120 | int lIndex = checkAndAddLock(l); 121 | return getVectorClockFrom1DArray(arr, lIndex); 122 | } 123 | 124 | public VectorClock getVectorClock(ArrayList arr, Variable v) { 125 | int vIndex = checkAndAddVariable(v); 126 | return getVectorClockFrom1DArray(arr, vIndex); 127 | } 128 | 129 | public void printThreadClock(){ 130 | ArrayList printVC = new ArrayList(); 131 | for(Thread thread : threadToIndex.keySet()){ 132 | VectorClock C_t = getVectorClock(this.HBThread, thread); 133 | printVC.add(C_t); 134 | } 135 | System.out.println(printVC); 136 | System.out.println(); 137 | System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); 138 | } 139 | 140 | public boolean isThreadRelevant(Thread t){ 141 | return this.threadToIndex.containsKey(t); 142 | } 143 | 144 | public void printMemory(){ 145 | System.err.println("Number of threads = " + Integer.toString(this.numThreads)); 146 | System.err.println("Number of locks = " + Integer.toString(this.numLocks)); 147 | System.err.println("Number of variables = " + Integer.toString(this.numVariables)); 148 | } 149 | } -------------------------------------------------------------------------------- /src/engine/racedetectionengine/hb_epoch/HBEpochEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.hb_epoch; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class HBEpochEngine extends RaceDetectionEngine{ 10 | 11 | public HBEpochEngine(ParserType pType, String trace_folder) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new HBEpochState(this.threadSet); 16 | handlerEvent = new HBEpochEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(HBEpochEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(HBEpochEvent handlerEvent) { 26 | // if(handlerEvent.getType().isAccessType()){ 27 | // if(state.verbosity == 1 || state.verbosity == 2){ 28 | // System.out.println(); 29 | // } 30 | // } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/lockset/LockSetEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.lockset; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class LockSetEngine extends RaceDetectionEngine{ 10 | 11 | public LockSetEngine(ParserType pType, String trace_folder, int verbosity) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new LockSetState(this.threadSet, verbosity); 16 | handlerEvent = new LockSetEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(LockSetEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(LockSetEvent handlerEvent) { 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/lockset/LockSetEvent.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.lockset; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEvent; 6 | import event.Lock; 7 | 8 | public class LockSetEvent extends RaceDetectionEvent { 9 | 10 | @Override 11 | public boolean Handle(LockSetState state, int verbosity) { 12 | return this.HandleSub(state, verbosity); 13 | } 14 | 15 | @Override 16 | public void printRaceInfoLockType(LockSetState state, int verbosity) { 17 | System.out.println("Dummy method called"); 18 | } 19 | 20 | @Override 21 | public void printRaceInfoAccessType(LockSetState state, int verbosity) { 22 | System.out.println("Dummy method called"); 23 | } 24 | 25 | @Override 26 | public void printRaceInfoExtremeType(LockSetState state, int verbosity) { 27 | System.out.println("Dummy method called"); 28 | } 29 | 30 | @Override 31 | public boolean HandleSubAcquire(LockSetState state, int verbosity) { 32 | int l = 1; 33 | if(state.locksHeldNesting.get(this.getThread()).containsKey(this.getLock())){ 34 | l = 1 + state.locksHeldNesting.get(this.getThread()).get(this.getLock()); 35 | } 36 | state.locksHeldNesting.get(this.getThread()).put(this.getLock(), l); 37 | state.locksHeldSet.get(this.getThread()).add(this.getLock()); 38 | return false; 39 | } 40 | 41 | @Override 42 | public boolean HandleSubRelease(LockSetState state, int verbosity) { 43 | int l; 44 | if(state.locksHeldNesting.get(this.getThread()).containsKey(this.getLock())){ 45 | l = state.locksHeldNesting.get(this.getThread()).get(this.getLock()) - 1; 46 | } 47 | else{ 48 | throw new IllegalArgumentException("Thread " + this.getThread().getName() + " is releasing lock " + this.getLock().getName() + " without acquiring it enough number of times ."); 49 | } 50 | state.locksHeldNesting.get(this.getThread()).put(this.getLock(), l); 51 | if(l == 0){ 52 | state.locksHeldSet.get(this.getThread()).remove(this.getLock()); 53 | } 54 | return false; 55 | } 56 | 57 | @Override 58 | public boolean HandleSubRead(LockSetState state, int verbosity) { 59 | boolean raceDetected = false; 60 | if(!state.lockSet.containsKey(this.getVariable())){ 61 | state.lockSet.put(getVariable(), new HashSet (state.locksHeldSet.get(this.getThread()))); 62 | state.lockSet.get(this.getVariable()).add(state.dummyReadLock); 63 | } 64 | if(state.lockSet.get(this.getVariable()).contains(state.dummyReadLock)){ 65 | state.lockSet.get(this.getVariable()).retainAll(state.locksHeldSet.get(this.getThread())); 66 | state.lockSet.get(this.getVariable()).add(state.dummyReadLock); 67 | } 68 | else{ 69 | state.lockSet.get(this.getVariable()).retainAll(state.locksHeldSet.get(this.getThread())); 70 | } 71 | if(state.lockSet.get(this.getVariable()).isEmpty()){ 72 | raceDetected = true; 73 | } 74 | if(raceDetected){ 75 | System.out.println("LockSet discipline violated on variable " + this.getVariable().getName()); 76 | } 77 | return raceDetected; 78 | } 79 | 80 | @Override 81 | public boolean HandleSubWrite(LockSetState state, int verbosity) { 82 | boolean raceDetected = false; 83 | if(!state.lockSet.containsKey(this.getVariable())){ 84 | state.lockSet.put(getVariable(), new HashSet (state.locksHeldSet.get(this.getThread()))); 85 | } 86 | state.lockSet.get(this.getVariable()).retainAll(state.locksHeldSet.get(this.getThread())); 87 | if(state.lockSet.get(this.getVariable()).isEmpty()){ 88 | raceDetected = true; 89 | } 90 | if(raceDetected){ 91 | System.out.println("LockSet discipline violated on variable " + this.getVariable().getName()); 92 | } 93 | return raceDetected; 94 | } 95 | 96 | @Override 97 | public boolean HandleSubFork(LockSetState state, int verbosity) { 98 | return false; 99 | } 100 | 101 | @Override 102 | public boolean HandleSubJoin(LockSetState state, int verbosity) { 103 | return false; 104 | } 105 | 106 | @Override 107 | public void printRaceInfoTransactionType(LockSetState state, int verbosity) { 108 | // TODO Auto-generated method stub 109 | 110 | } 111 | 112 | @Override 113 | public boolean HandleSubBegin(LockSetState state, int verbosity) { 114 | // TODO Auto-generated method stub 115 | return false; 116 | } 117 | 118 | @Override 119 | public boolean HandleSubEnd(LockSetState state, int verbosity) { 120 | // TODO Auto-generated method stub 121 | return false; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/lockset/LockSetOfflineEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.lockset; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.accesstimes.AccessTimesEngine; 7 | import engine.racedetectionengine.RaceDetectionEngine; 8 | import event.Thread; 9 | import parse.ParserType; 10 | 11 | 12 | public class LockSetOfflineEngine extends RaceDetectionEngine { 13 | 14 | private HashMap> variableToThreadSet; 15 | private HashMap> lockToThreadSet; 16 | 17 | 18 | public LockSetOfflineEngine(ParserType pType, String trace_folder, int verbosity) { 19 | super(pType); 20 | this.threadSet = new HashSet (); 21 | initializeReader(trace_folder); 22 | this.state = new LockSetState(this.threadSet, verbosity); 23 | handlerEvent = new LockSetEvent(); 24 | 25 | boolean time_reporting = true; 26 | long startTimeAnalysis = 0; 27 | if(time_reporting){ 28 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 29 | } 30 | AccessTimesEngine accessTimesEngine = new AccessTimesEngine(pType, trace_folder); 31 | accessTimesEngine.computeLastAccessTimes(); 32 | if(time_reporting){ 33 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 34 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 35 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 36 | } 37 | 38 | this.variableToThreadSet = accessTimesEngine.variableToThreadSet; 39 | this.lockToThreadSet = accessTimesEngine.lockToThreadSet; 40 | } 41 | 42 | @Override 43 | protected boolean skipEvent(LockSetEvent handlerEvent){ 44 | boolean skip = false; 45 | if(handlerEvent.getType().isAccessType()){ 46 | if(variableToThreadSet.get(handlerEvent.getVariable().getName()).size() <= 1 ){ 47 | skip = true; 48 | } 49 | } 50 | if(handlerEvent.getType().isLockType()){ 51 | if(lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1 ){ 52 | skip = true; 53 | } 54 | } 55 | return skip; 56 | } 57 | 58 | @Override 59 | protected void postHandleEvent(LockSetEvent handlerEvent) { 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/lockset/LockSetState.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.lockset; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.racedetectionengine.State; 7 | import event.Lock; 8 | import event.Thread; 9 | import event.Variable; 10 | 11 | public class LockSetState extends State { 12 | 13 | // Data for the algorithm data 14 | public HashMap> locksHeldNesting; 15 | public HashMap> locksHeldSet; 16 | public HashMap> lockSet; 17 | public Lock dummyReadLock; 18 | public HashMap threadLocks; 19 | 20 | public int verbosity; 21 | 22 | public LockSetState(HashSet tSet, int verbosity) { 23 | this.verbosity = verbosity; 24 | initData(tSet); 25 | } 26 | 27 | public void initData(HashSet tSet) { 28 | this.dummyReadLock = new Lock("dummy-read-lock"); 29 | this.threadLocks = new HashMap (); 30 | this.locksHeldNesting = new HashMap> (); 31 | this.locksHeldSet = new HashMap> (); 32 | for(Thread t: tSet){ 33 | Lock tLock = new Lock("ThreadLock-" + t.getName()); 34 | this.threadLocks.put(t, tLock); 35 | this.locksHeldNesting.put(t, new HashMap ()); 36 | this.locksHeldNesting.get(t).put(tLock, 1); 37 | this.locksHeldSet.put(t, new HashSet ()); 38 | this.locksHeldSet.get(t).add(tLock); 39 | } 40 | lockSet = new HashMap> (); 41 | } 42 | 43 | @Override 44 | public void printMemory() { 45 | System.out.println("Dummy method called"); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /src/engine/racedetectionengine/shb/SHBEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.shb; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class SHBEngine extends RaceDetectionEngine{ 10 | 11 | public SHBEngine(ParserType pType, String trace_folder) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new SHBState(this.threadSet); 16 | handlerEvent = new SHBEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(SHBEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(SHBEvent handlerEvent) { 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/shb/SHBEvent.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.shb; 2 | 3 | import engine.racedetectionengine.RaceDetectionEvent; 4 | import util.vectorclock.VectorClock; 5 | 6 | public class SHBEvent extends RaceDetectionEvent { 7 | 8 | @Override 9 | public boolean Handle(SHBState state, int verbosity) { 10 | return this.HandleSub(state, verbosity); 11 | } 12 | 13 | @Override 14 | public void printRaceInfoLockType(SHBState state, int verbosity) { 15 | if (this.getType().isLockType()) { 16 | if (verbosity >= 2) { 17 | String str = "#"; 18 | str += Integer.toString(getLocId()); 19 | str += "|"; 20 | str += this.getType().toString(); 21 | str += "|"; 22 | str += this.getLock().toString(); 23 | str += "|"; 24 | VectorClock C_t = state.getVectorClock(state.clockThread, 25 | this.getThread()); 26 | str += C_t.toString(); 27 | str += "|"; 28 | str += this.getThread().getName(); 29 | System.out.println(str); 30 | } 31 | } 32 | } 33 | 34 | @Override 35 | public void printRaceInfoAccessType(SHBState state, int verbosity) { 36 | if (this.getType().isAccessType()) { 37 | if (verbosity >= 2) { 38 | String str = "#"; 39 | str += Integer.toString(getLocId()); 40 | str += "|"; 41 | str += this.getType().toString(); 42 | str += "|"; 43 | str += this.getVariable().getName(); 44 | str += "|"; 45 | VectorClock C_t = state.getVectorClock(state.clockThread, 46 | this.getThread()); 47 | str += C_t.toString(); 48 | str += "|"; 49 | str += this.getThread().getName(); 50 | str += "|"; 51 | str += this.getAuxId(); 52 | System.out.println(str); 53 | } 54 | } 55 | } 56 | 57 | @Override 58 | public void printRaceInfoExtremeType(SHBState state, int verbosity) { 59 | if (this.getType().isExtremeType()) { 60 | if (verbosity >= 2) { 61 | String str = "#"; 62 | str += Integer.toString(getLocId()); 63 | str += "|"; 64 | str += this.getType().toString(); 65 | str += "|"; 66 | str += this.getTarget().toString(); 67 | str += "|"; 68 | VectorClock C_t = state.getVectorClock(state.clockThread, 69 | this.getThread()); 70 | str += C_t.toString(); 71 | str += "|"; 72 | str += this.getThread().getName(); 73 | System.out.println(str); 74 | } 75 | } 76 | } 77 | 78 | @Override 79 | public void printRaceInfoTransactionType(SHBState state, int verbosity) { 80 | } 81 | 82 | @Override 83 | public boolean HandleSubAcquire(SHBState state, int verbosity) { 84 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 85 | VectorClock L_l = state.getVectorClock(state.lastReleaseLock, this.getLock()); 86 | C_t.updateWithMax(C_t, L_l); 87 | this.printRaceInfo(state, verbosity); 88 | return false; 89 | } 90 | 91 | @Override 92 | public boolean HandleSubRelease(SHBState state, int verbosity) { 93 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 94 | VectorClock L_l = state.getVectorClock(state.lastReleaseLock, this.getLock()); 95 | L_l.copyFrom(C_t); 96 | this.printRaceInfo(state, verbosity); 97 | state.incClockThread(getThread()); 98 | return false; 99 | } 100 | 101 | @Override 102 | public boolean HandleSubRead(SHBState state, int verbosity) { 103 | boolean raceDetected = false; 104 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 105 | VectorClock LW_v = state.getVectorClock(state.lastWriteVariable, getVariable()); 106 | VectorClock W_v = state.getVectorClock(state.writeVariable, getVariable()); 107 | 108 | this.printRaceInfo(state, verbosity); 109 | 110 | if (!(W_v.isLessThanOrEqual(C_t))) { 111 | raceDetected = true; 112 | } 113 | 114 | C_t.updateWithMax(C_t, LW_v); 115 | 116 | VectorClock R_v = state.getVectorClock(state.readVariable, getVariable()); 117 | int c_t_t = state.getIndex(C_t, this.getThread()); 118 | state.setIndex(R_v, this.getThread(), c_t_t); 119 | 120 | return raceDetected; 121 | } 122 | 123 | @Override 124 | public boolean HandleSubWrite(SHBState state, int verbosity) { 125 | boolean raceDetected = false; 126 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 127 | VectorClock R_v = state.getVectorClock(state.readVariable, getVariable()); 128 | VectorClock W_v = state.getVectorClock(state.writeVariable, getVariable()); 129 | 130 | this.printRaceInfo(state, verbosity); 131 | 132 | if (!(R_v.isLessThanOrEqual(C_t))) { 133 | raceDetected = true; 134 | } 135 | if (!(W_v.isLessThanOrEqual(C_t))) { 136 | raceDetected = true; 137 | } 138 | 139 | // this.printRaceInfo(state); 140 | 141 | int c_t_t = state.getIndex(C_t, this.getThread()); 142 | state.setIndex(W_v, this.getThread(), c_t_t); 143 | VectorClock LW_v = state.getVectorClock(state.lastWriteVariable, getVariable()); 144 | LW_v.copyFrom(C_t); 145 | state.setLWLocId(this.getVariable(), this.getLocId()); 146 | state.incClockThread(getThread()); 147 | 148 | return raceDetected; 149 | } 150 | 151 | @Override 152 | public boolean HandleSubFork(SHBState state, int verbosity) { 153 | if (state.isThreadRelevant(this.getTarget())) { 154 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 155 | VectorClock C_tc = state.getVectorClock(state.clockThread, this.getTarget()); 156 | C_tc.copyFrom(C_t); 157 | state.setIndex(C_tc, this.getTarget(), 1); 158 | this.printRaceInfo(state, verbosity); 159 | state.incClockThread(getThread()); 160 | } 161 | return false; 162 | } 163 | 164 | @Override 165 | public boolean HandleSubJoin(SHBState state, int verbosity) { 166 | if (state.isThreadRelevant(this.getTarget())) { 167 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 168 | VectorClock C_tc = state.getVectorClock(state.clockThread, this.getTarget()); 169 | C_t.updateWithMax(C_t, C_tc); 170 | this.printRaceInfo(state, verbosity); 171 | } 172 | return false; 173 | } 174 | 175 | @Override 176 | public boolean HandleSubBegin(SHBState state, int verbosity) { 177 | return false; 178 | } 179 | 180 | @Override 181 | public boolean HandleSubEnd(SHBState state, int verbosity) { 182 | return false; 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/shb/SHBOfflineEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.shb; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.accesstimes.orderedvars.OrderedVarsEngine; 7 | import engine.racedetectionengine.RaceDetectionEngine; 8 | import event.Thread; 9 | import parse.ParserType; 10 | 11 | public class SHBOfflineEngine extends RaceDetectionEngine{ 12 | 13 | private HashMap> lockToThreadSet; 14 | private HashSet orderedVariables; 15 | 16 | public SHBOfflineEngine(ParserType pType, String trace_folder) { 17 | super(pType); 18 | this.threadSet = new HashSet (); 19 | initializeReader(trace_folder); 20 | this.state = new SHBState(this.threadSet); 21 | handlerEvent = new SHBEvent(); 22 | 23 | boolean time_reporting = true; 24 | long startTimeAnalysis = 0; 25 | if(time_reporting){ 26 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 27 | } 28 | OrderedVarsEngine orderedVarsEngine = new OrderedVarsEngine(pType, trace_folder, 0); 29 | orderedVarsEngine.analyzeTrace(true, 0); 30 | 31 | if(time_reporting){ 32 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 33 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 34 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 35 | } 36 | 37 | this.lockToThreadSet = orderedVarsEngine.getLockToThreadSet(); 38 | this.orderedVariables = orderedVarsEngine.getOrdredVars(); 39 | } 40 | 41 | @Override 42 | protected boolean skipEvent(SHBEvent handlerEvent) { 43 | if(handlerEvent.getType().isAccessType()){ 44 | String var_name = handlerEvent.getVariable().getName(); 45 | if(this.orderedVariables.contains(var_name)) { 46 | return true; 47 | } 48 | } 49 | else if(handlerEvent.getType().isLockType()){ 50 | if(lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1 ){ 51 | return true; 52 | } 53 | } 54 | return false; 55 | } 56 | 57 | @Override 58 | protected void postHandleEvent(SHBEvent handlerEvent) { 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/shb/SHBState.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.shb; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.Iterator; 7 | 8 | import engine.racedetectionengine.State; 9 | import event.Lock; 10 | import event.Thread; 11 | import event.Variable; 12 | import util.vectorclock.VectorClock; 13 | 14 | public class SHBState extends State { 15 | 16 | // Internal data 17 | private HashMap threadToIndex; 18 | private HashMap lockToIndex; 19 | private HashMap variableToIndex; 20 | private int numThreads; 21 | private int numLocks; 22 | private int numVariables; 23 | 24 | // Data used for algorithm 25 | public ArrayList clockThread; 26 | public ArrayList lastReleaseLock; 27 | public ArrayList readVariable; 28 | public ArrayList writeVariable; 29 | public ArrayList lastWriteVariable; 30 | 31 | //Book-keeping the last-write's location 32 | public ArrayList lastWriteVariableLocId; 33 | 34 | public SHBState(HashSet tSet) { 35 | initInternalData(tSet); 36 | initData(tSet); 37 | } 38 | 39 | private void initInternalData(HashSet tSet) { 40 | this.threadToIndex = new HashMap(); 41 | this.numThreads = 0; 42 | Iterator tIter = tSet.iterator(); 43 | while (tIter.hasNext()) { 44 | Thread thread = tIter.next(); 45 | //System.out.println("Adding thread to map " + thread.toString()); 46 | this.threadToIndex.put(thread, (Integer)this.numThreads); 47 | this.numThreads ++; 48 | } 49 | 50 | this.lockToIndex = new HashMap(); 51 | this.numLocks = 0; 52 | this.variableToIndex = new HashMap(); 53 | this.numVariables = 0; 54 | } 55 | 56 | private void initialize1DArrayOfVectorClocksWithBottom(ArrayList arr, int len) { 57 | for (int i = 0; i < len; i++) { 58 | arr.add(new VectorClock(this.numThreads)); 59 | } 60 | } 61 | 62 | public void initData(HashSet tSet) { 63 | 64 | // initialize clockThread 65 | this.clockThread = new ArrayList(); 66 | initialize1DArrayOfVectorClocksWithBottom(this.clockThread, this.numThreads); 67 | for (int i = 0; i < this.numThreads; i++) { 68 | VectorClock C_t = this.clockThread.get(i); 69 | C_t.setClockIndex(i, 1); 70 | } 71 | 72 | // initialize lastReleaseLock 73 | this.lastReleaseLock = new ArrayList(); 74 | 75 | // initialize readVariable 76 | this.readVariable = new ArrayList(); 77 | 78 | // initialize writeVariable 79 | this.writeVariable = new ArrayList(); 80 | 81 | // initialize lastWriteVariable 82 | this.lastWriteVariable = new ArrayList(); 83 | 84 | //initialize locationIds 85 | this.lastWriteVariableLocId = new ArrayList (); 86 | } 87 | 88 | // Access methods 89 | private VectorClock getVectorClockFrom1DArray(ArrayList arr, int index) { 90 | if (index < 0 || index >= arr.size()) { 91 | throw new IllegalArgumentException("Illegal Out of Bound access"); 92 | } 93 | return arr.get(index); 94 | } 95 | 96 | 97 | private int checkAndAddLock(Lock l){ 98 | if(!lockToIndex.containsKey(l)){ 99 | //System.err.println("New lock found " + this.numLocks); 100 | lockToIndex.put(l, this.numLocks); 101 | this.numLocks ++; 102 | 103 | lastReleaseLock.add(new VectorClock(this.numThreads)); 104 | } 105 | return lockToIndex.get(l); 106 | } 107 | 108 | private int checkAndAddVariable(Variable v){ 109 | if(!variableToIndex.containsKey(v)){ 110 | variableToIndex.put(v, this.numVariables); 111 | this.numVariables ++; 112 | readVariable .add(new VectorClock(this.numThreads)); 113 | writeVariable .add(new VectorClock(this.numThreads)); 114 | lastWriteVariable .add(new VectorClock(this.numThreads)); 115 | lastWriteVariableLocId .add(-1); //Initialize loc id's to be -1 116 | } 117 | return variableToIndex.get(v); 118 | } 119 | 120 | public void incClockThread(Thread t) { 121 | int tIndex = threadToIndex.get(t); 122 | VectorClock C_t = getVectorClock(clockThread, t); 123 | int origVal = C_t.getClockIndex(tIndex); 124 | C_t.setClockIndex(tIndex, origVal + 1); 125 | } 126 | 127 | public VectorClock getVectorClock(ArrayList arr, Thread t) { 128 | int tIndex = threadToIndex.get(t); 129 | return getVectorClockFrom1DArray(arr, tIndex); 130 | } 131 | 132 | public VectorClock getVectorClock(ArrayList arr, Lock l) { 133 | int lIndex = checkAndAddLock(l); 134 | return getVectorClockFrom1DArray(arr, lIndex); 135 | } 136 | 137 | public VectorClock getVectorClock(ArrayList arr, Variable v) { 138 | int vIndex = checkAndAddVariable(v); 139 | return getVectorClockFrom1DArray(arr, vIndex); 140 | } 141 | 142 | public int getLWLocId(Variable v){ 143 | int vIndex = checkAndAddVariable(v); 144 | return this.lastWriteVariableLocId.get(vIndex); 145 | } 146 | 147 | public void setLWLocId(Variable v, int loc){ 148 | int vIndex = checkAndAddVariable(v); 149 | this.lastWriteVariableLocId.set(vIndex, loc); 150 | } 151 | 152 | public void setIndex(VectorClock vc, Thread t, int val){ 153 | int tIndex = threadToIndex.get(t); 154 | vc.setClockIndex(tIndex, val); 155 | } 156 | 157 | public int getIndex(VectorClock vc, Thread t){ 158 | int tIndex = threadToIndex.get(t); 159 | return vc.getClockIndex(tIndex); 160 | } 161 | 162 | public void printThreadClock(){ 163 | ArrayList printVC = new ArrayList(); 164 | for(Thread thread : threadToIndex.keySet()){ 165 | VectorClock C_t = getVectorClock(clockThread, thread); 166 | printVC.add(C_t); 167 | } 168 | System.out.println(printVC); 169 | System.out.println(); 170 | System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); 171 | } 172 | 173 | public boolean isThreadRelevant(Thread t){ 174 | return this.threadToIndex.containsKey(t); 175 | } 176 | 177 | public void printMemory(){ 178 | System.err.println("Number of threads = " + Integer.toString(this.numThreads)); 179 | System.err.println("Number of locks = " + Integer.toString(this.numLocks)); 180 | System.err.println("Number of variables = " + Integer.toString(this.numVariables)); 181 | } 182 | } -------------------------------------------------------------------------------- /src/engine/racedetectionengine/shb/distance/SHBEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.shb.distance; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class SHBEngine extends RaceDetectionEngine{ 10 | 11 | public SHBEngine(ParserType pType, String trace_folder) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new SHBState(this.threadSet); 16 | handlerEvent = new SHBEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(SHBEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(SHBEvent handlerEvent) { 26 | } 27 | 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/shb/distance/SHBOfflineEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.shb.distance; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.accesstimes.orderedvars.OrderedVarsEngine; 7 | import engine.racedetectionengine.RaceDetectionEngine; 8 | import event.Thread; 9 | import parse.ParserType; 10 | 11 | public class SHBOfflineEngine extends RaceDetectionEngine { 12 | 13 | private HashMap> lockToThreadSet; 14 | private HashSet orderedVariables; 15 | 16 | public SHBOfflineEngine(ParserType pType, String trace_folder) { 17 | super(pType); 18 | this.threadSet = new HashSet(); 19 | initializeReader(trace_folder); 20 | this.state = new SHBState(this.threadSet); 21 | handlerEvent = new SHBEvent(); 22 | 23 | boolean time_reporting = true; 24 | long startTimeAnalysis = 0; 25 | if (time_reporting) { 26 | startTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 27 | } 28 | OrderedVarsEngine orderedVarsEngine = new OrderedVarsEngine(pType, trace_folder, 29 | 0); 30 | orderedVarsEngine.analyzeTrace(true, 0); 31 | if (time_reporting) { 32 | long stopTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 33 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 34 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 35 | } 36 | 37 | this.lockToThreadSet = orderedVarsEngine.getLockToThreadSet(); 38 | this.orderedVariables = orderedVarsEngine.getOrdredVars(); 39 | } 40 | 41 | @Override 42 | protected boolean skipEvent(SHBEvent handlerEvent) { 43 | if (handlerEvent.getType().isAccessType()) { 44 | String var_name = handlerEvent.getVariable().getName(); 45 | if (this.orderedVariables.contains(var_name)) { 46 | return true; 47 | } 48 | } else if (handlerEvent.getType().isLockType()) { 49 | if (lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1) { 50 | return true; 51 | } 52 | } 53 | return false; 54 | } 55 | 56 | @Override 57 | protected void postHandleEvent(SHBEvent handlerEvent) { 58 | } 59 | 60 | @Override 61 | protected void printCompletionStatus() { 62 | super.printCompletionStatus(); 63 | if (enablePrintStatus) { 64 | // System.out.println("Num races = " + state.numRaces); 65 | System.out.println("Number of 'racy' variables = " + state.racyVars.size()); 66 | System.out.println("Max distance = " + state.maxMinDistance); 67 | double avg_d = ((double) state.sumMinDistance) / ((double) state.numRaces); 68 | System.out.println("Avg. distance = " + String.format("%.2f", avg_d)); 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/shb_epoch/SHBEpochEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.shb_epoch; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class SHBEpochEngine extends RaceDetectionEngine{ 10 | 11 | public SHBEpochEngine(ParserType pType, String trace_folder) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new SHBEpochState(this.threadSet); 16 | handlerEvent = new SHBEpochEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(SHBEpochEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(SHBEpochEvent handlerEvent) { 26 | // if(handlerEvent.getType().isAccessType()){ 27 | // if(state.verbosity == 1 || state.verbosity == 2){ 28 | // System.out.println(); 29 | // } 30 | // } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/shb_epoch/SHBEpochEvent.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.shb_epoch; 2 | 3 | import engine.racedetectionengine.RaceDetectionEvent; 4 | import util.vectorclock.FullAdaptiveVC; 5 | import util.vectorclock.SemiAdaptiveVC; 6 | import util.vectorclock.VectorClock; 7 | 8 | public class SHBEpochEvent extends RaceDetectionEvent { 9 | 10 | @Override 11 | public boolean Handle(SHBEpochState state, int verbosity) { 12 | return this.HandleSub(state, verbosity); 13 | } 14 | 15 | @Override 16 | public void printRaceInfoLockType(SHBEpochState state, int verbosity) { 17 | if(this.getType().isLockType()){ 18 | if(verbosity == 2){ 19 | String str = "#"; 20 | str += Integer.toString(getLocId()); 21 | str += "|"; 22 | str += this.getType().toString(); 23 | str += "|"; 24 | str += this.getLock().toString(); 25 | str += "|"; 26 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 27 | str += C_t.toString(); 28 | str += "|"; 29 | str += this.getThread().getName(); 30 | System.out.println(str); 31 | } 32 | } 33 | } 34 | 35 | @Override 36 | public void printRaceInfoAccessType(SHBEpochState state, int verbosity) { 37 | if(this.getType().isAccessType()){ 38 | if(verbosity == 1 || verbosity == 2){ 39 | String str = "#"; 40 | str += Integer.toString(getLocId()); 41 | str += "|"; 42 | str += this.getType().toString(); 43 | str += "|"; 44 | str += this.getVariable().getName(); 45 | str += "|"; 46 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 47 | str += C_t.toString(); 48 | str += "|"; 49 | str += this.getThread().getName(); 50 | str += "|"; 51 | str += this.getAuxId(); 52 | System.out.println(str); 53 | } 54 | } 55 | } 56 | 57 | @Override 58 | public void printRaceInfoExtremeType(SHBEpochState state, int verbosity) { 59 | if(this.getType().isExtremeType()){ 60 | if(verbosity == 2){ 61 | String str = "#"; 62 | str += Integer.toString(getLocId()); 63 | str += "|"; 64 | str += this.getType().toString(); 65 | str += "|"; 66 | str += this.getTarget().toString(); 67 | str += "|"; 68 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 69 | str += C_t.toString(); 70 | str += "|"; 71 | str += this.getThread().getName(); 72 | System.out.println(str); 73 | } 74 | } 75 | } 76 | 77 | @Override 78 | public void printRaceInfoTransactionType(SHBEpochState state, int verbosity) { 79 | } 80 | 81 | @Override 82 | public boolean HandleSubAcquire(SHBEpochState state, int verbosity) { 83 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 84 | VectorClock L_l = state.getVectorClock(state.lastReleaseLock, this.getLock()); 85 | C_t.updateWithMax(C_t, L_l); 86 | this.printRaceInfo(state, verbosity); 87 | return false; 88 | } 89 | 90 | @Override 91 | public boolean HandleSubRelease(SHBEpochState state, int verbosity) { 92 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 93 | VectorClock L_l = state.getVectorClock(state.lastReleaseLock, this.getLock()); 94 | L_l.copyFrom(C_t); 95 | this.printRaceInfo(state, verbosity); 96 | state.incClockThread(getThread()); 97 | return false; 98 | } 99 | 100 | @Override 101 | public boolean HandleSubRead(SHBEpochState state, int verbosity) { 102 | boolean raceDetected = false; 103 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 104 | VectorClock LW_v = state.getVectorClock(state.lastWriteVariable, getVariable()); 105 | FullAdaptiveVC W_v = state.getAdaptiveVC(state.writeVariable, getVariable()); 106 | 107 | this.printRaceInfo(state, verbosity); 108 | 109 | if (!(W_v.isLessThanOrEqual(C_t))) { 110 | raceDetected = true; 111 | } 112 | 113 | C_t.updateWithMax(C_t, LW_v); 114 | 115 | SemiAdaptiveVC R_v = state.getAdaptiveVC(state.readVariable, getVariable()); 116 | R_v.updateWithMax(C_t, state.getThreadIndex(this.getThread())); 117 | 118 | return raceDetected; 119 | } 120 | 121 | @Override 122 | public boolean HandleSubWrite(SHBEpochState state, int verbosity) { 123 | boolean raceDetected = false; 124 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 125 | SemiAdaptiveVC R_v = state.getAdaptiveVC(state.readVariable, getVariable()); 126 | FullAdaptiveVC W_v = state.getAdaptiveVC(state.writeVariable, getVariable()); 127 | 128 | this.printRaceInfo(state, verbosity); 129 | 130 | if (!(R_v.isLessThanOrEqual(C_t))) { 131 | raceDetected = true; 132 | } 133 | 134 | boolean W_v_isLTE_C_t = W_v.isLTEUpdateWithMax(C_t, state.getThreadIndex(this.getThread())); 135 | if(! W_v_isLTE_C_t){ 136 | raceDetected = true; 137 | } 138 | 139 | VectorClock LW_v = state.getVectorClock(state.lastWriteVariable, getVariable()); 140 | LW_v.copyFrom(C_t); 141 | state.setLWLocId(this.getVariable(), this.getLocId()); 142 | state.incClockThread(getThread()); 143 | 144 | return raceDetected; 145 | } 146 | 147 | @Override 148 | public boolean HandleSubFork(SHBEpochState state, int verbosity) { 149 | if (state.isThreadRelevant(this.getTarget())) { 150 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 151 | VectorClock C_tc = state.getVectorClock(state.clockThread, this.getTarget()); 152 | C_tc.copyFrom(C_t); 153 | state.setIndex(C_tc, this.getTarget(), 1); 154 | this.printRaceInfo(state, verbosity); 155 | state.incClockThread(getThread()); 156 | } 157 | return false; 158 | } 159 | 160 | @Override 161 | public boolean HandleSubJoin(SHBEpochState state, int verbosity) { 162 | if (state.isThreadRelevant(this.getTarget())) { 163 | VectorClock C_t = state.getVectorClock(state.clockThread, this.getThread()); 164 | VectorClock C_tc = state.getVectorClock(state.clockThread, this.getTarget()); 165 | C_t.updateWithMax(C_t, C_tc); 166 | this.printRaceInfo(state, verbosity); 167 | } 168 | return false; 169 | } 170 | 171 | 172 | @Override 173 | public boolean HandleSubBegin(SHBEpochState state, int verbosity) { 174 | return false; 175 | } 176 | 177 | @Override 178 | public boolean HandleSubEnd(SHBEpochState state, int verbosity) { 179 | return false; 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/syncpreserving/SyncPreservingRaceEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.syncpreserving; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class SyncPreservingRaceEngine extends RaceDetectionEngine{ 10 | 11 | public SyncPreservingRaceEngine(ParserType pType, String trace_folder) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new SyncPreservingRaceState(this.threadSet); 16 | handlerEvent = new SyncPreservingRaceEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(SyncPreservingRaceEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(SyncPreservingRaceEvent handlerEvent) { 26 | // if(handlerEvent.getType().isAccessType()){ 27 | // if(state.verbosity == 1 || state.verbosity == 2){ 28 | // System.out.println(); 29 | // } 30 | // } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/syncpreserving/SyncPreservingRaceOfflineEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.syncpreserving; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.accesstimes.orderedvars.OrderedVarsEngine; 7 | import engine.racedetectionengine.RaceDetectionEngine; 8 | import event.Thread; 9 | import parse.ParserType; 10 | 11 | 12 | public class SyncPreservingRaceOfflineEngine extends RaceDetectionEngine { 13 | 14 | private HashMap> lockToThreadSet; 15 | private HashSet orderedVariables; 16 | 17 | public SyncPreservingRaceOfflineEngine(ParserType pType, String trace_folder) { 18 | super(pType); 19 | this.threadSet = new HashSet (); 20 | initializeReader(trace_folder); 21 | this.state = new SyncPreservingRaceState(this.threadSet); 22 | handlerEvent = new SyncPreservingRaceEvent(); 23 | 24 | boolean time_reporting = true; 25 | long startTimeAnalysis = 0; 26 | if(time_reporting){ 27 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 28 | } 29 | OrderedVarsEngine orderedVarsEngine = new OrderedVarsEngine(pType, trace_folder, 0); 30 | orderedVarsEngine.analyzeTrace(true, 0); 31 | 32 | if(time_reporting){ 33 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 34 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 35 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 36 | } 37 | 38 | this.lockToThreadSet = orderedVarsEngine.getLockToThreadSet(); 39 | this.state.stringVariableToThreadSet = orderedVarsEngine.getVariableToThreadSet(); 40 | this.orderedVariables = orderedVarsEngine.getOrdredVars(); 41 | } 42 | 43 | @Override 44 | protected boolean skipEvent(SyncPreservingRaceEvent handlerEvent){ 45 | if(handlerEvent.getType().isAccessType()){ 46 | String var_name = handlerEvent.getVariable().getName(); 47 | if(this.orderedVariables.contains(var_name)) { 48 | return true; 49 | } 50 | } 51 | else if(handlerEvent.getType().isLockType()){ 52 | if(lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1 ){ 53 | return true; 54 | } 55 | } 56 | return false; 57 | } 58 | 59 | @Override 60 | protected void postHandleEvent(SyncPreservingRaceEvent handlerEvent) { 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/syncpreserving/distance/SyncPreservingRaceEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.syncpreserving.distance; 2 | 3 | import java.util.HashSet; 4 | 5 | import engine.racedetectionengine.RaceDetectionEngine; 6 | import event.Thread; 7 | import parse.ParserType; 8 | 9 | public class SyncPreservingRaceEngine extends RaceDetectionEngine{ 10 | 11 | public SyncPreservingRaceEngine(ParserType pType, String trace_folder) { 12 | super(pType); 13 | this.threadSet = new HashSet (); 14 | initializeReader(trace_folder); 15 | this.state = new SyncPreservingRaceState(this.threadSet); 16 | handlerEvent = new SyncPreservingRaceEvent(); 17 | } 18 | 19 | @Override 20 | protected boolean skipEvent(SyncPreservingRaceEvent handlerEvent) { 21 | return false; 22 | } 23 | 24 | @Override 25 | protected void postHandleEvent(SyncPreservingRaceEvent handlerEvent) { 26 | // if(handlerEvent.getType().isAccessType()){ 27 | // if(state.verbosity == 1 || state.verbosity == 2){ 28 | // System.out.println(); 29 | // } 30 | // } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/syncpreserving/distance/SyncPreservingRaceOfflineEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.syncpreserving.distance; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.accesstimes.orderedvars.OrderedVarsEngine; 7 | import engine.racedetectionengine.RaceDetectionEngine; 8 | import event.Thread; 9 | import parse.ParserType; 10 | 11 | 12 | public class SyncPreservingRaceOfflineEngine extends RaceDetectionEngine { 13 | 14 | private HashMap> lockToThreadSet; 15 | private HashSet orderedVariables; 16 | 17 | public SyncPreservingRaceOfflineEngine(ParserType pType, String trace_folder) { 18 | super(pType); 19 | this.threadSet = new HashSet (); 20 | initializeReader(trace_folder); 21 | this.state = new SyncPreservingRaceState(this.threadSet); 22 | handlerEvent = new SyncPreservingRaceEvent(); 23 | 24 | boolean time_reporting = true; 25 | long startTimeAnalysis = 0; 26 | if(time_reporting){ 27 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 28 | } 29 | OrderedVarsEngine orderedVarsEngine = new OrderedVarsEngine(pType, trace_folder, 0); 30 | orderedVarsEngine.analyzeTrace(true, 0); 31 | 32 | if(time_reporting){ 33 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 34 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 35 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 36 | } 37 | 38 | this.lockToThreadSet = orderedVarsEngine.getLockToThreadSet(); 39 | this.state.stringVariableToThreadSet = orderedVarsEngine.getVariableToThreadSet(); 40 | this.orderedVariables = orderedVarsEngine.getOrdredVars(); 41 | } 42 | 43 | @Override 44 | protected boolean skipEvent(SyncPreservingRaceEvent handlerEvent){ 45 | if(handlerEvent.getType().isAccessType()){ 46 | String var_name = handlerEvent.getVariable().getName(); 47 | if(this.orderedVariables.contains(var_name)) { 48 | return true; 49 | } 50 | } 51 | else if(handlerEvent.getType().isLockType()){ 52 | if(lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1 ){ 53 | return true; 54 | } 55 | } 56 | return false; 57 | } 58 | 59 | @Override 60 | protected void postHandleEvent(SyncPreservingRaceEvent handlerEvent) { 61 | } 62 | 63 | @Override 64 | protected void printCompletionStatus() { 65 | super.printCompletionStatus(); 66 | if(enablePrintStatus) { 67 | // System.out.println("Num races = " + state.numRaces); 68 | System.out.println("Number of 'racy' variables = " + state.racyVars.size()); 69 | System.out.println("Max race distance = " + state.maxDistance); 70 | double avg_d = ((double) state.sumDistance) / ((double) state.numRaces); 71 | System.out.println("Avg. race distance = " + avg_d); 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/wcp/WCPEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.wcp; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | import engine.accesstimes.AccessTimesEngine; 6 | import engine.racedetectionengine.RaceDetectionEngine; 7 | import event.Thread; 8 | import parse.ParserType; 9 | 10 | public class WCPEngine extends RaceDetectionEngine{ 11 | 12 | private HashMap lockEndTimes; 13 | private HashMap> variableToThreadSet; 14 | private HashMap> lockToThreadSet; 15 | 16 | public WCPEngine(ParserType pType, String trace_folder) { 17 | super(pType); 18 | this.threadSet = new HashSet (); 19 | initializeReader(trace_folder); 20 | this.state = new WCPState(this.threadSet); 21 | handlerEvent = new WCPEvent(); 22 | 23 | boolean time_reporting = false; 24 | 25 | long startTimeAnalysis = 0; 26 | if(time_reporting){ 27 | startTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 28 | } 29 | 30 | AccessTimesEngine accessTimesEngine = new AccessTimesEngine(pType, trace_folder); 31 | accessTimesEngine.computeLastAccessTimes(); 32 | 33 | if(time_reporting){ 34 | long stopTimeAnalysis = System.currentTimeMillis(); //System.nanoTime(); 35 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 36 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 37 | } 38 | 39 | lockEndTimes = accessTimesEngine.lockLast; 40 | 41 | this.state.view.lockThreadLastInteraction = accessTimesEngine.lockThreadLast; 42 | this.state.existsLockReadVariableThreads = accessTimesEngine.existsLockReadVariableThreads; 43 | this.state.existsLockWriteVariableThreads = accessTimesEngine.existsLockWriteVariableThreads; 44 | this.state.variableToReadEquivalenceClass = accessTimesEngine.variableToReadEquivalenceClass; 45 | this.state.variableToWriteEquivalenceClass = accessTimesEngine.variableToWriteEquivalenceClass; 46 | 47 | this.variableToThreadSet = accessTimesEngine.variableToThreadSet; 48 | this.lockToThreadSet = accessTimesEngine.lockToThreadSet; 49 | } 50 | 51 | protected boolean skipEvent(WCPEvent handlerEvent){ 52 | boolean skip = false; 53 | if(handlerEvent.getType().isAccessType()){ 54 | if(variableToThreadSet.get(handlerEvent.getVariable().getName()).size() <= 1 ){ 55 | skip = true; 56 | } 57 | } 58 | if(handlerEvent.getType().isLockType()){ 59 | if(lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1 ){ 60 | skip = true; 61 | } 62 | } 63 | return skip; 64 | } 65 | 66 | protected void postHandleEvent(WCPEvent handlerEvent){ 67 | if(handlerEvent.getType().isLockType()){ 68 | long currEventIndex = handlerEvent.getAuxId(); 69 | long lockThreadEndIndex = this.state.view.lockThreadLastInteraction.get(handlerEvent.getLock().getName()).get(handlerEvent.getThread().getName()); 70 | if(currEventIndex >= lockThreadEndIndex){ 71 | state.destroyLockThreadStack(handlerEvent.getLock(), handlerEvent.getThread()); 72 | } 73 | //If the lock has to be deleted, it should be done at the end 74 | long lockEndIndex = lockEndTimes.get(handlerEvent.getLock().getName()); 75 | if(currEventIndex >= lockEndIndex){ 76 | state.destroyLock(handlerEvent.getLock()); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/engine/racedetectionengine/wcp/distance/WCPEngine.java: -------------------------------------------------------------------------------- 1 | package engine.racedetectionengine.wcp.distance; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import engine.accesstimes.RefinedAccessTimesEngine; 7 | import engine.accesstimes.orderedvars.OrderedVarsEngine; 8 | import engine.racedetectionengine.RaceDetectionEngine; 9 | import event.Thread; 10 | import parse.ParserType; 11 | 12 | public class WCPEngine extends RaceDetectionEngine { 13 | 14 | private HashSet orderedVariables; 15 | private HashMap> lockToThreadSet; 16 | 17 | public WCPEngine(ParserType pType, String trace_folder) { 18 | super(pType); 19 | this.threadSet = new HashSet(); 20 | initializeReader(trace_folder); 21 | handlerEvent = new WCPEvent(); 22 | 23 | boolean time_reporting = true; 24 | 25 | long startTimeAnalysis = 0; 26 | if (time_reporting) { 27 | startTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 28 | } 29 | 30 | RefinedAccessTimesEngine accessTimesEngine = new RefinedAccessTimesEngine(pType, 31 | trace_folder); 32 | accessTimesEngine.computeLastAccessTimes(); 33 | OrderedVarsEngine orderedVarsEngine = new OrderedVarsEngine(pType, trace_folder, 34 | 0); 35 | orderedVarsEngine.analyzeTrace(true, 0); 36 | 37 | if (time_reporting) { 38 | long stopTimeAnalysis = System.currentTimeMillis(); // System.nanoTime(); 39 | long timeAnalysis = stopTimeAnalysis - startTimeAnalysis; 40 | System.out.println("Time for Phase-1 = " + timeAnalysis + " milliseconds"); 41 | } 42 | 43 | this.state = new WCPState(this.threadSet, true); 44 | this.state.view.lockThreadLastInteraction = accessTimesEngine.lockThreadLast; 45 | this.state.existsLockReadVariableThreads = accessTimesEngine.existsLockReadVariableThreads; 46 | this.state.existsLockWriteVariableThreads = accessTimesEngine.existsLockWriteVariableThreads; 47 | this.state.variableToReadEquivalenceClass = accessTimesEngine.variableToReadEquivalenceClass; 48 | this.state.variableToWriteEquivalenceClass = accessTimesEngine.variableToWriteEquivalenceClass; 49 | this.lockToThreadSet = orderedVarsEngine.getLockToThreadSet(); 50 | this.orderedVariables = orderedVarsEngine.getOrdredVars(); 51 | } 52 | 53 | @Override 54 | protected boolean skipEvent(WCPEvent handlerEvent) { 55 | if (handlerEvent.getType().isAccessType()) { 56 | String var_name = handlerEvent.getVariable().getName(); 57 | if (this.orderedVariables.contains(var_name)) { 58 | return true; 59 | } 60 | } else if (handlerEvent.getType().isLockType()) { 61 | if (lockToThreadSet.get(handlerEvent.getLock().getName()).size() <= 1) { 62 | return true; 63 | } 64 | } 65 | return false; 66 | } 67 | 68 | @Override 69 | protected void postHandleEvent(WCPEvent handlerEvent) { 70 | } 71 | 72 | @Override 73 | protected void printCompletionStatus() { 74 | super.printCompletionStatus(); 75 | if (enablePrintStatus) { 76 | // System.out.println("Num races = " + state.numRaces); 77 | System.out.println("Number of 'racy' variables = " + state.racyVars.size()); 78 | System.out.println("Max distance = " + state.maxMinDistance); 79 | double avg_d = ((double) state.sumMinDistance) / ((double) state.numRaces); 80 | System.out.println("Avg. distance = " + String.format("%.2f", avg_d)); 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/event/Decoration.java: -------------------------------------------------------------------------------- 1 | package event; 2 | 3 | public abstract class Decoration { 4 | protected int id; 5 | protected String name; 6 | 7 | public int getId() { 8 | return this.id; 9 | } 10 | 11 | public String getName() { 12 | return this.name; 13 | } 14 | 15 | public String toString() { 16 | return getName(); 17 | //return "[Variable-" + Integer.toString(this.id) + "-" + this.name + "]"; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/event/EventType.java: -------------------------------------------------------------------------------- 1 | package event; 2 | 3 | public enum EventType { 4 | ACQUIRE, RELEASE, READ, WRITE, FORK, JOIN, BEGIN, END, DUMMY; 5 | 6 | public boolean isAcquire() { 7 | return this.ordinal() == ACQUIRE.ordinal(); 8 | } 9 | 10 | public boolean isRelease() { 11 | return this.ordinal() == RELEASE.ordinal(); 12 | } 13 | 14 | public boolean isRead() { 15 | return this.ordinal() == READ.ordinal(); 16 | } 17 | 18 | public boolean isWrite() { 19 | return this.ordinal() == WRITE.ordinal(); 20 | } 21 | 22 | public boolean isFork() { 23 | return this.ordinal() == FORK.ordinal(); 24 | } 25 | 26 | public boolean isJoin() { 27 | return this.ordinal() == JOIN.ordinal(); 28 | } 29 | 30 | public boolean isBegin() { 31 | return this.ordinal() == BEGIN.ordinal(); 32 | } 33 | 34 | public boolean isEnd() { 35 | return this.ordinal() == END.ordinal(); 36 | } 37 | 38 | public boolean isLockType() { 39 | return this.isAcquire() || this.isRelease(); 40 | } 41 | 42 | public boolean isAccessType() { 43 | return this.isRead() || this.isWrite(); 44 | } 45 | 46 | public boolean isExtremeType() { 47 | return this.isFork() || this.isJoin(); 48 | } 49 | 50 | /* 51 | * public boolean isSyncType() { return isLockType() || isExtremeType(); } 52 | */ 53 | 54 | public boolean isTransactionType() { 55 | return isBegin() || isEnd(); 56 | } 57 | 58 | public boolean isDummyType() { 59 | return this.ordinal() == DUMMY.ordinal(); 60 | } 61 | 62 | public static boolean conflicting(EventType et1, EventType et2) { 63 | return et1.isAccessType() && et2.isAccessType() 64 | && (et1.isWrite() || et2.isWrite()); 65 | } 66 | 67 | public String toString() { 68 | String str = ""; 69 | if (this.isAcquire()) 70 | str = "ACQUIRE"; 71 | if (this.isRelease()) 72 | str = "RELEASE"; 73 | if (this.isRead()) 74 | str = "READ"; 75 | if (this.isWrite()) 76 | str = "WRITE"; 77 | if (this.isFork()) 78 | str = "FORK"; 79 | if (this.isJoin()) 80 | str = "JOIN"; 81 | if (this.isBegin()) 82 | str = "BEGIN"; 83 | if (this.isEnd()) 84 | str = "END"; 85 | return str; 86 | } 87 | 88 | public String toStandardFormat() { 89 | String str = ""; 90 | if (this.isAcquire()) 91 | str = "acq"; 92 | if (this.isRelease()) 93 | str = "rel"; 94 | if (this.isRead()) 95 | str = "r"; 96 | if (this.isWrite()) 97 | str = "w"; 98 | if (this.isFork()) 99 | str = "fork"; 100 | if (this.isJoin()) 101 | str = "join"; 102 | if (this.isBegin()) 103 | str = "begin"; 104 | if (this.isEnd()) 105 | str = "end"; 106 | return str; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/event/Lock.java: -------------------------------------------------------------------------------- 1 | package event; 2 | 3 | public class Lock extends Decoration { 4 | 5 | public static int lockCountTracker = 0; 6 | 7 | public Lock() { 8 | this.id = lockCountTracker; 9 | lockCountTracker++; 10 | this.name = "__lock::" + Integer.toString(this.id) + "__"; 11 | } 12 | 13 | public Lock(String sname) { 14 | this.id = lockCountTracker; 15 | lockCountTracker++; 16 | this.name = sname; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/event/Thread.java: -------------------------------------------------------------------------------- 1 | package event; 2 | 3 | public class Thread extends Decoration { 4 | 5 | public static int threadCountTracker = 0; 6 | 7 | public Thread() { 8 | this.id = threadCountTracker; 9 | threadCountTracker++; 10 | this.name = "__thread::" + Integer.toString(this.id) + "__"; 11 | } 12 | 13 | public Thread(String sname) { 14 | this.id = threadCountTracker; 15 | threadCountTracker++; 16 | this.name = sname; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/event/Variable.java: -------------------------------------------------------------------------------- 1 | package event; 2 | 3 | public class Variable extends Decoration { 4 | 5 | public static int variableCountTracker = 0; 6 | 7 | public Variable() { 8 | this.id = variableCountTracker; 9 | variableCountTracker++; 10 | this.name = "__variable::" + Integer.toString(this.id) + "__"; 11 | } 12 | 13 | public Variable(String sname) { 14 | this.id = variableCountTracker; 15 | variableCountTracker++; 16 | this.name = sname; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/notes/Generate_RoadRunner_traces.md: -------------------------------------------------------------------------------- 1 | In order to support RoadRunner traces, I have added a custom printing tool (that only prints a small subset of events, unlike the pre-existing PrintTool [abbreviated `P`] ). 2 | This tool is called PrintSubsetTool and the supplied file `PrintSubsetTool.java` in this folder is the file that you have to put in the appropriate place. 3 | 4 | ## Instructions for generating RoadRunner files : 5 | 6 | 1. Download RoadRunner tool [here](https://github.com/stephenfreund/RoadRunner). 7 | Let us say that RoadRunner sits in ${RoadRunnerRoot} directory. 8 | 9 | 2. Move the file `PrintSubsetTool.java` to the folder ${RoadRunner}/src/rr/simple . 10 | That's it! RoadRunner is so designed as to automatically take care of all the book-keeping when you write a new tool. 11 | 12 | 3. Compile Roadrunner as you normally would (see `INSTALL.txt`) in ${RoadRunnerRoot} . 13 | Most likely, a simple `ant` (in ${RoadRunnerRoot} ) will do the job. 14 | 15 | 4. Once RoadRunner is compiled, we can run our tool. 16 | Let us say we want to print the events of the class `/path/to/class` . 17 | Then, the command you should run is 18 | ``` 19 | rrrun -noFP -noxml -quiet -noTidGC -tool=PS /path/to/class > /path/to/test.rr 20 | ``` 21 | `/path/to/test.rr` is the log file that is generated. 22 | This file is quite readable and you can open it to see the events for yourself. 23 | This is how the file would look like: 24 | ``` 25 | [main: RoadRunner Agent Loaded.] 26 | [main: Running in FAST Mode] 27 | [RR: Creating Fresh Meta Data] 28 | [main: ----- ----- ----- ----- Meep Meep. ----- ----- ----- -----] 29 | [main: ] 30 | @ main[tid = 0] started . 31 | @ Enter(0,test/Test.main([Ljava/lang/String;)V) from null 32 | @ Thread-0[tid = 1] started by main[tid = 0]. 33 | @ Start(0,1) 34 | . 35 | . 36 | . 37 | ``` 38 | 39 | The option `-noFP` disallows any fast-path optimization that RoadRunner would normally employ. In the absence of this flag, some of the access events are not printed. 40 | The options `-noxml` and `-quiet` reduce the clutter that RoadRunner normally produces. 41 | The option `-noTidGC` is (as of now) an unstable/experimental feature. In the absence of this flag, RoadRunner allows thread-id's of dead threads to be re-used. I did not explicitly handle such traces where you would reuse thread ids. Hence, this flag. -------------------------------------------------------------------------------- /src/parse/ParserType.java: -------------------------------------------------------------------------------- 1 | package parse; 2 | 3 | public enum ParserType { 4 | RV, RR, CSV, STD; 5 | 6 | public boolean isRV(){ 7 | return this.ordinal() == RV.ordinal(); 8 | } 9 | 10 | public boolean isRR(){ 11 | return this.ordinal() == RR.ordinal(); 12 | } 13 | 14 | public boolean isSTD(){ 15 | return this.ordinal() == STD.ordinal(); 16 | } 17 | 18 | public boolean isCSV(){ 19 | return this.ordinal() == CSV.ordinal(); 20 | } 21 | 22 | public boolean isLogType() { 23 | return this.isRR() || this.isCSV() || this.isSTD(); 24 | } 25 | 26 | public boolean isBinType() { 27 | return this.isRV(); 28 | } 29 | 30 | public String toString(){ 31 | String str = ""; 32 | if(isRV()) str = "RV"; 33 | else if (isCSV()) str = "CSV"; 34 | else if (isRR()) str = "RR"; 35 | else if (isSTD()) str = "STD"; 36 | return str; 37 | } 38 | 39 | public static ParserType getType(String str){ 40 | if(str.equals("csv")) return CSV; 41 | else if (str.equals("rr")) return RR; 42 | else if (str.equals("std")) return STD; 43 | else return RV; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/parse/csv/Parse.java: -------------------------------------------------------------------------------- 1 | package parse.csv; 2 | 3 | import java.lang.reflect.Array; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | import event.EventType; 10 | import parse.util.CannotParseException; 11 | import parse.util.EventInfo; 12 | 13 | public class Parse { 14 | // ACQUIRE, RELEASE, READ, WRITE, FORK, JOIN; 15 | public static String matchStr[] = { "acq", "rel", "r", "w", "start", "join", "enter", "exit", "dummy" }; 16 | 17 | public static String prefixPattern = "^("; 18 | public static String midFixPattern = String.join("|", matchStr); 19 | public static String suffixPattern = ")[(]([^\\s]+)[)]$"; 20 | public static String stringEventPattern = prefixPattern + midFixPattern + suffixPattern; 21 | public static Pattern primitiveEventPattern = Pattern.compile(stringEventPattern); 22 | public HashMap mapMatchType; 23 | 24 | public static String cvsSplitBy = ","; 25 | public static String stringGenericEventPattern = prefixPattern + midFixPattern + "|sync" + suffixPattern; 26 | public static Pattern genericEventPattern = Pattern.compile(stringGenericEventPattern); 27 | 28 | public Parse() { 29 | mapMatchType = new HashMap(); 30 | for (EventType type : EventType.values()) { 31 | mapMatchType.put(matchStr[type.ordinal()], type); 32 | } 33 | } 34 | 35 | public static void example() { 36 | String line = ",,,,sync(z),,"; 37 | Parse parse = new Parse(); 38 | try{ 39 | System.out.println(parse.getInfoList(line)); 40 | } 41 | catch(CannotParseException e){ 42 | System.out.println("Could not parse !"); 43 | } 44 | } 45 | 46 | public EventInfo getInfo(int tIndex, Matcher matcher) { 47 | String strType = matcher.group(1); 48 | EventType tp = mapMatchType.get(strType); 49 | String th = "T" + Integer.toString(tIndex); 50 | String aux = matcher.group(2); 51 | EventInfo str = new EventInfo(tp, th, aux, ""); 52 | return str; 53 | } 54 | 55 | public ArrayList getInfoList(String line) throws CannotParseException { 56 | String[] tArray = line.split(cvsSplitBy, -1); 57 | int len = Array.getLength(tArray); 58 | int tIndex = -1; 59 | String restInfo = null; 60 | ArrayList infoList = null; 61 | for(int i = 0; i < len; i ++){ 62 | if(!(tArray[i].equals(""))){ 63 | tIndex = i; 64 | restInfo = tArray[i]; 65 | break; 66 | } 67 | } 68 | if(tIndex < 0){ 69 | throw new CannotParseException(line); 70 | } 71 | else{ 72 | Matcher matcher = genericEventPattern.matcher(restInfo); 73 | if (matcher.find()) { 74 | infoList = new ArrayList(); 75 | Matcher primitiveMatcher = primitiveEventPattern.matcher(restInfo); 76 | if(primitiveMatcher.find()){ 77 | //Primitive pattern 78 | infoList.add(getInfo(tIndex, primitiveMatcher)); 79 | } 80 | else{ 81 | //Sync type 82 | String var = matcher.group(2); 83 | String varLock = "VARLOCK-" + var + "-KCOLRAV"; 84 | Matcher subMatcher = null; 85 | 86 | String e1 = "acq(" + varLock + ")"; 87 | subMatcher = primitiveEventPattern.matcher(e1); 88 | subMatcher.find(); 89 | infoList.add(getInfo(tIndex, subMatcher)); 90 | 91 | String e2 = "r(" + var + ")"; 92 | subMatcher = primitiveEventPattern.matcher(e2); 93 | subMatcher.find(); 94 | infoList.add(getInfo(tIndex, subMatcher)); 95 | 96 | String e3 = "w(" + var + ")"; 97 | subMatcher = primitiveEventPattern.matcher(e3); 98 | subMatcher.find(); 99 | infoList.add(getInfo(tIndex, subMatcher)); 100 | 101 | String e4 = "rel(" + varLock + ")"; 102 | subMatcher = primitiveEventPattern.matcher(e4); 103 | subMatcher.find(); 104 | infoList.add(getInfo(tIndex, subMatcher)); 105 | } 106 | } else { 107 | throw new CannotParseException(line); 108 | } 109 | } 110 | return infoList; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/parse/rr/Parse.java: -------------------------------------------------------------------------------- 1 | package parse.rr; 2 | 3 | import java.util.HashMap; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | import event.EventType; 8 | import parse.util.CannotParseException; 9 | import parse.util.EventInfo; 10 | 11 | public class Parse { 12 | // ACQUIRE, RELEASE, READ, WRITE, FORK, JOIN, BEGIN, END; 13 | public static String matchStr[] = { "Acquire", "Release", "[A]?Rd", "[A]?Wr", "Start", "Join", "Enter", "Exit", "Dummy" }; 14 | public static String prefixPattern = "^@[\\s]+("; 15 | public static String suffixPattern = ")[(]([^,\\s]+)[,]([^,\\s]+)[)]([\\s]+)?([^,\\s]+)?([\\s]+)?([^,\\s]+)?"; 16 | public static String stringEventPattern = prefixPattern + String.join("|", matchStr) + suffixPattern; 17 | public static Pattern eventPattern = Pattern.compile(stringEventPattern); 18 | public HashMap mapMatchType; 19 | 20 | public Parse() { 21 | mapMatchType = new HashMap(); 22 | for (EventType type : EventType.values()) { 23 | String tp_str = matchStr[type.ordinal()]; 24 | if(tp_str.equals("[A]?Rd") || tp_str.equals("[A]?Wr")){ 25 | tp_str = tp_str.substring(4); 26 | } 27 | mapMatchType.put(tp_str, type); 28 | } 29 | } 30 | 31 | public static void example() { 32 | String line = "@ ARd(2,null.test/Deadlock.value_I) Final Deadlock.java:50:7"; 33 | // String line = "@ Acquire(2,@03)"; 34 | // String line = "@ Exit(1,test/Deadlock.doSomething()V)"; 35 | Parse parse = new Parse(); 36 | EventInfo eInfo = new EventInfo(); 37 | try{ 38 | parse.getInfo(eInfo, line); 39 | } 40 | catch(CannotParseException e){ 41 | System.out.println("Could not parse !"); 42 | } 43 | System.out.println(eInfo); 44 | } 45 | 46 | public void getInfo(EventInfo eInfo, String line) throws CannotParseException { 47 | Matcher matcher = eventPattern.matcher(line); 48 | if (matcher.find()) { 49 | 50 | String tp_str = matcher.group(1); 51 | if(tp_str.equals("ARd") || tp_str.equals("AWr")){ 52 | tp_str = tp_str.substring(1); 53 | } 54 | EventType tp = mapMatchType.get(tp_str); 55 | String thId = matcher.group(2); 56 | String aux = matcher.group(3); 57 | String locId = ""; 58 | if(tp.isAccessType()){ 59 | locId = matcher.group(7); 60 | if(locId == null){ 61 | throw new CannotParseException(line); 62 | } 63 | } 64 | eInfo.updateEventInfo(tp, thId, aux, locId); 65 | } else { 66 | throw new CannotParseException(line); 67 | } 68 | } 69 | 70 | public static void main(String args[]){ 71 | example(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/parse/std/Parse.java: -------------------------------------------------------------------------------- 1 | package parse.std; 2 | 3 | import java.util.HashMap; 4 | import java.util.regex.Matcher; 5 | import java.util.regex.Pattern; 6 | 7 | import event.EventType; 8 | import parse.util.CannotParseException; 9 | import parse.util.EventInfo; 10 | 11 | public class Parse { 12 | // ACQUIRE, RELEASE, READ, WRITE, FORK, JOIN, BEGIN, END, BRANCH; 13 | public static String matchStr[] = { "acq", "rel", "r", "w", "fork", "join", "begin", "end", "dummy" }; 14 | 15 | public static String prefixPattern = "^("; 16 | public static String midFixPattern = String.join("|", matchStr); 17 | public static String suffixPattern = ")[(]([^\\s]+)[)]$"; 18 | public static String stringEventPattern = prefixPattern + midFixPattern + suffixPattern; 19 | public static Pattern primitiveEventPattern = Pattern.compile(stringEventPattern); 20 | public HashMap mapMatchType; 21 | 22 | public static String splitBy = "\\|"; 23 | public static String stringGenericEventPattern = prefixPattern + midFixPattern + "|sync" + suffixPattern; 24 | public static Pattern genericEventPattern = Pattern.compile(stringGenericEventPattern); 25 | 26 | //public EventInfo eInfo; 27 | 28 | public Parse() { 29 | mapMatchType = new HashMap(); 30 | for (EventType type : EventType.values()) { 31 | mapMatchType.put(matchStr[type.ordinal()], type); 32 | } 33 | } 34 | 35 | public static void example() { 36 | // String line = "345|T20|sync(z)"; 37 | // String line = "T20|join(T1)|345"; 38 | String line = "T20|branch|345"; 39 | Parse parse = new Parse(); 40 | EventInfo eInfo = new EventInfo(); 41 | try{ 42 | parse.getInfo(eInfo, line); 43 | } 44 | catch(CannotParseException e){ 45 | System.out.println("Could not parse !"); 46 | } 47 | System.out.println("Parsed successfully : " + eInfo); 48 | } 49 | 50 | public void getInfoOp(EventInfo eInfo, String th, String loc, Matcher matcher) { 51 | String strType = matcher.group(1); 52 | EventType tp = mapMatchType.get(strType); 53 | String aux = matcher.group(2); 54 | eInfo.updateEventInfo(tp, th, aux, loc); 55 | } 56 | 57 | public void getInfo(EventInfo eInfo, String line) throws CannotParseException { 58 | String[] eArray = line.split(splitBy, -1); 59 | if(eArray.length < 3 || eArray.length > 3){ 60 | throw new CannotParseException(line); 61 | } 62 | else{ 63 | String thId = eArray[0]; 64 | String op = eArray[1]; 65 | String locId = eArray[2]; 66 | if(op.startsWith("begin")){ 67 | eInfo.updateEventInfo(EventType.BEGIN, thId, null, locId); 68 | } 69 | else if(op.startsWith("end")){ 70 | eInfo.updateEventInfo(EventType.END, thId, null, locId); 71 | } 72 | else{ 73 | Matcher matcher = genericEventPattern.matcher(op); 74 | if (matcher.find()) { 75 | Matcher primitiveMatcher = primitiveEventPattern.matcher(op); 76 | if(primitiveMatcher.find()){ 77 | getInfoOp(eInfo, thId, locId, primitiveMatcher); 78 | } 79 | else{ 80 | throw new CannotParseException(line); 81 | } 82 | } else { 83 | throw new CannotParseException(line); 84 | } 85 | } 86 | 87 | } 88 | } 89 | 90 | public static void main(String args[]){ 91 | example(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/parse/std/ParseStandard.java: -------------------------------------------------------------------------------- 1 | package parse.std; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileReader; 7 | import java.util.HashMap; 8 | import java.util.HashSet; 9 | 10 | import event.Event; 11 | import event.Lock; 12 | import event.Thread; 13 | import event.Variable; 14 | import parse.util.CannotParseException; 15 | import parse.util.EventInfo; 16 | 17 | public class ParseStandard { 18 | private HashMap threadMap; 19 | private HashMap lockMap; 20 | private HashMap variableMap; 21 | int totThreads; 22 | BufferedReader bufferedReader; 23 | String line; 24 | Parse parser; 25 | EventInfo eInfo; 26 | long totEvents; 27 | 28 | public ParseStandard(String traceFile){ 29 | threadMap = new HashMap(); 30 | lockMap = new HashMap(); 31 | variableMap = new HashMap(); 32 | totThreads = 0; 33 | totEvents = 0; 34 | 35 | bufferedReader = null; 36 | try{ 37 | bufferedReader = new BufferedReader(new FileReader(traceFile)); 38 | } 39 | catch (FileNotFoundException ex) { 40 | System.out.println("Unable to open file '" + traceFile + "'"); 41 | } 42 | 43 | parser = new Parse(); 44 | eInfo = new EventInfo(); 45 | line = null; 46 | } 47 | 48 | public ParseStandard(String traceFile, boolean computeThreadSetAPriori){ 49 | this(traceFile); 50 | if(computeThreadSetAPriori){ 51 | Event e = new Event (); 52 | while(this.hasNext()){ 53 | getNextEvent(e); 54 | } 55 | this.totEvents = 0; //Resetting totEvents is required to ensure correct AuxId 56 | try{ 57 | bufferedReader = new BufferedReader(new FileReader(traceFile)); 58 | } 59 | catch (FileNotFoundException ex) { 60 | System.out.println("Unable to open file '" + traceFile + "'"); 61 | } 62 | } 63 | } 64 | 65 | public HashSet getThreadSet(){ 66 | return new HashSet (this.threadMap.values()); 67 | } 68 | 69 | public void eInfo2Event(Event e) { 70 | String tname = eInfo.thread; 71 | if (!(threadMap.containsKey(tname))) { 72 | threadMap.put(tname, new Thread(tname)); 73 | totThreads = totThreads + 1; 74 | } 75 | Thread t = threadMap.get(tname); 76 | 77 | int LID = Integer.parseInt(eInfo.locId); 78 | String ename = "E" + Long.toString(totEvents); 79 | 80 | if (eInfo.type.isRead()) { 81 | String vname = eInfo.decor; 82 | if (!(variableMap.containsKey(vname))) { 83 | variableMap.put(vname, new Variable(vname)); 84 | } 85 | Variable v = variableMap.get(vname); 86 | e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, v, null); 87 | } 88 | 89 | else if (eInfo.type.isWrite()) { 90 | String vname = eInfo.decor; 91 | if (!(variableMap.containsKey(vname))) { 92 | variableMap.put(vname, new Variable(vname)); 93 | } 94 | Variable v = variableMap.get(vname); 95 | 96 | e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, v, null); 97 | } 98 | 99 | else if (eInfo.type.isAcquire()) { 100 | String lname = eInfo.decor; 101 | if (!(lockMap.containsKey(lname))) { 102 | lockMap.put(lname, new Lock(lname)); 103 | } 104 | Lock l = lockMap.get(lname); 105 | 106 | e.updateEvent(totEvents, LID, ename, eInfo.type, t, l, null, null); 107 | } 108 | 109 | else if (eInfo.type.isRelease()) { 110 | String lname = eInfo.decor; 111 | if (!(lockMap.containsKey(lname))) { 112 | lockMap.put(lname, new Lock(lname)); 113 | } 114 | Lock l = lockMap.get(lname); 115 | 116 | e.updateEvent(totEvents, LID, ename, eInfo.type, t, l, null, null); 117 | } 118 | 119 | else if (eInfo.type.isFork()) { 120 | String target_name = eInfo.decor; 121 | if (!(threadMap.containsKey(target_name))) { 122 | threadMap.put(target_name, new Thread(target_name)); 123 | } 124 | Thread target = threadMap.get(target_name); 125 | 126 | e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, target); 127 | } 128 | 129 | else if (eInfo.type.isJoin()) { 130 | String target_name = eInfo.decor; 131 | if (!(threadMap.containsKey(target_name))) { 132 | threadMap.put(target_name, new Thread(target_name)); 133 | } 134 | Thread target = threadMap.get(target_name); 135 | 136 | e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, target); 137 | } 138 | 139 | else if (eInfo.type.isBegin()) { 140 | e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, null); 141 | } 142 | 143 | else if (eInfo.type.isEnd()) { 144 | e.updateEvent(totEvents, LID, ename, eInfo.type, t, null, null, null); 145 | } 146 | 147 | else { 148 | throw new IllegalArgumentException("Illegal type of event " + eInfo.type.toString()); 149 | } 150 | 151 | totEvents = totEvents + 1; 152 | } 153 | 154 | public void getNextEvent(Event e){ //e is supposed to be over-written (deep copy) by the event-generated from the line read 155 | try { 156 | parser.getInfo(eInfo, line); 157 | } catch (CannotParseException ex) { 158 | System.err.println("Canot parse line -> " + line); 159 | } 160 | eInfo2Event(e); 161 | } 162 | 163 | public boolean hasNext(){ 164 | try { 165 | line = bufferedReader.readLine() ; 166 | } catch (IOException ex) { 167 | System.err.println("Error reading buffered reader"); 168 | } 169 | 170 | boolean endOfFile = (line == null); 171 | if(endOfFile){ 172 | try { 173 | bufferedReader.close(); 174 | } catch (IOException e) { 175 | System.err.println("Error closing buffered reader"); 176 | } 177 | } 178 | return !endOfFile; 179 | } 180 | 181 | public int getTotalThreads(){ 182 | return totThreads; 183 | } 184 | 185 | public static void demo(){ 186 | String traceFile = "/Users/umang/Desktop/trace.txt"; 187 | Event e = new Event(); 188 | ParseStandard parser = new ParseStandard(traceFile); 189 | while(parser.hasNext()){ 190 | parser.getNextEvent(e); 191 | System.out.println(e.toCompactString()); 192 | } 193 | } 194 | 195 | public static void main(String args[]){ 196 | demo(); 197 | } 198 | 199 | } 200 | -------------------------------------------------------------------------------- /src/parse/util/CannotParseException.java: -------------------------------------------------------------------------------- 1 | package parse.util; 2 | 3 | public class CannotParseException extends Exception { 4 | 5 | private static final long serialVersionUID = -2061251787621673954L; 6 | //private static final long serialVersionUID = 1L; 7 | private String line; 8 | 9 | public CannotParseException(String str) { 10 | this.line = str; 11 | } 12 | 13 | public String getLine() { 14 | return this.line; 15 | } 16 | } -------------------------------------------------------------------------------- /src/parse/util/EventInfo.java: -------------------------------------------------------------------------------- 1 | package parse.util; 2 | 3 | import event.EventType; 4 | 5 | public class EventInfo { 6 | public EventType type; 7 | public String thread; 8 | public String decor; 9 | public String locId; 10 | 11 | public EventInfo(){} 12 | 13 | public EventInfo(EventType tp, String th, String dec, String l) { 14 | this.type = tp; 15 | this.thread = th; 16 | this.decor = dec; 17 | this.locId = l; 18 | } 19 | 20 | public void updateEventInfo(EventType tp, String th, String dec, String l){ 21 | this.type = tp; 22 | this.thread = th; 23 | this.decor = dec; 24 | this.locId = l; 25 | } 26 | 27 | public String toString(){ 28 | if (this.locId == ""){ 29 | return this.thread + "|" + this.type.toString() + "|" + this.decor ; 30 | } 31 | else{ 32 | return this.locId + "|" + this.thread + "|" + this.type.toString() + "|" + this.decor ; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/util/NeibhorsHardCodeWordTricks.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | // Using word tricks to store the neighbors (parent, first child, left sibling, right sibling) of a node in the tree clock 4 | 5 | public class NeibhorsHardCodeWordTricks { 6 | //The arrangement is next-previous-parent-headchild 7 | public static final int TID_BITS = 16; 8 | public static final long ALL_ONES_LONG = -1; 9 | public static final short ALL_ONES_SHORT = -1; 10 | public static final long NULL = (long) 0; 11 | public static final short T_NULL = -1; 12 | 13 | public static final long NEXT_MASK = ((ALL_ONES_LONG >>> ( 3 * TID_BITS ) ) << ( 3 * TID_BITS) ) >>> ( 0 * TID_BITS); 14 | public static final long PREVIOUS_MASK = ((ALL_ONES_LONG >>> ( 2 * TID_BITS ) ) << ( 3 * TID_BITS) ) >>> ( 1 * TID_BITS); 15 | public static final long PARENT_MASK = ((ALL_ONES_LONG >>> ( 1 * TID_BITS ) ) << ( 3 * TID_BITS) ) >>> ( 2 * TID_BITS); 16 | public static final long HEADCHILD_MASK = ((ALL_ONES_LONG >>> ( 0 * TID_BITS ) ) << ( 3 * TID_BITS) ) >>> ( 3 * TID_BITS); 17 | public static final long NEXT_AND_PARENT_MASK = NEXT_MASK | PARENT_MASK; 18 | 19 | 20 | 21 | public static final short getNext(long data) { 22 | return (short) (( data >>> (3*TID_BITS) ) -1); 23 | } 24 | 25 | public static final short getPrevious(long data) { 26 | return (short) (( (data & PREVIOUS_MASK) >>> (2*TID_BITS) ) -1 ); 27 | } 28 | 29 | public static final short getParent(long data) { 30 | return (short) (( (data & PARENT_MASK) >>> (1*TID_BITS) ) - 1); 31 | } 32 | 33 | public static final short getHeadChild(long data) { 34 | return (short) (( data & HEADCHILD_MASK ) - 1); 35 | } 36 | 37 | public static final long setNext(short next, long to) { 38 | to &= ~NEXT_MASK; 39 | to |= ( (next+1) & HEADCHILD_MASK) << (3 * TID_BITS); 40 | return to; 41 | } 42 | 43 | public static final long setPrevious(short previous, long to) { 44 | to &= ~PREVIOUS_MASK; 45 | to |= ( (previous+1) & HEADCHILD_MASK ) << (2 * TID_BITS); 46 | return to; 47 | } 48 | 49 | public static final long setParent(short parent, long to) { 50 | to &= ~PARENT_MASK; 51 | to |= ( (parent+1) & HEADCHILD_MASK ) << (1 * TID_BITS); 52 | return to; 53 | } 54 | 55 | public static final long setNextAndParent(short next, short parent, long to) { 56 | to &= ~NEXT_AND_PARENT_MASK; 57 | to |= ( (parent+1) & HEADCHILD_MASK ) << (1 * TID_BITS); 58 | to |= ( (next+1) & HEADCHILD_MASK) << (3 * TID_BITS); 59 | return to; 60 | } 61 | 62 | public static final long setHeadChild(short headChild, long to) { 63 | to &= ~HEADCHILD_MASK; 64 | to |= ( (headChild+1) & HEADCHILD_MASK ); 65 | return to; 66 | } 67 | 68 | public static final long setNextNull(long data) { 69 | data &= ~NEXT_MASK; 70 | return data; 71 | } 72 | 73 | public static final long setPreviousNull(long data) { 74 | data &= ~PREVIOUS_MASK; 75 | return data; 76 | } 77 | 78 | public static final long setParentNull(long data) { 79 | data &= ~PARENT_MASK; 80 | return data; 81 | } 82 | 83 | public static final long setHeadChildNull(long data) { 84 | data &= ~HEADCHILD_MASK; 85 | return data; 86 | } 87 | 88 | public static final boolean isNull(long data) { 89 | return data == NULL; 90 | } 91 | 92 | public static final boolean isTNull(short t) { 93 | return t == T_NULL; 94 | } 95 | 96 | public static final boolean isNextNull(long data) { 97 | return ( data & NEXT_MASK ) == 0; 98 | } 99 | 100 | public static final boolean isPreviousNull(long data) { 101 | return ( data & PREVIOUS_MASK ) == 0; 102 | } 103 | 104 | public static final boolean isParentNull(long data) { 105 | return ( data & PARENT_MASK ) == 0; 106 | } 107 | 108 | public static final boolean isHeadChildNull(long data) { 109 | return ( data & HEADCHILD_MASK ) == 0; 110 | } 111 | 112 | public static final long copyNextToHeadChild(long from, long to) { 113 | to = (to & ~HEADCHILD_MASK) | ((from & NEXT_MASK) >>> (3 * TID_BITS)); 114 | return to; 115 | } 116 | 117 | public static final long copyHeadChildToNext(long from, long to) { 118 | to = (to & ~NEXT_MASK) | ((from & HEADCHILD_MASK) << (3 * TID_BITS)); 119 | return to; 120 | } 121 | 122 | public static final long copyHeadChildToHeadChild(long from, long to) { 123 | to = (to & ~HEADCHILD_MASK) | ((from & HEADCHILD_MASK)); 124 | return to; 125 | } 126 | 127 | public static final long copyNextToNext(long from, long to) { 128 | to = (to & ~NEXT_MASK) | (from & NEXT_MASK); 129 | return to; 130 | } 131 | 132 | public static final long copyPreviousToPrevious(long from, long to) { 133 | to = (to & ~PREVIOUS_MASK) | (from & PREVIOUS_MASK); 134 | return to; 135 | } 136 | 137 | 138 | 139 | 140 | public static String toString(long data) { 141 | 142 | //String str = String.format("0x%016x", data) + " - "; 143 | String str = ""; 144 | str += "<"; 145 | str += getNext(data)-1; 146 | str += ", "; 147 | str += getPrevious(data)-1; 148 | str += ", "; 149 | str += getParent(data)-1; 150 | str += ", "; 151 | str += getHeadChild(data)-1; 152 | str += ">"; 153 | return str; 154 | } 155 | 156 | } -------------------------------------------------------------------------------- /src/util/Pair.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.util.Objects; 4 | 5 | public class Pair { 6 | public T first; 7 | public U second; 8 | public Pair(T f, U s){ 9 | this.first = f; 10 | this.second = s; 11 | } 12 | public boolean equals(Pair other){ 13 | return this.first.equals(other.first) && this.second.equals(other.second); 14 | } 15 | 16 | public int hashCode(){ 17 | return Objects.hash(first, second); 18 | } 19 | 20 | public String toString(){ 21 | return "<" + first.toString() + ", " + second.toString() + ">"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/util/PairComparators.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.util.Comparator; 4 | 5 | public class PairComparators{ 6 | public static class FirstComparator, B> implements Comparator> { 7 | @Override 8 | public int compare(Pair o1, Pair o2) { 9 | return o1.first.compareTo(o2.first); 10 | } 11 | } 12 | 13 | public static class SecondComparator> implements Comparator> { 14 | @Override 15 | public int compare(Pair o1, Pair o2) { 16 | return o1.second.compareTo(o2.second); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/util/PairHardCodeWordTricks.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | 4 | 5 | public final class PairHardCodeWordTricks{ 6 | 7 | //The arrangement is PCLOCK - CLOCK 8 | public static final int CLOCK_BITS = 32; 9 | public static final int PCLOCK_BITS = 32; 10 | public static final long ALL_ONES_LONG = -1; 11 | public static final long PCLOCK_MASK = (ALL_ONES_LONG >>> PCLOCK_BITS) << PCLOCK_BITS; 12 | public static final long CLOCK_MASK = (ALL_ONES_LONG << PCLOCK_BITS ) >>> PCLOCK_BITS; 13 | 14 | 15 | 16 | public static int getClock(long data) { 17 | return (int)( data & CLOCK_MASK ); 18 | } 19 | 20 | public static int getPclock(long data) { 21 | return (int)( data >> (CLOCK_BITS) ); 22 | } 23 | 24 | 25 | public static long copyClock(long from, long to) { 26 | to &= ~CLOCK_MASK; 27 | to |= from & CLOCK_MASK; 28 | return to; 29 | } 30 | 31 | public static long copyPclock(long from, long to) { 32 | to &= ~PCLOCK_MASK; 33 | to |= from & PCLOCK_MASK; 34 | return to; 35 | } 36 | 37 | 38 | public static long copyClockToPclock(long from, long to) { 39 | 40 | to &= ~PCLOCK_MASK; 41 | to |= (from & CLOCK_MASK) << CLOCK_BITS; 42 | 43 | return to; 44 | } 45 | 46 | 47 | 48 | public static long setPclock(int pclock, long to) { 49 | to &= ~PCLOCK_MASK; 50 | to |= ( pclock & CLOCK_MASK ) << CLOCK_BITS; 51 | return to; 52 | } 53 | 54 | public static long setClock(int clock, long to) { 55 | to &= ~CLOCK_MASK; 56 | to |= ( clock & CLOCK_MASK); 57 | return to; 58 | } 59 | 60 | 61 | public static long incrementClockBy(int inc, long to) { 62 | to += inc; 63 | return to; 64 | } 65 | 66 | public static boolean clockIsLessThan(long first, long second) { 67 | return (first & CLOCK_MASK) < (second & CLOCK_MASK); 68 | } 69 | 70 | public static boolean clockIsLessThanOrEqual(long first, long second) { 71 | return (first & CLOCK_MASK) <= (second & CLOCK_MASK); 72 | } 73 | 74 | 75 | 76 | 77 | 78 | public static String toString(int data) { 79 | 80 | String str = ""; 81 | str += "<"; 82 | str += getClock(data); 83 | str += ", "; 84 | str += getPclock(data); 85 | str += ">"; 86 | return str; 87 | } 88 | } -------------------------------------------------------------------------------- /src/util/Quintet.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.util.Objects; 4 | 5 | public class Quintet { 6 | public A first; 7 | public B second; 8 | public C third; 9 | public D fourth; 10 | public E fifth; 11 | 12 | public Quintet(A a, B b, C c, D d, E e){ 13 | this.first = a; 14 | this.second = b; 15 | this.third = c; 16 | this.fourth = d; 17 | this.fifth = e; 18 | } 19 | 20 | @Override 21 | public boolean equals(Object o){ 22 | if (this == o) 23 | return true; 24 | 25 | if (o == null || getClass() != o.getClass()) 26 | return false; 27 | 28 | Quintet quintet = (Quintet) o; 29 | 30 | if (!first.equals(quintet.first)) 31 | return false; 32 | if (!second.equals(quintet.second)) 33 | return false; 34 | if (!third.equals(quintet.third)) 35 | return false; 36 | if (!fourth.equals(quintet.fourth)) 37 | return false; 38 | return fifth.equals(quintet.fifth); 39 | } 40 | 41 | public int hashCode(){ 42 | return Objects.hash(first, second, third, fourth, fifth); 43 | } 44 | 45 | public String toString(){ 46 | String str = "<"; 47 | str += first; 48 | str += ", "; 49 | str += second; 50 | str += ", "; 51 | str += third; 52 | str += ", "; 53 | str += fourth; 54 | str += ", "; 55 | str += fifth; 56 | str += ">"; 57 | return str; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/util/Transaction.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.util.Objects; 4 | 5 | import event.Thread; 6 | 7 | 8 | public class Transaction { 9 | public int id; 10 | public Thread thread; 11 | public Transaction(){ 12 | this.id = -1; 13 | } 14 | public Transaction(Thread t, int id){ 15 | if(id == -1){ 16 | throw new IllegalArgumentException("Trnsaction: Cannot use custom constructor for id=-1"); 17 | } 18 | this.thread = t; 19 | this.id = id; 20 | } 21 | public boolean equals(Transaction other){ 22 | return this.id == other.id && this.thread.equals(other.thread); 23 | } 24 | 25 | public int hashCode(){ 26 | return Objects.hash(this.id, this.thread); 27 | } 28 | 29 | public String toString() { 30 | if(thread != null) return "<" + thread.toString() + ":" + Integer.toString(id) + ">"; 31 | else return ""; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/util/Triplet.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.util.Objects; 4 | 5 | public class Triplet { 6 | public A first; 7 | public B second; 8 | public C third; 9 | public Triplet(A a, B b, C c){ 10 | this.first = a; 11 | this.second = b; 12 | this.third = c; 13 | } 14 | 15 | @Override 16 | public boolean equals(Object o){ 17 | if (this == o) 18 | return true; 19 | 20 | if (o == null || getClass() != o.getClass()) 21 | return false; 22 | 23 | Triplet triplet = (Triplet) o; 24 | 25 | // call equals() method of the underlying objects 26 | if (!first.equals(triplet.first)) 27 | return false; 28 | if (!second.equals(triplet.second)) 29 | return false; 30 | return third.equals(triplet.third); 31 | } 32 | 33 | public int hashCode(){ 34 | return Objects.hash(first, second, third); 35 | } 36 | 37 | public String toString(){ 38 | String str = "<"; 39 | str += first; 40 | str += ", "; 41 | str += second; 42 | str += ", "; 43 | str += third; 44 | str += ">"; 45 | return str; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/util/TripletComparators.java: -------------------------------------------------------------------------------- 1 | package util; 2 | 3 | import java.util.Comparator; 4 | 5 | public class TripletComparators{ 6 | public static class FirstComparator, B, C> implements Comparator> { 7 | @Override 8 | public int compare(Triplet o1, Triplet o2) { 9 | return o1.first.compareTo(o2.first); 10 | } 11 | } 12 | 13 | public static class SecondComparator, C> implements Comparator> { 14 | @Override 15 | public int compare(Triplet o1, Triplet o2) { 16 | return o1.second.compareTo(o2.second); 17 | } 18 | } 19 | 20 | public static class ThirdComparator> implements Comparator> { 21 | @Override 22 | public int compare(Triplet o1, Triplet o2) { 23 | return o1.third.compareTo(o2.third); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/util/ll/EfficientLinkedList.java: -------------------------------------------------------------------------------- 1 | package util.ll; 2 | 3 | public class EfficientLinkedList { 4 | private int sz; 5 | private EfficientNode headNode; 6 | private EfficientNode tailNode; 7 | 8 | public EfficientLinkedList() { 9 | this.sz = 0; 10 | this.headNode = null; 11 | this.tailNode = null; 12 | } 13 | 14 | public int getLength() { 15 | return this.sz; 16 | } 17 | 18 | public boolean isEmpty() { 19 | return (sz <= 0); 20 | } 21 | 22 | // Earliest inserted element 23 | public T bottom() { 24 | if (this.isEmpty()) { 25 | throw new IllegalArgumentException("Cannot get bottom: Store is empty"); 26 | } 27 | return this.headNode.getData(); 28 | } 29 | 30 | // Latest inserted element 31 | public T top() { 32 | if (this.isEmpty()) { 33 | throw new IllegalArgumentException("Cannot get top: Store is empty"); 34 | } 35 | return this.tailNode.getData(); 36 | } 37 | 38 | public T removeBottom() { 39 | if (this.isEmpty()) { 40 | throw new IllegalArgumentException("Cannot remove first: Store is empty"); 41 | } 42 | T retData = this.headNode.getData(); 43 | if (sz == 1) { 44 | this.headNode = null; 45 | this.tailNode = null; 46 | } else { 47 | EfficientNode nextNode = this.headNode.getNext(); 48 | this.headNode = nextNode; 49 | } 50 | this.sz = this.sz - 1; 51 | return retData; 52 | } 53 | 54 | public void removeBottomPrefixOfLength(int i) { 55 | if (i > this.sz) { 56 | throw new IllegalArgumentException("Array out of bound: removePrefix : i =" 57 | + Integer.toString(i) + ", size = " + Integer.toString(this.sz)); 58 | } 59 | for (int k = 0; k < i; k++) { 60 | this.removeBottom(); 61 | } 62 | } 63 | 64 | public void pushTop(T data) { 65 | EfficientNode newNode = new EfficientNode(data); 66 | if (this.isEmpty()) { 67 | this.headNode = newNode; 68 | this.tailNode = newNode; 69 | } else { 70 | this.tailNode.setNext(newNode); 71 | this.tailNode = newNode; 72 | } 73 | this.sz = this.sz + 1; 74 | } 75 | 76 | public void setTop(T data) { 77 | if (this.isEmpty()) { 78 | throw new IllegalArgumentException("Cannot get top: Store is empty"); 79 | } 80 | this.tailNode.setData(data); 81 | } 82 | 83 | public EfficientNode getHeadNode() { 84 | return this.headNode; 85 | } 86 | 87 | public String toString() { 88 | String strPre = "["; 89 | String strPost = "]"; 90 | String strMid = ""; 91 | if (sz >= 1) { 92 | strMid = strMid + this.headNode.getData().toString(); 93 | EfficientNode itrNode = this.headNode.getNext(); 94 | for (int i = 1; i < sz; i++) { 95 | strMid = strMid + ", " + itrNode.getData().toString(); 96 | itrNode = itrNode.getNext(); 97 | } 98 | } 99 | return strPre + strMid + strPost; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/util/ll/EfficientNode.java: -------------------------------------------------------------------------------- 1 | package util.ll; 2 | 3 | public class EfficientNode { 4 | private T data; 5 | private EfficientNode next; 6 | 7 | public EfficientNode() { 8 | this.data = null; 9 | this.next = null; 10 | } 11 | 12 | public EfficientNode(T data) { 13 | this.data = data; 14 | this.next = null; 15 | } 16 | 17 | public T getData() { 18 | return this.data; 19 | } 20 | 21 | public void setData(T data) { 22 | this.data = data; 23 | } 24 | 25 | public EfficientNode getNext() { 26 | return this.next; 27 | } 28 | 29 | public void setNext(EfficientNode n) { 30 | this.next = n; 31 | } 32 | 33 | public boolean hasNext() { 34 | return !(this.next == null); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/util/trace/Trace.java: -------------------------------------------------------------------------------- 1 | package util.trace; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Comparator; 5 | import java.util.HashMap; 6 | import java.util.PriorityQueue; 7 | 8 | import event.Event; 9 | import event.Thread; 10 | /* 11 | import wcp.event.EventType; 12 | import wcp.thread.Thread; 13 | import wcp.variable.Variable; 14 | */ 15 | public class Trace { 16 | 17 | private ArrayList eventList; 18 | 19 | public Trace() { 20 | eventList = new ArrayList(); 21 | } 22 | 23 | public void addEvent(Event e) { 24 | eventList.add(e); 25 | } 26 | 27 | public ArrayList getEventList() { 28 | return eventList; 29 | } 30 | 31 | public int getSize(){ 32 | return eventList.size(); 33 | } 34 | 35 | public Event getEventAt(int index){ 36 | Event e = null; 37 | if(index < eventList.size()){ 38 | e = eventList.get(index); 39 | } 40 | return e; 41 | } 42 | 43 | public String toString() { 44 | return eventList.toString() + "\n"; 45 | } 46 | 47 | public String toPrettyString() { 48 | String str = "{\n"; 49 | for (int e_i = 0; e_i < eventList.size() - 1; e_i++) { 50 | Event e = eventList.get(e_i); 51 | str += Long.toString(e.getAuxId()) + "::" + e.toString(); 52 | str += ",\n"; 53 | } 54 | Event e = eventList.get(eventList.size() - 1); 55 | str += Long.toString(e.getAuxId()) + "::" + e.toString(); 56 | str += "\n}\n"; 57 | return str; 58 | } 59 | 60 | public void printPrototypeStyle(){ 61 | for (int e_i = 0; e_i < eventList.size(); e_i++) { 62 | Event e = eventList.get(e_i); 63 | System.out.println(e.toPrototypeString()); 64 | } 65 | } 66 | 67 | public static Trace mergeTraceList(ArrayList traceList) { 68 | 69 | Trace trace = new Trace(); 70 | if (traceList.size() > 0) { 71 | // PriorityQueue is a sorted queue 72 | PriorityQueue q = new PriorityQueue(traceList.size(), new Comparator() { 73 | public int compare(Event a, Event b) { 74 | if (a.getAuxId() > b.getAuxId()) 75 | return 1; 76 | else if (a.getAuxId() == b.getAuxId()) 77 | return 0; 78 | else 79 | return -1; 80 | } 81 | }); 82 | 83 | // The following container will map thread-names to indices in 84 | // traceList 85 | HashMap threadMap = new HashMap(); 86 | int num_threads = traceList.size(); 87 | int[] eventCounter = new int[num_threads]; // This is not 88 | // necessarily right. 89 | // The GID's were Long 90 | // add first node of each list to the queue 91 | for (int tr_i = 0; tr_i < traceList.size(); tr_i++) { 92 | Event e = traceList.get(tr_i).getEventList().get(0); 93 | q.add(e); 94 | eventCounter[tr_i] = 0; 95 | 96 | threadMap.put(e.getThread(), (Integer)tr_i); 97 | } 98 | 99 | while (q.size() > 0) { 100 | Event e = q.poll(); 101 | trace.addEvent(e); 102 | int tr_i = threadMap.get(e.getThread()); 103 | eventCounter[tr_i]++; 104 | // keep adding next element of each list 105 | if (eventCounter[tr_i] < traceList.get(tr_i).getEventList().size()) { 106 | q.add(traceList.get(tr_i).getEventList().get(eventCounter[tr_i])); 107 | } 108 | } 109 | } 110 | return trace; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/util/trace/TraceAndDataSets.java: -------------------------------------------------------------------------------- 1 | package util.trace; 2 | 3 | import java.util.HashSet; 4 | 5 | import event.Lock; 6 | import event.Thread; 7 | import event.Variable; 8 | 9 | public class TraceAndDataSets { 10 | 11 | private Trace trace; 12 | 13 | private HashSet threadSet; 14 | private HashSet lockSet; 15 | private HashSet variableSet; 16 | 17 | public TraceAndDataSets(Trace tr, HashSet tSet, HashSet lSet, HashSet vSet) { 18 | this.trace = tr; 19 | this.threadSet = tSet; 20 | this.lockSet = lSet; 21 | this.variableSet = vSet; 22 | } 23 | 24 | public Trace getTrace() { 25 | return this.trace; 26 | } 27 | 28 | public HashSet getThreadSet() { 29 | return this.threadSet; 30 | } 31 | 32 | public HashSet getLockSet() { 33 | return this.lockSet; 34 | } 35 | 36 | public HashSet getVariableSet() { 37 | return this.variableSet; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/util/vectorclock/AdaptiveVC.java: -------------------------------------------------------------------------------- 1 | package util.vectorclock; 2 | 3 | public abstract class AdaptiveVC { 4 | 5 | protected boolean is_epoch; 6 | protected Epoch epoch; 7 | protected VectorClock vc; 8 | 9 | public AdaptiveVC() { 10 | this.is_epoch = true; 11 | this.epoch = new Epoch(); 12 | this.vc = null; 13 | } 14 | 15 | // public AdaptiveVC(int dim) { 16 | // this.is_epoch = true; 17 | // this.epoch = new Epoch(); 18 | // this.vc = new VectorClock(dim); 19 | // } 20 | 21 | public Epoch getEpoch() { 22 | return this.epoch; 23 | } 24 | 25 | public VectorClock getVC(){ 26 | return this.vc; 27 | } 28 | 29 | public boolean isEpoch(){ 30 | return is_epoch; 31 | } 32 | 33 | public String toString() { 34 | if(is_epoch){ 35 | return this.epoch.toString(); 36 | } 37 | else{ 38 | return this.vc.toString(); 39 | } 40 | } 41 | 42 | public boolean isLessThanOrEqual(VectorClock vc) { 43 | if(is_epoch){ 44 | return this.epoch.getClock() <= vc.getClock().get(this.epoch.getThreadIndex()); 45 | } 46 | else{ 47 | return this.vc.isLessThanOrEqual(vc); 48 | } 49 | } 50 | 51 | //Returns true iff this.is_epoch and this.epoch.clock == vc[this.epoch.thread] 52 | public boolean isSameEpoch(int c, int t){ 53 | if(is_epoch){ 54 | return this.epoch.getClock() == c && this.epoch.getThreadIndex() == t; 55 | } 56 | else{ 57 | return false; 58 | } 59 | } 60 | 61 | public int getClockIndex(int tIndex){ 62 | if(this.is_epoch){ 63 | if(this.epoch.getThreadIndex() == tIndex){ 64 | return this.epoch.getClock(); 65 | } 66 | else return 0; 67 | } 68 | else return this.getVC().getClock().get(tIndex); 69 | } 70 | 71 | //Checks if this <= vc. If true, return true; else {this := this \join vc; return false} 72 | public abstract boolean isLTEUpdateWithMax(VectorClock vc, int t); 73 | 74 | public void setEpoch(int c, int t){ 75 | if(!this.is_epoch){ 76 | throw new IllegalArgumentException("setEpoch can only be invoked when the clock is an epoch"); 77 | } 78 | this.epoch.setClock(c); 79 | this.epoch.setThreadIndex(t); 80 | } 81 | 82 | public void setClockIndex(int tIndex, int tValue){ 83 | if(this.is_epoch){ 84 | throw new IllegalArgumentException("setClockIndex can only be invoked when the clock is a VC, not an epoch"); 85 | } 86 | this.vc.setClockIndex(tIndex, tValue); 87 | } 88 | 89 | public void forceBottomEpoch(){ 90 | this.is_epoch = true; 91 | this.epoch.setClock(0); 92 | this.epoch.setThreadIndex(0); 93 | } 94 | 95 | } -------------------------------------------------------------------------------- /src/util/vectorclock/ClockPair.java: -------------------------------------------------------------------------------- 1 | package util.vectorclock; 2 | 3 | public class ClockPair { 4 | 5 | private int dim; 6 | private VectorClock acquireClock; 7 | private VectorClock releaseClock; 8 | 9 | ClockPair(int dim) { 10 | this.dim = dim; 11 | this.acquireClock = new VectorClock(dim); 12 | this.releaseClock = new VectorClock(dim); 13 | } 14 | 15 | public ClockPair(VectorClock acquire) { 16 | this.dim = acquire.getDim(); 17 | this.acquireClock = new VectorClock(acquire); 18 | this.releaseClock = new VectorClock(dim); 19 | } 20 | 21 | ClockPair(VectorClock acquire, VectorClock release) { 22 | if (acquire.getDim() != release.getDim()) { 23 | throw new IllegalArgumentException("Dimensions of acquire and release clocks do not match"); 24 | } 25 | this.dim = acquire.getDim(); 26 | this.acquireClock = new VectorClock(acquire); 27 | this.releaseClock = new VectorClock(release); 28 | } 29 | 30 | public int getDim() { 31 | return this.dim; 32 | } 33 | 34 | public VectorClock getAcquire() { 35 | return this.acquireClock; 36 | } 37 | 38 | public VectorClock getRelease() { 39 | return this.releaseClock; 40 | } 41 | 42 | public void setAcquire(VectorClock acquire) { 43 | if (this.dim != acquire.getDim()) { 44 | throw new IllegalArgumentException( 45 | "Dimension of argument acquire does not match with initialized dimension"); 46 | } 47 | this.acquireClock.copyFrom(acquire); 48 | } 49 | 50 | public void setRelease(VectorClock release) { 51 | if (this.dim != release.getDim()) { 52 | throw new IllegalArgumentException( 53 | "Dimension of argument release does not match with initialized dimension"); 54 | } 55 | this.releaseClock.copyFrom(release); 56 | } 57 | 58 | public String toString(){ 59 | String str = "(" + this.acquireClock.toString() + " , " + this.releaseClock.toString() + ")"; 60 | return str; 61 | } 62 | } -------------------------------------------------------------------------------- /src/util/vectorclock/Epoch.java: -------------------------------------------------------------------------------- 1 | package util.vectorclock; 2 | 3 | public class Epoch { 4 | 5 | private int clock; 6 | private int threadIdx; 7 | 8 | public Epoch() { 9 | this.clock = 0; 10 | this.threadIdx = 0; 11 | } 12 | 13 | public Epoch(int c, int t) { 14 | this.clock = c; 15 | this.threadIdx = t; 16 | } 17 | 18 | public Epoch(Epoch fromEpoch) { 19 | this.clock = fromEpoch.clock; 20 | this.threadIdx = fromEpoch.threadIdx; 21 | } 22 | 23 | public int getClock() { 24 | return this.clock; 25 | } 26 | 27 | public int getThreadIndex(){ 28 | return this.threadIdx; 29 | } 30 | 31 | public void setClock(int c){ 32 | this.clock = c; 33 | } 34 | 35 | public void setThreadIndex(int t){ 36 | this.threadIdx = t; 37 | } 38 | 39 | public String toString() { 40 | return Integer.toString(this.clock) + "@" + Integer.toString(this.threadIdx) ; 41 | } 42 | 43 | public boolean isZero() { 44 | return this.clock == 0; 45 | } 46 | 47 | public boolean isEqual(Epoch epoch) { 48 | return (this.clock == epoch.clock) && (this.threadIdx == epoch.threadIdx); 49 | } 50 | 51 | public boolean isLessThanOrEqual(VectorClock vc) { 52 | return this.clock <= vc.getClock().get(this.threadIdx); 53 | } 54 | } -------------------------------------------------------------------------------- /src/util/vectorclock/FullAdaptiveVC.java: -------------------------------------------------------------------------------- 1 | package util.vectorclock; 2 | 3 | public class FullAdaptiveVC extends AdaptiveVC{ 4 | 5 | public FullAdaptiveVC() { 6 | super(); 7 | } 8 | 9 | // public FullAdaptiveVC(int dim) { 10 | // super(dim); 11 | // } 12 | 13 | @Override 14 | public boolean isLTEUpdateWithMax(VectorClock vc, int t){ 15 | boolean isLTE = isLessThanOrEqual(vc); 16 | if(isLTE){ 17 | this.is_epoch = true; 18 | this.vc = null; 19 | this.epoch.setClock(vc.getClockIndex(t)); 20 | this.epoch.setThreadIndex(t); 21 | } 22 | else{ 23 | if(is_epoch){ 24 | is_epoch = false; 25 | this.vc = new VectorClock(vc.getDim()); 26 | this.vc.setClockIndex(this.epoch.getThreadIndex(), this.epoch.getClock()); 27 | } 28 | this.vc.setClockIndex(t, vc.getClockIndex(t)); 29 | } 30 | return isLTE; 31 | } 32 | } -------------------------------------------------------------------------------- /src/util/vectorclock/SemiAdaptiveVC.java: -------------------------------------------------------------------------------- 1 | package util.vectorclock; 2 | 3 | public class SemiAdaptiveVC extends AdaptiveVC{ 4 | 5 | public SemiAdaptiveVC() { 6 | super(); 7 | } 8 | 9 | // public SemiAdaptiveVC(int dim) { 10 | // super(dim); 11 | // } 12 | 13 | @Override 14 | public boolean isLTEUpdateWithMax(VectorClock vc, int t){ 15 | boolean isLTE = isLessThanOrEqual(vc); 16 | if(is_epoch){ 17 | if(isLTE){ 18 | this.epoch.setClock(vc.getClockIndex(t)); 19 | this.epoch.setThreadIndex(t); 20 | } 21 | else{ 22 | is_epoch = false; 23 | this.vc = new VectorClock(vc.getDim()); 24 | this.vc.setClockIndex(this.epoch.getThreadIndex(), this.epoch.getClock()); 25 | this.vc.setClockIndex(t, vc.getClockIndex(t)); 26 | } 27 | } 28 | else{ 29 | this.vc.setClockIndex(t, vc.getClockIndex(t)); 30 | } 31 | return isLTE; 32 | } 33 | 34 | public void updateWithMax(VectorClock vc, int t){ 35 | boolean isLTE = isLessThanOrEqual(vc); 36 | if(is_epoch){ 37 | if(isLTE){ 38 | this.epoch.setClock(vc.getClockIndex(t)); 39 | this.epoch.setThreadIndex(t); 40 | } 41 | else{ 42 | is_epoch = false; 43 | this.vc = new VectorClock(vc.getDim()); 44 | this.vc.setClockIndex(this.epoch.getThreadIndex(), this.epoch.getClock()); 45 | this.vc.setClockIndex(t, vc.getClockIndex(t)); 46 | } 47 | } 48 | else{ 49 | this.vc.setClockIndex(t, vc.getClockIndex(t)); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/util/vectorclock/VectorClockOpt.java: -------------------------------------------------------------------------------- 1 | package util.vectorclock; 2 | 3 | import java.util.Vector; 4 | 5 | public class VectorClockOpt { 6 | 7 | private int dim; 8 | private Vector clock; 9 | 10 | public VectorClockOpt(int d) { 11 | this.dim = d; 12 | this.clock = new Vector(dim); 13 | for (int ind = 0; ind < this.dim; ind++) { 14 | this.clock.addElement(0); 15 | } 16 | } 17 | 18 | public VectorClockOpt(VectorClockOpt fromVectorClock) { 19 | this.dim = fromVectorClock.getDim(); 20 | this.clock = new Vector(dim); 21 | Vector fromClock = fromVectorClock.getClock(); 22 | for (int ind = 0; ind < fromVectorClock.getDim(); ind++) { 23 | this.clock.addElement((Integer) fromClock.get(ind)); 24 | } 25 | } 26 | 27 | public int getDim() { 28 | return this.dim; 29 | } 30 | 31 | public Vector getClock() { 32 | return this.clock; 33 | } 34 | 35 | public String toString() { 36 | return this.clock.toString(); 37 | } 38 | 39 | public boolean isZero() { 40 | boolean itIsZero = true; 41 | for (int ind = 0; ind < this.dim; ind++) { 42 | int thisVal = this.clock.get(ind).intValue(); 43 | if (thisVal != 0) { 44 | itIsZero = false; 45 | break; 46 | } 47 | } 48 | return itIsZero; 49 | } 50 | 51 | public boolean isEqual(VectorClockOpt vc) { 52 | boolean itIsEqual = true; 53 | Vector vcClock = vc.getClock(); 54 | for (int ind = 0; ind < this.dim; ind++) { 55 | int thisVal = this.clock.get(ind).intValue(); 56 | int vcVal = vcClock.get(ind).intValue(); 57 | // System.out.println("Comparing: " + thisVal + " | " + vcVal); 58 | if (thisVal != vcVal) { 59 | itIsEqual = false; 60 | break; 61 | } 62 | } 63 | return itIsEqual; 64 | } 65 | 66 | public boolean isLessThan(VectorClockOpt vc) { 67 | boolean OneComponentIsLess = false; 68 | boolean isLessThanOrEqual = true; 69 | Vector vcClock = vc.getClock(); 70 | for (int ind = 0; ind < this.dim; ind++) { 71 | int thisVal = this.clock.get(ind).intValue(); 72 | int vcVal = vcClock.get(ind).intValue(); 73 | if (thisVal > vcVal) { 74 | isLessThanOrEqual = false; 75 | break; 76 | } 77 | else if(thisVal < vcVal) { 78 | OneComponentIsLess = true; 79 | } 80 | } 81 | return OneComponentIsLess && isLessThanOrEqual; 82 | } 83 | 84 | public boolean isLessThanOrEqual(VectorClockOpt vc) { 85 | boolean itIsLessThanOrEqual = true; 86 | Vector vcClock = vc.getClock(); 87 | for (int ind = 0; ind < this.dim; ind++) { 88 | int thisVal = this.clock.get(ind).intValue(); 89 | int vcVal = vcClock.get(ind).intValue(); 90 | if (!(thisVal <= vcVal)) { 91 | itIsLessThanOrEqual = false; 92 | break; 93 | } 94 | } 95 | return itIsLessThanOrEqual; 96 | } 97 | 98 | public boolean isLessThanOrEqual(VectorClockOpt vc, int ind) { 99 | return this.clock.get(ind).intValue() <= vc.getClock().get(ind).intValue(); 100 | } 101 | 102 | public void setToZero() { 103 | for (int ind = 0; ind < this.dim; ind++) { 104 | this.clock.set(ind, (Integer) 0 ); 105 | } 106 | } 107 | 108 | public void copyFrom(VectorClockOpt vc) { 109 | for (int ind = 0; ind < this.dim; ind++) { 110 | this.clock.set(ind, (Integer) vc.clock.get(ind)); 111 | } 112 | } 113 | 114 | private void updateMax2(VectorClockOpt vc) { 115 | for (int ind = 0; ind < this.dim; ind++) { 116 | int this_c = this.clock.get(ind); 117 | int vc_c = vc.clock.get(ind); 118 | int max_c = this_c > vc_c ? this_c : vc_c; 119 | this.clock.set(ind, (Integer) max_c); 120 | } 121 | } 122 | 123 | //The following function update this as : this := \lambda t . if t == tIndex then this[tIndex] else max(this[t], vc[t]) 124 | public void updateMax2WithoutLocal(VectorClockOpt vc, int tIndex) { 125 | for (int ind = 0; ind < this.dim; ind++) { 126 | if(ind != tIndex){ 127 | int this_c = this.clock.get(ind); 128 | int vc_c = vc.clock.get(ind); 129 | int max_c = this_c > vc_c ? this_c : vc_c; 130 | this.clock.set(ind, (Integer) max_c); 131 | } 132 | } 133 | } 134 | 135 | public void updateWithMax(VectorClockOpt... vcList) { 136 | this.copyFrom(vcList[0]); 137 | for (int i = 1; i < vcList.length; i++) { 138 | VectorClockOpt vc = vcList[i]; 139 | this.updateMax2(vc); 140 | } 141 | } 142 | 143 | private void updateMin2(VectorClockOpt vc) { 144 | for (int ind = 0; ind < this.dim; ind++) { 145 | int this_c = this.clock.get(ind); 146 | int vc_c = vc.clock.get(ind); 147 | int max_c = this_c < vc_c ? this_c : vc_c; 148 | this.clock.set(ind, (Integer) max_c); 149 | } 150 | } 151 | 152 | public void updateWithMin(VectorClockOpt... vcList) { 153 | this.copyFrom(vcList[0]); 154 | for (int i = 1; i < vcList.length; i++) { 155 | VectorClockOpt vc = vcList[i]; 156 | this.updateMin2(vc); 157 | } 158 | } 159 | 160 | public int getClockIndex(int tIndex){ 161 | return this.clock.get(tIndex); 162 | } 163 | 164 | public void setClockIndex(int tIndex, int tValue){ 165 | this.clock.set(tIndex, (Integer) tValue); 166 | } 167 | 168 | } --------------------------------------------------------------------------------