]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/BarrierTracing.java
Add possibility to bookkeep barrier tracing with env var
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / graph / BarrierTracing.java
1 package org.simantics.db.impl.graph;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import org.simantics.db.impl.BlockingAsyncProcedure;
9 import org.simantics.db.impl.query.CacheEntry;
10 import org.simantics.db.impl.query.QueryProcessor.SessionTask;
11
12 public class BarrierTracing {
13
14     private static final String KEY = "SIMANTICS_DB_IMPL_BARRIER_TRACING";
15
16     public static final boolean BOOKKEEPING = Boolean.parseBoolean(
17             System.getProperty("org.simantics.db.impl.barrierTracing",
18             System.getenv(KEY) != null ? System.getenv(KEY) : "false")
19         );
20     static final boolean RESTART_GUARD = BOOKKEEPING && false;
21
22     public static Map<SessionTask,Exception> tasks = new HashMap<>();
23     public static final HashMap<AsyncBarrierImpl, Collection<AsyncBarrierImpl>> reverseLookup = new HashMap<>();
24     public static final HashMap<AsyncBarrierImpl, Debugger> debuggerMap = new HashMap<>();
25     public static final HashMap<AsyncBarrierImpl, CacheEntry<?>> entryMap = new HashMap<>();
26     public static final HashMap<AsyncBarrierImpl, Throwable> restartMap = new HashMap<>();
27     public static final HashMap<AsyncBarrierImpl, Throwable> startMap = new HashMap<>();
28     public static final HashMap<BlockingAsyncProcedure, Throwable> baps = new HashMap<>();
29
30     synchronized public static void registerBAP(BlockingAsyncProcedure bap) {
31         baps.put(bap, new Exception());
32     }
33     
34     synchronized public static void unregisterBAP(BlockingAsyncProcedure bap) {
35         baps.remove(bap);
36     }
37
38     synchronized public static void printBAPS() {
39         for(BlockingAsyncProcedure bap : baps.keySet()) {
40             bap.print();
41             Throwable t = baps.get(bap);
42             if(t != null)
43                 t.printStackTrace();
44         }
45     }
46     
47     public static void trace(AsyncBarrierImpl barrier, CacheEntry<?> entry) {
48
49         if (RESTART_GUARD) {
50             synchronized (startMap) {
51                 startMap.put(barrier, new Exception());
52             }
53         }
54         synchronized (entryMap) {
55             entryMap.put(barrier, entry);
56         }
57         synchronized (debuggerMap) {
58             debuggerMap.put(barrier, new Debugger());
59         }
60         synchronized (reverseLookup) {
61             Collection<AsyncBarrierImpl> barriers = reverseLookup
62                     .get(barrier.caller);
63             if (barriers == null) {
64                 barriers = new ArrayList<AsyncBarrierImpl>();
65                 reverseLookup.put(barrier.caller, barriers);
66             }
67             barriers.add(barrier);
68         }
69
70     }
71
72     public static void inc(AsyncBarrierImpl barrier) {
73
74         barrier.inc(barrier, new Exception().getStackTrace()[2].toString());
75
76         if (RESTART_GUARD)
77             if(restartMap.containsKey(barrier)) {
78                 startMap.get(barrier).printStackTrace();
79                 restartMap.get(barrier).printStackTrace();
80                 new Exception().printStackTrace();
81                 throw new IllegalStateException("Unplanned restart");
82             }
83
84
85     }
86
87     public static void restart(AsyncBarrierImpl barrier) {
88         if (RESTART_GUARD)
89             BarrierTracing.restartMap.remove(barrier);
90         if (BOOKKEEPING)
91             BarrierTracing.debuggerMap.put(barrier, new Debugger());
92     }
93
94     public static void dec(AsyncBarrierImpl barrier, int count) {
95         if (count == 0) {
96             if (RESTART_GUARD) {
97                 restartMap.put(barrier, new Exception());
98             }
99             debuggerMap.remove(barrier);
100         }
101         else if (count < 0) {
102             BarrierTracing.startMap.get(barrier).printStackTrace();
103             BarrierTracing.restartMap.get(barrier).printStackTrace();
104             new Exception().printStackTrace();
105         }
106     }
107
108     public static class Debugger {
109
110         public Map<AsyncBarrierImpl, String> infos = new HashMap<>();
111
112         public synchronized void inc(AsyncBarrierImpl id, String info) {
113             if (id == null)
114                 return;
115             String exist = infos.get(id);
116             if (exist != null)
117                 throw new IllegalStateException("Already existing info " + id + " " + info);
118             infos.put(id, exist);
119         }
120
121         public synchronized void dec(AsyncBarrierImpl id) {
122             if (id == null)
123                 return;
124             String exist = infos.get(id);
125             if (exist == null) {
126                 System.err.println("No data for " + id);
127             } else {
128                 infos.remove(id);
129             }
130         }
131
132         @Override
133         public synchronized String toString() {
134             StringBuilder b = new StringBuilder();
135             for (String s : infos.values()) {
136                 b.append("info " + s + "\r\n");
137             }
138             return b.toString();
139         }
140
141         public boolean isEmpty() {
142             return infos.isEmpty();
143         }
144
145     }
146
147 }