Commit 7d36e247 authored by Johannes Roith's avatar Johannes Roith

- Removed monitors from Model, since we only call it from UI thread.

  Added a debugging check to enforce this requirement.
- Added controller statistics.
parent 916b80f1
......@@ -8,22 +8,28 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.ui.progress.UIJob;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.model.Model;
class CallbackJob extends UIJob {
private CupTextEditor editor = null;
private List<JobStatus>jobStatusList;
public CallbackJob(CupTextEditor editor, List<JobStatus>jobStatusList) {
private ControllerStatistics controllerStats;
public CallbackJob(CupTextEditor editor, List<JobStatus>jobStatusList, ControllerStatistics controllerStats) {
super("" + editor.hashCode());
this.editor = editor;
this.jobStatusList = jobStatusList;
this.controllerStats = controllerStats;
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
for(JobStatus status:jobStatusList) {
for(JobStatus status:jobStatusList)
Controller.getInstance(editor).notifyObserversOfJobStatus(status);
}
Model model = Model.getInstanceForDocument(editor.getDocument());
model.setControllerStatistics(controllerStats);
Controller.getInstance(editor).notifyChangeJobFinished();
return Status.OK_STATUS;
}
......
package de.tum.in.www2.cupplugin.controller;
/**
*
*/
public class ControllerStatistics {
private long parserRuns;
private long parserRunFailures;
private long lastParserRunNanos;
private long lastParserRunDate;
private long lalrRuns;
private long lalrRunFailures;
private long lastLALRRunNanos;
private long lastLALRRunDate;
public void addParserRun(long nanos) {
parserRuns++;
lastParserRunNanos = nanos;
}
public void addTableRun(long nanos) {
lalrRuns++;
lastParserRunNanos = nanos;
}
}
......@@ -2,6 +2,8 @@ package de.tum.in.www2.cupplugin.controller;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
......@@ -36,13 +38,17 @@ public class DocumentDidChangeJob extends Job {
private CupContext context;
private LALRResult lalrResult;
private List<JobStatus> jobStatusList;
private ThreadMXBean tmxb;
private ControllerStatistics controllerStats;
public long revNumber;
public DocumentDidChangeJob(CupTextEditor editor) {
super("" + editor.hashCode());
this.editor = editor;
jobStatusList = new ArrayList<JobStatus>();
this.jobStatusList = new ArrayList<JobStatus>();
this.tmxb = ManagementFactory.getThreadMXBean();
this.controllerStats = new ControllerStatistics();
}
public boolean running() {
......@@ -73,6 +79,9 @@ public class DocumentDidChangeJob extends Job {
if (editor == null || editor.getDocument() == null)
return Status.CANCEL_STATUS;
long parseTimeNano = -1;
long tableTimeNano = -1;
IFile file = ((FileEditorInput) editor.getEditorInput()).getFile();
CupEditorErrorReporter errorReporter = new CupEditorErrorReporter(file);
errorReporter.resetOnNextPush();
......@@ -85,7 +94,9 @@ public class DocumentDidChangeJob extends Job {
parser = new CupParser(errorReporter, in);
result = null;
try {
long before = tmxb.getCurrentThreadCpuTime();
result = parser.parse();
parseTimeNano = tmxb.getCurrentThreadCpuTime() - before;
} catch (Exception e1) {
e1.printStackTrace();
}
......@@ -122,8 +133,11 @@ public class DocumentDidChangeJob extends Job {
lalrResult = null;
try {
if (parser != null && !parser.hasParseErrors())
if (parser != null && !parser.hasParseErrors()) {
long before = tmxb.getCurrentThreadCpuTime();
lalrResult = LALRResult.Compute(context, context.start_production);
tableTimeNano = tmxb.getCurrentThreadCpuTime() - before;
}
else
hasParserErrors = true;
} catch (internal_error e) {
......@@ -166,8 +180,13 @@ public class DocumentDidChangeJob extends Job {
documentEvents.clear();
jobs.clear();
if (parseTimeNano != -1)
controllerStats.addParserRun(parseTimeNano);
if (tableTimeNano != -1)
controllerStats.addTableRun(tableTimeNano);
currentlyRunning = false;
CallbackJob cb = new CallbackJob(editor, jobStatusList);
CallbackJob cb = new CallbackJob(editor, jobStatusList, controllerStats);
cb.setSystem(true);
cb.schedule();
return Status.OK_STATUS;
......
......@@ -5,11 +5,13 @@ import java.util.List;
import java.util.WeakHashMap;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.widgets.Display;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.LALRResult;
import de.in.tum.www2.cup.Statistics;
import de.in.tum.www2.cup.ast.ParserResult;
import de.tum.in.www2.cupplugin.controller.ControllerStatistics;
public class Model {
......@@ -24,10 +26,9 @@ public class Model {
private CupContext lalrContext;
private Statistics statistics;
private ControllerStatistics controllerStats;
private final Object statisticsLock = new Object();
private final Object parserModelLock = new Object(); // TODO: this is also used for the modelObservers?
private final Object lalrModellock = new Object();
private final Object observerLock = new Object();
private List<Object> modelObservers;
public static void deleteForDocument(IDocument document) {
......@@ -43,7 +44,7 @@ public class Model {
}
public void dispose() {
synchronized (parserModelLock) {
synchronized (observerLock) {
if (modelObservers != null)
modelObservers.clear();
}
......@@ -70,7 +71,7 @@ public class Model {
public void registerModelObserver(Object modelObserver) {
if (modelObserver == null)
return;
synchronized (parserModelLock) {
synchronized (observerLock) {
if (this.modelObservers.contains(modelObserver))
return;
this.modelObservers.add(modelObserver);
......@@ -80,7 +81,7 @@ public class Model {
public boolean unregisterModelObserver(Object modelObserver) {
if (modelObserver == null)
return false;
synchronized (parserModelLock) {
synchronized (observerLock) {
if (this.modelObservers.contains(modelObserver)) {
this.modelObservers.remove(modelObserver);
return true;
......@@ -88,92 +89,92 @@ public class Model {
return false;
}
}
private void ensureUIThread() {
if (Thread.currentThread() != Display.getCurrent().getThread())
throw new RuntimeException("The model can only be modified or read from the UI thread.");
}
public ParserResult getAstModel() {
synchronized(parserModelLock) {
return astModel;
}
ensureUIThread();
return astModel;
}
public Statistics getStatistics() {
synchronized(statisticsLock) {
return statistics;
}
ensureUIThread();
return statistics;
}
public void setStatistics(Statistics statistics, long revisionNumber) {
synchronized(statisticsLock) {
this.statistics = statistics;
for(Object observer : modelObservers) {
if(observer instanceof ICupStatisticsChangeObserver) {
((ICupStatisticsChangeObserver) observer).modelChanged(this);
}
}
}
ensureUIThread();
this.statistics = statistics;
for(Object observer : modelObservers)
if(observer instanceof ICupStatisticsChangeObserver)
((ICupStatisticsChangeObserver) observer).modelChanged(this);
}
public void setControllerStatistics(ControllerStatistics stats) {
ensureUIThread();
this.controllerStats = stats;
}
public ControllerStatistics getControllerStatistics() {
ensureUIThread();
return this.controllerStats;
}
public void setASTModel(ParserResult result, CupContext context, long revisionNumber) {
synchronized (parserModelLock) {
this.astModel = result;
this.astContext = context;
this.astModelRevisionNumber = revisionNumber;
for(Object observer : modelObservers) {
if(observer instanceof ICupParserASTChangeObserver) {
((ICupParserASTChangeObserver) observer).modelChanged(this);
}
}
}
ensureUIThread();
this.astModel = result;
this.astContext = context;
this.astModelRevisionNumber = revisionNumber;
for(Object observer : modelObservers)
if(observer instanceof ICupParserASTChangeObserver)
((ICupParserASTChangeObserver) observer).modelChanged(this);
}
public void setAstModelRevisionNumber(long revisionNumber) {
synchronized(parserModelLock) {
this.astModelRevisionNumber = revisionNumber;
}
ensureUIThread();
this.astModelRevisionNumber = revisionNumber;
}
public long getAstModelRevisionNumber() {
ensureUIThread();
return this.astModelRevisionNumber;
}
public LALRResult getLaLrResult() {
synchronized (lalrModellock) {
return this.lalrModel;
}
ensureUIThread();
return this.lalrModel;
}
public CupContext getAstModelContext() {
synchronized (parserModelLock) {
return this.astContext;
}
ensureUIThread();
return this.astContext;
}
public void setLaLrResultModel(LALRResult result, long revisionNumber, CupContext lalrContext) {
synchronized (lalrModellock) {
this.lalrModel = result;
this.lalrModelRevisionNumber = revisionNumber;
this.lalrContext = lalrContext;
for(Object observer : modelObservers) {
if (observer instanceof ICupParserLaLrChangeObserver) {
((ICupParserLaLrChangeObserver) observer).modelChanged(this);
}
}
//System.out.println(lalrModel.getReduceTable().toString());
}
ensureUIThread();
this.lalrModel = result;
this.lalrModelRevisionNumber = revisionNumber;
this.lalrContext = lalrContext;
for(Object observer : modelObservers)
if (observer instanceof ICupParserLaLrChangeObserver)
((ICupParserLaLrChangeObserver) observer).modelChanged(this);
}
public CupContext getLaLrContext() {
synchronized (lalrModellock) {
return this.lalrContext;
}
ensureUIThread();
return this.lalrContext;
}
public void setLaLrModelRevisionNumber(long revisionNumber) {
synchronized (lalrModellock) {
this.lalrModelRevisionNumber = revisionNumber;
}
ensureUIThread();
this.lalrModelRevisionNumber = revisionNumber;
}
public long getLaLrRevisionNumber() {
ensureUIThread();
return this.lalrModelRevisionNumber;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment