2026-03-17 13:31:18 -07:00

564 lines
21 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* javax.baja.nre.util.SortUtil
*/
package com.tridium.sys.engine;
import com.tridium.sys.Nre;
import com.tridium.sys.engine.ActionQueue;
import com.tridium.sys.engine.EngineUtil;
import com.tridium.sys.engine.NClockTicket;
import com.tridium.sys.engine.TicketQueue;
import com.tridium.sys.resource.ResourceReport;
import java.text.DecimalFormat;
import java.util.Iterator;
import javax.baja.log.Log;
import javax.baja.nre.util.SortUtil;
import javax.baja.spy.Spy;
import javax.baja.spy.SpyDir;
import javax.baja.spy.SpyWriter;
import javax.baja.sys.Action;
import javax.baja.sys.BAbsTime;
import javax.baja.sys.BComponent;
import javax.baja.sys.BLink;
import javax.baja.sys.BObject;
import javax.baja.sys.BRelTime;
import javax.baja.sys.BStation;
import javax.baja.sys.BValue;
import javax.baja.sys.Clock;
import javax.baja.sys.Flags;
import javax.baja.sys.NotRunningException;
import javax.baja.sys.SlotCursor;
import javax.baja.sys.Sys;
/*
* Illegal identifiers - consider using --renameillegalidents true
*/
public class EngineManager {
static DecimalFormat timeFormat = new DecimalFormat("#.000 ms");
public static final Log log = Log.getLog("sys.engine");
public static long engineSleepPeriod = 20L;
private static final int SYSTEM_CLOCK_CHANGE_TOLERANCE = 1000;
public static long shortTimerThreshold = 2100L;
public static long mediumTimerThreshold = 61000L;
private long startTicks;
private volatile int scanCount;
private int ticketScanCount;
private long totalTicksInsideScan;
private long lastTotalTicksInsideScan;
private long deltaTicksInsideScan;
private long peakTicksInsideScan;
private boolean suspended;
private ActionQueue actionQueue;
private BComponent currentComponent;
private Action currentAction;
private long lastMillisVsTicksDelta;
public TicketQueue shortTimers;
public TicketQueue mediumTimers;
public TicketQueue longTimers;
public void start(BComponent bComponent) {
if (!bComponent.isRunning()) {
throw new IllegalStateException();
}
this.activateLinks(bComponent);
EngineUtil.started(bComponent);
SlotCursor slotCursor = bComponent.getProperties();
while (slotCursor.nextComponent()) {
if (Flags.isNoRun(bComponent, slotCursor.property())) continue;
slotCursor.get().asComponent().start();
}
EngineUtil.descendantsStarted(bComponent);
}
private final void activateLinks(BComponent bComponent) {
SlotCursor slotCursor = bComponent.getProperties();
while (slotCursor.nextObject()) {
BObject bObject = slotCursor.get();
if (!(bObject instanceof BLink)) continue;
EngineUtil.activate((BLink)bObject);
}
}
public void stop(BComponent bComponent) {
if (bComponent.isRunning()) {
throw new IllegalStateException();
}
this.deactivateLinks(bComponent);
EngineUtil.stopped(bComponent);
SlotCursor slotCursor = bComponent.getProperties();
while (slotCursor.nextComponent()) {
slotCursor.get().asComponent().stop();
}
EngineUtil.descendantsStopped(bComponent);
}
private final void deactivateLinks(BComponent bComponent) {
SlotCursor slotCursor = bComponent.getProperties();
while (slotCursor.nextObject()) {
BObject bObject = slotCursor.get();
if (!(bObject instanceof BLink)) continue;
EngineUtil.deactivate((BLink)bObject);
}
}
public void stationStarted(BComponent bComponent) {
EngineUtil.stationStarted(bComponent);
SlotCursor slotCursor = bComponent.getProperties();
while (slotCursor.nextComponent()) {
this.stationStarted(slotCursor.get().asComponent());
}
}
public void atSteadyState(BComponent bComponent) {
if (!bComponent.isRunning()) {
log.warning("Not running: " + bComponent);
return;
}
EngineUtil.atSteadyState(bComponent);
SlotCursor slotCursor = bComponent.getProperties();
while (slotCursor.nextComponent()) {
this.atSteadyState(slotCursor.get().asComponent());
}
}
void execute() {
long l = Clock.ticks();
this.checkIfSystemClockChanged();
this.shortTimers.check();
this.mediumTimers.check();
this.longTimers.check();
this.checkAsyncActions();
long l2 = Clock.ticks();
long l3 = l2 - l;
if (l3 > this.peakTicksInsideScan) {
this.peakTicksInsideScan = l3;
}
this.totalTicksInsideScan += l3;
++this.scanCount;
if (this.scanCount % 10 == 0) {
this.deltaTicksInsideScan = this.totalTicksInsideScan - this.lastTotalTicksInsideScan;
this.lastTotalTicksInsideScan = this.totalTicksInsideScan;
}
}
private final void checkIfSystemClockChanged() {
long l = this.getSystemClockWarp();
if (l != 0L) {
log.warning("System clock modified: " + l + "ms");
this.clockChanged(Sys.getStation(), BRelTime.make(l));
}
}
private final long getMillisVsTicksDelta() {
long l = Clock.ticks();
long l2 = Clock.millis();
long l3 = Clock.ticks();
if (l3 - l > 1000L) {
return 0L;
}
long l4 = l3 - l2;
return l4 >= 0L ? l4 : -l4;
}
private final long getSystemClockWarp() {
long l = this.getMillisVsTicksDelta();
if (l == 0L) {
return 0L;
}
long l2 = l - this.lastMillisVsTicksDelta;
if (Math.abs(l2) < 1000L) {
return 0L;
}
this.lastMillisVsTicksDelta = l;
return l2;
}
public void clockChanged(BComponent bComponent, BRelTime bRelTime) {
try {
if (bComponent == null) {
return;
}
EngineUtil.clockChanged(bComponent, bRelTime);
SlotCursor slotCursor = bComponent.getProperties();
while (slotCursor.nextComponent()) {
this.clockChanged(slotCursor.get().asComponent(), bRelTime);
}
}
catch (Throwable throwable) {
throwable.printStackTrace();
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public void enqueueAction(BComponent bComponent, Action action, BValue bValue) {
ActionQueue actionQueue = this.actionQueue;
synchronized (actionQueue) {
if (bComponent == this.currentComponent && action == this.currentAction) {
return;
}
this.actionQueue.enqueue(bComponent, action, bValue);
return;
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Unable to fully structure code
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
void checkAsyncActions() {
var1_1 = null;
var2_2 = this.actionQueue;
synchronized (var2_2) {
var1_1 = this.actionQueue.reset();
// MONITOREXIT @DISABLED, blocks:[0, 1] lbl6 : MonitorExitStatement: MONITOREXIT : var2_2
if (true) ** GOTO lbl17
}
do {
this.currentComponent = var1_1.component;
this.currentAction = var1_1.action;
EngineUtil.doInvoke(var1_1.component, var1_1.action, var1_1.arg, null);
var4_3 = var1_1;
var1_1 = var1_1.next;
var4_3.next = null;
lbl17:
// 2 sources
} while (var1_1 != null);
this.currentComponent = null;
this.currentAction = null;
}
public NClockTicket schedule(BComponent bComponent, BRelTime bRelTime, Action action, BValue bValue) {
if (!bComponent.isRunning()) {
throw new NotRunningException();
}
if (action == null) {
throw new NullPointerException("Null action");
}
long l = bRelTime.getMillis();
if (l <= 0L) {
throw new IllegalArgumentException("time <= 0");
}
NClockTicket nClockTicket = new NClockTicket(bComponent, action, bValue);
nClockTicket.nextUpdate = -(Clock.ticks() + l);
nClockTicket.period = 0L;
this.enqueueTicket(nClockTicket);
return nClockTicket;
}
public NClockTicket schedule(BComponent bComponent, BAbsTime bAbsTime, Action action, BValue bValue) {
if (!bComponent.isRunning()) {
throw new NotRunningException();
}
if (action == null) {
throw new NullPointerException("Null action");
}
long l = bAbsTime.getMillis();
if (l <= 0L) {
throw new IllegalArgumentException("time <= 0");
}
NClockTicket nClockTicket = new NClockTicket(bComponent, action, bValue);
nClockTicket.nextUpdate = l;
nClockTicket.period = 0L;
this.enqueueTicket(nClockTicket);
return nClockTicket;
}
public NClockTicket schedulePeriodically(BComponent bComponent, BRelTime bRelTime, Action action, BValue bValue) {
if (!bComponent.isRunning()) {
throw new NotRunningException();
}
if (action == null) {
throw new NullPointerException("Null action");
}
long l = bRelTime.getMillis();
if (l <= 0L) {
throw new IllegalArgumentException("period <= 0");
}
NClockTicket nClockTicket = new NClockTicket(bComponent, action, bValue);
nClockTicket.nextUpdate = -(Clock.ticks() + l);
nClockTicket.period = l;
this.enqueueTicket(nClockTicket);
return nClockTicket;
}
public NClockTicket schedulePeriodically(BComponent bComponent, BAbsTime bAbsTime, BRelTime bRelTime, Action action, BValue bValue) {
if (!bComponent.isRunning()) {
throw new NotRunningException();
}
if (action == null) {
throw new NullPointerException("Null action");
}
long l = bAbsTime.getMillis();
long l2 = bRelTime.getMillis();
if (l <= 0L) {
throw new IllegalArgumentException("start <= 0");
}
if (l2 <= 0L) {
throw new IllegalArgumentException("period <= 0");
}
NClockTicket nClockTicket = new NClockTicket(bComponent, action, bValue);
nClockTicket.nextUpdate = l;
nClockTicket.period = l2;
this.enqueueTicket(nClockTicket);
return nClockTicket;
}
void enqueueTicket(NClockTicket nClockTicket) {
long l = nClockTicket.period;
if (l <= 0L) {
l = nClockTicket.millisLeft();
}
if (l < shortTimerThreshold) {
this.shortTimers.enqueue(nClockTicket);
} else if (l < mediumTimerThreshold) {
this.mediumTimers.enqueue(nClockTicket);
} else {
this.longTimers.enqueue(nClockTicket);
}
}
public void reportResources(ResourceReport resourceReport) {
double d = (double)this.totalTicksInsideScan / (double)this.scanCount;
double d2 = (double)this.deltaTicksInsideScan / 10.0;
double d3 = Clock.ticks() - this.startTicks;
double d4 = (double)this.totalTicksInsideScan / d3 * 100.0;
resourceReport.put("engine.scan.lifetime", timeFormat.format(d));
resourceReport.put("engine.scan.peak", timeFormat.format(this.peakTicksInsideScan));
resourceReport.put("engine.scan.recent", timeFormat.format(d2));
resourceReport.put("engine.scan.usage", "" + (int)d4 + '%');
resourceReport.put("engine.queue.shortTimers", this.shortTimers.size + " (Peak " + this.shortTimers.peak + ')');
resourceReport.put("engine.queue.mediumTimers", this.mediumTimers.size + " (Peak " + this.mediumTimers.peak + ')');
resourceReport.put("engine.queue.longTimers", this.longTimers.size + " (Peak " + this.longTimers.peak + ')');
resourceReport.put("engine.queue.actions", this.actionQueue.size() + " (Peak " + this.actionQueue.peak() + ')');
}
public void postInit() {
SummaryPage summaryPage = new SummaryPage();
Nre.spySysManagers.add("engineManager", summaryPage);
summaryPage.add("shortTimers", new TicketQueuePage(this.shortTimers));
summaryPage.add("mediumTimers", new TicketQueuePage(this.mediumTimers));
summaryPage.add("longTimers", new TicketQueuePage(this.longTimers));
summaryPage.add("asyncQueue", new AsyncQueuePage());
summaryPage.add("hogs", new HogsPage());
}
static String timeStr(long l) {
return l + "ms [" + BRelTime.toString(l) + ']';
}
public void suspend() {
this.suspended = true;
}
public void resume() {
this.suspended = false;
}
public int getCycles() {
return this.scanCount;
}
public long getTotalTicksInsideCycle() {
return this.totalTicksInsideScan;
}
public float getAvgerageTicks() {
double d = (double)this.deltaTicksInsideScan / 10.0;
return (float)d;
}
private final /* synthetic */ void this() {
this.lastTotalTicksInsideScan = 0L;
this.deltaTicksInsideScan = 0L;
this.peakTicksInsideScan = 0L;
this.suspended = false;
this.actionQueue = new ActionQueue();
this.shortTimers = new TicketQueue(100, 1000);
this.mediumTimers = new TicketQueue(1000, 10000);
this.longTimers = new TicketQueue(1000, 30000);
}
public EngineManager() {
this.this();
this.startTicks = Clock.ticks();
this.lastMillisVsTicksDelta = this.getMillisVsTicksDelta();
new EngineThread().start();
}
/*
* Illegal identifiers - consider using --renameillegalidents true
*/
public class SummaryPage
extends SpyDir {
public void write(SpyWriter spyWriter) throws Exception {
double d = (double)EngineManager.this.totalTicksInsideScan / (double)EngineManager.this.scanCount;
double d2 = (double)EngineManager.this.deltaTicksInsideScan / 10.0;
BComponent bComponent = EngineManager.this.currentComponent;
Action action = EngineManager.this.currentAction;
spyWriter.startProps();
spyWriter.prop((Object)"atSteadyState", Sys.atSteadyState());
spyWriter.prop((Object)"suspended", "" + EngineManager.this.suspended);
spyWriter.prop((Object)"scanCount", "" + EngineManager.this.scanCount);
spyWriter.prop((Object)"runtime", EngineManager.timeStr(Clock.ticks() - EngineManager.this.startTicks));
spyWriter.prop((Object)"totalTicksInsideScan", EngineManager.timeStr(EngineManager.this.totalTicksInsideScan));
spyWriter.prop((Object)"averageTime/scan", d + "ms");
spyWriter.prop((Object)"averageTimeLast10Scan", d2 + "ms");
spyWriter.prop((Object)"peakScanTime", EngineManager.this.peakTicksInsideScan + "ms");
spyWriter.trTitle("Actions", 2);
spyWriter.prop((Object)"currentComponent", bComponent == null ? "null" : bComponent.toDebugString());
spyWriter.prop((Object)"currentAction", action);
spyWriter.prop((Object)("<a href='" + spyWriter.href("asyncQueue") + "'>Async Action Queue</a>"), EngineManager.this.actionQueue.size() + " (Peak " + EngineManager.this.actionQueue.peak() + ')');
spyWriter.prop((Object)("<a href='" + spyWriter.href("hogs") + "'>Engine Hogs</a>"), "");
spyWriter.trTitle("Short Timers (" + shortTimerThreshold + "ms or less)", 2);
EngineManager.this.shortTimers.writeSummary(spyWriter, "shortTimers");
spyWriter.trTitle("Medium Timers (" + shortTimerThreshold + "ms to " + mediumTimerThreshold + "ms)", 2);
EngineManager.this.mediumTimers.writeSummary(spyWriter, "mediumTimers");
spyWriter.trTitle("Long Timers (" + mediumTimerThreshold + "ms or greater)", 2);
EngineManager.this.longTimers.writeSummary(spyWriter, "longTimers");
spyWriter.endProps();
}
}
/*
* Illegal identifiers - consider using --renameillegalidents true
*/
public class TicketQueuePage
extends Spy {
TicketQueue q;
public void write(SpyWriter spyWriter) throws Exception {
long l = Clock.millis();
long l2 = Clock.ticks();
spyWriter.startTable(true);
spyWriter.trTitle("Timer Clock.Ticket Queue: " + BAbsTime.make(), 6);
spyWriter.w("<tr>").th("Mode").th("Next Update").th("Period").th("Component").th("Action").th("ActionArg").w("</tr>\n");
int n = 0;
NClockTicket nClockTicket = this.q.head;
while (nClockTicket != null) {
long l3 = nClockTicket.millisLeft();
if (++n > 1000) {
spyWriter.tr("more...", "", "", "", "", "");
break;
}
spyWriter.tr(nClockTicket.nextUpdate < 0L ? "ticks" : "millis", EngineManager.timeStr(l3), "" + nClockTicket.period, nClockTicket.component.toDebugString(), nClockTicket.action, nClockTicket.arg);
nClockTicket = nClockTicket.next;
}
spyWriter.endTable();
}
TicketQueuePage(TicketQueue ticketQueue) {
this.q = ticketQueue;
}
}
/*
* Illegal identifiers - consider using --renameillegalidents true
*/
public class AsyncQueuePage
extends Spy {
/*
* WARNING - Removed try catching itself - possible behaviour change.
* Enabled aggressive block sorting
* Enabled unnecessary exception pruning
* Enabled aggressive exception aggregation
*/
public void write(SpyWriter spyWriter) throws Exception {
spyWriter.startTable(true);
spyWriter.trTitle("Async Action Queue", 2);
spyWriter.w("<tr>").th("Component").th("Action").w("</tr>\n");
ActionQueue actionQueue = EngineManager.this.actionQueue;
synchronized (actionQueue) {
int n = 0;
Iterator iterator = EngineManager.this.actionQueue.iterator();
while (iterator.hasNext()) {
if (++n > 1000) {
spyWriter.tr("more...", "");
break;
}
ActionQueue.Entry entry = (ActionQueue.Entry)iterator.next();
spyWriter.tr(entry.component.toDebugString(), entry.action);
}
}
spyWriter.endTable();
}
}
/*
* Illegal identifiers - consider using --renameillegalidents true
*/
public class HogsPage
extends Spy {
public void write(SpyWriter spyWriter) throws Exception {
BStation bStation = Sys.getStation();
if (bStation == null) {
spyWriter.w("Not station VM");
return;
}
Object[] objectArray = bStation.getComponentSpace().getAllComponents();
Object[] objectArray2 = new Long[objectArray.length];
Long l = new Long(0L);
int n = 0;
while (n < objectArray.length) {
objectArray2[n] = (Long)((BObject)objectArray[n]).fw(22);
if (objectArray2[n] == null) {
objectArray2[n] = l;
}
++n;
}
SortUtil.sort((Object[])objectArray2, (Object[])objectArray, (boolean)false);
spyWriter.startTable(true);
spyWriter.trTitle("Engine Hogs", 4);
spyWriter.w("<tr>").th("Rank").th("Component").th("Type").th("Total Time").w("</tr>\n");
n = 0;
while (n < 100 && n < objectArray.length) {
Object object = objectArray[n];
if (objectArray2[n] == l) break;
long l2 = (Long)objectArray2[n];
spyWriter.tr("" + n, ((BComponent)object).toPathString(), ((BComponent)object).getType(), EngineManager.timeStr(l2 / 1000000L));
++n;
}
spyWriter.endTable();
}
}
/*
* Illegal identifiers - consider using --renameillegalidents true
*/
class EngineThread
extends Thread {
public void run() {
while (true) {
try {
Thread.sleep(engineSleepPeriod);
if (EngineManager.this.suspended) continue;
EngineManager.this.execute();
continue;
}
catch (Throwable throwable) {
log.error("Error in run", throwable);
continue;
}
break;
}
}
public EngineThread() {
super(Nre.mainThreadGroup, "Nre:Engine");
this.setDaemon(true);
}
}
}