Merge branch 'app4mc0.9.7/rttca' into master
Compliant to Amalthea 0.9.8
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.classpath b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.classpath
index eca7bdb..0d8f9cd 100644
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.classpath
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.classpath
@@ -3,5 +3,7 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="xtend-gen"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.gitignore b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.gitignore
new file mode 100644
index 0000000..b33f6af
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.gitignore
@@ -0,0 +1,2 @@
+/bin/
+/xtend-gen/
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.project b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.project
index dd2a679..cfe32e5 100644
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.project
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/.project
@@ -6,6 +6,11 @@
</projects>
<buildSpec>
<buildCommand>
+ <name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
@@ -24,5 +29,6 @@
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
</projectDescription>
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/doc/APP4RTA_1.0_Description.pdf b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/doc/APP4RTA_1.0_Description.pdf
deleted file mode 100644
index ad1c41c..0000000
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/doc/APP4RTA_1.0_Description.pdf
+++ /dev/null
Binary files differ
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/doc/Class_Diagram.png b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/doc/Class_Diagram.png
deleted file mode 100644
index 96608a1..0000000
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/doc/Class_Diagram.png
+++ /dev/null
Binary files differ
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/model-input/SingleTCs/SingleTCs.amxmi b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/model-input/SingleTCs/SingleTCs.amxmi
new file mode 100644
index 0000000..c714b75
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/model-input/SingleTCs/SingleTCs.amxmi
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<am:Amalthea xmlns:am="http://app4mc.eclipse.org/amalthea/0.9.8" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmi:version="2.0">
+ <swModel>
+ <tasks xmi:id="Task0?type=Task" name="Task0" stimuli="periodic_03s?type=PeriodicStimulus" multipleTaskActivationLimit="0">
+ <activityGraph>
+ <items xsi:type="am:RunnableCall" runnable="Run0?type=Runnable" />
+ </activityGraph>
+ </tasks>
+ <tasks xmi:id="Task1?type=Task" name="Task1" stimuli="periodic_05s?type=PeriodicStimulus" multipleTaskActivationLimit="0">
+ <activityGraph>
+ <items xsi:type="am:RunnableCall" runnable="Run1?type=Runnable" />
+ </activityGraph>
+ </tasks>
+ <tasks xmi:id="Task2?type=Task" name="Task2" stimuli="periodic_06s?type=PeriodicStimulus" multipleTaskActivationLimit="0">
+ <activityGraph>
+ <items xsi:type="am:RunnableCall" runnable="Run2?type=Runnable" />
+ </activityGraph>
+ </tasks>
+ <tasks xmi:id="Task3?type=Task" name="Task3" stimuli="periodic_10s?type=PeriodicStimulus" multipleTaskActivationLimit="0">
+ <activityGraph>
+ <items xsi:type="am:RunnableCall" runnable="Run3?type=Runnable" />
+ </activityGraph>
+ </tasks>
+ <runnables xmi:id="Run0?type=Runnable" name="Run0" callback="false" service="false">
+ <activityGraph>
+ <items xsi:type="am:Ticks">
+ <default xsi:type="am:DiscreteValueConstant" value="1" />
+ </items>
+ </activityGraph>
+ </runnables>
+ <runnables xmi:id="Run1?type=Runnable" name="Run1" callback="false" service="false">
+ <activityGraph>
+ <items xsi:type="am:Ticks">
+ <default xsi:type="am:DiscreteValueConstant" value="1" />
+ </items>
+ </activityGraph>
+ </runnables>
+ <runnables xmi:id="Run2?type=Runnable" name="Run2" callback="false" service="false">
+ <activityGraph>
+ <items xsi:type="am:Ticks">
+ <default xsi:type="am:DiscreteValueConstant" value="1" />
+ </items>
+ </activityGraph>
+ </runnables>
+ <runnables xmi:id="Run3?type=Runnable" name="Run3" callback="false" service="false">
+ <activityGraph>
+ <items xsi:type="am:Ticks">
+ <default xsi:type="am:DiscreteValueConstant" value="2" />
+ </items>
+ </activityGraph>
+ </runnables>
+ </swModel>
+ <hwModel>
+ <definitions xsi:type="am:ProcessingUnitDefinition" xmi:id="A57?type=ProcessingUnitDefinition" name="A57" puType="CPU">
+ <customProperties key="baseline">
+ <value xsi:type="am:Time" value="20" unit="ns" />
+ </customProperties>
+ <customProperties key="k">
+ <value xsi:type="am:Time" value="20" unit="ns" />
+ </customProperties>
+ <customProperties key="sGPU">
+ <value xsi:type="am:Time" value="100" unit="ns" />
+ </customProperties>
+ </definitions>
+ <definitions xsi:type="am:ProcessingUnitDefinition" xmi:id="Denver?type=ProcessingUnitDefinition" name="Denver" puType="CPU">
+ <customProperties key="baseline">
+ <value xsi:type="am:Time" value="8" unit="ns" />
+ </customProperties>
+ <customProperties key="k">
+ <value xsi:type="am:Time" value="2" unit="ns" />
+ </customProperties>
+ <customProperties key="sGPU">
+ <value xsi:type="am:Time" value="20" unit="ns" />
+ </customProperties>
+ </definitions>
+ <definitions xsi:type="am:ProcessingUnitDefinition" xmi:id="GPU_def?type=ProcessingUnitDefinition" name="GPU_def" puType="GPU">
+ <customProperties key="baseline">
+ <value xsi:type="am:Time" value="3" unit="ns" />
+ </customProperties>
+ </definitions>
+ <definitions xsi:type="am:MemoryDefinition" xmi:id="LPDDR4?type=MemoryDefinition" name="LPDDR4" memoryType="DRAM">
+ <size value="8" unit="GB" />
+ <accessLatency xsi:type="am:DiscreteValueConstant" value="0" />
+ </definitions>
+ <definitions xsi:type="am:ConnectionHandlerDefinition" xmi:id="Interconnect?type=ConnectionHandlerDefinition" name="Interconnect" policy="RoundRobin" maxBurstSize="4" maxConcurrentTransfers="1" />
+ <definitions xsi:type="am:CacheDefinition" xmi:id="CPU_L2?type=CacheDefinition" name="CPU_L2" cacheType="unified" writeStrategy="writeback" nWays="4" coherency="false" exclusive="false" hitRate="0.0">
+ <size value="2" unit="MB" />
+ <lineSize value="64" unit="B" />
+ </definitions>
+ <definitions xsi:type="am:CacheDefinition" xmi:id="GPU_L2?type=CacheDefinition" name="GPU_L2" cacheType="data" writeStrategy="writeback" nWays="4" coherency="false" exclusive="false" hitRate="0.0">
+ <size value="512" unit="kB" />
+ <lineSize value="64" unit="B" />
+ </definitions>
+ <structures xmi:id="JetsonTX2?type=HwStructure" name="JetsonTX2" structureType="System">
+ <structures xmi:id="ARM+island?type=HwStructure" name="ARM island" structureType="Cluster">
+ <modules xsi:type="am:ProcessingUnit" xmi:id="Core0?type=ProcessingUnit" name="Core0" frequencyDomain="A57_Domain?type=FrequencyDomain" definition="A57?type=ProcessingUnitDefinition">
+ <accessElements name="C2toDRAM">
+ <readLatency xsi:type="am:DiscreteValueConstant" value="40" />
+ <writeLatency xsi:type="am:DiscreteValueConstant" value="40" />
+ <dataRate value="4500" unit="MBPerSecond" />
+ </accessElements>
+ </modules>
+ </structures>
+ </structures>
+ <domains xsi:type="am:FrequencyDomain" xmi:id="A57_Domain?type=FrequencyDomain" name="A57_Domain" clockGating="false">
+ <defaultValue value="1.0" unit="Hz" />
+ </domains>
+ </hwModel>
+ <stimuliModel>
+ <stimuli xsi:type="am:PeriodicStimulus" xmi:id="periodic_03s?type=PeriodicStimulus" name="periodic_03s">
+ <recurrence value="3" unit="s" />
+ </stimuli>
+ <stimuli xsi:type="am:PeriodicStimulus" xmi:id="periodic_05s?type=PeriodicStimulus" name="periodic_05s">
+ <recurrence value="5" unit="s" />
+ </stimuli>
+ <stimuli xsi:type="am:PeriodicStimulus" xmi:id="periodic_06s?type=PeriodicStimulus" name="periodic_06s">
+ <recurrence value="6" unit="s" />
+ </stimuli>
+ <stimuli xsi:type="am:PeriodicStimulus" xmi:id="periodic_10s?type=PeriodicStimulus" name="periodic_10s">
+ <recurrence value="10" unit="s" />
+ </stimuli>
+ </stimuliModel>
+ <eventModel>
+ <events xsi:type="am:ProcessEvent" xmi:id="Task0+event?type=ProcessEvent" name="Task0 event" description="" entity="Task0?type=Task" />
+ <events xsi:type="am:ProcessEvent" xmi:id="Task1+event?type=ProcessEvent" name="Task1 event" entity="Task1?type=Task" />
+ <events xsi:type="am:ProcessEvent" xmi:id="Task2+event?type=ProcessEvent" name="Task2 event" entity="Task2?type=Task" />
+ <events xsi:type="am:ProcessEvent" xmi:id="Task3+event?type=ProcessEvent" name="Task3 event" description="" entity="Task3?type=Task" />
+ </eventModel>
+ <constraintsModel>
+ <eventChains xmi:id="EC_3-5-6-10?type=EventChain" name="EC_3-5-6-10" itemType="sequence" minItemsCompleted="1">
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task0+event?type=ProcessEvent" response="Task1+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task1+event?type=ProcessEvent" response="Task2+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task2+event?type=ProcessEvent" response="Task3+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ </eventChains>
+ <eventChains xmi:id="EC_3-6-5-10?type=EventChain" name="EC_3-6-5-10" itemType="sequence" minItemsCompleted="1">
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task0+event?type=ProcessEvent" response="Task2+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task2+event?type=ProcessEvent" response="Task1+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task1+event?type=ProcessEvent" response="Task3+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ </eventChains>
+ <eventChains xmi:id="EC_10-5-6-3?type=EventChain" name="EC_10-5-6-3" itemType="sequence" minItemsCompleted="1">
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task3+event?type=ProcessEvent" response="Task1+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task1+event?type=ProcessEvent" response="Task2+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task2+event?type=ProcessEvent" response="Task0+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ </eventChains>
+ <eventChains xmi:id="EC_10-6-5-3?type=EventChain" name="EC_10-6-5-3" itemType="sequence" minItemsCompleted="1">
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task3+event?type=ProcessEvent" response="Task2+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task2+event?type=ProcessEvent" response="Task1+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ <items xsi:type="am:EventChainContainer">
+ <eventChain name="" stimulus="Task1+event?type=ProcessEvent" response="Task0+event?type=ProcessEvent" minItemsCompleted="1" />
+ </items>
+ </eventChains>
+ </constraintsModel>
+</am:Amalthea>
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CPURta.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CPURta.java
new file mode 100644
index 0000000..629c65b
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CPURta.java
@@ -0,0 +1,1234 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * FH Dortmund - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.app4mc.gsoc_rta;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.log4j.Logger;
+import org.eclipse.app4mc.gsoc_rta.IRTA;
+import org.eclipse.app4mc.gsoc_rta.CommonUtils;
+import org.eclipse.app4mc.gsoc_rta.SharedConsts;
+import org.eclipse.app4mc.gsoc_rta.Contention;
+import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
+import org.eclipse.app4mc.amalthea.model.Amalthea;
+import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
+import org.eclipse.app4mc.amalthea.model.ClearEvent;
+import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
+import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
+import org.eclipse.app4mc.amalthea.model.Label;
+import org.eclipse.app4mc.amalthea.model.LabelAccess;
+import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
+import org.eclipse.app4mc.amalthea.model.Preemption;
+import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
+import org.eclipse.app4mc.amalthea.model.PuType;
+import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.RunnableCall;
+import org.eclipse.app4mc.amalthea.model.SetEvent;
+import org.eclipse.app4mc.amalthea.model.Task;
+import org.eclipse.app4mc.amalthea.model.Time;
+import org.eclipse.app4mc.amalthea.model.TimeUnit;
+import org.eclipse.app4mc.amalthea.model.WaitEvent;
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
+import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
+import org.eclipse.emf.common.util.EList;
+
+public class CPURta implements IRTA {
+ final Logger log = Logger.getLogger(CPURta.class);
+ private Amalthea model;
+
+ /**
+ * CPURta Constructor
+ * @param forFunctions
+ * true: when creating a class instance just to use functions
+ * false: when creating a default class instance for CPURta simulation
+ * @param file target Amalthea file
+ * @param ia interger array mapping model
+ */
+ public CPURta(final boolean forFunctions, final Amalthea model, final int[] ia) {
+ if (!forFunctions) {
+ if (model == null) {
+ log.error("The file is empty. Please check the model path.");
+ return;
+ }
+ this.setModel(model);
+ this.setTRT(getDefaultTRT(model));
+ this.setIA(ia);
+ this.setPUl(CommonUtils.getPUs(model));
+ this.setContention(ia, model);
+ }
+ }
+
+ /**
+ * CPURta Constructor - when manually creating a class instance for CPURta simulation
+ * @param model the observed Amalthea Model
+ * @param trt the observed HashMap Task with Response Time (null works => the default testing trt will be assigned)
+ * @param ia the observed IntegerArray Mapping Model
+ * @param pul the observed List of ProcessingUnits
+ */
+ public CPURta(final Amalthea model, final HashMap<Task, Time> trt, final int[] ia, final List<ProcessingUnit> pul) {
+ if (model == null) {
+ log.error("Model is empty. Please check the model path.");
+ return;
+ }
+ this.setModel(model);
+ if (trt == null) {
+ this.setTRT(this.getDefaultTRT(model));
+ } else {
+ this.setTRT(trt);
+ }
+ this.setIA(ia);
+ if (pul == null) {
+ this.setPUl(CommonUtils.getPUs(model));
+ } else {
+ this.setPUl(pul);
+ }
+ this.setContention(ia, model);
+ }
+
+ /**
+ * CPURta Constructor - when there is only one processing unit inside the model. (Therefore, IA mapping is not required.)
+ * @param model
+ */
+ public CPURta(final Amalthea model) {
+ if (model == null) {
+ log.error("Model is empty. Please check the model path.");
+ }
+ this.setModel(model);
+ final int numOfTasks = model.getSwModel().getTasks().size();
+ final int[] ia = new int[numOfTasks];
+ for (int i = 0; i < numOfTasks; i++) {
+ ia[i] = 0;
+ }
+ this.setTRT(getDefaultTRT(model));
+ this.setIA(ia);
+ this.setPUl(CommonUtils.getPUs(model));
+ this.setContention(ia, model);
+ }
+
+ /**
+ * Since this method is used by RTARuntimeUtil, the visibility should be 'public'
+ * @return
+ * The Amalthea model instance of the current CPURta class
+ */
+ public Amalthea getModel() {
+ return this.model;
+ }
+
+ /**
+ * Set the Amalthea model object of the current CPURta class as the given Amalthea model parameter.
+ * @param pAmalthea the parameter Amalthea model which would reinitialize the Amalthea model
+ */
+ public void setModel(final Amalthea pAmalthea) {
+ this.model = pAmalthea;
+ this.setGTCL(this.model);
+ }
+
+ private HashMap<Task, Time> trt = null;
+
+ /**
+ * Since this method is used by GAMapping, the visibility should be 'public'
+ * @return
+ * trt(task with response time) HashMap variable
+ */
+ @Override
+ public HashMap<Task, Time> getTRT() {
+ return this.trt;
+ }
+
+ /**
+ * Set the trt(task with response time) HashMap variable as the given trtp parameter variable.
+ * Which would contains GPU tasks' response times from the beginning
+ * @param trtp the HashMap variable parameter which would reinitialize the trt variable of the current CPURta class.
+ */
+ public void setTRT(final HashMap<Task, Time> trtp) {
+ this.trt = trtp;
+ }
+
+ /**
+ * Get the default trt(task with response time) value in case of running CPURta class itself.
+ * @param model the current class's Amalthea model which is used to get the trt value out of it
+ * @return
+ * the trt value which is derived out of the given parameter Amalthea model
+ */
+ public HashMap<Task, Time> getDefaultTRT(final Amalthea model) {
+ final HashMap<Task, Time> trt = new HashMap<Task, Time>();
+ final EList<Task> allTaskList = model.getSwModel().getTasks();
+ final long val = 2000000000;
+ for (final Task t : allTaskList) {
+ if (this.gpuTaskList.contains(t)) {
+ trt.put(t, FactoryUtil.createTime(BigInteger.valueOf(val), TimeUnit.PS));
+ }
+ else {
+ trt.put(t, FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS));
+ }
+ }
+ return trt;
+ }
+
+ private int[] tpuMapping = null;
+
+ /**
+ * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
+ *
+ * @return
+ * The tpuMapping integer array
+ */
+ public int[] getIA() {
+ return this.tpuMapping;
+ }
+
+ /**
+ * Set the tpuMapping integer array (which would be used to modify the current task mapping to different Processing Units)
+ * as the given tpumap parameter variable.
+ * (The integer array would be used to modify the current task mapping to different Processing Units)
+ * @param tpumap the parameter integer array which would reinitialize the tpuMapping array of the current CPURta class.
+ */
+ public void setIA(final int[] tpumap) {
+ if (tpumap == null) {
+ this.tpuMapping = null;
+ } else if (tpumap.length == this.model.getSwModel().getTasks().size()) {
+ this.tpuMapping = tpumap;
+ } else {
+ log.error("integer array size MUST match the number of tasks");
+ }
+ }
+
+ private List<ProcessingUnit> pul = new ArrayList<>();
+
+ /**
+ * Get a list of ProcessingUnits
+ * @return
+ * this.pul
+ */
+ public List<ProcessingUnit> getPUl() {
+ return this.pul;
+ }
+
+ /**
+ * Set the pul, the list of Processing Units variable (which would be used to map tasks along with tpuMapping array)
+ * as the given pul parameter variable.
+ * @param pul the parameter pul list which would reinitialize the pul list variable of the current CPURta class
+ */
+ public void setPUl(final List<ProcessingUnit> pul) {
+ this.pul = pul;
+ }
+
+ private Contention ct = null;
+
+ /**
+ * Get the contention instance
+ * @return
+ * this.ct
+ */
+ protected Contention getCT() {
+ return this.ct;
+ }
+
+ /**
+ * Set the ct (Contention) variable which would be used to calculate memory contention of the given task that will be added up to the response time result
+ * as the newly generated contention instance with the given integer array
+ * and Amalthea model parameters.
+ * @param ia Integer Array which is referred to map tasks of the given model
+ * @param model Amalthea model
+ */
+ public void setContention(final int[] ia, final Amalthea model) {
+ this.ct = new Contention(ia, model);
+ }
+
+ private List<Task> gpuTaskList = new ArrayList<Task>();
+
+ /**
+ * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
+ * @return
+ * gpuTaskList which contains tasks (which are originally designed for GPU) of the Amalthea model
+ */
+ protected List<Task> getGpuTaskList() {
+ return this.gpuTaskList;
+ }
+
+ private final List<Task> triggeringTaskList = new ArrayList<Task>();
+ /**
+ * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
+ * @return
+ * triggeringTaskList which contains tasks (which contain InterProcessTrigger) of the Amalthea model
+ */
+ protected List<Task> getTriggeringTaskList() {
+ return this.triggeringTaskList;
+ }
+
+ /* this runnable is used to calculate execution time in RTARuntimeUtil class */
+ protected Runnable offloadingAsyncRunnable = null;
+
+ private final HashMap<Task, List<List<Label>>> gpuToCpuLabels = new HashMap<Task, List<List<Label>>>();
+
+ /**
+ * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
+ * @return
+ * gpuToCpuLabels HashMap which contains required labels (of the corresponding task)
+ * that need to be taken into account when GPU tasks are mapped to CPU
+ */
+ protected HashMap<Task, List<List<Label>>> getGTCL() {
+ return this.gpuToCpuLabels;
+ }
+
+ /**
+ * Not only set gpuToCpuLabels HashMap, this also set gpuTaskList (only contains GPU tasks),
+ * triggeringTaskList (only contains tasks with InterProcessTrigger)
+ * and offloadingAsyncRunnable (the Runnable that is taken into account for triggering tasks when the mode is asynchronous)
+ * @param model the parameter Amalthea model which is used to derived required labels of the corresponding GPU task
+ */
+ private void setGTCL(final Amalthea model) {
+ final EList<Task> allTaskList = model.getSwModel().getTasks();
+ this.gpuTaskList = allTaskList.stream().filter(s -> s.getStimuli().get(0) instanceof InterProcessStimulus).collect(Collectors.toList());
+ /* find the triggering tasks */
+ for (final Task t : allTaskList) {
+ final List<ActivityGraphItem> triggerList = SoftwareUtil.collectActivityGraphItems(t.getActivityGraph(), null, (call -> call instanceof InterProcessTrigger));
+ if (triggerList.size() != 0) {
+ this.triggeringTaskList.add(t);
+ if (RTARuntimeUtil.doesTaskHaveAsyncRunnable(t, this)) {
+ final List<ActivityGraphItem> cList = SoftwareUtil.collectActivityGraphItems(t.getActivityGraph(), null, (call -> call instanceof RunnableCall
+ || call instanceof InterProcessTrigger || call instanceof ClearEvent || call instanceof SetEvent || call instanceof WaitEvent));
+ final int waitIndex = cList.indexOf(cList.stream().filter(s -> s instanceof WaitEvent).iterator().next());
+ final int asyncOffloadingIndex = waitIndex + 1;
+ if (cList.get(asyncOffloadingIndex) instanceof RunnableCall) {
+ this.offloadingAsyncRunnable = ((RunnableCall) cList.get(asyncOffloadingIndex)).getRunnable();
+ }
+ }
+ }
+ }
+ for (final Task t : this.gpuTaskList) {
+ final InterProcessStimulus ips = (InterProcessStimulus) (t.getStimuli().get(0));
+ Task triggeringTask = null;
+ for (final Task tt : this.triggeringTaskList) {
+ final InterProcessTrigger ipt = (InterProcessTrigger) SoftwareUtil
+ .collectActivityGraphItems(tt.getActivityGraph(), null, (call -> call instanceof InterProcessTrigger)).stream().iterator().next();
+ if (ips.equals(ipt.getStimulus())) {
+ triggeringTask = tt;
+ break;
+ }
+ }
+ final List<Label> readLabelList = new ArrayList<Label>();
+ final List<Label> writeLabelList = new ArrayList<Label>();
+ if (null != triggeringTask) {
+ final List<ActivityGraphItem> callList = SoftwareUtil.collectActivityGraphItems(triggeringTask.getActivityGraph(), null,
+ (call -> call instanceof RunnableCall || call instanceof InterProcessTrigger || call instanceof ClearEvent || call instanceof SetEvent
+ || call instanceof WaitEvent));
+ final InterProcessTrigger ipt = (InterProcessTrigger) callList.stream().filter(s -> s instanceof InterProcessTrigger).iterator().next();
+ final int indexforTrigger = callList.indexOf(ipt);
+ for (int i = 0; i < callList.size(); i++) {
+ Runnable thisRunnable = null;
+ /* Pre-processing Runnable */
+ if ((i < indexforTrigger) && (callList.get(i) instanceof RunnableCall)) {
+ thisRunnable = ((RunnableCall) callList.get(i)).getRunnable();
+ final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(thisRunnable, null);
+ for (final LabelAccess la : thisLAList) {
+ if (la.getAccess().equals(LabelAccessEnum.READ)) {
+ readLabelList.add(la.getData());
+ }
+ }
+ }
+ /* Post-processing Runnable */
+ else if ((i > indexforTrigger) && (callList.get(i) instanceof RunnableCall)) {
+ thisRunnable = ((RunnableCall) callList.get(i)).getRunnable();
+ final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(thisRunnable, null);
+ for (final LabelAccess la : thisLAList) {
+ if (la.getAccess().equals(LabelAccessEnum.WRITE)) {
+ writeLabelList.add(la.getData());
+ }
+ }
+ }
+ }
+ }
+ final List<List<Label>> aryofLabelList = new ArrayList<List<Label>>();
+ aryofLabelList.add(readLabelList);
+ aryofLabelList.add(writeLabelList);
+ this.gpuToCpuLabels.put(t, aryofLabelList);
+ }
+ }
+
+ /* To calculate pure memory access latency cost (without contention & pure computation(Ticks)) */
+ protected Time cumuAcTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+
+ /**
+ * @return
+ * cumuAcTime, the total time of latency (Read & Write memory access) from CPUs
+ */
+ public Time getCumulatedMemAccCosts() {
+ return this.cumuAcTime;
+ }
+
+ /**
+ * Initializing cumuAcTime to 0 ps
+ */
+ public void initCumulatedMemAccCosts() {
+ this.cumuAcTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+
+ /* To calculate pure latency cost (without memory access latency & pure computation(Ticks)) */
+ protected Time cumuConTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+
+ /**
+ * @return
+ * cumulatedCon, the total time of latency (Contention of the task)
+ */
+ public Time getCumulatedContention() {
+ return this.cumuConTime;
+ }
+
+ /**
+ * Initializing cumulatedCon to 0 ps
+ */
+ public void initCumulatedContention() {
+ this.cumuConTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+
+ HashMap<Task, Time> accessCosts = new HashMap<>();
+
+ public HashMap<Task, Time> getAccessCosts() {
+ return this.accessCosts;
+ }
+
+ /**
+ * Calculate the total sum of response times of the tasks of the given Amalthea model with the mapping model (tpuMapping)
+ * @param executionCase BCET, ACET, WCET
+ * @return
+ * total sum of all tasks' response times of the given mapped model (tpuMapping)
+ */
+ @Override
+ public Time getRTSum(final TimeType executionCase) {
+ if (this.model == null) {
+ log.error("No Model Loaded!");
+ return null;
+ } else if (this.trt == null) {
+ log.error("No HashMap Loaded!");
+ return null;
+ } else if (this.tpuMapping == null) {
+ log.error("No IntegerArray Loaded!");
+ return null;
+ } else if (this.pul == null) {
+ log.error("No PUList Loaded!");
+ return null;
+ }
+ this.setContention(this.getIA(), this.getModel());
+ Time time = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ final EList<Task> allTaskList = this.model.getSwModel().getTasks();
+ for (int i = 0; i < this.tpuMapping.length; i++) {
+ final Time rt = getTaskRTIA(allTaskList.get(i), executionCase);
+ if (rt.getValue().equals(BigInteger.valueOf(Long.MAX_VALUE)) && !SharedConsts.ignoreInfeasibility) {
+ return rt;
+ }
+ time = time.add(rt);
+ if (!rt.getValue().equals(BigInteger.ZERO)) {
+ /* only put CPU tasks */
+ this.trt.put(this.model.getSwModel().getTasks().get(i), rt);
+ }
+ }
+ return time;
+ }
+
+ /**
+ * Calculate worst-case response time of the given task of the given Amalthea model with the mapping model (tpuMapping)
+ * @param task the observed task
+ * @param executionCase BCET, ACET, WCET
+ * @return
+ * response time of the observed task
+ */
+ protected Time getTaskRTIA(final Task task, final TimeType executionCase) {
+ /* 1. validate thisTask is mapped to CPU */
+ final int tindex = this.model.getSwModel().getTasks().indexOf(task);
+ final int puindex = this.tpuMapping[tindex];
+ final ProcessingUnit pu = this.pul.get(puindex);
+ if (!pu.getDefinition().getPuType().equals(PuType.CPU)) {
+ Logger.getLogger(CPURta.class).debug(task.getName() + " is not mapped to a CPU");
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ /* 2. get all tasks mapped to this CPU */
+ final List<Task> puTaskList = new ArrayList<Task>();
+ for (int i = 0; i < this.tpuMapping.length; i++) {
+ if (this.tpuMapping[i] == puindex) {
+ puTaskList.add(this.model.getSwModel().getTasks().get(i));
+ }
+ }
+ final List<Task> sortedTaskList = taskSorting(puTaskList);
+ if (executionCase.equals(TimeType.BCET)) {
+ return this.bestCaseCPURT(task, sortedTaskList, pu);
+ } else if (executionCase.equals(TimeType.WCET)) {
+ return SharedConsts.levelIBusyPeriod ? this.responseTimeLevelI(task, sortedTaskList, TimeType.WCET, pu)
+ : this.preciseTestCPURT(task, sortedTaskList, TimeType.WCET, pu);
+ }
+ return SharedConsts.levelIBusyPeriod ? this.responseTimeLevelI(task, sortedTaskList, TimeType.WCET, pu)
+ : this.preciseTestCPURT(task, sortedTaskList, TimeType.ACET, pu);
+ }
+
+ /**
+ * Sort out the given list of tasks (in order of shorter period first - Rate Monotonic Scheduling)
+ * @param taskList list of tasks that is mapped to the same core
+ * @return
+ * the sorted list of tasks
+ */
+ protected List<Task> taskSorting(final List<Task> taskList) {
+ /* Getting stimuliList out of the given taskList (because it is RMS) */
+ final List<Time> stimuliList = new ArrayList<>();
+ for (final Task t : taskList) {
+ stimuliList.add(CommonUtils.getStimInTime(t));
+ }
+ /* Sorting (Shortest Period(Time) first) */
+ Collections.sort(stimuliList, new TimeCompIA());
+ /* Sort tasks to the newTaskList in order of Period length (shortest first
+ * longest last)-(according to the stimuliList) */
+ final List<Task> newTaskList = new ArrayList<>();
+ for (int i = 0; i < stimuliList.size(); i++) {
+ for (final Task t : taskList) {
+ if ((!newTaskList.contains(t)) && (stimuliList.get(i).compareTo(CommonUtils.getStimInTime(t)) == 0)) {
+ newTaskList.add(t);
+ }
+ }
+ }
+ return newTaskList;
+ }
+
+ /**
+ * Calculate response time of the observed task according to the worst-case RMS response time analysis algorithm.
+ * @param task the observed task
+ * @param taskList list of tasks that is mapped to the same core
+ * @param executionCase BCET, ACET, WCET
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @return
+ * the worst-case response time of the observed task
+ */
+ public Time preciseTestCPURT(final Task task, final List<Task> taskList, final TimeType executionCase, final ProcessingUnit pu) {
+ Time thisRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Time period = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (taskList.size() == 0) {
+ log.debug("!!! This taskList is empty so I am returning MAX !!!");
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ /* to check if the given task is in the taskList */
+ int flag = 0;
+ int index = 0;
+ for (int i = 0; i < taskList.size(); i++) {
+ if (task.equals(taskList.get(i))) {
+ flag = 1;
+ index = i;
+ break;
+ }
+ }
+ if (flag == 0) {
+ log.debug("!!! Nothing in the taskList matches the given Task !!! So I am returning 0s" + " --- thisTask: " + task.getName());
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ period = CommonUtils.getStimInTime(taskList.get(index));
+ if (index == 0) {
+ thisRT = rtaut.getExecutionTimeforCPUTaskIA(taskList.get(index), pu, executionCase, this);
+ if (thisRT.compareTo(period) <= 0) {
+ /* To analyze the pure latency time */
+ if (thisRT.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) > 0) {
+ this.cumuAcTime = this.cumuAcTime.add(rtaut.getTaskMemoryAccessTime(task, pu, executionCase));
+ if (this.getIA() != null) {
+ this.cumuConTime = this.cumuConTime.add(this.getCT().contentionForTask(task));
+ }
+ }
+ return thisRT;
+ }
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the execution time of " + thisRT
+ + " for task " + task.getName());
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ else {
+ /* In the case of a COOPERATIVE Preemption typed Task */
+ if (taskList.get(index).getPreemption().equals(Preemption.COOPERATIVE)) {
+ // TODO: Blocking
+ }
+ final Time thisExeTime = rtaut.getExecutionTimeforCPUTaskIA(taskList.get(index), pu, executionCase, this);
+ if (thisExeTime.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) == 0) {
+ return thisExeTime;
+ } else if (thisExeTime.compareTo(period) > 0) {
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the execution time of " + thisRT
+ + " for task " + task.getName());
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ Time cumulativeRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ /* 1. add all the execution time till the index - RT_0 */
+ for (int j = 0; j < index + 1; j++) {
+ final Time thisTime = rtaut.getExecutionTimeforCPUTaskIA(taskList.get(j), pu, executionCase, this);
+ cumulativeRT = cumulativeRT.add(thisTime);
+ }
+ if (cumulativeRT.compareTo(period) <= 0) {
+ while (true) {
+ Time excepThisExeTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ for (int j = 0; j < index; j++) {
+ Time localPeriod = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ localPeriod = CommonUtils.getStimInTime(taskList.get(j));
+ final Time preExeTime = rtaut.getExecutionTimeforCPUTaskIA(taskList.get(j), pu, executionCase, this);
+ final double ri_period = Math.ceil(cumulativeRT.divide(localPeriod));
+ excepThisExeTime = excepThisExeTime.add(preExeTime.multiply(ri_period));
+ }
+ Time cumulativeRT_x = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ cumulativeRT_x = thisExeTime.add(excepThisExeTime);
+ if (cumulativeRT_x.compareTo(period) <= 0) {
+ if (cumulativeRT_x.compareTo(cumulativeRT) == 0) {
+ thisRT = cumulativeRT_x;
+ /* To analyze the pure latency time */
+ if (thisRT.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) > 0) {
+ this.cumuAcTime = this.cumuAcTime.add(rtaut.getTaskMemoryAccessTime(task, pu, executionCase));
+ if (this.getIA() != null) {
+ this.cumuConTime = this.cumuConTime.add(this.getCT().contentionForTask(task));
+ }
+ }
+ return thisRT;
+ }
+ cumulativeRT = cumulativeRT_x;
+ } else {
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period
+ + " being less than the response time (cumulativeRT_x) of " + cumulativeRT_x + " for task " + task.getName());
+ if (SharedConsts.ignoreInfeasibility) {
+ return cumulativeRT_x;
+ }
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ }
+ }
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the response time of " + cumulativeRT
+ + " for task " + task.getName());
+ if (SharedConsts.ignoreInfeasibility) {
+ return cumulativeRT;
+ }
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ }
+
+ /**
+ * Calculate response time of the observed task according to the best-case RMS response time analysis algorithm.
+ * (source: https://www.researchgate.net/publication/3958297_Exact_best-case_response_time_analysis_of_fixed_priority_scheduled_tasks (equ_16))
+ * @param task the observed task
+ * @param taskList list of tasks that is mapped to the same core
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @return
+ * the best-case response time of the observed task
+ */
+ public Time bestCaseCPURT(final Task task, final List<Task> taskList, final ProcessingUnit pu) {
+ Time bcrt = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (taskList.size() == 0) {
+ log.debug("!!! This taskList is empty so I am returning MAX !!!");
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ } else if (!taskList.contains(task)) {
+ log.debug("!!! This taskList is empty so I am returning MAX !!!");
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ /* to check if the given task is in the taskList */
+ int flag = 0;
+ int index = 0;
+ for (int i = 0; i < taskList.size(); i++) {
+ if (task.equals(taskList.get(i))) {
+ flag = 1;
+ index = i;
+ break;
+ }
+ }
+ if (flag == 0) {
+ log.debug("!!! Nothing in the taskList matches the given Task !!! So I am returning 0s" + " --- thisTask: " + task.getName());
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ Time bR_0 = this.preciseTestCPURT(task, taskList, TimeType.BCET, pu);
+ for (int i = 0; i < index + 1; i++) {
+ if (index == 0) {
+ bcrt = bR_0;
+ break;
+ }
+ else if (i == index) {
+ final Time i_BCET = rtaut.getExecutionTimeforCPUTaskIA(task, pu, TimeType.BCET, this);
+ final Time rt_0 = this.preciseTestCPURT(task, taskList, TimeType.BCET, pu);
+ Time rt_n = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ boolean isItFirst = true;
+ while (true) {
+ Time sum = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ for (int j = 0; j < i; j++) {
+ final Task curTask = taskList.get(j);
+ final Time curTask_period = CommonUtils.getStimInTime(curTask);
+ final Time curTask_BCET = rtaut.getExecutionTimeforCPUTaskIA(curTask, pu, TimeType.BCET, this);
+ if (isItFirst) {
+ double ceil_value = Math.ceil((rt_0.subtract(curTask_period)).divide(curTask_period));
+ if (ceil_value < 0) {
+ ceil_value = 0;
+ }
+ final Time curIterTime = curTask_BCET.multiply(ceil_value);
+ sum = sum.add(curIterTime);
+ } else {
+ double ceil_value = Math.ceil((rt_n.subtract(curTask_period)).divide(curTask_period));
+ if (ceil_value < 0) {
+ ceil_value = 0;
+ }
+ final Time curIterTime = curTask_BCET.multiply(ceil_value);
+ sum = sum.add(curIterTime);
+ }
+ }
+ Time temp = i_BCET.add(sum);
+ if(isItFirst) {
+ if (temp.compareTo(rt_0) == 0) {
+ bcrt = temp;
+ break;
+ } else {
+ rt_n = temp;
+ }
+ } else {
+ if (temp.compareTo(rt_n) == 0) {
+ bcrt = temp;
+ break;
+ } else {
+ rt_n = temp;
+ }
+ }
+ isItFirst = false;
+ }
+ }
+ }
+ return bcrt;
+ }
+
+ /** New method implement from the news paper with Level_i
+ * @param thisTask
+ * @param thisTaskList
+ * @param executionCase
+ * @param pu
+ * @return
+ */
+ private Time responseTimeLevelI(final Task thisTask, final List<Task> thisTaskList, final TimeType executionCase, final ProcessingUnit pu) {
+ Time thisRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Time period = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+
+ if (thisTaskList.size() == 0) {
+ log.debug("!!! This taskList is empty !!!");
+ // TODO: Catch Exception
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+
+ /* to check if the given task is in the thisTaskList */
+ int flag = 0;
+ int index = 0;
+ for (int i = 0; i < thisTaskList.size(); i++) {
+ if (thisTask.equals(thisTaskList.get(i))) {
+ flag = 1;
+ index = i;
+ break;
+ }
+ }
+ /*
+ * the problem seems like once a gpu task (mapped to cpu) changes its stimulus it becomes completely new (or maybe not)
+ */
+ if (flag == 0) {
+ log.debug("!!! Nothing in the taskList matches the given Task !!!" + " --- thisTask: " + thisTask.getName());
+
+ // TODO: Catch Exception
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ final Time checkingTime = rtaut.getExecutionTimeforCPUTaskIA(thisTask, pu, executionCase, this);
+
+ if (checkingTime.getValue().longValue() == 0) {
+
+ return checkingTime;
+ }
+
+ /* Checking whether task list is schedulable or not */
+ double UtilizationValue = 0.0;
+ for (final Task task : thisTaskList) {
+ final Time exeTime = rtaut.getExecutionTimeforCPUTaskIA(task, pu, executionCase, this);
+ final Time periodTime = CommonUtils.getStimInTime(task);
+ final BigInteger exeTimePico = AmaltheaServices.convertToPicoSeconds(exeTime);
+ final BigInteger periodTimePico = AmaltheaServices.convertToPicoSeconds(periodTime);
+
+ UtilizationValue += (exeTimePico.doubleValue()) / (periodTimePico.doubleValue());
+ }
+
+ if (UtilizationValue > 1.0) {
+ final Time rpTime = FactoryUtil.createTime(Long.MAX_VALUE, TimeUnit.PS);
+ return rpTime;
+ }
+
+ /* ----------------------------------------------- */
+ /* Start applying level i approach from here */
+ for (int i = 0; i < index + 1; i++) {
+ period = CommonUtils.getStimInTime(thisTaskList.get(i));
+ if (index == 0) {
+ thisRT = rtaut.getExecutionTimeforCPUTaskIA(thisTaskList.get(i), pu, executionCase, this);
+ if (thisRT.compareTo(period) <= 0) {
+ if (thisRT.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) > 0) {
+ this.cumuAcTime = this.cumuAcTime.add(rtaut.getTaskMemoryAccessTime(thisTask, pu, executionCase));
+ }
+ return thisRT;
+ }
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period + " is less than the execution time of " + thisRT + " for task "
+ + thisTask.getName());
+
+ // TODO: Catch Exception
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ else if (i == index) {
+ /* In the case of a COOPERATIVE Preemption typed Task */
+ if (thisTaskList.get(i).getPreemption().equals(Preemption.COOPERATIVE)) {
+ // TODO: Blocking
+ }
+ final Time thisExeTime = rtaut.getExecutionTimeforCPUTaskIA(thisTaskList.get(i), pu, executionCase, this);
+ if (thisExeTime.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) == 0) {
+ return thisExeTime;
+ }
+ else if (thisExeTime.compareTo(period) > 0) {
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the execution time of " + thisRT
+ + " for task " + thisTask.getName());
+ // TODO: Catch Exception
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+
+ BigDecimal l_value = BigDecimal.valueOf(1.0);
+ BigDecimal currentL_value = BigDecimal.valueOf(1.0);
+ BigDecimal temp = BigDecimal.valueOf(2.0);
+ BigDecimal localSum = BigDecimal.valueOf(0.0);
+ while (localSum.compareTo(temp) != 0) {
+ localSum = BigDecimal.valueOf(0);
+ for (int j = 0; j < i + 1; j++) {
+ temp = currentL_value;
+ Time thePeriod = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Time localExe = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ thePeriod = CommonUtils.getStimInTime(thisTaskList.get(j));
+
+ localExe = rtaut.getExecutionTimeforCPUTaskIA(thisTaskList.get(j), pu, executionCase, this);
+ final double periodInDouble = AmaltheaServices.convertToPicoSeconds(thePeriod).doubleValue();
+ final double exeInDouble = AmaltheaServices.convertToPicoSeconds(localExe).doubleValue();
+ final BigDecimal periodInDoubleBD = BigDecimal.valueOf(periodInDouble);
+ final BigDecimal exeInDoubleBD = BigDecimal.valueOf(exeInDouble);
+
+ /* l_value = Math.ceil(currentL_value / periodInDouble) * exeInDouble; */
+ l_value = currentL_value.divide(periodInDoubleBD, 0, BigDecimal.ROUND_UP).multiply(exeInDoubleBD);
+ localSum = localSum.add(l_value);
+ }
+ currentL_value = localSum;
+
+ }
+ final BigDecimal taskPeriodBD = BigDecimal.valueOf(AmaltheaServices.convertToPicoSeconds(period).doubleValue());
+
+ /*
+ * final int k_value = (int) Math.ceil(localSum /AmaltheaServices.convertToPicoSeconds(period).doubleValue());
+ */
+ final BigDecimal k_value = localSum.divide(taskPeriodBD, 0, BigDecimal.ROUND_UP);
+ // System.out.println("k value = " + k_value);
+ final List<Double> rtList = new ArrayList<Double>();
+
+ // double fl_value = 1.0;
+ BigDecimal fl_value = BigDecimal.valueOf(1.0);
+ // double ftemp = 3.0;
+ BigDecimal ftemp = BigDecimal.valueOf(3.0);
+
+ for (int j = 1; j <= k_value.intValue(); j++) {
+ ftemp = BigDecimal.valueOf(3.0);
+ while (fl_value.compareTo(ftemp) != 0) {
+ // double flocalSum = 0.0;
+ BigDecimal flocalSum = BigDecimal.valueOf(0.0);
+ // double fSum = 0.0;
+ BigDecimal fSum = BigDecimal.valueOf(0.0);
+ // Assign temp for comparation
+ ftemp = fl_value;
+ for (int m = 0; m < i; m++) {
+ Time thePeriod = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Time localExe = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ thePeriod = CommonUtils.getStimInTime(thisTaskList.get(j));
+ localExe = rtaut.getExecutionTimeforCPUTaskIA(thisTaskList.get(m), pu, executionCase, this);
+ final BigInteger periodInteger = AmaltheaServices.convertToPicoSeconds(thePeriod);
+ final BigInteger exeInteger = AmaltheaServices.convertToPicoSeconds(localExe);
+ // Value parsing
+ final double Tj = periodInteger.doubleValue();
+ final double Cj = exeInteger.doubleValue();
+ final BigDecimal TjBD = BigDecimal.valueOf(Tj);
+ final BigDecimal CjBD = BigDecimal.valueOf(Cj);
+
+ // flocalSum = Math.ceil(fl_value / Tj) * Cj;
+ flocalSum = fl_value.divide(TjBD, 0, BigDecimal.ROUND_UP).multiply(CjBD);
+
+ fSum = fSum.add(flocalSum);
+ }
+ final double Ci = AmaltheaServices.convertToPicoSeconds(thisExeTime).doubleValue();
+ // Fvalue of 1 iteration
+ // fl_value = fSum + j * Ci;
+ fl_value = BigDecimal.valueOf(fSum.doubleValue() + j * Ci);
+ }
+ // Final fl_value landed here
+ final double this_rt = fl_value.doubleValue() - (j - 1) * AmaltheaServices.convertToPicoSeconds(period).doubleValue();
+ rtList.add(this_rt);
+ }
+ final double rpt = Collections.max(rtList);
+ final Time responseTime = FactoryUtil.createTime(BigInteger.valueOf((long) rpt), TimeUnit.PS);
+ if (thisRT.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) > 0) {
+ this.cumuAcTime = this.cumuAcTime.add(rtaut.getTaskMemoryAccessTime(thisTask, pu, executionCase));
+ }
+ return responseTime;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Calculate the worst-case response time of the observed task according to the implicit periodic tasks response time analysis algorithm.
+ * @param task the observed task
+ * @param taskList list of tasks that is mapped to the same core
+ * @param executionCase BCET, ACET, WCET
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @param cpurta the instance of CPURta class that contains model & mapping IA info
+ * @return
+ * the worst-case response time of the observed task (implicit communication paradigm)
+ */
+ public Time implicitPreciseTest(final Task task, final List<Task> taskList, final TimeType executionCase,
+ final ProcessingUnit pu, final CPURta cpurta) {
+ Time thisRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Time period = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (taskList.size() == 0) {
+ log.debug("!!! This taskList is empty so I am returning MAX !!!");
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ /* to check if the given task is in the taskList */
+ int flag = 0;
+ int index = 0;
+ for (int i = 0; i < taskList.size(); i++) {
+ if (task.equals(taskList.get(i))) {
+ flag = 1;
+ index = i;
+ break;
+ }
+ }
+ if (flag == 0) {
+ log.debug("!!! Nothing in the taskList matches the given Task !!! So I am returning 0s" + " --- thisTask: " + task.getName());
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ for (int i = 0; i < index + 1; i++) {
+ period = CommonUtils.getStimInTime(taskList.get(i));
+ if (index == 0) {
+ thisRT = rtaut.getExecutionTimeforCPUTaskIA(taskList.get(i), pu, executionCase, cpurta);
+ final Time[] ta = rtaut.getLocalCopyTimeArray(taskList.get(i), pu, executionCase, cpurta);
+ for (int j = 0; j < ta.length; j++) {
+ thisRT = thisRT.add(ta[j]);
+ }
+ if (thisRT.compareTo(period) <= 0) {
+ return thisRT;
+ }
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the execution time of " + thisRT
+ + " for task " + task.getName());
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ } else if (i == index) {
+ /* In the case of a COOPERATIVE Preemption typed Task */
+ Time thisExeTime = rtaut.getExecutionTimeforCPUTaskIA(taskList.get(i), pu, executionCase, cpurta);
+ final Time[] ta = rtaut.getLocalCopyTimeArray(taskList.get(i), pu, executionCase, cpurta);
+ for (int j = 0; j < ta.length; j++) {
+ thisExeTime = thisExeTime.add(ta[j]);
+ }
+ if (thisExeTime.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) == 0) {
+ return thisExeTime;
+ } else if (thisExeTime.compareTo(period) > 0) {
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the execution time of " + thisRT
+ + " for task " + task.getName());
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ Time cumulativeRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ /* 1. add all the execution time till the index */
+ for (int j = 0; j < i + 1; j++) {
+ Time thisTime = rtaut.getExecutionTimeforCPUTaskIA(taskList.get(j), pu, executionCase, cpurta);
+ final Time[] ta_ = rtaut.getLocalCopyTimeArray(taskList.get(j), pu, executionCase, cpurta);
+ for (int k = 0; k < ta_.length; k++) {
+ thisTime = thisTime.add(ta[k]);
+ }
+ cumulativeRT = cumulativeRT.add(thisTime);
+ }
+ if (cumulativeRT.compareTo(period) <= 0) {
+ while (true) {
+ Time excepThisExeTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ for (int j = 0; j < i; j++) {
+ Time localPeriod = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ localPeriod = CommonUtils.getStimInTime(taskList.get(j));
+ Time preExeTime = rtaut.getExecutionTimeforCPUTaskIA(taskList.get(j), pu, executionCase, cpurta);
+ final Time[] ta_ = rtaut.getLocalCopyTimeArray(taskList.get(j), pu, executionCase, cpurta);
+ for (int k = 0; k < ta_.length; k++) {
+ preExeTime = preExeTime.add(ta_[k]);
+ }
+ final double ri_period = Math.ceil(cumulativeRT.divide(localPeriod));
+ excepThisExeTime = excepThisExeTime.add(preExeTime.multiply(ri_period));
+ }
+ Time cumulativeRT_x = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ cumulativeRT_x = thisExeTime.add(excepThisExeTime);
+ if (cumulativeRT_x.compareTo(period) <= 0) {
+ if (cumulativeRT_x.compareTo(cumulativeRT) == 0) {
+ thisRT = cumulativeRT_x;
+ return thisRT;
+ }
+ cumulativeRT = cumulativeRT_x;
+ } else {
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period
+ + " being less than the response time (cumulativeRT_x) of " + cumulativeRT_x + " for task " + task.getName());
+ if (SharedConsts.ignoreInfeasibility) {
+ return cumulativeRT_x;
+ }
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ }
+ }
+ log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the response time of " + cumulativeRT
+ + " for task " + task.getName());
+ if (SharedConsts.ignoreInfeasibility) {
+ return cumulativeRT;
+ }
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ }
+ return thisRT;
+ }
+
+ /**
+ * Calculate response time of the observed task according to the best-case RMS response time analysis algorithm with Implicit Communication.
+ * (source: https://www.researchgate.net/publication/3958297_Exact_best-case_response_time_analysis_of_fixed_priority_scheduled_tasks (equ_16))
+ * @param task the observed task
+ * @param taskList list of tasks that is mapped to the same core
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @return
+ * the best-case response time of the observed task with Implicit Communication
+ */
+ public Time implicitBCCPURT(final Task task, final List<Task> taskList, final ProcessingUnit pu, final CPURta cpurta) {
+ Time bcrt = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (taskList.size() == 0) {
+ log.debug("!!! This taskList is empty so I am returning MAX !!!");
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ } else if (!taskList.contains(task)) {
+ log.debug("!!! This taskList is empty so I am returning MAX !!!");
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ /* to check if the given task is in the taskList */
+ int flag = 0;
+ int index = 0;
+ for (int i = 0; i < taskList.size(); i++) {
+ if (task.equals(taskList.get(i))) {
+ flag = 1;
+ index = i;
+ break;
+ }
+ }
+ if (flag == 0) {
+ log.debug("!!! Nothing in the taskList matches the given Task !!! So I am returning 0s" + " --- thisTask: " + task.getName());
+ return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
+ }
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ Time bR_0 = this.implicitPreciseTest(task, taskList, TimeType.BCET, pu, cpurta);
+ for (int i = 0; i < index + 1; i++) {
+ if (index == 0) {
+ bcrt = bR_0;
+ break;
+ }
+ else if (i == index) {
+ Time i_BCET = rtaut.getExecutionTimeforCPUTaskIA(task, pu, TimeType.BCET, this);
+ final Time[] ta = rtaut.getLocalCopyTimeArray(task, pu, TimeType.BCET, this);
+ for (int j = 0; j < ta.length; j++) {
+ i_BCET = i_BCET.add(ta[j]);
+ }
+ final Time rt_0 = this.implicitPreciseTest(task, taskList, TimeType.BCET, pu, cpurta);
+ Time rt_n = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ boolean isItFirst = true;
+ while (true) {
+ Time sum = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ for (int j = 0; j < i; j++) {
+ final Task curTask = taskList.get(j);
+ final Time curTask_period = CommonUtils.getStimInTime(curTask);
+ Time curTask_BCET = rtaut.getExecutionTimeforCPUTaskIA(curTask, pu, TimeType.BCET, this);
+ final Time[] ta_ = rtaut.getLocalCopyTimeArray(curTask, pu, TimeType.BCET, this);
+ for (int k = 0; k < ta_.length; k++) {
+ curTask_BCET = curTask_BCET.add(ta[k]);
+ }
+ if (isItFirst) {
+ double ceil_value = Math.ceil((rt_0.subtract(curTask_period)).divide(curTask_period));
+ if (ceil_value < 0) {
+ ceil_value = 0;
+ }
+ final Time curIterTime = curTask_BCET.multiply(ceil_value);
+ sum = sum.add(curIterTime);
+ } else {
+ double ceil_value = Math.ceil((rt_n.subtract(curTask_period)).divide(curTask_period));
+ if (ceil_value < 0) {
+ ceil_value = 0;
+ }
+ final Time curIterTime = curTask_BCET.multiply(ceil_value);
+ sum = sum.add(curIterTime);
+ }
+ }
+ Time temp = i_BCET.add(sum);
+ System.out.println("sum: " + sum + ", temp: " + temp);
+ if(isItFirst) {
+ if (temp.compareTo(rt_0) == 0) {
+ bcrt = temp;
+ break;
+ } else {
+ rt_n = temp;
+ }
+ } else {
+ if (temp.compareTo(rt_n) == 0) {
+ bcrt = temp;
+ break;
+ } else {
+ rt_n = temp;
+ }
+ }
+ isItFirst = false;
+ }
+ }
+ }
+ return bcrt;
+ }
+
+ /**
+ * get the processing unit that the observed task is mapped to
+ * @param task the observed task
+ * @param cpurta the instance of CPURta class
+ * @return
+ * pu
+ */
+ protected ProcessingUnit getPU(final Task task, final CPURta cpurta) {
+ final int tindex = cpurta.getModel().getSwModel().getTasks().indexOf(task);
+ final int puindex = cpurta.getIA()[tindex];
+ final ProcessingUnit pu = cpurta.getPUl().get(puindex);
+ return pu;
+ }
+
+ /**
+ * get the sorted task listed based on the given integer array mapping
+ * @param task the observed task
+ * @param pu ProcessingUnit that would compute the given method
+ * @param cpurta the instance of CPURta class
+ * @return
+ * sortedTaskList
+ */
+ protected List<Task> getSortedTaskList(final Task task, final ProcessingUnit pu, final CPURta cpurta) {
+ final int puIndex = cpurta.getPUl().indexOf(pu);
+ /* 2. get all tasks mapped to this CPU */
+ final List<Task> puTaskList = new ArrayList<Task>();
+ for (int i = 0; i < cpurta.getIA().length; i++) {
+ if (cpurta.getIA()[i] == puIndex) {
+ puTaskList.add(cpurta.getModel().getSwModel().getTasks().get(i));
+ }
+ }
+ final List<Task> sortedTaskList = taskSorting(puTaskList);
+ return sortedTaskList;
+ }
+
+ /**
+ * get a list of tasks that are mapped to the same core and have a higher priority than the observed task has
+ * @param task the observed task
+ * @param cpurta the instance of CPURta class
+ * @return
+ * hpList
+ */
+ protected List<Task> getHigherPriorityTasks(final Task task, CPURta cpurta) {
+ final ProcessingUnit pu = getPU(task, cpurta);
+ final List<Task> hpList = getSortedTaskList(task, pu, cpurta);
+ final int index = hpList.indexOf(task);
+ final int count = hpList.size() - index;
+ for (int i = 0; i < count; i++) {
+ hpList.remove(hpList.size()-1);
+ }
+ return hpList;
+ }
+
+ /**
+ * get a list of tasks that are mapped to the same core and have a higher priority than the observed task has
+ * @param task the observed task
+ * @param cpurta the instance of CPURta class
+ * @return
+ * hpList
+ */
+ protected List<Task> getHigherPriorityTasksInChain(final Task task, final List<Task> chain) {
+ if (!chain.contains(task)) {
+ System.out.println("ERROR: The observed task chain does not contain the observed task.");
+ return null;
+ }
+ List<Time> periodList = chain.stream().map(s -> CommonUtils.getStimInTime(s)).collect(Collectors.toList());
+ /* Sorting (Shortest Period(Time) first) */
+ Collections.sort(periodList, new TimeCompIA());
+ final List<Task> sortedChain = new ArrayList<Task>();
+ for (int i = 0; i < periodList.size(); i++) {
+ final Time thisPeriod = periodList.get(i);
+ for (int j = 0; j < chain.size(); j++) {
+ final Task thisTask = chain.get(j);
+ if (thisPeriod.compareTo(CommonUtils.getStimInTime(thisTask)) == 0) {
+ if (!sortedChain.contains(thisTask)) {
+ sortedChain.add(thisTask);
+ break;
+ }
+ }
+ }
+ }
+ final int index = sortedChain.indexOf(task);
+ final List<Task> hpList = new ArrayList<Task>();
+ for (int i = 0; i < index; i++) {
+ hpList.add(sortedChain.get(i));
+ }
+ return hpList;
+ }
+
+ /**
+ * Visibility - public (This method is for EffectChainLatency)
+ * It returns HashMap<Integer, List<Task>> Type reference that contains an Integer(number of Processing Unit index) and the corresponding List of Tasks
+ * This is to visualize which task is mapped to which processing unit.
+ * @return
+ * HashMap<Integer, List<Task>> puListHashMap
+ */
+ public HashMap<Integer, List<Task>> getPUTaskListHashMap(final Amalthea model) {
+ final HashMap<Integer, List<Task>> puListHashMap = new HashMap<>();
+ final EList<Task> allTaskList = model.getSwModel().getTasks();
+ for (int i = 0; i < this.pul.size(); i++) {
+ final List<Task> puTaskList = new ArrayList<Task>();
+ for (int j = 0; j < this.tpuMapping.length; j++) {
+ final int puIndex = this.tpuMapping[j];
+ if (i == puIndex) {
+ puTaskList.add(allTaskList.get(j));
+ }
+ }
+ puListHashMap.put(i, taskSorting(puTaskList));
+ }
+ return puListHashMap;
+ }
+
+ @Override
+ public Time getRT(final Task t, final TimeType timeType) {
+ if (null == getTRT().get(t)) {
+ getRTSum(timeType);
+ }
+ return getTRT().get(t);
+ }
+}
+
+/**
+ * @author Junhyung Ki
+ * this inner class is used for the method "taskSorting" to help compare between two tasks' periods (which is longer)
+ */
+class TimeCompIA implements Comparator<Time> {
+ @Override
+ public int compare(final Time arg0, final Time arg1) {
+ if (arg0.compareTo(arg1) < 0) {
+ return -1;
+ }
+ return 1;
+ }
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CommonUtils.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CommonUtils.java
index 5097077..a49bd8b 100644
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CommonUtils.java
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CommonUtils.java
@@ -13,7 +13,6 @@
*******************************************************************************/
package org.eclipse.app4mc.gsoc_rta;
-import org.apache.log4j.Logger;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
@@ -31,39 +30,39 @@
import java.util.Set;
import java.util.stream.Collectors;
+import org.apache.log4j.Logger;
+import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.Amalthea;
import org.eclipse.app4mc.amalthea.model.AmaltheaFactory;
-import org.eclipse.app4mc.amalthea.model.CallSequence;
-import org.eclipse.app4mc.amalthea.model.CallSequenceItem;
+import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
import org.eclipse.app4mc.amalthea.model.DiscreteValueConstant;
import org.eclipse.app4mc.amalthea.model.DiscreteValueStatistics;
import org.eclipse.app4mc.amalthea.model.ExecutionNeed;
-import org.eclipse.app4mc.amalthea.model.GraphEntryBase;
+import org.eclipse.app4mc.amalthea.model.Frequency;
+import org.eclipse.app4mc.amalthea.model.Group;
import org.eclipse.app4mc.amalthea.model.HwDefinition;
import org.eclipse.app4mc.amalthea.model.IDiscreteValueDeviation;
import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
import org.eclipse.app4mc.amalthea.model.Label;
import org.eclipse.app4mc.amalthea.model.LabelAccess;
-import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
import org.eclipse.app4mc.amalthea.model.MappingModel;
import org.eclipse.app4mc.amalthea.model.PeriodicStimulus;
-import org.eclipse.app4mc.amalthea.model.Process;
import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
import org.eclipse.app4mc.amalthea.model.ProcessingUnitDefinition;
import org.eclipse.app4mc.amalthea.model.PuType;
import org.eclipse.app4mc.amalthea.model.Runnable;
-import org.eclipse.app4mc.amalthea.model.RunnableItem;
-import org.eclipse.app4mc.amalthea.model.SWModel;
+import org.eclipse.app4mc.amalthea.model.RunnableCall;
import org.eclipse.app4mc.amalthea.model.SchedulerAllocation;
import org.eclipse.app4mc.amalthea.model.Stimulus;
import org.eclipse.app4mc.amalthea.model.Task;
import org.eclipse.app4mc.amalthea.model.TaskAllocation;
-import org.eclipse.app4mc.amalthea.model.TaskRunnableCall;
+import org.eclipse.app4mc.amalthea.model.TaskScheduler;
import org.eclipse.app4mc.amalthea.model.Ticks;
import org.eclipse.app4mc.amalthea.model.Time;
import org.eclipse.app4mc.amalthea.model.TimeUnit;
import org.eclipse.app4mc.amalthea.model.UserSpecificSchedulingAlgorithm;
+import org.eclipse.app4mc.amalthea.model.util.DeploymentUtil;
import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
import org.eclipse.app4mc.amalthea.model.util.HardwareUtil;
import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil;
@@ -100,14 +99,14 @@
*/
public static Set<Label> getAccessedLabelSet(final Task t) {
final Set<Label> ls = new HashSet<Label>();
- for (final GraphEntryBase geb : t.getCallGraph().getGraphEntries()) {
- if (geb instanceof CallSequence) {
- final CallSequence cs = (CallSequence) geb;
- for (final CallSequenceItem csi : cs.getCalls()) {
- if (csi instanceof TaskRunnableCall) {
- final TaskRunnableCall trc = (TaskRunnableCall) csi;
+ for (final ActivityGraphItem geb : t.getActivityGraph().getItems()) {
+ if (geb instanceof Group) {
+ final Group cs = (Group) geb;
+ for (final ActivityGraphItem csi : cs.getItems()) {
+ if (csi instanceof RunnableCall) {
+ final RunnableCall trc = (RunnableCall) csi;
final Runnable r = trc.getRunnable();
- for (final RunnableItem ri : r.getRunnableItems()) {
+ for (final ActivityGraphItem ri : r.getRunnableItems()) {
if (ri instanceof LabelAccess) {
final LabelAccess la = (LabelAccess) ri;
ls.add(la.getData());
@@ -121,71 +120,6 @@
}
/**
- * @param l Label
- * @param swm Amalthea software model
- * @return Set of runnables which write label l
- */
- public static Set<Runnable> getWriterSetOfLabel(final Label l, final SWModel swm) {
- final Set<Runnable> rs = new HashSet<>();
- for (final Runnable r : swm.getRunnables()) {
- for (final RunnableItem ri : r.getRunnableItems()) {
- if (ri instanceof LabelAccess) {
- final LabelAccess la = (LabelAccess) ri;
- if (la.getData().equals(l) && la.getAccess().equals(LabelAccessEnum.WRITE)) {
- rs.add(r);
- }
- }
- }
- }
- return rs;
- }
-
- /**
- * @param l Label
- * @param swm Amalthea software model
- * @return Set of runnables which read label l
- */
- public static Set<Runnable> getReadersSetOfLabel(final Label l, final SWModel swm) {
- final Set<Runnable> rs = new HashSet<>();
- for (final Runnable r : swm.getRunnables()) {
- for (final RunnableItem ri : r.getRunnableItems()) {
- if (ri instanceof LabelAccess) {
- final LabelAccess la = (LabelAccess) ri;
- if (la.getData().equals(l) && la.getAccess().equals(LabelAccessEnum.READ)) {
- rs.add(r);
- }
- }
- }
- }
- return rs;
- }
-
- /**
- * @param r Runnable
- * @param swm Amalthea Software model
- * @return List of Processes that call runnable r (via taskRunnableCall)
- */
- public static List<Process> getProcesses(final Runnable r, final SWModel swm) {
- final List<Process> pl = new ArrayList<Process>();
- for (final Task t : swm.getTasks()) {
- for (final GraphEntryBase geb : t.getCallGraph().getGraphEntries()) {
- if (geb instanceof CallSequence) {
- final CallSequence cs = (CallSequence) geb;
- for (final CallSequenceItem csi : cs.getCalls()) {
- if (csi instanceof TaskRunnableCall) {
- final TaskRunnableCall trc = (TaskRunnableCall) csi;
- if (trc.getRunnable().equals(r)) {
- pl.add(t);
- }
- }
- }
- }
- }
- }
- return pl;
- }
-
- /**
* @param model Amalthea
* @return integer array size of tasks, that contains processing unit indexes
* for each task for the processing unit the tasks are mapped to according to
@@ -224,11 +158,11 @@
tsl = tsl * (tl.size() - tl.indexOf(t));
break;
case TSxUtil:
- final double util = getET(t, gpu).divide(getStimInTime(t));
+ final double util = RuntimeUtil.getExecutionTimeForProcess(t, gpu, null, SharedConsts.timeType).divide(getStimInTime(t));
tsl = (long) (util * SharedConsts.timeSliceLengthPS);
break;
case TSxUtilxNbTasks:
- final double util2 = getET(t, gpu).divide(getStimInTime(t));
+ final double util2 = RuntimeUtil.getExecutionTimeForProcess(t, gpu, null, SharedConsts.timeType).divide(getStimInTime(t));
tsl = (long) (util2 * tl.size() * SharedConsts.timeSliceLengthPS);
break;
default:
@@ -289,8 +223,8 @@
final TaskAllocation tsa = tsal.get(0);
Time time = ta[0];
if (null != ta[1]) {
- /*TODO handle min max*/
- /*setting time to average*/
+ /* TODO handle min max */
+ /* setting time to average */
time = time.add(ta[1]);
time.setValue(time.getValue().divide(BigInteger.valueOf(2)));
}
@@ -373,51 +307,122 @@
/**
* @param t Task
- * @param pu Processing Unit
- * @return Time execution time of t at pu
+ * @param amalthea Model
+ * @return Time execution time based on DeploymentUtil.getAssignedCoreForProcess
*/
- public static Time getET(final Task t, final ProcessingUnit pu) {
- Time ct = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- for (final ExecutionNeed en : SoftwareUtil.getExecutionNeeds(t, null)) {
- for (final Entry<String, IDiscreteValueDeviation> needs : en.getNeeds().entrySet()) {
- ct = ct.add(RuntimeUtil.getExecutionTimeForExecutionNeedEntry(needs.getValue(), null, pu, SharedConsts.timeType));
+ public static Time getSimpleET(final Task t, final Amalthea amalthea) {
+ final ProcessingUnit pu = DeploymentUtil.getAssignedCoreForProcess(t, amalthea).size() > 0
+ ? DeploymentUtil.getAssignedCoreForProcess(t, amalthea).iterator().next()
+ : getFirstMappedPuFromTask(amalthea, t);
+ final Time time = RuntimeUtil.getExecutionTimeForProcess(t, pu, null, SharedConsts.timeType);
+ return time;
+ }
+
+ private static ProcessingUnit getFirstMappedPuFromTask(final Amalthea amalthea, final Task t) {
+ for (final TaskAllocation ta : amalthea.getMappingModel().getTaskAllocation()) {
+ if (ta.getTask().equals(t) && ta.getAffinity().size() > 0) {
+ return ta.getAffinity().get(0);
}
}
- for (final Ticks ticks : getTicks(t)) {
- /* considers extended */
- ct = ct.add(RuntimeUtil.getExecutionTimeForTicks(ticks, pu, SharedConsts.timeType));
- }
- if (ct.getValue().toString().endsWith("999")) {
- ct.setValue(ct.getValue().add(BigInteger.ONE));
- }
- return ct;
+ return null;
}
/**
+ * Only returns execution time until the first InterProcessTrigger event
* @param t Task
- * @return set of Task t's ticks
+ * @param pu Processing Unit
+ * @return Time execution time of t at pu
*/
- public static Set<Ticks> getTicks(final Task t) {
- final Set<Ticks> tickss = new HashSet<>();
- for (final GraphEntryBase geb : t.getCallGraph().getGraphEntries()) {
- if (geb instanceof CallSequence) {
- final CallSequence cs = (CallSequence) geb;
- for (final CallSequenceItem csi : cs.getCalls()) {
- if (csi instanceof TaskRunnableCall) {
- final TaskRunnableCall trc = (TaskRunnableCall) csi;
- for (final RunnableItem ri : trc.getRunnable().getRunnableItems()) {
- if (ri instanceof Ticks) {
- final Ticks ticks = (Ticks) ri;
- tickss.add(ticks);
- }
+ public static Time getETPre(final Amalthea ama, final Task t, final ProcessingUnit pu, final int[] tpumap, final TimeType tt) {
+ Time ct = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (taskTriggersGPUTask(ama, t, tpumap)) {
+ final List<ActivityGraphItem> csil = SoftwareUtil.collectActivityGraphItems(t.getActivityGraph());
+ for (final ActivityGraphItem csi : csil) {
+ if (csi instanceof InterProcessTrigger) {
+ break;
+ }
+ else if (csi instanceof RunnableCall) {
+ final RunnableCall trc = (RunnableCall) csi;
+ for (final ExecutionNeed en : SoftwareUtil.getExecutionNeeds(trc.getRunnable(), null)) {
+ for (final Entry<String, IDiscreteValueDeviation> needs : en.getNeeds().entrySet()) {
+ ct = ct.add(RuntimeUtil.getExecutionTimeForExecutionNeedEntry(needs.getValue(), null, pu, tt));
}
}
+ for (final Ticks ticks : SoftwareUtil.getTicks(trc.getRunnable(), null)) {
+ /* considers extended */
+ ct = ct.add(getExecutionTimeForTicks(ticks, pu, tt));
+ }
}
}
}
- return tickss;
+ else {
+ Logger.getLogger(CommonUtils.class).debug("Task " + t.getName() + " does not trigger a GPU task");
+ return RuntimeUtil.getExecutionTimeForProcess(t, pu, null, tt);
+ }
+ return ct;
}
+ /*--------------------------------------BEGIN COPY FROM RUNTIMEUTIL------------------------------------------------*/
+ /**
+ * FIX for APP4MC<0.9.6
+ * @param ticks
+ * @param pu
+ * @param tt
+ * @return Time execution time for a given Ticks value derived from given ProcessingUnit and TimeType
+ */
+ public static Time getExecutionTimeForTicks(final Ticks ticks, final ProcessingUnit pu, final TimeType tt) {
+ Time result = FactoryUtil.createTime();
+
+ if (ticks.getExtended().get(pu.getDefinition()) != null) {
+ final IDiscreteValueDeviation deviation = ticks.getExtended().get(pu.getDefinition());
+ result = getExecutionTimeForTicksDeviation(deviation, pu, tt);
+ }
+ else {
+ result = getExecutionTimeForTicksDeviation(ticks.getDefault(), pu, tt);
+ }
+ return result;
+ }
+
+ /**
+ * FIX for APP4MC<0.9.6
+ * @param deviation
+ * @param pu
+ * @param tt
+ * @return Time execution time for a given IDiscreteValueDeviation value derived from given ProcessingUnit and TimeType
+ */
+ private static Time getExecutionTimeForTicksDeviation(final IDiscreteValueDeviation deviation, final ProcessingUnit pu, final TimeType tt) {
+ double ticks = 0d;
+ switch (tt) {
+ case BCET:
+ ticks = deviation.getLowerBound().doubleValue();
+ break;
+ case ACET:
+ ticks = deviation.getAverage();
+ break;
+ case WCET:
+ ticks = deviation.getUpperBound().doubleValue();
+ break;
+ }
+ final Time result = getExecutionTimeForCycles(ticks, pu.getFrequencyDomain().getDefaultValue());
+ return result;
+ }
+
+ /**
+ * FIX for APP4MC<0.9.6
+ * @param ticks Double
+ * @param frequency
+ * @return Time execution time for a given double value derived from the frequency
+ */
+ public static Time getExecutionTimeForCycles(final double ticks, final Frequency frequency) {
+ final double cyclesPerSecond = AmaltheaServices.convertToHertz(frequency).doubleValue();
+ final double factor = 1.0d / cyclesPerSecond;
+ final Time oneSecond = FactoryUtil.createTime(1, TimeUnit.S);
+ final Time t1 = oneSecond.multiply(ticks);
+ final Time result = t1.multiply(factor);
+ return result.adjustUnit();
+ }
+ /*--------------------------------------END COPY FROM RUNTIMEUTIL------------------------------------------------*/
+
/**
* @param amalthea Amalthea model
@@ -426,12 +431,18 @@
*/
public static List<PeriodicStimulus> getSortedStim(final Amalthea amalthea, final boolean... onlyGPUStim) {
final List<PeriodicStimulus> stimListSorted = new ArrayList<PeriodicStimulus>();
- final List<Task> tl = amalthea.getMappingModel().getTaskAllocation().stream()
- .filter(ta -> ta.getAffinity().get(0).getDefinition().getPuType().equals(PuType.GPU)).map(ta -> ta.getTask()).collect(Collectors.toList());
+ List<Task> tl = null;
+ if (null != onlyGPUStim && onlyGPUStim.length > 0) {
+ if (onlyGPUStim[0]) {
+ tl = amalthea.getMappingModel().getTaskAllocation().stream()
+ .filter(ta -> ta.getAffinity().get(0).getDefinition().getPuType().equals(PuType.GPU)).map(ta -> ta.getTask())
+ .collect(Collectors.toList());
+ }
+ }
for (final Stimulus s : amalthea.getStimuliModel().getStimuli()) {
if (s instanceof PeriodicStimulus) {
final PeriodicStimulus ps = (PeriodicStimulus) s;
- if (null != onlyGPUStim && onlyGPUStim[0]) {
+ if (null != onlyGPUStim && onlyGPUStim.length > 0 && null != tl) {
for (final Task t : tl) {
if (t.getStimuli().contains(ps) && !stimListSorted.contains(ps)) {
stimListSorted.add(ps);
@@ -478,9 +489,8 @@
}
/**
- * Logs mutliple stimuli / stimuli != (Periodic,InterProcessTrigger)
* @param t Task
- * @return PeriodicStimulus of Task t
+ * @return PeriodicStimulus of Task t or if t is triggered by interProcessStimulus, the PeriodicStimulus of the triggering task is returned
*/
public static PeriodicStimulus getStim(final Task t) {
final Logger log = Logger.getLogger(CommonUtils.class);
@@ -495,8 +505,6 @@
}
if (s instanceof InterProcessStimulus) {
final InterProcessStimulus ips = (InterProcessStimulus) s;
- // final List<Process> triggers = ips.getExplicitTriggers().stream().map(ipt -> ipt.getContainingProcess()).collect(Collectors.toList());
- // final Time rec = ((PeriodicStimulus) triggers.get(0).getStimuli().get(0)).getRecurrence();
final Task trigger = getFirstTrigger(ips);
return ((PeriodicStimulus) trigger.getStimuli().get(0));
}
@@ -513,10 +521,10 @@
private static Task getFirstTrigger(final InterProcessStimulus ips) {
final Amalthea model = (Amalthea) ips.eContainer().eContainer();
for (final Task t : model.getSwModel().getTasks()) {
- for (final GraphEntryBase geb : t.getCallGraph().getGraphEntries()) {
- if (geb instanceof CallSequence) {
- final CallSequence cs = (CallSequence) geb;
- for (final CallSequenceItem csi : cs.getCalls()) {
+ for (final ActivityGraphItem geb : t.getActivityGraph().getItems()) {
+ if (geb instanceof Group) {
+ final Group cs = (Group) geb;
+ for (final ActivityGraphItem csi : cs.getItems()) {
if (csi instanceof InterProcessTrigger) {
final InterProcessTrigger ipt = (InterProcessTrigger) csi;
if (ipt.getStimulus().equals(ips)) {
@@ -532,7 +540,10 @@
return null;
}
- /** requires mapping model*/
+ /**
+ * requires mapping model within the given AMALTHEA model. Prints all task acllocations into log.
+ * @param amalthea Model
+ */
public void printTaskAllocs(final Amalthea amalthea) {
final Logger log = Logger.getLogger(this.getClass().getName().substring(this.getClass().getName().lastIndexOf("." + 1)));
for (final TaskAllocation ta : amalthea.getMappingModel().getTaskAllocation()) {
@@ -557,11 +568,11 @@
il.add(gpus.indexOf(pu));
}
}
- /*il = only indexes of GPUs*/
+ /* il = only indexes of GPUs */
final List<Task> gpuTasks = new ArrayList<Task>();
for (int i = 0; i < mapping.length; i++) {
if (il.contains(mapping[i])) {
- /*task i is mapped tp a GPU*/
+ /* task i is mapped tp a GPU */
gpuTasks.add(am.getSwModel().getTasks().get(i));
}
}
@@ -570,13 +581,7 @@
tl.sort(new Comparator<Task>() {
@Override
public int compare(final Task t1, final Task t2) {
- final List<Stimulus> psl1 = t1.getStimuli().stream().filter(s -> s instanceof PeriodicStimulus).collect(Collectors.toList());
- final List<Stimulus> psl2 = t2.getStimuli().stream().filter(s -> s instanceof PeriodicStimulus).collect(Collectors.toList());
- if (psl1.size() != 1 || psl2.size() != 1) {
- Logger.getLogger("CommonUtils").debug("Task " + t1.getName() + " has no periodic stimulus.");
- return 0;
- }
- return ((PeriodicStimulus) psl1.get(0)).getRecurrence().compareTo(((PeriodicStimulus) psl2.get(0)).getRecurrence());
+ return (CommonUtils.getStimInTime(t1).compareTo(CommonUtils.getStimInTime(t2)));
}
});
return tl;
@@ -586,24 +591,34 @@
public static boolean isSchedulable(final List<Task> tl, final ProcessingUnit pu) {
Double sum = 0d;
for (final Task t : tl) {
- final Time et = CommonUtils.getET(t, pu);
+ final Time et = RuntimeUtil.getExecutionTimeForProcess(t, pu, null, SharedConsts.timeType);
final Time per = getStimInTime(t);
sum += et.divide(per);
}
return sum > 1 ? false : true;
}
- /** Creates a Mapping Model from a Chromosome; Decreases efficiency */
+ /** Creates a Mapping Model from an integer array*/
public static MappingModel createMMFromIA(final Amalthea amalthea, final int[] ia) {
final List<ProcessingUnit> pul = getPUs(amalthea);
final MappingModel mm = AmaltheaFactory.eINSTANCE.createMappingModel();
- for (int i = 0; i < amalthea.getSwModel().getTasks().size(); i++) {
- // for (final IntegerGene ig : chromosome) {
- final TaskAllocation ta = AmaltheaFactory.eINSTANCE.createTaskAllocation();
- ta.setTask(amalthea.getSwModel().getTasks().get(i));
- ta.getAffinity().add(pul.get(ia[i]));
- ta.getParameterExtensions().put("Timeslice", "7200us");
- mm.getTaskAllocation().add(ta);
+ for (final ProcessingUnit pu : pul) {
+ final TaskScheduler ts = AmaltheaFactory.eINSTANCE.createTaskScheduler();
+ final SchedulerAllocation sa = AmaltheaFactory.eINSTANCE.createSchedulerAllocation();
+ sa.setExecutingPU(pu);
+ sa.getResponsibility().add(pu);
+ ts.setName("TS_" + pu.getName());
+ sa.setScheduler(ts);
+ for (int i = 0; i < amalthea.getSwModel().getTasks().size(); i++) {
+ if (pul.get(ia[i]).equals(pu)) {
+ final TaskAllocation ta = AmaltheaFactory.eINSTANCE.createTaskAllocation();
+ ta.setTask(amalthea.getSwModel().getTasks().get(i));
+ ta.getAffinity().add(pul.get(ia[i]));
+ ta.setScheduler(ts);
+ mm.getTaskAllocation().add(ta);
+ }
+ }
+ mm.getSchedulerAllocation().add(sa);
}
return mm;
}
@@ -664,6 +679,8 @@
return pus;
}
+ @SuppressWarnings("resource")
+ /** writes a stringbuffer into either measurements.csv or optional @param filename */
public static void writeCSV(final StringBuffer sbp, final String... filenamep) {
if (null == sbp) {
Logger.getLogger(CommonUtils.class).error("Nothing to write. Probably, the system is not schedulable.");
@@ -697,13 +714,13 @@
Time time = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
final List<InterProcessTrigger> ipts = getTriggered(t);
final List<ProcessingUnit> pul = CommonUtils.getPUs(model);
- /*task triggers other task*/
+ /* task triggers other task */
for (final InterProcessTrigger ipt : ipts) {
final List<Task> triggered = model.getSwModel().getTasks().stream().filter(task -> task.getStimuli().get(0).equals(ipt.getStimulus()))
.collect(Collectors.toList());
for (final Task task : triggered) {
final ProcessingUnit pu = pul.get(ia[model.getSwModel().getTasks().indexOf(task)]);
- time = time.add(RuntimeUtil.getExecutionTimeForProcess(task, pu, null, TimeType.WCET));
+ time = time.add(RuntimeUtil.getExecutionTimeForProcess(task, pu, null, SharedConsts.timeType));
}
}
return time;
@@ -717,7 +734,7 @@
public static List<Task> getTriggeredTasks(final Amalthea ama, final Task t) {
final List<Task> tl = new ArrayList<>();
final List<InterProcessTrigger> ipts = getTriggered(t);
- /*task triggers other task*/
+ /* task triggers other task */
for (final InterProcessTrigger ipt : ipts) {
tl.addAll(ama.getSwModel().getTasks().stream().filter(task -> task.getStimuli().get(0).equals(ipt.getStimulus())).collect(Collectors.toList()));
}
@@ -731,7 +748,7 @@
*/
public static long getTicksLongForPU(final ProcessingUnit pu, final Task t) {
long sum = 0;
- for (final Ticks ticks : CommonUtils.getTicks(t)) {
+ for (final Ticks ticks : SoftwareUtil.getTicks(t, null)) {
if (null != ticks && null != ticks.getExtended() && null != ticks.getExtended().get(pu.getDefinition())) {
if (null != ticks.getExtended().get(pu.getDefinition())) {
@@ -753,18 +770,14 @@
/**
* @param t
- * @return List of tasks triggered by Task t via interProcessTrigger CallSequenceItem
+ * @return List of interProcessTriggers of Task t
*/
public static List<InterProcessTrigger> getTriggered(final Task t) {
- /*DOES NOT WORK*/
- // t.getCallGraph().getGraphEntries().stream().filter(geb -> geb instanceof CallSequence)
- // .map(cs -> ((CallSequence) cs).getCalls()).filter(csi -> csi instanceof InterProcessTrigger).map(csi -> ((InterProcessTrigger) csi))
- // .collect(Collectors.toList());
final List<InterProcessTrigger> iptl = new ArrayList<>();
- for (final GraphEntryBase geb : t.getCallGraph().getGraphEntries()) {
- if (geb instanceof CallSequence) {
- final CallSequence cs = (CallSequence) geb;
- for (final CallSequenceItem csi : cs.getCalls()) {
+ for (final ActivityGraphItem geb : t.getActivityGraph().getItems()) {
+ if (geb instanceof Group) {
+ final Group cs = (Group) geb;
+ for (final ActivityGraphItem csi : cs.getItems()) {
if (csi instanceof InterProcessTrigger) {
final InterProcessTrigger ipt = (InterProcessTrigger) csi;
iptl.add(ipt);
@@ -776,6 +789,59 @@
}
/**
+ * @param Amalthea model ama
+ * @param Task t
+ * @return List of Tasks triggered by Task t
+ */
+ public static List<Task> getTriggered(final Amalthea ama, final Task t) {
+ final List<Task> tl = new ArrayList<>();
+ for (final ActivityGraphItem geb : t.getActivityGraph().getItems()) {
+ if (geb instanceof Group) {
+ final Group cs = (Group) geb;
+ for (final ActivityGraphItem csi : cs.getItems()) {
+ if (csi instanceof InterProcessTrigger) {
+ final InterProcessTrigger ipt = (InterProcessTrigger) csi;
+ for (final Task tmp : ama.getSwModel().getTasks()) {
+ if (tmp.getStimuli().get(0) instanceof InterProcessStimulus) {
+ final InterProcessStimulus ips = (InterProcessStimulus) tmp.getStimuli().get(0);
+ if (ips.equals(ipt.getStimulus())) {
+ tl.add(tmp);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return tl;
+ }
+
+ /**
+ * Returns the first task within the given AMALTHEA model, which has the given InterProcessStimulus as a stimulus.
+ * @param amalthea model to search tasks
+ * @param ips interProcessStimulus to check
+ * @return the task, that is activated by the IPS
+ */
+ public static Task getTrigger(final Amalthea amalthea, final InterProcessStimulus ips) {
+ for (final Task t : amalthea.getSwModel().getTasks()) {
+ for (final ActivityGraphItem geb : t.getActivityGraph().getItems()) {
+ if (geb instanceof Group) {
+ final Group cs = (Group) geb;
+ for (final ActivityGraphItem csi : cs.getItems()) {
+ if (csi instanceof InterProcessTrigger) {
+ final InterProcessTrigger iptc = (InterProcessTrigger) csi;
+ if (iptc.getStimulus().getName().equals(ips.getName())) {
+ return t;
+ }
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
* @param model Amalthea
* @param ia task to processing unit mapping int array
* @param t Task under consideration
@@ -784,7 +850,7 @@
public static long getTicksLongOfTriggeredTask(final Amalthea model, final int[] ia, final Task t) {
final List<InterProcessTrigger> ipts = getTriggered(t);
long ticks = 0;
- /*task triggers other task*/
+ /* task triggers other task */
for (final InterProcessTrigger ipt : ipts) {
final List<Task> triggered = model.getSwModel().getTasks().stream().filter(task -> task.getStimuli().get(0).equals(ipt.getStimulus()))
.collect(Collectors.toList());
@@ -803,10 +869,38 @@
public static StringBuffer appendConfig(final String model, final int[] mapping) {
final StringBuffer sbl = new StringBuffer();
sbl.append(
- "Configuration:\n Model,Mapping,SyncOffloading,UseModelTimeSlices,TimeSliceDerication,TimeSliceLengthInPSDefault,LevelI,TimeType,CEOnlyWrittenLabels,IgnoreInfeasibility\n");
+ "Configuration:\n Model,Mapping,SyncOffloading,UseModelTimeSlices,TimeSliceDerication,TimeSliceLengthInPSDefault,LevelI,TimeType,CEOnlyWrittenLabels,IgnoreInfeasibility,OffsetRTA\n");
sbl.append(model + "," + Arrays.toString(mapping).replace(",", ";") + "," + SharedConsts.synchronousOffloading + "," + SharedConsts.useModelTimeSlices
+ "," + SharedConsts.tsDeriv + "," + SharedConsts.timeSliceLengthPS + "," + SharedConsts.levelIBusyPeriod + "," + SharedConsts.timeType + ","
- + SharedConsts.onlyWrittenLabelsCE + "," + SharedConsts.ignoreInfeasibility + "\n");
+ + SharedConsts.onlyWrittenLabelsCE + "," + SharedConsts.ignoreInfeasibility + "," + SharedConsts.offsetCPURTA + "\n");
return sbl;
}
+
+ /**
+ * Determines whether given processing unit as index is a GPU or CPU
+ * @param pul list of PUs, of which GPUs are at the list's tail (end)
+ * @param index of the PU within given list to be chaecked
+ * @return true if pu index is a GPU
+ */
+ public static boolean isGPUTask(final List<ProcessingUnit> pul, final int index) {
+ if (pul.get(index).getDefinition().getPuType().equals(PuType.CPU)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @param ama Amalthea model
+ * @param t Task
+ * @param tpumap Task to PU mapping
+ * @return true, if triggered task is mapped to GPU
+ */
+ public static boolean taskTriggersGPUTask(final Amalthea ama, final Task t, final int[] tpumap) {
+ for (final Task trigger : getTriggered(ama, t)) {
+ if (tpumap[ama.getSwModel().getTasks().indexOf(trigger)] >= getNumberofCPUs(ama)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/Contention.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/Contention.java
index c68bf5d..ed5127e 100644
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/Contention.java
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/Contention.java
@@ -21,8 +21,8 @@
import java.util.stream.Collectors;
import org.eclipse.app4mc.gsoc_rta.CommonUtils;
+import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.Amalthea;
-import org.eclipse.app4mc.amalthea.model.CallSequenceItem;
import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
import org.eclipse.app4mc.amalthea.model.Label;
@@ -32,9 +32,9 @@
import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
import org.eclipse.app4mc.amalthea.model.PuType;
import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.RunnableCall;
import org.eclipse.app4mc.amalthea.model.SetEvent;
import org.eclipse.app4mc.amalthea.model.Task;
-import org.eclipse.app4mc.amalthea.model.TaskRunnableCall;
import org.eclipse.app4mc.amalthea.model.Time;
import org.eclipse.app4mc.amalthea.model.TimeUnit;
import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
@@ -50,12 +50,16 @@
private final int[] ia;
private final Amalthea model;
private final int[] flagArray;
- private final HashMap<Task, List<Label>[]> gpuLabels = new HashMap<Task, List<Label>[]>();
+ private final HashMap<Task, List<List<Label>>> gpuLabels = new HashMap<Task, List<List<Label>>>();
public Contention(final int[] iap, final Amalthea modelp) {
this.ia = iap;
this.model = modelp;
- this.flagArray = new int[iap.length];
+ if(iap != null) {
+ this.flagArray = new int[iap.length];
+ return ;
+ }
+ this.flagArray = null;
}
/**
@@ -79,12 +83,10 @@
}
/**
- * Initiallize hashmap contain GPU tasks' labels hashmap <task, List<label>> (readList = hashmap.get(task)[0];)
+ * Initiallize hashmap contain GPU tasks' labels hashmap <task, List<label>> (readList = hashmap.get(task)[0];)
* and create flagarray that have the same length with our integerArray, then loop through all the PRE_POST tasks ( via looking for InterProcessStimulus) and check whether the triggered task (GPU task) are located on GPU or not, if it is, then I will give the value of that task in flagArray equal 1. It will look like this
-
- ia = { 5, 1, 5, 0, 1, 0, 2, 1, 2, 1, 6, 3, 4, 6 } - our mapping array
- fa = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,} - the flag array
- *
+ * ia = { 5, 1, 5, 0, 1, 0, 2, 1, 2, 1, 6, 3, 4, 6 } - our mapping array
+ * fa = { 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,} - the flag array
* @param tpumapping (or ia)
*/
private void setUpFlagArrayAndHashMap(final int[] iap) {
@@ -96,6 +98,9 @@
for (final Task t : gpuTask) {
/* shotting task => t.getName */
final List<SetEvent> shottingTaskEvent = SoftwareUtil.collectSetEvents(t, null);
+ if (shottingTaskEvent.size() < 1) {
+ continue;
+ }
final Process shottingTask = shottingTaskEvent.get(0).getProcess();
final int shotIndex = this.model.getSwModel().getTasks().indexOf(shottingTask);
final int gpuIndex = this.model.getSwModel().getTasks().indexOf(t);
@@ -106,8 +111,8 @@
/* create HashMap for GPU task that mapped to CPU start here*/
final List<Label> readLabelList = new ArrayList<Label>();
final List<Label> writeLabelList = new ArrayList<Label>();
- final List<CallSequenceItem> callList = SoftwareUtil.collectCalls(shottingTask);
- final CallSequenceItem ipt = callList.stream().filter(a -> a instanceof InterProcessTrigger).iterator().next();
+ final List<ActivityGraphItem> callList = SoftwareUtil.collectActivityGraphItems(shottingTask.getActivityGraph());
+ final ActivityGraphItem ipt = callList.stream().filter(a -> a instanceof InterProcessTrigger).iterator().next();
/*
* get the position of InterProcessTrigger within task taking
* readLabel and write labels from pre and post processing (
@@ -118,8 +123,8 @@
for (int i = 0; i < callList.size(); i++) {
Runnable thisRunnable = null;
/* Pre-processing Runnable */
- if ((i < indexforTrigger) && (callList.get(i) instanceof TaskRunnableCall)) {
- thisRunnable = ((TaskRunnableCall) callList.get(i)).getRunnable();
+ if ((i < indexforTrigger) && (callList.get(i) instanceof RunnableCall)) {
+ thisRunnable = ((RunnableCall) callList.get(i)).getRunnable();
final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(thisRunnable, null);
for (final LabelAccess la : thisLAList) {
if (la.getAccess().equals(LabelAccessEnum.READ)) {
@@ -128,8 +133,8 @@
}
}
/* Post-processing Runnable */
- else if ((i > indexforTrigger) && (callList.get(i) instanceof TaskRunnableCall)) {
- thisRunnable = ((TaskRunnableCall) callList.get(i)).getRunnable();
+ else if ((i > indexforTrigger) && (callList.get(i) instanceof RunnableCall)) {
+ thisRunnable = ((RunnableCall) callList.get(i)).getRunnable();
final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(thisRunnable, null);
for (final LabelAccess la : thisLAList) {
if (la.getAccess().equals(LabelAccessEnum.WRITE)) {
@@ -139,9 +144,9 @@
}
}
- final List<Label>[] aryofLabelList = new ArrayList[2];
- aryofLabelList[0] = readLabelList;
- aryofLabelList[1] = writeLabelList;
+ final List<List<Label>> aryofLabelList = new ArrayList<List<Label>>();
+ aryofLabelList.add(readLabelList);
+ aryofLabelList.add(writeLabelList);
this.gpuLabels.put(t, aryofLabelList);
// HashMap created with <Task, ArrayofLabelList>
}
@@ -157,7 +162,6 @@
public Time contentionForTask(final Task task) {
/* Initialize hashmap */
setUpFlagArrayAndHashMap(this.ia);
-
final Time time = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
/**
* Constant and variable init, change those constant for different model number
@@ -222,7 +226,7 @@
final Set<Runnable> wL = SoftwareUtil.getWriterSetOfLabel(l, null);
for (final Runnable r : wL) {
- final List<Process> lT = SoftwareUtil.getProcesses(r, null);
+ final List<Process> lT = SoftwareUtil.getCallingProcesses(r, null);
for (final Process lTT : lT) {
/* get related task through checking which runnable are accessing the same label
* put the task that contain those runnable into b2 and the core of that task in c2
@@ -251,7 +255,7 @@
final Set<Runnable> rL = SoftwareUtil.getReadersSetOfLabel(l, null);
for (final Runnable r : rL) {
- final List<Process> lT1 = SoftwareUtil.getProcesses(r, null);
+ final List<Process> lT1 = SoftwareUtil.getCallingProcesses(r, null);
for (final Process lTT1 : lT1) {
/* get related task through checking which runnable are accessing the same label
* put the task that contain those runnable into b2 and the core of that task in c2
@@ -361,8 +365,8 @@
final int shotIndex = this.model.getSwModel().getTasks().indexOf(shottingTask);
if (this.flagArray[shotIndex] == 1) {
- final List<Label> readList = this.gpuLabels.get(task)[0];
- final List<Label> writeList = this.gpuLabels.get(task)[1];
+ final List<Label> readList = this.gpuLabels.get(task).get(0);
+ final List<Label> writeList = this.gpuLabels.get(task).get(1);
for (final Label l : readList) {
sumCycle += (long) Math.ceil(l.getSize().getNumberBytes() / 64.0);
@@ -487,7 +491,7 @@
final Set<Runnable> wL = SoftwareUtil.getWriterSetOfLabel(l, null);
for (final Runnable r : wL) {
- final List<Process> lT = SoftwareUtil.getProcesses(r, null);
+ final List<Process> lT = SoftwareUtil.getCallingProcesses(r, null);
for (final Process lTT : lT) {
for (int taskIndex = 0; taskIndex < this.ia.length; taskIndex++) {
@@ -517,7 +521,7 @@
}
final Set<Runnable> rL = SoftwareUtil.getReadersSetOfLabel(l, null);
for (final Runnable r : rL) {
- final List<Process> lT1 = SoftwareUtil.getProcesses(r, null);
+ final List<Process> lT1 = SoftwareUtil.getCallingProcesses(r, null);
for (final Process lTT1 : lT1) {
for (int taskIndex = 0; taskIndex < this.ia.length; taskIndex++) {
final ProcessingUnit pup = pul.get(this.ia[taskIndex]);
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CpuRTA.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CpuRTA.java
deleted file mode 100644
index 4febdc0..0000000
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/CpuRTA.java
+++ /dev/null
@@ -1,587 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors: FH Dortmund - initial API and implementation
- *
- *******************************************************************************/
-package org.eclipse.app4mc.gsoc_rta;
-
-import java.io.File;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.apache.log4j.Logger;
-import org.eclipse.app4mc.amalthea.model.Amalthea;
-import org.eclipse.app4mc.amalthea.model.CallSequenceItem;
-import org.eclipse.app4mc.amalthea.model.ClearEvent;
-import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
-import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
-import org.eclipse.app4mc.amalthea.model.Label;
-import org.eclipse.app4mc.amalthea.model.LabelAccess;
-import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
-import org.eclipse.app4mc.amalthea.model.Preemption;
-import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
-import org.eclipse.app4mc.amalthea.model.PuType;
-import org.eclipse.app4mc.amalthea.model.Runnable;
-import org.eclipse.app4mc.amalthea.model.SetEvent;
-import org.eclipse.app4mc.amalthea.model.Task;
-import org.eclipse.app4mc.amalthea.model.TaskRunnableCall;
-import org.eclipse.app4mc.amalthea.model.Time;
-import org.eclipse.app4mc.amalthea.model.TimeUnit;
-import org.eclipse.app4mc.amalthea.model.WaitEvent;
-import org.eclipse.app4mc.amalthea.model.io.AmaltheaLoader;
-import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
-import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
-import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
-import org.eclipse.emf.common.util.EList;
-
-/**
- * Date: June 21-2019
- * @author Junhyung Ki
- * @version 1.0
- * This class is to analyze Response Times of CPU(e.g., ARM, Denver cores) Tasks in a CPU-GPU Heterogeneous System
- * The entire class is designed for Generic Algorithm Mapping to find the most optimized task mapping solution.
- * Therefore, setting the integer array variable, 'tpuMapping' (which is considered as a mapping solution) along with
- * others ( Amalthea Model, 'model' setting, Task Response Time HashMap, 'trt' setting (for GPU Tasks), Processing Unit List, 'pul' setting
- * should be the first step before executing any response time method.
- */
-public class CpuRTA {
- public final File inputFile = new File("model-input/WATERS19_release/ChallengeModel_release.amxmi");
-
- /**
- * Get Default IA Map
- * @return
- * this.defaultIAMapping
- */
- public int[] getDefaultIAMapping() {
- return SharedConsts.defaultIAMapping;
- }
-
- private Amalthea model;
-
- /**
- * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
- *
- * @return
- * The Amalthea model object of the current CPURtaIA class
- */
- public Amalthea getModel() {
- return this.model;
- }
-
- /**
- * Set the Amalthea model object of the current CPURtaIA class as the given Amalthea model parameter.
- *
- * @param pAmalthea the parameter Amalthea model which would reinitialize the Amalthea model
- */
- public void setModel(final Amalthea pAmalthea) {
- this.model = pAmalthea;
- this.setGTCL(this.model);
- }
-
- private HashMap<Task, Time> trt = null;
-
- /**
- * Since this method is used by GAMapping, the visibility should be 'public'
- *
- * @return
- * trt(task with response time) HashMap variable
- */
- public HashMap<Task, Time> getTRT() {
- return this.trt;
- }
-
- /**
- * Set the trt(task with response time) HashMap variable as the given trtp parameter variable.
- * Which would contains GPU tasks' response times from the beginning
- *
- * @param trtp the HashMap variable parameter which would reinitialize the trt variable of the current CPURtaIA class.
- */
- public void setTRT(final HashMap<Task, Time> trtp) {
- this.trt = trtp;
- }
-
- /**
- * Get the default trt(task with response time) value in case of running CPURtaIA class itself.
- *
- * @param model the current class's Amalthea model which is used to get the trt value out of it
- * @return
- * the trt value which is derived out of the given parameter Amalthea model
- */
- public HashMap<Task, Time> getDefaultTRT(final Amalthea model) {
- final HashMap<Task, Time> trt = new HashMap<Task, Time>();
- final EList<Task> allTaskList = model.getSwModel().getTasks();
- final long val = 2000000000;
- for (final Task t : allTaskList) {
- if (this.gpuTaskList.contains(t)) {
- trt.put(t, FactoryUtil.createTime(BigInteger.valueOf(val), TimeUnit.PS));
- }
- else {
- trt.put(t, FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS));
- }
- }
- return trt;
- }
-
- private int[] tpuMapping = null;
-
- /**
- * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
- *
- * @return
- * The tpuMapping integer array
- */
- public int[] getIA() {
- return this.tpuMapping;
- }
-
- /**
- * Set the tpuMapping integer array (which would be used to modify the current task mapping to different Processing Units)
- * as the given tpumap parameter variable.
- * (The integer array would be used to modify the current task mapping to different Processing Units)
- *
- * @param tpumap the parameter integer array which would reinitialize the tpuMapping array of the current CPURtaIA class.
- */
- public void setIA(final int[] tpumap) {
- final Logger log = Logger.getLogger(CpuRTA.class);
- if (tpumap == null) {
- this.tpuMapping = null;
- }
- else if (tpumap.length == this.model.getSwModel().getTasks().size()) {
- this.tpuMapping = tpumap;
- }
- else {
- log.error("integer array size MUST match the number of tasks");
- }
- }
-
- private List<ProcessingUnit> pul = new ArrayList<>();
-
- /**
- * Get a list of ProcessingUnits
- *
- * @return
- * this.pul
- */
- public List<ProcessingUnit> getPUl() {
- return this.pul;
- }
-
- /**
- * Set the pul, the list of Processing Units variable (which would be used to map tasks along with tpuMapping array)
- * as the given pul parameter variable.
- *
- * @param pul the parameter pul list which would reinitialize the pul list variable of the current CPURtaIA class
- */
- public void setPUl(final List<ProcessingUnit> pul) {
- this.pul = pul;
- }
-
- //TODO: Contention not considered
-
- private List<Task> gpuTaskList = new ArrayList<Task>();
-
- /**
- * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
- *
- * @return
- * gpuTaskList which contains tasks (which are originally designed for GPU) of the Amalthea model
- */
- protected List<Task> getGpuTaskList() {
- return this.gpuTaskList;
- }
-
- private final List<Task> triggeringTaskList = new ArrayList<Task>();
- /**
- * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
- *
- * @return
- * triggeringTaskList which contains tasks (which contain InterProcessTrigger) of the Amalthea model
- */
- protected List<Task> getTriggeringTaskList() {
- return this.triggeringTaskList;
- }
-
- /* this runnable is used to calculate execution time in RTARuntimeUtil class */
- protected Runnable offloadingAsyncRunnable = null;
-
- private final HashMap<Task, List<Label>[]> gpuToCpuLabels = new HashMap<Task, List<Label>[]>();
-
- /**
- * Since this method is used by RTARuntimeUtil, the visibility should be 'protected'
- *
- * @return
- * gpuToCpuLabels HashMap which contains required labels (of the corresponding task)
- * that need to be taken into account when GPU tasks are mapped to CPU
- */
- protected HashMap<Task, List<Label>[]> getGTCL() {
- return this.gpuToCpuLabels;
- }
-
- /**
- * Not only set gpuToCpuLabels HashMap, this also set gpuTaskList (only contains GPU tasks),
- * triggeringTaskList (only contains tasks with InterProcessTrigger)
- * and offloadingAsyncRunnable (the Runnable that is taken into account for triggering tasks when the mode is asynchronous)
- *
- * @param model the parameter Amalthea model which is used to derived required labels of the corresponding GPU task
- */
- @SuppressWarnings("unchecked")
- private void setGTCL(final Amalthea model) {
- if (model != null) {
- final EList<Task> allTaskList = model.getSwModel().getTasks();
- this.gpuTaskList = allTaskList.stream().filter(s -> s.getStimuli().get(0) instanceof InterProcessStimulus).collect(Collectors.toList());
- /* find the triggering tasks */
- for (final Task t : allTaskList) {
- final List<CallSequenceItem> triggerList = SoftwareUtil.collectCalls(t, null,
- (call -> call instanceof InterProcessTrigger));
- if (triggerList.size() != 0) {
- this.triggeringTaskList.add(t);
- if (RuntimeUtilRTA.doesTaskHaveAsyncRunnable(t, this)) {
- final List<CallSequenceItem> cList = SoftwareUtil.collectCalls(t, null, (call -> call instanceof TaskRunnableCall ||
- call instanceof InterProcessTrigger || call instanceof ClearEvent || call instanceof SetEvent || call instanceof WaitEvent));
- final int waitIndex = cList.indexOf(cList.stream().filter(s -> s instanceof WaitEvent).iterator().next());
- final int asyncOffloadingIndex = waitIndex + 1;
- if (cList.get(asyncOffloadingIndex) instanceof TaskRunnableCall) {
- this.offloadingAsyncRunnable = ((TaskRunnableCall) cList.get(asyncOffloadingIndex)).getRunnable();
- }
- }
- }
- }
- for (final Task t : this.gpuTaskList) {
- final InterProcessStimulus ips = (InterProcessStimulus) (t.getStimuli().get(0));
- Task triggeringTask = null;
- for (final Task tt : this.triggeringTaskList) {
- final InterProcessTrigger ipt = (InterProcessTrigger) SoftwareUtil.collectCalls(tt, null,
- (call -> call instanceof InterProcessTrigger)).stream().iterator().next();
- if (ips.equals(ipt.getStimulus())) {
- triggeringTask = tt;
- break;
- }
- }
- final List<Label> readLabelList = new ArrayList<Label>();
- final List<Label> writeLabelList = new ArrayList<Label>();
- final List<CallSequenceItem> callList = SoftwareUtil.collectCalls(triggeringTask, null, (call -> call instanceof TaskRunnableCall ||
- call instanceof InterProcessTrigger || call instanceof ClearEvent || call instanceof SetEvent || call instanceof WaitEvent));
- final InterProcessTrigger ipt = (InterProcessTrigger) callList.stream().filter(s -> s instanceof InterProcessTrigger).iterator().next();
- final int indexforTrigger = callList.indexOf(ipt);
- for (int i = 0; i < callList.size(); i++) {
- Runnable thisRunnable = null;
- /* Pre-processing Runnable */
- if ((i < indexforTrigger) && (callList.get(i) instanceof TaskRunnableCall)) {
- thisRunnable = (Runnable) ((TaskRunnableCall) callList.get(i)).getRunnable();
- final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(thisRunnable, null);
- for (final LabelAccess la : thisLAList) {
- if (la.getAccess().equals(LabelAccessEnum.READ)) {
- readLabelList.add(la.getData());
- }
- }
- }
- /* Post-processing Runnable */
- else if ((i > indexforTrigger) && (callList.get(i) instanceof TaskRunnableCall)) {
- thisRunnable = ((TaskRunnableCall) callList.get(i)).getRunnable();
- final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(thisRunnable, null);
- for (final LabelAccess la : thisLAList) {
- if (la.getAccess().equals(LabelAccessEnum.WRITE)) {
- writeLabelList.add(la.getData());
- }
- }
- }
- }
- final List<Label>[] aryofLabelList = new ArrayList[2];
- aryofLabelList[0] = readLabelList;
- aryofLabelList[1] = writeLabelList;
- this.gpuToCpuLabels.put(t, aryofLabelList);
- }
- }
- else {
- this.gpuTaskList.clear();
- this.triggeringTaskList.clear();
- this.offloadingAsyncRunnable = null;
- this.gpuToCpuLabels.clear();
- }
- }
-
- // TODO: Consider Offloading Runnable
- // TODO: Cumulative Latency Time
- public static void main(String[] args) {
- org.apache.log4j.BasicConfigurator.configure();
- final CpuRTA cpurta = new CpuRTA();
- cpurta.setModel(AmaltheaLoader.loadFromFile(cpurta.inputFile));
- cpurta.setTRT(cpurta.getDefaultTRT(cpurta.getModel()));
- cpurta.setIA(SharedConsts.defaultIAMapping);
- cpurta.setPUl(CommonUtils.getPUs(cpurta.getModel()));
- cpurta.run();
- }
-
- /**
- * Executable method
- */
- public void run() {
- final Logger log = Logger.getLogger(CpuRTA.class);
- if (this.model == null) {
- log.error("No model loaded!");
- return;
- }
- log.debug("\n####################### The Test ########################\n");
- log.debug("RT Time Sum: " + getCPUResponseTimeSum(SharedConsts.timeType));
- }
-
- /**
- * Calculate the total sum of response times of the tasks of the given Amalthea model with the mapping model (tpuMapping)
- *
- * @param executionCase BCET, ACET, WCET
- * @return
- * total sum of all tasks' response times of the given mapped model (tpuMapping)
- */
- public Time getCPUResponseTimeSum(final TimeType executionCase) {
- final Logger log = Logger.getLogger(CpuRTA.class);
- if (this.model == null) {
- log.error("No Model Loaded!");
- return null;
- }
- else if (this.trt == null) {
- log.error("No HashMap Loaded!");
- return null;
- }
- else if (this.tpuMapping == null) {
- log.error("No IntegerArray Loaded!");
- return null;
- }
- else if (this.pul == null) {
- log.error("No PUList Loaded!");
- return null;
- }
- // TODO: Contention
- Time time = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- for (int i = 0; i < this.tpuMapping.length; i++) {
- final Time rt = getTaskCPURT(this.model.getSwModel().getTasks().get(i), executionCase);
- if (rt.getValue().equals(BigInteger.valueOf(Long.MAX_VALUE)) && !SharedConsts.ignoreInfeasibility) {
- return rt;
- }
- time = time.add(rt);
- if (!rt.getValue().equals(BigInteger.ZERO)) {
- /* only put CPU tasks */
- this.trt.put(this.model.getSwModel().getTasks().get(i), rt);
- }
- }
- return time;
- }
-
- /**
- * Calculate response time of the given task of the given Amalthea model with the mapping model (tpuMapping)
- *
- * @param task the observed task
- * @param executionCase BCET, ACET, WCET
- * @return
- * response time of the observed task
- */
- protected Time getTaskCPURT(final Task task, final TimeType executionCase) {
- /* 1. validate thisTask is mapped to CPU */
- final int tindex = this.model.getSwModel().getTasks().indexOf(task);
- final int puindex = this.tpuMapping[tindex];
- final ProcessingUnit pu = this.pul.get(puindex);
- if (!pu.getDefinition().getPuType().equals(PuType.CPU)) {
- Logger.getLogger(CpuRTA.class).debug(task.getName() + " is not mapped to a CPU");
- return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- }
- /* 2. get all tasks mapped to this CPU */
- final List<Task> puTaskList = new ArrayList<Task>();
- for (int i = 0; i < this.tpuMapping.length; i++) {
- if (this.tpuMapping[i] == puindex) {
- puTaskList.add(this.model.getSwModel().getTasks().get(i));
- }
- }
- final List<Task> sortedTaskList = taskSorting(puTaskList);
- return preciseTestCPURT(task, sortedTaskList, executionCase, pu);
- }
-
- /**
- * Sort out the given list of tasks (in order of shorter period first - Rate Monotonic Scheduling)
- *
- * @param taskList list of tasks that is mapped to the same core
- * @return
- * the sorted list of tasks
- */
- private List<Task> taskSorting(final List<Task> taskList) {
- /* Getting stimuliList out of the given taskList (because it is RMS) */
- final List<Time> stimuliList = new ArrayList<>();
- for (final Task t : taskList) {
- stimuliList.add(CommonUtils.getStimInTime(t));
- }
- /* Sorting (Shortest Period(Time) first) */
- Collections.sort(stimuliList, new TimeCompIA());
- /* Sort tasks to the newTaskList in order of Period length (shortest first
- * longest last)-(according to the stimuliList) */
- final List<Task> newTaskList = new ArrayList<>();
- for (int i = 0; i < stimuliList.size(); i++) {
- for (final Task t : taskList) {
- if ((!newTaskList.contains(t)) && (stimuliList.get(i).compareTo(CommonUtils.getStimInTime(t)) == 0)) {
- newTaskList.add(t);
- }
- }
- }
- return newTaskList;
- }
-
- /**
- * Visibility - public (This method is for the UI version code (ui package > RTApp.java))
- * Calculate response time of the observed task according to the periodic tasks response time analysis algorithm.
- *
- * @param task the observed task
- * @param taskList list of tasks that is mapped to the same core
- * @param executionCase BCET, ACET, WCET
- * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
- * @return
- * response time of the observed task
- */
- public Time preciseTestCPURT(final Task task, final List<Task> taskList, final TimeType executionCase, final ProcessingUnit pu) {
- final Logger log = Logger.getLogger(CpuRTA.class);
- Time thisRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- Time period = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- if (taskList.size() == 0) {
- log.debug("!!! This taskList is empty so I am returning MAX !!!");
- return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
- }
- /* to check if the given task is in the taskList */
- int flag = 0;
- int index = 0;
- for (int i = 0; i < taskList.size(); i++) {
- if (task.equals(taskList.get(i))) {
- flag = 1;
- index = i;
- break;
- }
- }
- if (flag == 0) {
- log.debug("!!! Nothing in the taskList matches the given Task !!! So I am returning 0s" + " --- thisTask: " + task.getName());
- return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
- }
- final RuntimeUtilRTA rtaut = new RuntimeUtilRTA();
- for (int i = 0; i < index + 1; i++) {
- period = CommonUtils.getStimInTime(taskList.get(i));
- if (index == 0) {
- thisRT = rtaut.getExecutionTimeforCPUTask(taskList.get(i), pu, executionCase, this);
- if (thisRT.compareTo(period) <= 0) {
- // TODO: cumulative if (thisRT.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) > 0)
- return thisRT;
- }
- log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the execution time of " + thisRT
- + " for task " + task.getName());
- return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
- }
- else if (i == index) {
- /* In the case of a COOPERATIVE Preemption typed Task */
- if (taskList.get(i).getPreemption().equals(Preemption.COOPERATIVE)) {
- // TODO: Blocking
- }
- final Time thisExeTime = rtaut.getExecutionTimeforCPUTask(taskList.get(i), pu, executionCase, this);
- if (thisExeTime.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) == 0) {
- return thisExeTime;
- }
- else if (thisExeTime.compareTo(period) > 0) {
- log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the execution time of " + thisRT
- + " for task " + task.getName());
- return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
- }
- Time culmulativeRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- /* 1. add all the execution time till the index */
- for (int j = 0; j < i + 1; j++) {
- final Time thisTime = rtaut.getExecutionTimeforCPUTask(taskList.get(j), pu, executionCase, this);
- culmulativeRT = culmulativeRT.add(thisTime);
- }
- if (culmulativeRT.compareTo(period) <= 0) {
- while (true) {
- Time excepThisExeTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- for (int k = 0; k < i; k++) {
- Time localPeriod = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- localPeriod = CommonUtils.getStimInTime(taskList.get(k));
- final Time preExeTime = rtaut.getExecutionTimeforCPUTask(taskList.get(k), pu, executionCase, this);
- final double ri_period = Math.ceil(culmulativeRT.divide(localPeriod));
- excepThisExeTime = excepThisExeTime.add(preExeTime.multiply(ri_period));
- }
- Time culmulativeRT_x = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- culmulativeRT_x = thisExeTime.add(excepThisExeTime);
- if (culmulativeRT_x.compareTo(period) <= 0) {
- if (culmulativeRT_x.compareTo(culmulativeRT) == 0) {
- thisRT = culmulativeRT_x;
- // TODO: cumulative if (thisRT.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) > 0)
- return thisRT;
- }
- culmulativeRT = culmulativeRT_x;
- }
- else {
- log.debug("!!! This is non schedulable...!!! Because of the period " + period
- + " being less than the response time (culmulativeRT_x) of " + culmulativeRT_x + " for task " + task.getName());
- if (SharedConsts.ignoreInfeasibility) {
- return culmulativeRT_x;
- }
- return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
- }
- }
- }
- log.debug("!!! This is non schedulable...!!! Because of the period " + period + " being less than the response time of " + culmulativeRT
- + " for task " + task.getName());
- if (SharedConsts.ignoreInfeasibility) {
- return culmulativeRT;
- }
- return FactoryUtil.createTime(BigInteger.valueOf(Long.MAX_VALUE), TimeUnit.PS);
- }
- }
- // TODO: cumulative if (thisRT.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) > 0)
- return thisRT;
- }
-
- /**
- * Visibility - public (This method is for the UI version code (ui package > RTApp.java))
- * It returns HashMap<Integer, List<Task>> Type reference that contains an Integer(number of Processing Unit index) and the corresponding List of Tasks
- * This is to visualize which task is mapped to which processing unit.
- *
- * @return
- * HashMap<Integer, List<Task>> puListHashMap
- */
- public HashMap<Integer, List<Task>> be_getPUTaskListHashMap(final Amalthea model) {
- HashMap<Integer, List<Task>> puListHashMap = new HashMap<>();
- final EList<Task> allTaskList = model.getSwModel().getTasks();
- for(int i = 0; i < this.pul.size(); i++) {
- final List<Task> puTaskList = new ArrayList<Task>();
- for(int j = 0; j < this.tpuMapping.length; j++) {
- final int puIndex = this.tpuMapping[j];
- if (i == puIndex) {
- puTaskList.add(allTaskList.get(j));
- }
- }
- puListHashMap.put(i, taskSorting(puTaskList));
- }
- return puListHashMap;
- }
-}
-
-/**
- * @Date: June 21-2019
- * @author Junhyung Ki
- * @version 1.0
- * This inner class is used for the method "taskSorting" to help compare between two tasks' periods (which is longer)
- * If the time of arg0 is shorter than that of arg1, it returns -1.
- * If the time of arg0 is longer than that of arg1, it returns 1.
- */
-class TimeCompIA implements Comparator<Time> {
- @Override
- public int compare(final Time arg0, final Time arg1) {
- if (arg0.compareTo(arg1) < 0) {
- return -1;
- }
- return 1;
- }
-}
\ No newline at end of file
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/E2ELatency.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/E2ELatency.java
new file mode 100644
index 0000000..3840d3d
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/E2ELatency.java
@@ -0,0 +1,1389 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * FH Dortmund - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.app4mc.gsoc_rta;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.log4j.Logger;
+import org.eclipse.app4mc.gsoc_rta.CommonUtils;
+import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
+import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
+import org.eclipse.app4mc.amalthea.model.Event;
+import org.eclipse.app4mc.amalthea.model.EventChain;
+import org.eclipse.app4mc.amalthea.model.EventChainContainer;
+import org.eclipse.app4mc.amalthea.model.EventChainItem;
+import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
+import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
+import org.eclipse.app4mc.amalthea.model.Label;
+import org.eclipse.app4mc.amalthea.model.LabelAccess;
+import org.eclipse.app4mc.amalthea.model.ProcessEvent;
+import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
+import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.Task;
+import org.eclipse.app4mc.amalthea.model.Time;
+import org.eclipse.app4mc.amalthea.model.TimeUnit;
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
+import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
+import org.eclipse.emf.common.util.EList;
+
+public class E2ELatency {
+ final Logger log = Logger.getLogger(E2ELatency.class);
+ public static StringBuffer sb = new StringBuffer();
+
+ public enum SinglecoreLatCase {
+ CriInitRct, BCInitRct, WCInitRct,
+ CriWCRct, BCWCRct, WCWCRct
+ }
+
+ public enum MulticoreLatCase {
+ BCRctIm, BCRctLET,
+ WCRctIm, WCRctLET,
+ BCInitRctIm, BCInitRctLET,
+ WCInitRctIm, WCInitRctLET,
+ BCAgeIm, BCAgeLET,
+ WCAgeIm, WCAgeLET
+ }
+
+ /**
+ * To derive the total sum of all task chains' latency values
+ * @param cpurta the instance of CPURta class
+ * @param pu processing unit that computes task chains' latency
+ * @param latCase the target single-core latency case
+ * @return
+ * the total sum of all task chains' latency values
+ */
+ public Time getSingleTCLsum(final CPURta cpurta, final ProcessingUnit pu, final SinglecoreLatCase latCase) {
+ if (cpurta == null) {
+ log.debug("The cpurta instance is empty. Please check the instance.");
+ return null;
+ } else if (cpurta.getModel() == null) {
+ log.debug("Model is empty. Please check the model path.");
+ return null;
+ }
+ Time tclSum = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ final EList<EventChain> ecList = cpurta.getModel().getConstraintsModel().getEventChains();
+ for (int i = 0; i < ecList.size(); i++) {
+ final EventChain chain = ecList.get(i);
+ log.debug("\n");
+ log.debug(" ----- " + chain.getName() + " ----- ");
+ Time lat = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (latCase.equals(SinglecoreLatCase.CriInitRct) || latCase.equals(SinglecoreLatCase.BCInitRct)
+ || latCase.equals(SinglecoreLatCase.WCInitRct)) {
+ lat = this.getSingleCoreInitialRct(ecList.get(i), pu, latCase, cpurta);
+ } else if (latCase.equals(SinglecoreLatCase.CriWCRct) || latCase.equals(SinglecoreLatCase.BCWCRct)
+ || latCase.equals(SinglecoreLatCase.WCWCRct)) {
+ lat = this.getSingleCoreWCRct(chain, pu, latCase, cpurta);
+ }
+ tclSum = tclSum.add(lat);
+ }
+ return tclSum;
+ }
+
+ /**
+ * To derive the total sum of all task chains' multi-core latency values
+ * @param cpurta the instance of CPURta class
+ * @param latCase the target multi-core latency case
+ * @return
+ * the total sum of all task chains' multi-core latency values
+ */
+ public Time getMultiTCLsum(final CPURta cpurta, final MulticoreLatCase latCase) {
+ if (cpurta == null) {
+ log.debug("The cpurta instance is empty. Please check the instance.");
+ return null;
+ } else if (cpurta.getModel() == null) {
+ log.debug("Model is empty. Please check the model path.");
+ return null;
+ }
+ Time tclSum = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ final EList<EventChain> ecList = cpurta.getModel().getConstraintsModel().getEventChains();
+ for (int i = 0; i < ecList.size(); i++) {
+ final EventChain chain = ecList.get(i);
+ log.debug("");
+ log.debug(" ----- " + chain.getName() + " ----- ");
+ Time lat = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (latCase.equals(MulticoreLatCase.BCRctIm)) {
+ lat = this.getBCReactionImplicit(chain, cpurta);
+ log.debug("Best-case Task-Chain Reaction(Implicit): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.BCRctLET)) {
+ lat = this.getBCReactionLET(chain, cpurta);
+ log.debug("Best-case Task-Chain Reaction(LET): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.WCRctIm)) {
+ lat = this.getWCReactionImplicit(chain, cpurta);
+ log.debug("Worst-case Task-Chain Reaction(Implicit): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.WCRctLET)) {
+ lat = this.getWCReactionLET(chain, cpurta);
+ log.debug("Worst-case Task-Chain Reaction(LET): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.BCInitRctIm)) {
+ lat = this.getBCInitialRctImplicit(chain, cpurta);
+ log.debug("Best-case Initial Task-Chain Reaction(Implicit): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.BCInitRctLET)) {
+ lat = this.getBCInitialRctLET(chain, cpurta);
+ log.debug("Best-case Initial Task-Chain Reaction(LET): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.WCInitRctIm)) {
+ lat = this.getWCInitialRctImplicit(chain, cpurta);
+ log.debug("Worst-case Initial Task-Chain Reaction(Implicit): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.WCInitRctLET)) {
+ lat = this.getWCInitialRctLET(chain, cpurta);
+ log.debug("Worst-case Initial Task-Chain Reaction(LET): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.BCAgeIm)) {
+ lat = this.getBCAgeImplicit(chain, cpurta);
+ log.debug("Best-case Task-Chain Age(Implicit): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.BCAgeLET)) {
+ lat = this.getBCAgeLET(chain, cpurta);
+ log.debug("Best-case Task-Chain Age(LET): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.WCAgeIm)) {
+ lat = this.getWCAgeImplicit(chain, cpurta);
+ log.debug("Worst-case Task-Chain Age(Implicit): " + lat);
+ } else if (latCase.equals(MulticoreLatCase.WCAgeLET)) {
+ lat = this.getWCAgeLET(chain, cpurta);
+ log.debug("Worst-case Task-Chain Age(LET): " + lat);
+ }
+ if (lat.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) < 0) {
+ log.error("Error: Latency is smaller than 0!");
+ return null;
+ }
+ tclSum = tclSum.add(lat);
+ }
+ log.debug("");
+ return tclSum;
+ }
+
+ /**
+ * Check the readiness of the observed class instance
+ * @param cpurta the instance of CPURta class
+ * @return
+ * boolean value that indicates whether cpurta instance is ready
+ */
+ protected boolean isTheRTAClassReadySingle(final CPURta cpurta) {
+ if (cpurta.getModel() == null) {
+ log.debug("Model Setting needs to be done for cpurta!");
+ return false;
+ } else if (cpurta.getCT() == null) {
+ log.debug("CT Setting needs to be done for cpurta!");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check the readiness of the observed class instance
+ * @param cpurta the instance of CPURta class
+ * @return
+ * boolean value that indicates whether cpurta instance is ready
+ */
+ protected boolean isTheRTAClassReadyMulti(final CPURta cpurta) {
+ if (cpurta.getModel() == null) {
+ log.debug("Model Setting needs to be done for cpurta!");
+ return false;
+ } else if (cpurta.getTRT() == null) {
+ log.debug("TRT Setting needs to be done for cpurta!");
+ return false;
+ } else if (cpurta.getIA() == null) {
+ log.debug("IA Setting needs to be done for cpurta!");
+ return false;
+ } else if (cpurta.getPUl().size() == 0) {
+ log.debug("PUl Setting needs to be done for cpurta!");
+ return false;
+ } else if (cpurta.getCT() == null) {
+ log.debug("CT Setting needs to be done for cpurta!");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * To derive the observed event chain's initial single-core reaction according to the target latency case
+ * @param ec the observed event chain
+ * @param pu processing unit that computes the observed event chain
+ * @param latCase the target single-core latency case (critical-case, best-case, worst-case)
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the initial single-core reaction time of the observed event chain with the given latCase
+ */
+ public Time getSingleCoreInitialRct(final EventChain ec, final ProcessingUnit pu, final SinglecoreLatCase latCase, final CPURta cpurta) {
+ if (isTheRTAClassReadySingle(cpurta)) {
+ if (latCase.equals(SinglecoreLatCase.CriWCRct) || latCase.equals(SinglecoreLatCase.BCWCRct)
+ || latCase.equals(SinglecoreLatCase.WCWCRct)) {
+ log.error("latCase needs to be changed into one of three: CriInitRct, BCInitRct, WCInitRct");
+ return null;
+ }
+ final List<Task> taskChain = getECTaskList(ec);
+ if (taskChain.size() == 0) {
+ log.error("This task chain is empty.");
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ final Task task_0 = taskChain.get(0);
+ final List<Task> sortedChain = cpurta.taskSorting(taskChain);
+ final Time period_0 = CommonUtils.getStimInTime(task_0);
+ final Time hyper = this.getHyperPeriod(sortedChain);
+ final BigInteger period_0_BI = AmaltheaServices.convertToPicoSeconds(period_0);
+ final BigInteger hyper_BI = AmaltheaServices.convertToPicoSeconds(hyper);
+ final long chainsToCheck = hyper_BI.divide(period_0_BI).longValue();
+ /* Checking the first element's all instances in the hyper-period to see whether each can make a chain
+ * and to calculate latency if they can */
+ final List<Time> latencyList = new ArrayList<Time>();
+ for (int i = 0; i < chainsToCheck; i++) {
+ Time lat = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ lat = this.getSingleCoreInitialRct_(i, ec, pu, cpurta);
+ /* Critical-case */
+ if ((i == 0) && latCase.equals(SinglecoreLatCase.CriInitRct)) {
+ return lat;
+ }
+ if (lat.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) != 0) {
+ latencyList.add(lat);
+ }
+ log.debug(i + "-th instance: " + lat);
+ }
+ Collections.sort(latencyList, new TimeComp());
+ /* Best-case */
+ if (latCase.equals(SinglecoreLatCase.BCInitRct)) {
+ return latencyList.get(0);
+ }
+ /* Worst-case */
+ return latencyList.get(latencyList.size()-1);
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * To derive the initial single-core reaction that starts with (i+1)_th instance of the first task
+ * in the observed event chain (in the hyper-period with the critical instant)
+ * @param i the number(i+1) of the observed instance of the first of the event chain in the hyper-period
+ * @param ec the observed event chain
+ * @param pu processing unit that computes the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the initial single-core reaction of the observed task chain starting with (i+1)_th instance of the first task
+ */
+ protected Time getSingleCoreInitialRct_(final int i, final EventChain ec, final ProcessingUnit pu, final CPURta cpurta) {
+ if (isTheRTAClassReadySingle(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ final Task task_0 = taskChain.get(0);
+ final Time period_0 = CommonUtils.getStimInTime(task_0);
+ Time lat = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ lat = this.getCRtoRT(i, task_0, taskChain, pu, cpurta);
+ for (int j = 1; j < taskChain.size(); j++) {
+ final Task task = taskChain.get(j);
+ final BigInteger latBI = AmaltheaServices.convertToPicoSeconds(lat);
+ final BigDecimal latBD = BigDecimal.valueOf(latBI.doubleValue());
+ final Time period = CommonUtils.getStimInTime(task);
+ final BigInteger periodBI = AmaltheaServices.convertToPicoSeconds(period);
+ final BigDecimal periodBD = BigDecimal.valueOf(periodBI.doubleValue());
+ final Task preTask = taskChain.get(j-1);
+ final Time pre_period = CommonUtils.getStimInTime(preTask);
+ final BigInteger pre_periodBI = AmaltheaServices.convertToPicoSeconds(pre_period);
+ final BigDecimal pre_periodBD = BigDecimal.valueOf(pre_periodBI.doubleValue());
+ final List<Task> preHPList = cpurta.getHigherPriorityTasksInChain(preTask, taskChain);
+ long offset = 0;
+ /* To check whether the observed task is a higher priority than the previous chain element */
+ if (preHPList.contains(task)) {
+ final BigDecimal offsetBD = latBD.divide(periodBD, 0, BigDecimal.ROUND_CEILING);
+ offset = offsetBD.longValue();
+ } else {
+ final BigDecimal flo = latBD.divide(pre_periodBD, 0, BigDecimal.ROUND_FLOOR);
+ offset = (flo.multiply(pre_periodBD)).divide(periodBD, 0, BigDecimal.ROUND_CEILING).longValue();
+ }
+ final long preTask_offset = latBD.divide(pre_periodBD, 0, BigDecimal.ROUND_CEILING).longValue();
+ final Time preTaskCRIP = this.getCRtoIP(preTask_offset, preTask, taskChain, pu, cpurta);
+ Time taskCRRT = this.getCRtoRT(offset, task, taskChain, pu, cpurta);
+ /* The current task is a higher priority than the previous one */
+ if (preHPList.contains(task)) {
+ final Time preTaskCRRT = this.getCRtoRT(preTask_offset, preTask, taskChain, pu, cpurta);
+ if (preTaskCRRT.compareTo(taskCRRT) < 0) {
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ }
+ /* The current task is a lower priority than the previous one */
+ else {
+ Time taskCRIP = this.getCRtoIP(offset, task, taskChain, pu, cpurta);
+ if (preTaskCRIP.compareTo(taskCRIP) < 0) {
+ offset = offset-1;
+ taskCRIP = this.getCRtoIP(offset, task, taskChain, pu, cpurta);
+ /* it can not make a task chain */
+ if (lat.compareTo(taskCRIP) > 0 || preTaskCRIP.compareTo(taskCRIP) < 0) {
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ taskCRRT = this.getCRtoRT(offset, task, taskChain, pu, cpurta);
+ }
+ }
+ lat = taskCRRT;
+ }
+ /* delete the offset time */
+ if (lat.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) != 0) {
+ lat = lat.subtract(period_0.multiply(i));
+ }
+ return lat;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * To derive the observed event chain's worst-case single-core reaction according to the target latency case
+ * @param ec the observed event chain
+ * @param pu processing unit that computes the observed event chain
+ * @param latCase the target single-core latency case (critical-case, best-case, worst-case)
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case single-core reaction time of the observed event chain with the given latCase
+ */
+ public Time getSingleCoreWCRct(final EventChain ec, final ProcessingUnit pu, final SinglecoreLatCase latCase, final CPURta cpurta) {
+ if (isTheRTAClassReadySingle(cpurta)) {
+ if (latCase.equals(SinglecoreLatCase.CriInitRct) || latCase.equals(SinglecoreLatCase.BCInitRct)
+ || latCase.equals(SinglecoreLatCase.WCInitRct)) {
+ log.error("latCase needs to be changed into one of three: CriWCRct, BCWCRct, WCWCRct");
+ return null;
+ }
+ final List<Task> taskChain = getECTaskList(ec);
+ if (taskChain.size() == 0) {
+ log.error("This task chain is empty.");
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ final Task task_0 = taskChain.get(0);
+ final List<Task> sortedChain = cpurta.taskSorting(taskChain);
+ final Time period_0 = CommonUtils.getStimInTime(task_0);
+ final Time hyper = this.getHyperPeriod(sortedChain);
+ final BigInteger period_0_BI = AmaltheaServices.convertToPicoSeconds(period_0);
+ final BigInteger hyper_BI = AmaltheaServices.convertToPicoSeconds(hyper);
+ final long chainsToCheck = hyper_BI.divide(period_0_BI).longValue();
+ /* Checking the first element's all instances in the hyper-period to see whether each can make a chain
+ * and to calculate latency if they can */
+ final List<Time> latencyList = new ArrayList<Time>();
+ for (int i = 0; i < chainsToCheck; i++) {
+ Time lat = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ lat = this.getSingleCoreWCRct_(i, ec, pu, cpurta);
+ /* Critical-case */
+ if ((i == 0) && latCase.equals(SinglecoreLatCase.CriWCRct)) {
+ return lat;
+ }
+ if (lat.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) != 0) {
+ latencyList.add(lat);
+ }
+ log.debug(i + "-th instance: " + lat);
+ }
+ Collections.sort(latencyList, new TimeComp());
+ /* Best-case */
+ if (latCase.equals(SinglecoreLatCase.BCWCRct)) {
+ return latencyList.get(0);
+ }
+ /* Worst-case */
+ return latencyList.get(latencyList.size()-1);
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * To derive the worst-case single-core reaction that starts with (i+1)_th instance of the first task
+ * in the observed event chain (in the hyper-period with the critical instant)
+ * @param i the number(i+1) of the observed instance of the first of the event chain in the hyper-period
+ * @param ec the observed event chain
+ * @param pu processing unit that computes the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case single-core reaction of the observed task chain starting with (i+1)_th instance of the first task
+ */
+ protected Time getSingleCoreWCRct_(final int i, final EventChain ec, final ProcessingUnit pu, final CPURta cpurta) {
+ if (isTheRTAClassReadySingle(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ final Task task_0 = taskChain.get(0);
+ final Time period_0 = CommonUtils.getStimInTime(task_0);
+ Time temp = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Time pre_previousVal = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Time lat = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ lat = this.getCRtoRT(i, task_0, taskChain, pu, cpurta);
+ for (int j = 1; j < taskChain.size(); j++) {
+ final Task task = taskChain.get(j);
+ final BigInteger latBI = AmaltheaServices.convertToPicoSeconds(lat);
+ final BigDecimal latBD = BigDecimal.valueOf(latBI.doubleValue());
+ final Time period = CommonUtils.getStimInTime(task);
+ final BigInteger periodBI = AmaltheaServices.convertToPicoSeconds(period);
+ final BigDecimal periodBD = BigDecimal.valueOf(periodBI.doubleValue());
+ final Task preTask = taskChain.get(j-1);
+ final Time pre_period = CommonUtils.getStimInTime(preTask);
+ final BigInteger pre_periodBI = AmaltheaServices.convertToPicoSeconds(pre_period);
+ final BigDecimal pre_periodBD = BigDecimal.valueOf(pre_periodBI.doubleValue());
+ final List<Task> preHPList = cpurta.getHigherPriorityTasksInChain(preTask, taskChain);
+ final long preTask_offset = latBD.divide(pre_periodBD, 0, BigDecimal.ROUND_CEILING).longValue();
+ /* The current task is a higher priority than the previous one */
+ Time taskCRRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (preHPList.contains(task)) {
+ final Time preTaskCRRT = this.getCRtoRT(preTask_offset, preTask, taskChain, pu, cpurta);
+ final BigInteger preTaskCrrtBI = AmaltheaServices.convertToPicoSeconds(preTaskCRRT);
+ final BigDecimal preTaskCrrtBD = BigDecimal.valueOf(preTaskCrrtBI.longValue());
+ final long offwhp = preTaskCrrtBD.divide(periodBD, 0, BigDecimal.ROUND_FLOOR).longValue();
+ final Time crrt_cr = this.getCRtoRT(offwhp, task, taskChain, pu, cpurta);
+ final Time crrt_cr_ = this.getCRtoRT(offwhp-1, task, taskChain, pu, cpurta);
+ /* When there is an instance(s) of \tau_j between f(j-1)_x and the crrt time of the next instance of \tau_{j-1} */
+ if ((preTaskCrrtBI.mod(periodBI).compareTo(BigInteger.ZERO) != 0) &&
+ (lat.compareTo(crrt_cr) < 0) &&
+ (preTaskCRRT.compareTo(crrt_cr) > 0)) {
+ taskCRRT = crrt_cr;
+ }
+ /* In the worst-case, this part is only needed when the current task's priority is higher than the previous one's.
+ * Because the current task's crrt is calculated based on the crrt time of the next instance of the previous task.
+ * Due to the fact that there can be more than one instance of the higher priority task between the lower priority task's instances. */
+ else if ((preTaskCrrtBI.mod(periodBI).compareTo(BigInteger.ZERO) == 0) &&
+ (lat.compareTo(crrt_cr_) < 0) &&
+ (preTaskCRRT.compareTo(crrt_cr_) > 0)) {
+ taskCRRT = crrt_cr_;
+ }
+ }
+ /* The current task is a lower priority than the previous one */
+ else {
+ final Time previousValIP = this.getCRtoIP(preTask_offset-1, preTask, taskChain, pu, cpurta);
+ final Time preTaskCRIP = this.getCRtoIP(preTask_offset, preTask, taskChain, pu, cpurta);
+ final BigInteger preTaskCripBI = AmaltheaServices.convertToPicoSeconds(preTaskCRIP);
+ final BigDecimal preTaskCripBD = BigDecimal.valueOf(preTaskCripBI.longValue());
+ final long offlhp = preTaskCripBD.divide(periodBD, 0, BigDecimal.ROUND_FLOOR).longValue();
+ final Time crip = this.getCRtoIP(offlhp, task, taskChain, pu, cpurta);
+ /* When there is an instance(s) of \tau_j between f(j-1)_x and the crip time of the next instance of \tau_{j-1} */
+ if ((preTaskCripBI.mod(periodBI).compareTo(BigInteger.ZERO) != 0) &&
+ (previousValIP.compareTo(crip) < 0) &&
+ (preTaskCRIP.compareTo(crip) > 0)) {
+ taskCRRT = this.getCRtoRT(offlhp, task, taskChain, pu, cpurta);
+ }
+ /* In the worst-case, this part is only needed when the current task's priority is lower than the previous one's
+ * Because the current task's crrt is calculated based on the crip time of the next instance of \tau_{j-1}.
+ * Due to the fact that there can be no instance of the lower priority task between the higher priority task's instances. */
+ else {
+ /* When \tau_j is the second element of the chain and there is no instance of \tau_j between f(j-1)_x and the crip time of the next instance of \tau_{j-1} */
+ if (pre_previousVal.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) == 0) {
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ taskCRRT = this.getCRWC(task, preTask, 1, lat, pre_previousVal, taskChain, pu, cpurta);
+ /* To consider a situation where there is another chain path that goes through the earlier instance of \tau_{j-1} */
+ if (taskCRRT.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) == 0) {
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ }
+ }
+ temp = lat;
+ lat = taskCRRT;
+ pre_previousVal = temp;
+ }
+ /* delete the offset time */
+ if (lat.compareTo(FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS)) != 0) {
+ lat = lat.subtract(period_0.multiply(i));
+ }
+ return lat;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * this method is used by getSingleCoreWCRct_() when getSingleCoreWCRct_() fails to identify a valid task's instance.
+ * the method is intended to find an alternative chain path from the time point of prepre:
+ * : the finishing point of the worst-case reaction of the successor of preTask.
+ * @param task the observed task
+ * @param preTask the successor of the observed task
+ * @param k constant to subtract to calculate the initial point to identify the alternative chain path
+ * @param pre the finishing point of the worst-case reaction of preTask
+ * @param prepre the finishing point of the worst-case reaction of the successor of preTask
+ * @param chain the observed task chain
+ * @param pu processing unit that computes the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the alternative getSingleCoreWCRct_() result (the crwc time value of the observed task)
+ */
+ private Time getCRWC(final Task task, final Task preTask, final long k,
+ final Time pre, final Time prepre, final List<Task> chain, final ProcessingUnit pu, final CPURta cpurta) {
+ final BigInteger preBI = AmaltheaServices.convertToPicoSeconds(pre);
+ final BigDecimal preBD = BigDecimal.valueOf(preBI.longValue());
+ final Time period = CommonUtils.getStimInTime(task);
+ final BigInteger periodBI = AmaltheaServices.convertToPicoSeconds(period);
+ final BigDecimal periodBD = BigDecimal.valueOf(periodBI.longValue());
+ final Time prePeriod = CommonUtils.getStimInTime(preTask);
+ final BigInteger prePeriodBI = AmaltheaServices.convertToPicoSeconds(prePeriod);
+ final BigDecimal prePeriodBD = BigDecimal.valueOf(prePeriodBI.longValue());
+ final long preOffcr = preBD.divide(prePeriodBD, 0, BigDecimal.ROUND_FLOOR).longValue();
+ final long offcr = preBD.divide(periodBD, 0, BigDecimal.ROUND_FLOOR).longValue();
+ final long offcr_ = offcr - 1;
+ final Time preCripCr = this.getCRtoIP(preOffcr - k, preTask, chain, pu, cpurta);
+ final Time crrtCr = this.getCRtoRT(offcr, task, chain, pu, cpurta);
+ final Time crrtCr_ = this.getCRtoRT(offcr_, task, chain, pu, cpurta);
+ final Time cripCr = this.getCRtoIP(offcr, task, chain, pu, cpurta);
+ final Time cripCr_ = this.getCRtoIP(offcr_, task, chain, pu, cpurta);
+ if (preCripCr.compareTo(prepre) < 0) {
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ } else if ((preBI.mod(periodBI).compareTo(BigInteger.ZERO) != 0) &&
+ (cripCr.compareTo(pre) < 0) &&
+ (cripCr.compareTo(preCripCr) > 0)){
+ return crrtCr;
+ } else if ((preBI.mod(periodBI).compareTo(BigInteger.ZERO) == 0) &&
+ (cripCr_.compareTo(pre) < 0) &&
+ (cripCr_.compareTo(preCripCr) > 0)){
+ return crrtCr_;
+ } else {
+ return this.getCRWC(task, preTask, k+1, pre, prepre, chain, pu, cpurta);
+ }
+ }
+
+ /**
+ * to derive the best-case reaction of the observed event chain with Implicit communication
+ * (for now calculation is done with direct response time functions)
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case reaction of the observed event chain with Implicit communication
+ */
+ public Time getBCReactionImplicit(final EventChain ec, final CPURta cpurta) {
+ Time bcRctImplicit = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ for (int i = 0; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ final ProcessingUnit pu = cpurta.getPU(task, cpurta);
+ final List<Task> taskList = cpurta.getSortedTaskList(task, pu, cpurta);
+ final Time bcrt = cpurta.bestCaseCPURT(task, taskList, pu);
+ bcRctImplicit = bcRctImplicit.add(bcrt);
+ if (i != 0) {
+ final Time bcip = this.getBCInitialPending(task, cpurta);
+ bcRctImplicit = bcRctImplicit.subtract(bcip);
+ }
+ }
+ return bcRctImplicit;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the worst-case reaction of the observed event chain with Implicit communication
+ * (for now calculation is done with direct response time functions)
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case reaction of the observed event chain with Implicit communication
+ */
+ public Time getWCReactionImplicit(final EventChain ec, final CPURta cpurta) {
+ Time wcRctImplicit = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ final Task task_0 = taskChain.get(0);
+ final ProcessingUnit pu_0 = cpurta.getPU(task_0, cpurta);
+ final List<Task> taskList_0 = cpurta.getSortedTaskList(task_0, pu_0, cpurta);
+ final Time rt_0 = cpurta.preciseTestCPURT(task_0, taskList_0, TimeType.WCET, pu_0);
+ final Time period_0 = CommonUtils.getStimInTime(task_0);
+ wcRctImplicit = wcRctImplicit.add(rt_0);
+ wcRctImplicit = wcRctImplicit.add(period_0);
+ for (int i = 1; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ final ProcessingUnit pu = cpurta.getPU(task, cpurta);
+ final List<Task> taskList = cpurta.getSortedTaskList(task, pu, cpurta);
+ final Time rt = cpurta.preciseTestCPURT(task, taskList, TimeType.WCET, pu);
+ wcRctImplicit = wcRctImplicit.add(rt);
+ if (i != taskChain.size() - 1) {
+ final Time period = CommonUtils.getStimInTime(task);
+ final Time bcip = this.getBCInitialPending(task, cpurta);
+ wcRctImplicit = wcRctImplicit.add(period.subtract(bcip));
+ } else {
+ final Time wcip = this.getWCInitialPending(task, cpurta);
+ wcRctImplicit = wcRctImplicit.subtract(wcip);
+ }
+ }
+ return wcRctImplicit;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the best-case initial reaction of the observed event chain with Implicit communication
+ * (for now calculation is done with direct response time functions)
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case initial reaction of the observed event chain with Implicit communication
+ */
+ public Time getBCInitialRctImplicit(final EventChain ec, final CPURta cpurta) {
+ return getBCReactionImplicit(ec, cpurta);
+ }
+
+ /**
+ * to derive the worst-case initial reaction of the observed event chain with Implicit communication
+ * (for now calculation is done with direct response time functions)
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case initial reaction of the observed event chain with Implicit communication
+ */
+ public Time getWCInitialRctImplicit(final EventChain ec, final CPURta cpurta) {
+ Time wcInitialRct = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ for (int i = 0; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ final ProcessingUnit pu = cpurta.getPU(task, cpurta);
+ final List<Task> taskList = cpurta.getSortedTaskList(task, pu, cpurta);
+ final Time period = CommonUtils.getStimInTime(task);
+ final Time rt = cpurta.preciseTestCPURT(task, taskList, TimeType.WCET, pu);
+ wcInitialRct = wcInitialRct.add(rt);
+ if (i != 0) {
+ final Task preTask = taskChain.get(i-1);
+ final Time prePeriod = CommonUtils.getStimInTime(preTask);
+ if (period.compareTo(prePeriod) >= 0 && taskChain.size() - 1 < 3) {
+ final Time wcip = this.getWCInitialPending(task, cpurta);
+ wcInitialRct = wcInitialRct.add(prePeriod.subtract(wcip));
+ } else if (period.compareTo(prePeriod) >= 0 && i == taskChain.size() - 1) {
+ final Time wcip = this.getWCInitialPending(task, cpurta);
+ wcInitialRct = wcInitialRct.subtract(wcip);
+ } else if (period.compareTo(prePeriod) >= 0 && i == 1) {
+ final Time bcip = this.getBCInitialPending(task, cpurta);
+ wcInitialRct = wcInitialRct.add(prePeriod.add(period).subtract(bcip));
+ } else {
+ final Time bcip = this.getBCInitialPending(task, cpurta);
+ wcInitialRct = wcInitialRct.add(period.subtract(bcip));
+ }
+ }
+ }
+ return wcInitialRct;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the best-case reaction of the observed event chain with LET communication
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case reaction of the observed event chain with LET communication
+ */
+ public Time getBCReactionLET(final EventChain ec, final CPURta cpurta) {
+ Time bcRctLET = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ for (int i = 0; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ final Time period = CommonUtils.getStimInTime(task);
+ bcRctLET = bcRctLET.add(period);
+ }
+ return bcRctLET;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the worst-case reaction of the observed event chain with LET communication
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case reaction of the observed event chain with LET communication
+ */
+ public Time getWCReactionLET(final EventChain ec, final CPURta cpurta) {
+ Time wcRctLET = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ for (int i = 0; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ final Time period = CommonUtils.getStimInTime(task);
+ if (i != taskChain.size() - 1) {
+ wcRctLET = wcRctLET.add(period.multiply(2));
+ } else {
+ wcRctLET = wcRctLET.add(period);
+ }
+ }
+ return wcRctLET;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the best-case initial reaction of the observed event chain with LET communication
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case initial reaction of the observed event chain with LET communication
+ */
+ public Time getBCInitialRctLET(final EventChain ec, final CPURta cpurta) {
+ return getBCReactionLET(ec, cpurta);
+ }
+
+ /**
+ * to derive the worst-case initial reaction of the observed event chain with LET communication
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case initial reaction of the observed event chain with LET communication
+ */
+ public Time getWCInitialRctLET(final EventChain ec, final CPURta cpurta) {
+ Time wcInitialRct = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ for (int i = 0; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ final Time period = CommonUtils.getStimInTime(task);
+ wcInitialRct = wcInitialRct.add(period);
+ if (i != 0) {
+ final Task preTask = taskChain.get(i-1);
+ final Time prePeriod = CommonUtils.getStimInTime(preTask);
+ if (period.compareTo(prePeriod) > 0) {
+ wcInitialRct = wcInitialRct.add(prePeriod);
+ } else {
+ wcInitialRct = wcInitialRct.add(period);
+ }
+ }
+ }
+ return wcInitialRct;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the best-case age of the observed event chain with Implicit communication
+ * (for now calculation is done with direct response time functions)
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case age of the observed event chain with Implicit communication
+ */
+ public Time getBCAgeImplicit(final EventChain ec, final CPURta cpurta) {
+ Time bcAgeImplicit = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ final Task task_0 = taskChain.get(0);
+ final Time period_0 = CommonUtils.getStimInTime(task_0);
+ final Time bcInitialRct = getBCInitialRctImplicit(ec, cpurta);
+ final Time wcReaction = getWCReactionImplicit(ec, cpurta);
+ if ((period_0.add(bcInitialRct)).compareTo(wcReaction) < 0) {
+ final Task lastTask = taskChain.get(taskChain.size() - 1);
+ final Time lastTaskAge = getBCTaskAgeImplicit(lastTask, cpurta);
+ bcAgeImplicit = bcAgeImplicit.add(lastTaskAge);
+ } else {
+ bcAgeImplicit = bcAgeImplicit.add(period_0.add(bcInitialRct).subtract(wcReaction));
+ }
+ return bcAgeImplicit;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the worst-case age of the observed event chain with Implicit communication
+ * (for now calculation is done with direct response time functions)
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case age of the observed event chain with Implicit communication
+ */
+ public Time getWCAgeImplicit(final EventChain ec, final CPURta cpurta) {
+ Time wcAgeImplicit = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ final Task task_0 = taskChain.get(0);
+ final Time period_0 = CommonUtils.getStimInTime(task_0);
+ final Time wcInitialRct = getWCInitialRctImplicit(ec, cpurta);
+ final Time bcInitialRct = getBCInitialRctImplicit(ec, cpurta);
+ wcAgeImplicit = wcAgeImplicit.add(period_0.add(wcInitialRct).subtract(bcInitialRct));
+ return wcAgeImplicit;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the subtraction between the worst- and best-case reaction times of the observed event chain with Implicit communication
+ * (to compare to the worst-case age of the observed event chain with Implicit communication)
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the subtraction between the worst- and best-case reaction times with Implicit communication
+ */
+ public Time getWCBCSubAgeImplicit(final EventChain ec, final CPURta cpurta) {
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final Time wcAgeRctImplicit = this.getWCReactionImplicit(ec, cpurta);
+ final Time bcAgeRctImplicit = this.getBCReactionImplicit(ec, cpurta);
+ return wcAgeRctImplicit.subtract(bcAgeRctImplicit);
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the best-case age of the observed event chain with LET communication
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case age of the observed event chain with LET communication
+ */
+ public Time getBCAgeLET(final EventChain ec, final CPURta cpurta) {
+ Time bcAgeLET = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ final Task lastTask = taskChain.get(taskChain.size() - 1);
+ final Time lastTaskPeriod = CommonUtils.getStimInTime(lastTask);
+ bcAgeLET = bcAgeLET.add(lastTaskPeriod);
+ return bcAgeLET;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the worst-case age of the observed event chain with LET communication
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case age of the observed event chain with LET communication
+ */
+ public Time getWCAgeLET(final EventChain ec, final CPURta cpurta) {
+ Time wcAgeLET = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Task> taskChain = getECTaskList(ec);
+ for (int i = 0; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ final Time period = FactoryUtil.createTime(AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(task)), TimeUnit.PS);
+ if (i == 0) {
+ wcAgeLET = wcAgeLET.add(period);
+ } else {
+ if (period.compareTo(wcAgeLET) == 0) {
+ wcAgeLET = period.multiply(2);
+ } else if (period.compareTo(wcAgeLET) > 0) {
+ wcAgeLET = period;
+ } else {
+ final BigInteger periodBI = AmaltheaServices.convertToPicoSeconds(period);
+ final BigInteger wcAgeLETBI = AmaltheaServices.convertToPicoSeconds(wcAgeLET);
+ final BigDecimal periodBD = BigDecimal.valueOf(periodBI.doubleValue());
+ final BigDecimal wcAgeLETBD = BigDecimal.valueOf(wcAgeLETBI.doubleValue());
+ if (wcAgeLETBI.mod(periodBI) != BigInteger.ZERO) {
+ final BigDecimal ceiledValueBD = wcAgeLETBD.divide(periodBD, 0, BigDecimal.ROUND_CEILING);
+ final BigInteger ceiledValueBI = BigInteger.valueOf(ceiledValueBD.longValue());
+ wcAgeLET = FactoryUtil.createTime(periodBI.multiply(ceiledValueBI), TimeUnit.PS);
+ } else {
+ wcAgeLET = FactoryUtil.createTime(periodBI.multiply(wcAgeLETBI.divide(periodBI)
+ .add(BigInteger.ONE)), TimeUnit.PS);
+ }
+ }
+ }
+ }
+ return wcAgeLET;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the subtraction between the worst- and best-case reaction times of the observed event chain with LET communication
+ * (to compare to the worst-case age of the observed event chain with LET communication)
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the subtraction between the worst- and best-case reaction times with LET communication
+ */
+ public Time getWCBCSubAgeLET(final EventChain ec, final CPURta cpurta) {
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final Time wcRctLET = this.getWCReactionLET(ec, cpurta);
+ final Time bcRctLET = this.getBCReactionLET(ec, cpurta);
+ return wcRctLET.subtract(bcRctLET);
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the best-case task age latency of the observed task with Implicit communication
+ * (for now calculation is done with direct response time functions)
+ * @param task the observed task
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case task age latency of the observed task with Implicit communication
+ */
+ public Time getBCTaskAgeImplicit(final Task task, final CPURta cpurta) {
+ Time bcTaskAge = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final ProcessingUnit pu = cpurta.getPU(task, cpurta);
+ final List<Task> taskList = cpurta.getSortedTaskList(task, pu, cpurta);
+ final Time bcrt = cpurta.bestCaseCPURT(task, taskList, pu);
+ final Time wcrt = cpurta.preciseTestCPURT(task, taskList, TimeType.WCET, pu);
+ final Time period = CommonUtils.getStimInTime(task);
+ bcTaskAge = bcTaskAge.add(period.subtract(wcrt).add(bcrt));
+ return bcTaskAge;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the worst-case task age latency of the observed task with Implicit communication
+ * (for now calculation is done with direct response time functions)
+ * @param task the observed task
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case task age latency of the observed task with Implicit communication
+ */
+ public Time getWCTaskAgeImplicit(final Task task, final CPURta cpurta) {
+ Time wcTaskAge = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final ProcessingUnit pu = cpurta.getPU(task, cpurta);
+ final List<Task> taskList = cpurta.getSortedTaskList(task, pu, cpurta);
+ final Time bcrt = cpurta.bestCaseCPURT(task, taskList, pu);
+ final Time wcrt = cpurta.preciseTestCPURT(task, taskList, TimeType.WCET, pu);
+ final Time period = CommonUtils.getStimInTime(task);
+ wcTaskAge = wcTaskAge.add(period.subtract(bcrt).add(wcrt));
+ return wcTaskAge;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the best-case data age regarding the observed label in the given event chain
+ * @param label the observed label
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case data age regarding the observed label in the given event chain
+ */
+ public Time getBCDataAge(final Label label, final EventChain ec, final CPURta cpurta) {
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Time> bcDataAgeList = new ArrayList<Time>();
+ final List<Task> taskChain = getECTaskList(ec);
+ for (int i = 0; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ if (isMappedToCPU(task, cpurta)) {
+ Set<Label> labelSet = SoftwareUtil.getAccessedLabelSet(task, null);
+ if (cpurta.getTriggeringTaskList().contains(task)) {
+ final List<ActivityGraphItem> triggerList = SoftwareUtil.collectActivityGraphItems(task.getActivityGraph(), null, (call -> call instanceof InterProcessTrigger));
+ final InterProcessTrigger ipt = (InterProcessTrigger) triggerList.get(0);
+ final InterProcessStimulus ips = ipt.getStimulus();
+ final Task gpuTask = cpurta.getGpuTaskList().stream().filter(s -> s.getStimuli().get(0).equals(ips)).iterator().next();
+ final Set<Label> gpuLabelSet = SoftwareUtil.getAccessedLabelSet(gpuTask, null);
+ labelSet.addAll(gpuLabelSet);
+ labelSet = labelSet.stream().distinct().collect(Collectors.toSet());
+ }
+ if(labelSet.contains(label)) {
+ final Time bcDataAge = getBCTaskAgeImplicit(task, cpurta);
+ bcDataAgeList.add(bcDataAge);
+ }
+ } else {
+ /* GPU Task - there is no best case or worst case reponse time for GPU Task => Age Latency = Period */
+ bcDataAgeList.add(CommonUtils.getStimInTime(task));
+ }
+ }
+ if (bcDataAgeList.size() != 0) {
+ Collections.sort(bcDataAgeList, new TimeComp());
+ return bcDataAgeList.get(0);
+ }
+ log.error("This chain does not have the observed label.");
+ return null;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the worst-case data age regarding the observed label in the given event chain
+ * @param label the observed label
+ * @param ec the observed event chain
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case data age regarding the observed label in the given event chain
+ */
+ public Time getWCDataAge(final Label label, final EventChain ec, final CPURta cpurta) {
+ if (isTheRTAClassReadyMulti(cpurta)) {
+ final List<Time> wcDataAgeList = new ArrayList<Time>();
+ final List<Task> taskChain = getECTaskList(ec);
+ for (int i = 0; i < taskChain.size(); i++) {
+ final Task task = taskChain.get(i);
+ if (isMappedToCPU(task, cpurta)) {
+ Set<Label> labelSet = SoftwareUtil.getAccessedLabelSet(task, null);
+ if (cpurta.getTriggeringTaskList().contains(task)) {
+ final List<ActivityGraphItem> triggerList = SoftwareUtil.collectActivityGraphItems(task.getActivityGraph(), null, (call -> call instanceof InterProcessTrigger));
+ final InterProcessTrigger ipt = (InterProcessTrigger) triggerList.get(0);
+ final InterProcessStimulus ips = ipt.getStimulus();
+ final Task gpuTask = cpurta.getGpuTaskList().stream().filter(s -> s.getStimuli().get(0).equals(ips)).iterator().next();
+ final Set<Label> gpuLabelSet = SoftwareUtil.getAccessedLabelSet(gpuTask, null);
+ labelSet.addAll(gpuLabelSet);
+ labelSet = labelSet.stream().distinct().collect(Collectors.toSet());
+ }
+ if(labelSet.contains(label)) {
+ final Time wcDataAge = getWCTaskAgeImplicit(task, cpurta);
+ wcDataAgeList.add(wcDataAge);
+ }
+ } else {
+ /* GPU Task - there is no best case or worst case reponse time for GPU Task => Age Latency = Period */
+ wcDataAgeList.add(CommonUtils.getStimInTime(task));
+ }
+ }
+ if (wcDataAgeList.size() != 0) {
+ Collections.sort(wcDataAgeList, new TimeComp());
+ return wcDataAgeList.get(0);
+ }
+ log.error("This chain does not have the observed label.");
+ return null;
+ }
+ log.error("cpurta instance is not ready!");
+ return null;
+ }
+
+ /**
+ * to derive the best-case intial pending time of the observed task
+ * @param task the observed task
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the best-case intial pending time of the observed task
+ */
+ protected Time getBCInitialPending(final Task task, final CPURta cpurta) {
+ if (this.isTheRTAClassReadyMulti(cpurta)) {
+ /*
+ final ProcessingUnit pu = cpurta.getPU(task, cpurta);
+ final List<Task> taskList = cpurta.getSortedTaskList(task, pu, cpurta);
+ final Time bcrt = cpurta.bestCaseCPURT(task, taskList, pu);
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ final Time bcct = rtaut.getExecutionTimeforCPUTaskIA(task, pu, TimeType.BCET, cpurta);
+ return bcrt.subtract(bcct);
+ */
+ // TODO: find the best-case initial pending in the given task's hyper-period
+ // (for E2E Latency with the worst-case sampling interval time.)
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ return null;
+ }
+
+ /**
+ * to derive the worst-case initial pending time of the observed task with the observed task chain
+ * @param task the observed task
+ * @param chain the observed task chain
+ * @param pu processing unit that computes to derive the wc initial pending time
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case initial pending time of the observed task in the observed task chain
+ */
+ protected Time getWCInitialPending(final Task task, final List<Task> chain, final ProcessingUnit pu, final CPURta cpurta) {
+ if (this.isTheRTAClassReadySingle(cpurta)) {
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ final List<Task> hpList = cpurta.getHigherPriorityTasksInChain(task, chain);
+ if (hpList.size() == 0) {
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ final Task oneHigherTask = hpList.get(hpList.size()-1);
+ Time wcIPTime = cpurta.preciseTestCPURT(oneHigherTask, hpList, TimeType.WCET, pu);
+ BigInteger wcIPTimeBI = AmaltheaServices.convertToPicoSeconds(wcIPTime);
+ for (int i = 0; i < hpList.size(); i++) {
+ final Task curTask = hpList.get(i);
+ final Time curPeriod = CommonUtils.getStimInTime(curTask);
+ BigInteger curPeriodBI = AmaltheaServices.convertToPicoSeconds(curPeriod);
+ if (i == hpList.size()-1 || wcIPTimeBI.compareTo(curPeriodBI) < 0) {
+ break;
+ } else if (wcIPTimeBI.mod(curPeriodBI) == BigInteger.ZERO) {
+ final Time curExeTime = rtaut.getExecutionTimeforCPUTaskIA(curTask, pu, TimeType.WCET, cpurta);
+ final BigInteger curExeTimeBI = AmaltheaServices.convertToPicoSeconds(curExeTime);
+ wcIPTimeBI = wcIPTimeBI.add(curExeTimeBI);
+ i = -1;
+ }
+ }
+ wcIPTime = FactoryUtil.createTime(wcIPTimeBI, TimeUnit.PS);
+ return wcIPTime;
+ }
+ return null;
+ }
+
+ /**
+ * to derive the worst-case initial pending time of the observed task
+ * @param task the observed task
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the worst-case initial pending time of the observed task
+ */
+ protected Time getWCInitialPending(final Task task, final CPURta cpurta) {
+ if (this.isTheRTAClassReadyMulti(cpurta)) {
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ final ProcessingUnit pu = cpurta.getPU(task, cpurta);
+ final List<Task> hpList = cpurta.getHigherPriorityTasks(task, cpurta);
+ if (hpList.size() == 0) {
+ return FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ }
+ final Task oneHigherTask = hpList.get(hpList.size()-1);
+ Time wcIPTime = cpurta.preciseTestCPURT(oneHigherTask, hpList, TimeType.WCET, pu);
+ BigInteger wcIPTimeBI = AmaltheaServices.convertToPicoSeconds(wcIPTime);
+ for (int i = 0; i < hpList.size(); i++) {
+ final Task curTask = hpList.get(i);
+ final Time curPeriod = CommonUtils.getStimInTime(curTask);
+ BigInteger curPeriodBI = AmaltheaServices.convertToPicoSeconds(curPeriod);
+ if (i == hpList.size()-1 || wcIPTimeBI.compareTo(curPeriodBI) < 0) {
+ break;
+ } else if (wcIPTimeBI.mod(curPeriodBI) == BigInteger.ZERO) {
+ final Time curExeTime = rtaut.getExecutionTimeforCPUTaskIA(curTask, pu, TimeType.WCET, cpurta);
+ final BigInteger curExeTimeBI = AmaltheaServices.convertToPicoSeconds(curExeTime);
+ wcIPTimeBI = wcIPTimeBI.add(curExeTimeBI);
+ i = -1;
+ }
+ }
+ wcIPTime = FactoryUtil.createTime(wcIPTimeBI, TimeUnit.PS);
+ return wcIPTime;
+ }
+ return null;
+ }
+
+ /**
+ * to derive the time between the critical instant and the given offset's task instance's finishing point
+ * @param offset the offset constant number (to set the initial point to analyze, initial point: offset * period of task)
+ * @param task the target task to derive the time between the critical instant and its current instance's finishing point
+ * @param chain the observed task chain
+ * @param pu processing unit that computes to derive the crrt time
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the time between the critical instant and the given offset's task instance's finishing point
+ */
+ protected Time getCRtoRT(final long offset, final Task task, final List<Task> chain, final ProcessingUnit pu, final CPURta cpurta) {
+ Time crToRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (this.isTheRTAClassReadySingle(cpurta)) {
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ final List<Task> sortedChain = cpurta.taskSorting(chain);
+ final Time hyper = this.getHyperPeriod(sortedChain);
+ final Time period = CommonUtils.getStimInTime(task);
+ final BigInteger hyper_BI = AmaltheaServices.convertToPicoSeconds(hyper);
+ final BigInteger period_BI = AmaltheaServices.convertToPicoSeconds(period);
+ final long cycle = hyper_BI.divide(period_BI).longValue();
+ if (offset % cycle != 0) {
+ final Time wcct = rtaut.getExecutionTimeforCPUTaskIA(task, pu, TimeType.WCET, cpurta);
+ final Time initialTime = period.multiply(offset).add(wcct);
+ crToRT = initialTime;
+ /* Incremental CRtoRT Part */
+ final List<Task> hpList = cpurta.getHigherPriorityTasksInChain(task, chain);
+ for (int i = 0; i < hpList.size(); i++) {
+ final BigInteger time_BI = AmaltheaServices.convertToPicoSeconds(crToRT);
+ final BigDecimal time_BD = BigDecimal.valueOf(time_BI.doubleValue());
+ final Task hpTask = hpList.get(i);
+ final Time hpWcct = rtaut.getExecutionTimeforCPUTaskIA(hpTask, pu, TimeType.WCET, cpurta);
+ final Time hpPeriod = CommonUtils.getStimInTime(hpTask);
+ final BigInteger hpPeriod_BI = AmaltheaServices.convertToPicoSeconds(hpPeriod);
+ final BigDecimal hpPeriod_BD = BigDecimal.valueOf(hpPeriod_BI.doubleValue());
+ long hpOffset = time_BD.divide(hpPeriod_BD, 0, BigDecimal.ROUND_FLOOR).longValue();
+ if (hpPeriod.multiply(hpOffset).add(hpWcct).compareTo(crToRT.subtract(wcct)) > 0 && time_BI.mod(hpPeriod_BI).longValue() != 0) {
+ crToRT = hpPeriod.multiply(hpOffset).add(hpWcct).add(wcct);
+ i = -1;
+ }
+ }
+ } else {
+ crToRT = cpurta.preciseTestCPURT(task, sortedChain, TimeType.WCET, pu).add(period.multiply(offset));
+ }
+ return crToRT;
+ }
+ return null;
+ }
+
+ /**
+ * to derive the time between the critical instant and the given offset's task instance's starting point
+ * @param offset the offset constant number (to set the initial point to analyze, initial point: offset * period of task)
+ * @param task the target task to derive the time between the critical instant and its current instance's starting point
+ * @param chain the observed task chain
+ * @param pu processing unit that computes to derive the crip time
+ * @param cpurta the instance of CPURta class
+ * @return
+ * the time between the critical instant and the given offset's task instance's starting point
+ */
+ protected Time getCRtoIP(final long offset, final Task task, final List<Task> chain, final ProcessingUnit pu, final CPURta cpurta) {
+ Time crToIP = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (this.isTheRTAClassReadySingle(cpurta)) {
+ final RTARuntimeUtil rtaut = new RTARuntimeUtil();
+ final List<Task> sortedChain = cpurta.taskSorting(chain);
+ final Time hyper = this.getHyperPeriod(sortedChain);
+ final Time period = CommonUtils.getStimInTime(task);
+ final BigInteger hyper_BI = AmaltheaServices.convertToPicoSeconds(hyper);
+ final BigInteger period_BI = AmaltheaServices.convertToPicoSeconds(period);
+ final long cycle = hyper_BI.divide(period_BI).longValue();
+ if (offset % cycle != 0) {
+ final Time initialTime = period.multiply(offset);
+ crToIP = initialTime;
+ /* Incremental CRtoIP Part */
+ final List<Task> hpList = cpurta.getHigherPriorityTasksInChain(task, chain);
+ for (int i = 0; i < hpList.size(); i++) {
+ final BigInteger time_BI = AmaltheaServices.convertToPicoSeconds(crToIP);
+ final BigDecimal time_BD = BigDecimal.valueOf(time_BI.doubleValue());
+ final Task hpTask = hpList.get(i);
+ final Time hpWcct = rtaut.getExecutionTimeforCPUTaskIA(hpTask, pu, TimeType.WCET, cpurta);
+ final Time hpPeriod = CommonUtils.getStimInTime(hpTask);
+ final BigInteger hpPeriod_BI = AmaltheaServices.convertToPicoSeconds(hpPeriod);
+ final BigDecimal hpPeriod_BD = BigDecimal.valueOf(hpPeriod_BI.doubleValue());
+ final long hpOffset = time_BD.divide(hpPeriod_BD, 0, BigDecimal.ROUND_FLOOR).longValue();
+ if (hpPeriod.multiply(hpOffset).add(hpWcct).compareTo(crToIP) > 0) {
+ crToIP = hpPeriod.multiply(hpOffset).add(hpWcct);
+ i = -1;
+ }
+ }
+ } else {
+ crToIP = this.getWCInitialPending(task, chain, pu, cpurta).add(period.multiply(offset));
+ }
+ return crToIP;
+ }
+ return null;
+ }
+
+ /**
+ * to derive the hyper-period of the observed task chain
+ * @param taskChain the observed task chain
+ * @return
+ * the hyper-period of the observed task chain
+ */
+ protected Time getHyperPeriod(List<Task> taskChain) {
+ final List<Time> periodList = taskChain.stream().map(s -> CommonUtils.getStimInTime(s))
+ .collect(Collectors.toList());
+ Time result = periodList.get(0);
+ BigInteger resultBI = AmaltheaServices.convertToPicoSeconds(result);
+ for (int i = 1; i < periodList.size(); i++) {
+ final BigInteger comTime = AmaltheaServices.convertToPicoSeconds(periodList.get(i));
+ resultBI = getLCM(resultBI, comTime);
+ }
+ result = FactoryUtil.createTime(resultBI, TimeUnit.PS);
+ return result;
+ }
+
+ /**
+ * to derive the least common multiple of two different BigInteger values
+ * @param time0 BigInteger A
+ * @param time1 BigInteger B
+ * @return
+ * the least common multiple of BigInteger A and BigInteger B
+ */
+ private BigInteger getLCM(BigInteger time0, BigInteger time1) {
+ return time0.multiply(time1.divide(getGCD(time0, time1)));
+ }
+
+ /**
+ * to derive the greatest common divisor of two different BigInteger values
+ * @param time0 BigInteger A
+ * @param time1 BigInteger B
+ * @return
+ * the greatest common divisor of BigInteger A and BigInteger B
+ */
+ private BigInteger getGCD(BigInteger time0, BigInteger time1) {
+ while (time1.compareTo(BigInteger.ZERO) == 1) {
+ BigInteger temp = time1;
+ time1 = time0.mod(time1);
+ time0 = temp;
+ }
+ return time0;
+ }
+
+ /**
+ * Get an Event-Chain Entity List (Task-based)
+ * @param ec the observed event chain
+ * @return
+ * the corresponding EC task list
+ */
+ public List<Task> getECTaskList(final EventChain ec) {
+ final List<Task> chain = new ArrayList<Task>();
+ for (int i = 0; i < ec.getItems().size(); i++) {
+ final EventChainItem eci = ec.getItems().get(i);
+ if (eci instanceof EventChainContainer) {
+ final EventChainContainer ecc = (EventChainContainer) eci;
+ final Event stiEvent = ecc.getEventChain().getStimulus();
+ if (stiEvent instanceof ProcessEvent) {
+ final Task stiTask = (Task)((ProcessEvent) stiEvent).getEntity();
+ chain.add(stiTask);
+ }
+ if (i == ec.getItems().size() - 1) {
+ final Event resEvent = ecc.getEventChain().getResponse();
+ if (resEvent instanceof ProcessEvent) {
+ final Task resTask = (Task)((ProcessEvent) resEvent).getEntity();
+ chain.add(resTask);
+ }
+ break;
+ }
+ }
+ }
+ return chain;
+ }
+
+ /**
+ * conver an event-chain to a list of Labels that belong to the chain
+ * @param ec the observed event-chain
+ * @return
+ * a list of the observed event-chain
+ */
+ public List<Label> convertECtoLabels(final EventChain ec, final CPURta cpurta) {
+ final List<Task> chain = getECTaskList(ec);
+ final List<Label> labels = new ArrayList<Label>();
+ for (int i = 0; i < chain.size(); i++) {
+ final Task task = chain.get(i);
+ final List<Runnable> runnables = SoftwareUtil.getRunnableList(task, null);
+ for (int j = 0; j < runnables.size(); j++) {
+ final Runnable runnable = runnables.get(j);
+ final List<LabelAccess> laList = SoftwareUtil.getLabelAccessList(runnable, null);
+ final List<Label> temp = laList.stream().map(s -> s.getData()).distinct().collect(Collectors.toList());
+ labels.addAll(temp);
+ }
+ /* runnables from the triggered task (gpu task) */
+ if (cpurta.getTriggeringTaskList().contains(task)) {
+ final List<ActivityGraphItem> triggerList = SoftwareUtil.collectActivityGraphItems(task.getActivityGraph(), null, (call -> call instanceof InterProcessTrigger));
+ final InterProcessTrigger ipt = (InterProcessTrigger) triggerList.get(0);
+ final InterProcessStimulus ips = ipt.getStimulus();
+ final Task gpuTask = cpurta.getGpuTaskList().stream().filter(s -> s.getStimuli().get(0).equals(ips)).iterator().next();
+ final List<Runnable> gpuRunnables = SoftwareUtil.getRunnableList(gpuTask, null);
+ for (int j = 0; j < gpuRunnables.size(); j++) {
+ final Runnable runnable = gpuRunnables.get(j);
+ final List<LabelAccess> laList = SoftwareUtil.getLabelAccessList(runnable, null);
+ final List<Label> temp = laList.stream().map(s -> s.getData()).distinct().collect(Collectors.toList());
+ labels.addAll(temp);
+ }
+ }
+ }
+ final List<Label> labelList = labels.stream().distinct().collect(Collectors.toList());
+ return labelList;
+ }
+
+ /**
+ * To check whether or not the observed task is mapped to CPU (according to the integer array)
+ * @param task the observed task
+ * @param cpurta the instance of CPURta class that contains model & mapping IA info
+ * @return
+ * boolean value that says whether or not it is mapped to CPU
+ */
+ private static boolean isMappedToCPU (final Task task, final CPURta cpurta) {
+ /* The observed task is a GPU task */
+ if (cpurta.getGpuTaskList().contains(task)) {
+ final int index = cpurta.getModel().getSwModel().getTasks().indexOf(task);
+ final int cpuThreshold = CommonUtils.getNumberofCPUs(cpurta.getModel()) - 1;
+ final int[] ia = cpurta.getIA();
+ /* when the observed GPU task is mapped to GPU */
+ if (ia[index] > cpuThreshold) {
+ return false;
+ }
+ }
+ /* when the observed task(CPU or GPU) is mapped to CPU */
+ return true;
+ }
+}
+
+/**
+ * @Date: July 10-2019
+ * @version 1.0
+ * This inner class is used for sorting a Time type list.
+ * If the Time of a is smaller than that of b, it returns -1.
+ * If the Time of a is bigger than that of b, it returns 1.
+ */
+class TimeComp implements Comparator<Time> {
+ @Override
+ public int compare(final Time a, final Time b) {
+ if (a.compareTo(b) < 0) {
+ return -1;
+ }
+ return 1;
+ }
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/IRTA.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/IRTA.java
new file mode 100644
index 0000000..726d59e
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/IRTA.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2020 Dortmund University of Applied Sciences and Arts.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * FH Dortmund - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.app4mc.gsoc_rta;
+
+import java.util.HashMap;
+
+import org.eclipse.app4mc.amalthea.model.Task;
+import org.eclipse.app4mc.amalthea.model.Time;
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
+
+public interface IRTA {
+
+ /**
+ * Get the sum of all response times contained in an AMALTHEA model
+ * @param timeType (BCET, WCET supported)
+ * @return Time response time sum across all tasks
+ */
+ public Time getRTSum(final TimeType timeType);
+
+ /**
+ * @return Hashmap<Task,Time> all tasks with corresponding response times
+ */
+ public HashMap<Task, Time> getTRT();
+
+ /**
+ * Get the response time of a task based on offsets for interProcessStimuli
+ * @param t Task
+ * @return Time reponse time
+ */
+ public Time getRT(final Task t, final TimeType timeType);
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/RuntimeUtilRTA.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/RTARuntimeUtil.java
similarity index 61%
rename from eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/RuntimeUtilRTA.java
rename to eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/RTARuntimeUtil.java
index 4713894..71a96a7 100644
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/RuntimeUtilRTA.java
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/RTARuntimeUtil.java
@@ -1,477 +1,564 @@
-/*******************************************************************************
- * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors: FH Dortmund - initial API and implementation
- *
- *******************************************************************************/
-package org.eclipse.app4mc.gsoc_rta;
-
-import java.math.BigInteger;
-import java.util.HashMap;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.apache.log4j.Logger;
-import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
-import org.eclipse.app4mc.amalthea.model.CallSequenceItem;
-import org.eclipse.app4mc.amalthea.model.ClearEvent;
-import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
-import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
-import org.eclipse.app4mc.amalthea.model.Label;
-import org.eclipse.app4mc.amalthea.model.LabelAccess;
-import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
-import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
-import org.eclipse.app4mc.amalthea.model.Runnable;
-import org.eclipse.app4mc.amalthea.model.SetEvent;
-import org.eclipse.app4mc.amalthea.model.Task;
-import org.eclipse.app4mc.amalthea.model.TaskRunnableCall;
-import org.eclipse.app4mc.amalthea.model.Ticks;
-import org.eclipse.app4mc.amalthea.model.Time;
-import org.eclipse.app4mc.amalthea.model.TimeUnit;
-import org.eclipse.app4mc.amalthea.model.WaitEvent;
-import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
-import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil;
-import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
-import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
-import org.eclipse.emf.common.util.EList;
-
-/**
- * Date: June 21-2019
- * @author Junhyung Ki
- * @version 1.0
- * This class is to support CpuRTA class. Response Time Analysis contains low level calculation
- * such as deriving execution time of a Task or Runnable. Execution time calculation varies depending on the analyzed model.
- * Therefore, it is necessary to separate from Response Time calculation to increase adaptability.
- * Only 'getExecutionTimeforCPUTask' method is accessible for CpuRTA and the rest are sub-methods of it.
- */
-public class RuntimeUtilRTA {
- /**
- * Calculate execution time of the given task under one of the several configurations.
- * Since this method is used by CPURtaIA, the visibility should be 'protected'
- * 1. triggering task in the synchronous mode
- * 2. triggering task in the asynchronous mode
- * 3. GPU task on CPU
- * 4. task with only Ticks
- *
- * @param task the observed task
- * @param pu ProcessingUnit that would compute the given task (A57 or Denver)
- * @param executionCase BCET, ACET, WCET
- * @param trt HashMap that would contain the corresponding GPU task's response time
- * @param cpurta the instance of CPURtaIA class that calls this method
- * (to access to the cumuAcTime Time variable that accumulate access latency)
- * @return
- * execution time of the observed task
- */
- protected Time getExecutionTimeforCPUTask(final Task task, final ProcessingUnit pu, final TimeType executionCase, final CpuRTA cpurta) {
- Logger.getLogger(RuntimeUtilRTA.class);
- // TODO: Contention Parameter
- /* set the default result time variable as 0s */
- Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- /* check if the current task is a triggering task.
- * If so, check whether or not it triggers the target task which is newly mapped to CPU.
- * In that case, returns 0 ps */
- if (doesThisTaskTriggerCPUTask(task, cpurta)) {
- return result;
- }
- // TODO: Contention
- /* The list of runnables of the given task */
- final List<Runnable> runnableList = SoftwareUtil.getRunnableList(task, null);
- /* To identify the index of the triggerEvent */
- final List<CallSequenceItem> callSequenceList = SoftwareUtil.collectCalls(task, null,
- (call -> call instanceof TaskRunnableCall || call instanceof InterProcessTrigger || call instanceof ClearEvent
- || call instanceof SetEvent || call instanceof WaitEvent));
- int indexforTrigger = 0;
- for (int i = 0; i < callSequenceList.size(); i++) {
- if (callSequenceList.get(i) instanceof InterProcessTrigger) {
- indexforTrigger = i;
- }
- }
- /* To distinguish CPU Tasks between Sync & Async */
- if (isTriggeringTask(task)) {
- /* all should be synchronous (wait should not be ignored) - active wait */
- if (SharedConsts.synchronousOffloading == true) {
- result = syncTypeOperation(indexforTrigger, callSequenceList, runnableList, pu, executionCase, cpurta);
- /* if this task has the OffloadingAsync runnable, subtract the runnable part from the result */
- if (doesTaskHaveAsyncRunnable(task, cpurta)) {
- result = result.subtract(getExecutionTimeForRTARunnable(cpurta.offloadingAsyncRunnable, pu, executionCase));
- }
- }
- /* all should be asynchronous (wait should be ignored) - passive wait */
- else {
- result = asyncTypeOperation(runnableList, pu, executionCase);
- /* if this task is missing the OffloadingAsync runnable, add the runnable part to the result */
- if (!doesTaskHaveAsyncRunnable(task, cpurta)) {
- result = result.add(getExecutionTimeForRTARunnable(cpurta.offloadingAsyncRunnable, pu, executionCase));
- }
- }
- }
- else {
- /* GPU Origin Task on CPU & No Triggering Behavior (No InterProcessTrigger) */
- if (!(callSequenceList.get(indexforTrigger) instanceof InterProcessTrigger)) {
- /* GPU Origin task that is newly mapped to CPU */
- if (cpurta.getGpuTaskList().contains(task)) {
- result = result.add(getExecutionTimeForGPUTaskOnCPU(task, runnableList, pu, executionCase, cpurta));
- // TODO: result = result.add(contention);
- return result;
- }
- /* No Triggering Behavior (No InterProcessTrigger) */
- for (final Runnable r : runnableList) {
- result = result.add(getExecutionTimeForRTARunnable(r, pu, executionCase));
- }
- // TODO: result = result.add(contention);
- return result;
- }
- }
- // TODO: result = result.add(contention);
- return result;
- }
-
- /**
- * Find out whether the given triggering task(that has an InterProcessTrigger) triggers a GPU task which is newly mapped to CPU.
- * If the ProcessingUnit index of the triggered task is bigger than the biggest CPU index, that means the triggered task is mapped to GPU
- * which would return false.
- *
- * @param task the observed task
- * @param cpurta the instance of CPURtaIA class that calls this method
- * (to get the task List & the integer array to identify the ProcessingUnit index of the triggered task)
- * @return
- * boolean value (true: the observed task triggers a task that is mapped to CPU /
- * false: the observed task triggers a task that is mapped to GPU)
- */
- private boolean doesThisTaskTriggerCPUTask(final Task task, final CpuRTA cpurta) {
- if (cpurta.getTriggeringTaskList().contains(task)) {
- final List<CallSequenceItem> callList = SoftwareUtil.collectCalls(task, null,
- (call -> call instanceof TaskRunnableCall || call instanceof InterProcessTrigger || call instanceof ClearEvent
- || call instanceof SetEvent || call instanceof WaitEvent));
- final InterProcessStimulus ips = ((InterProcessTrigger) callList.stream().filter(s -> s instanceof InterProcessTrigger).iterator().next())
- .getStimulus();
- final EList<Task> allTaskList = cpurta.getModel().getSwModel().getTasks();
- final int[] ia = cpurta.getIA();
- final int cpuThreshold = CommonUtils.getNumberofCPUs(cpurta.getModel()) - 1;
- for (int i = 0; i < ia.length; i++) {
- if (ia[i] > cpuThreshold) {
- final Task theTask = allTaskList.get(i);
- if (theTask.getStimuli().get(0) instanceof InterProcessStimulus) {
- final InterProcessStimulus thisIPS = (InterProcessStimulus) theTask.getStimuli().get(0);
- if (ips.equals(thisIPS)) {
- Logger.getLogger(RuntimeUtilRTA.class).debug("Confirmation: The triggered task mapped to (GPU)");
- return false;
- }
- }
- }
- }
- Logger.getLogger(RuntimeUtilRTA.class).debug("Confirmation: The triggered task mapped to (CPU)");
- return true;
- }
- return false;
- }
-
- /**
- * Calculate execution time of the given runnableList in a synchronous manner.
- * (execution time of pre-processing) + GPU task response time + (execution time of post-processing)
- *
- * @param indexforTrigger Integer variable that is used to get InterProcessTrigger to identify the triggered GPU task
- * @param callSequenceList callSequenceList List variable that is used to get InterProcessTrigger to identify the triggered GPU task
- * @param runnableList the observed runnable List to calculate execution time in the synchronous mode
- * @param trt HashMap that would contain the corresponding GPU task's response time
- * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
- * @param executionCase BCET, ACET, WCET
- * @param cpurta the instance of CPURtaIA class that calls this method
- * (to get the identified triggered GPU task in the model)
- * (to access to the cumuAcTime Time variable that accumulate access latency)
- * @return
- * synchronous execution time of the observed set
- */
- private Time syncTypeOperation(final int indexforTrigger, final List<CallSequenceItem> callSequenceList, final List<Runnable> runnableList,
- final ProcessingUnit pu, final TimeType executionCase, final CpuRTA cpurta) {
- Logger.getLogger(RuntimeUtilRTA.class).debug("TYPE: SYNC");
- /* set the default result time variable as 0s */
- Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- /* Sum all the runnable ExecutionTime of the CPU Task */
- for (final Runnable r : runnableList) {
- result = result.add(getExecutionTimeForRTARunnable(r, pu, executionCase));
- }
- final InterProcessTrigger ipt = (InterProcessTrigger) callSequenceList.get(indexforTrigger);
- final Task triggeredGPUTask = cpurta.getModel().getSwModel().getTasks().stream().filter(t -> t.getStimuli().get(0).equals(ipt.getStimulus())).iterator()
- .next();
- result = result.add(cpurta.getTRT().get(triggeredGPUTask));
- return result;
- }
-
- /**
- * Calculate execution time of the given runnableList in an asynchronous manner.
- * (execution time of pre-processing) + (execution time of post-processing)
- *
- * @param runnableList the observed runnable List to calculate execution time in the asynchronous mode
- * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
- * @param executionCase BCET, ACET, WCET
- * @return
- * asynchronous execution time of the observed runnable List
- */
- private Time asyncTypeOperation(final List<Runnable> runnableList, final ProcessingUnit pu, final TimeType executionCase) {
- Logger.getLogger(RuntimeUtilRTA.class).debug("TYPE: ASYNC");
- /**
- * <Asynchronous Task> et_t=sum_{runnable calls before GPU trigger
- * event}et_r + et_{runnable calls after GPU trigger event};
- */
- /* set the default result time variable as 0s */
- Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- /* Sum all the runnable ExecutionTime */
- for (final Runnable r : runnableList) {
- /* In case of Pre_Detection_Post task, the AsyncOffloading runnable is already taken into account here. */
- result = result.add(getExecutionTimeForRTARunnable(r, pu, executionCase));
- }
- return result;
- }
-
- /**
- * Identify whether or not the given task has the OffloadingAsyncCosts Runnable (that takes costs into account in the Asynchronous mode)
- * which some triggering tasks do not have.
- * Since this method is used by CPURtaIA, the visibility should be 'protected'
- *
- * @param task the observed task
- * @param cpurta the instance of CPURtaIA class that calls this method
- * (to access to the triggeringTaskList List<Task> variable that contains tasks with an InterProcessTrigger)
- * @return
- * boolean value of the result
- */
- protected static boolean doesTaskHaveAsyncRunnable (final Task task, final CpuRTA cpurta) {
- boolean result = false;
- if (cpurta.getTriggeringTaskList().contains(task)) {
- final List<CallSequenceItem> callList = SoftwareUtil.collectCalls(task, null,
- (call -> call instanceof TaskRunnableCall || call instanceof InterProcessTrigger || call instanceof ClearEvent
- || call instanceof SetEvent || call instanceof WaitEvent));
- final int waitIndex = callList.indexOf(callList.stream().filter(s -> s instanceof WaitEvent).iterator().next());
- final int clearIndex = callList.indexOf(callList.stream().filter(s -> s instanceof ClearEvent).iterator().next());
- if ((clearIndex - waitIndex) > 1) {
- result = true;
- }
- }
- else {
- Logger.getLogger(RuntimeUtilRTA.class).debug("ERROR: This task is not a triggering task!!");
- }
- return result;
- }
-
- /**
- * Calculate execution time of the given task which was originally designed for GPU but newly mapped to CPU by Generic Algorithm Mapping.
- * It should ignore offloading runnables and take the required labels(read from pre-processing, write from post-processing) into account.
- * The method follows Read / Compute(Ticks) / Write semantic.
- * Read(Write)_Access_Time = Round_UP(Size_of_Read_Labels / 64.0 Bytes) * (Read_Latency / Frequency)
- *
- * @param task the observed task
- * @param runnableList runnable list of the given task
- * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
- * @param executionCase BCET, ACET, WCET
- * @param cpurta the instance of CPURtaIA class that calls this method
- * (to access to the gpuToCpuLabels HashMap variable that contains List<Label> of required read & write labels)
- * @return
- * execution time of the observed task
- */
- private Time getExecutionTimeForGPUTaskOnCPU(final Task task, final List<Runnable> runnableList, final ProcessingUnit pu,
- final TimeType executionCase, final CpuRTA cpurta) {
- Logger.getLogger(RuntimeUtilRTA.class).debug("TYPE: GPUTaskOnCPU // " + "Task: " + task.getName());
- Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- Runnable funcRunnable = null;
- for (final Runnable r : runnableList) {
- final List<Ticks> thisTicksList = SoftwareUtil.getTicks(r, null);
- if (thisTicksList.size() != 0) {
- funcRunnable = r;
- break;
- }
- }
- final Time parameter = FactoryUtil.createTime(BigInteger.ONE, TimeUnit.S);
- final double freq = AmaltheaServices.convertToHertz(pu.getFrequencyDomain().getDefaultValue()).longValue();
- final HashMap<Task, List<Label>[]> gtcl = cpurta.getGTCL();
- final List<Label>[] thisLabelList = gtcl.get(task);
- final List<Label> readLabelList = thisLabelList[0];
- final List<Label> writeLabelList = thisLabelList[1];
- for (final Label l : readLabelList) {
- Logger.getLogger(RuntimeUtilRTA.class).debug("Label(Read): " + l.getName() + " // (" + task.getName() + ")");
- }
- for (final Label l : writeLabelList) {
- Logger.getLogger(RuntimeUtilRTA.class).debug("Label(Write): " + l.getName() + " // (" + task.getName() + ")");
- }
- double readLatency = 0;
- double writeLatency = 0;
- if (executionCase.equals(TimeType.WCET)) {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getUpperBound();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getUpperBound();
- }
- else if (executionCase.equals(TimeType.BCET)) {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getLowerBound();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getLowerBound();
- }
- else {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getAverage();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getAverage();
- }
- /* Read (LabelAccess): */
- double readAccessParameter = 0;
- double sizeofReadLabels = 0;
- for (final Label rl : readLabelList) {
- sizeofReadLabels += rl.getSize().getNumberBytes();
- }
- readAccessParameter = (Math.ceil(sizeofReadLabels / 64.0) * (readLatency / freq));
- final Time readAccess = parameter.multiply(readAccessParameter);
- result = result.add(readAccess); // LabelAccess(Read) added
- /* Execution (Ticks): */
- final List<Ticks> ticksList = SoftwareUtil.getTicks(funcRunnable, null);
- for (final Ticks t : ticksList) {
- final Time tickExecution = RuntimeUtil.getExecutionTimeForTicks(t, pu, executionCase);
- result = result.add(tickExecution); // Execution(Ticks) added
- }
- /* Write (LabelAccess): */
- double writeAccessParameter = 0;
- double sizeofWriteLabels = 0;
- for (final Label wl : writeLabelList) {
- sizeofWriteLabels += wl.getSize().getNumberBytes();
- }
- writeAccessParameter = (Math.ceil(sizeofWriteLabels / 64.0) * (writeLatency / freq));
- final Time writeAccess = parameter.multiply(writeAccessParameter);
- result = result.add(writeAccess); // LabelAccess(Write) added
- return result;
- }
-
- /**
- * Calculate execution time of the given runnable.
- * The method consider Read / Compute(Ticks) / Write semantic.
- *
- * @param runnable the observed runnable
- * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
- * @param executionCase BCET, ACET, WCET
- * @return
- * execution time of the observed runnable
- */
- protected Time getExecutionTimeForRTARunnable(final Runnable runnable, final ProcessingUnit pu, final TimeType executionCase) {
- Logger.getLogger(RuntimeUtilRTA.class).debug(executionCase.toString());
- Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- final double freq = AmaltheaServices.convertToHertz(pu.getFrequencyDomain().getDefaultValue()).longValue();
- double readLatency = 0;
- double writeLatency = 0;
- if (executionCase.equals(TimeType.WCET)) {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getUpperBound();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getUpperBound();
- }
- else if (executionCase.equals(TimeType.BCET)) {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getLowerBound();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getLowerBound();
- }
- else {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getAverage();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getAverage();
- }
- /* Read & Write Memory Access Time */
- result = result.add(getRunnableMemoryAccessTime(runnable, freq, readLatency, writeLatency));
-
- /* Execution (Ticks): */
- final List<Ticks> ticksList = SoftwareUtil.getTicks(runnable, null);
- for (final Ticks t : ticksList) {
- final Time tickExecution = RuntimeUtil.getExecutionTimeForTicks(t, pu, executionCase);
- result = result.add(tickExecution); // Execution(Ticks) added
- }
- return result;
- }
-
- /**
- * Calculate memory access time of the observed task.
- * Since this method is used by CPURtaIA, the visibility should be 'protected'
- *
- * @param task the observed task
- * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
- * @param executionCase BCET, ACET, WCET
- * @return
- * memory access time of the observed task
- */
- protected Time getTaskMemoryAccessTime (final Task task, final ProcessingUnit pu, final TimeType executionCase) {
- Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- final double freq = AmaltheaServices.convertToHertz(pu.getFrequencyDomain().getDefaultValue()).longValue();
- final List<Runnable> runnableList = SoftwareUtil.getRunnableList(task, null);
- double readLatency = 0;
- double writeLatency = 0;
- if (executionCase.equals(TimeType.WCET)) {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getUpperBound();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getUpperBound();
- }
- else if (executionCase.equals(TimeType.BCET)) {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getLowerBound();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getLowerBound();
- }
- else {
- readLatency = pu.getAccessElements().get(0).getReadLatency().getAverage();
- writeLatency = pu.getAccessElements().get(0).getWriteLatency().getAverage();
- }
- for(final Runnable r : runnableList ) {
- result = result.add(getRunnableMemoryAccessTime(r, freq, readLatency, writeLatency));
- }
- return result;
- }
-
- /**
- * Calculate memory access time of the observed runnable.
- * The method follows Read / Compute(Ticks) / Write semantic.
- * Read(Write)_Access_Time = Round_UP(Size_of_Read_Labels / 64.0 Bytes) * (Read_Latency / Frequency)
- *
- * @param runnable the observed runnable
- * @param frequency frequency value of the Processing Unit
- * @param readLatency readLatency value of the Processing Unit
- * @param writeLatency writeLatency value of the Processing Unit
- * @return
- * memory access time of the observed runnable
- */
- private Time getRunnableMemoryAccessTime (final Runnable runnable, final double frequency,
- final double readLatency, final double writeLatency) {
- Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- final Time parameter = FactoryUtil.createTime(BigInteger.ONE, TimeUnit.S);
- final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(runnable, null);
- final List<LabelAccess> readList = thisLAList.stream().filter(x -> (x.getAccess()).equals(LabelAccessEnum.READ)).collect(Collectors.toList());
- final List<LabelAccess> writeList = thisLAList.stream().filter(x -> (x.getAccess()).equals(LabelAccessEnum.WRITE)).collect(Collectors.toList());
- /* Read (LabelAccess): */
- double readAccessParameter = 0;
- double sizeofReadLabels = 0;
- for (final LabelAccess rl : readList) {
- sizeofReadLabels += rl.getData().getSize().getNumberBytes();
- }
- readAccessParameter = (Math.ceil(sizeofReadLabels / 64.0) * (readLatency / frequency));
- final Time readAccess = parameter.multiply(readAccessParameter);
- result = result.add(readAccess); // LabelAccess(Read) added
-
- /* Write (LabelAccess): */
- double writeAccessParameter = 0;
- double sizeofWriteLabels = 0;
- for (final LabelAccess wl : writeList) {
- sizeofWriteLabels += wl.getData().getSize().getNumberBytes();
- }
- writeAccessParameter = (Math.ceil(sizeofWriteLabels / 64.0) * (writeLatency / frequency));
- final Time writeAccess = parameter.multiply(writeAccessParameter);
- result = result.add(writeAccess); // LabelAccess(Write) added
- return result;
- }
-
- /**
- * Identify whether the given task has an InterProcessTrigger or not.
- *
- * @param task the observed task
- * @return
- * boolean value of the result
- */
- protected static boolean isTriggeringTask(final Task task) {
- /* true: Triggering Task, false: Non-Triggering Task */
- boolean result = false;
- final List<CallSequenceItem> callList = SoftwareUtil.collectCalls(task, null,
- (call -> call instanceof TaskRunnableCall || call instanceof InterProcessTrigger || call instanceof ClearEvent
- || call instanceof SetEvent || call instanceof WaitEvent));
- List<CallSequenceItem> iptList = callList.stream().filter(s -> s instanceof InterProcessTrigger).collect(Collectors.toList());
- if (iptList.size() != 0) {
- result = true;
- }
- return result;
- }
-}
\ No newline at end of file
+/*******************************************************************************
+ * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * FH Dortmund - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.app4mc.gsoc_rta;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.eclipse.app4mc.gsoc_rta.CommonUtils;
+import org.eclipse.app4mc.gsoc_rta.SharedConsts;
+import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
+import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
+import org.eclipse.app4mc.amalthea.model.ClearEvent;
+import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
+import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
+import org.eclipse.app4mc.amalthea.model.Label;
+import org.eclipse.app4mc.amalthea.model.LabelAccess;
+import org.eclipse.app4mc.amalthea.model.LabelAccessEnum;
+import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
+import org.eclipse.app4mc.amalthea.model.Runnable;
+import org.eclipse.app4mc.amalthea.model.RunnableCall;
+import org.eclipse.app4mc.amalthea.model.SetEvent;
+import org.eclipse.app4mc.amalthea.model.Task;
+import org.eclipse.app4mc.amalthea.model.Ticks;
+import org.eclipse.app4mc.amalthea.model.Time;
+import org.eclipse.app4mc.amalthea.model.TimeUnit;
+import org.eclipse.app4mc.amalthea.model.WaitEvent;
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil;
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
+import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
+import org.eclipse.emf.common.util.EList;
+
+public class RTARuntimeUtil {
+ final static Logger log = Logger.getLogger(RTARuntimeUtil.class);
+ /**
+ * Calculate execution time of the given task under one of the four cases with some configurations.
+ * Since this method is used by CPURta, the visibility should be 'public'
+ * 1. triggering task in the synchronous mode
+ * 2. triggering task in the asynchronous mode
+ * 3. GPU task on CPU
+ * 4. task with only Ticks
+ * @param task the observed task
+ * @param pu ProcessingUnit that would compute the given task (A57 or Denver)
+ * @param executionCase BCET, ACET, WCET
+ * @param cpurta the instance of CPURta class that calls this method
+ * (to access to the cumuAcTime Time variable that accumulate access latency)
+ * @return
+ * execution time of the observed task
+ */
+ public Time getExecutionTimeforCPUTaskIA(final Task task, final ProcessingUnit pu, final TimeType executionCase, final CPURta cpurta) {
+ log.setLevel(Level.ERROR);
+ /* set the default result time variable as 0s */
+ Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ /* check if the current task is a triggering task.
+ * If so, check whether or not it triggers the target task which is newly mapped to CPU.
+ * In that case, returns 0 ps */
+ if (doesThisTaskTriggerCPUTask(task, cpurta)) {
+ return result;
+ }
+ /* contention time */
+ Time contention = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (cpurta.getIA() != null) {
+ contention = cpurta.getCT().contentionForTask(task);
+ }
+ /* The list of runnables of the given task */
+ final List<Runnable> runnableList = SoftwareUtil.getRunnableList(task, null);
+ /* To identify the index of the triggerEvent */
+ final List<ActivityGraphItem> callSequenceList = SoftwareUtil.collectActivityGraphItems(task.getActivityGraph(), null, (call -> call instanceof RunnableCall
+ || call instanceof InterProcessTrigger || call instanceof ClearEvent || call instanceof SetEvent || call instanceof WaitEvent));
+ int indexforTrigger = 0;
+ for (int i = 0; i < callSequenceList.size(); i++) {
+ if (callSequenceList.get(i) instanceof InterProcessTrigger) {
+ indexforTrigger = i;
+ }
+ }
+ /* To distinguish CPU Tasks between Sync & Async */
+ if (isTriggeringTask(task)) {
+ /* all should be synchronous (wait should not be ignored) - active wait */
+ if (SharedConsts.synchronousOffloading == true) {
+ result = syncTypeOperation(indexforTrigger, callSequenceList, runnableList, pu, executionCase, cpurta);
+ /* if this task has the OffloadingAsync runnable, subtract the runnable part from the result */
+ if (doesTaskHaveAsyncRunnable(task, cpurta)) {
+ result = result.subtract(getExecutionTimeForRTARunnable(cpurta.offloadingAsyncRunnable, pu, executionCase));
+ }
+ }
+ /* all should be asynchronous (wait should be ignored) - passive wait */
+ else {
+ result = asyncTypeOperation(runnableList, pu, executionCase);
+ /* if this task is missing the OffloadingAsync runnable, add the runnable part to the result */
+ if (!doesTaskHaveAsyncRunnable(task, cpurta)) {
+ result = result.add(getExecutionTimeForRTARunnable(cpurta.offloadingAsyncRunnable, pu, executionCase));
+ }
+ }
+ }
+ else {
+ /* GPU Origin Task on CPU & No Triggering Behavior (No InterProcessTrigger) */
+ if (!(callSequenceList.get(indexforTrigger) instanceof InterProcessTrigger)) {
+ /* GPU Origin task that is newly mapped to CPU */
+ if (cpurta.getGpuTaskList().contains(task)) {
+ result = result.add(getExecutionTimeForGPUTaskOnCPU(task, runnableList, pu, executionCase, cpurta));
+ result = result.add(contention);
+ return result;
+ }
+ /* No Triggering Behavior (No InterProcessTrigger) */
+ for (final Runnable r : runnableList) {
+ result = result.add(getExecutionTimeForRTARunnable(r, pu, executionCase));
+ }
+ }
+ }
+ result = result.add(contention);
+ return result;
+ }
+
+ /**
+ * Find out whether the given triggering task(that has an InterProcessTrigger) triggers a GPU task which is newly mapped to CPU.
+ * If the ProcessingUnit index of the triggered task is bigger than the biggest CPU index, that means the triggered task is mapped to GPU
+ * which would return false.
+ * @param task the observed task
+ * @param cpurta the instance of CPURtaIA class that calls this method
+ * (to get the task List & the integer array to identify the ProcessingUnit index of the triggered task)
+ * @return
+ * boolean value (true: the observed task triggers a task that is mapped to CPU /
+ * false: the observed task triggers a task that is mapped to GPU)
+ */
+ private boolean doesThisTaskTriggerCPUTask(final Task task, final CPURta cpurta) {
+ if (cpurta.getTriggeringTaskList().contains(task)) {
+ final List<ActivityGraphItem> callList = SoftwareUtil.collectActivityGraphItems(task.getActivityGraph(), null, (call -> call instanceof RunnableCall
+ || call instanceof InterProcessTrigger || call instanceof ClearEvent || call instanceof SetEvent || call instanceof WaitEvent));
+ final InterProcessStimulus ips = ((InterProcessTrigger) callList.stream().filter(s -> s instanceof InterProcessTrigger).iterator().next())
+ .getStimulus();
+ final EList<Task> allTaskList = cpurta.getModel().getSwModel().getTasks();
+ final int[] ia = cpurta.getIA();
+ final int cpuThreshold = CommonUtils.getNumberofCPUs(cpurta.getModel()) - 1;
+ for (int i = 0; i < ia.length; i++) {
+ if (ia[i] > cpuThreshold) {
+ final Task theTask = allTaskList.get(i);
+ if (theTask.getStimuli().get(0) instanceof InterProcessStimulus) {
+ final InterProcessStimulus thisIPS = (InterProcessStimulus) theTask.getStimuli().get(0);
+ if (ips.equals(thisIPS)) {
+ log.debug("Confirmation: The triggered task mapped to (GPU)");
+ return false;
+ }
+ }
+ }
+ }
+ log.debug("Confirmation: The triggered task mapped to (CPU)");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Calculate execution time of the given runnableList in a synchronous manner.
+ * (execution time of pre-processing) + GPU task response time + (execution time of post-processing)
+ * @param indexforTrigger Integer variable that is used to get InterProcessTrigger to identify the triggered GPU task
+ * @param callSequenceList callSequenceList List variable that is used to get InterProcessTrigger to identify the triggered GPU task
+ * @param runnableList the observed runnable List to calculate execution time in the synchronous mode
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @param executionCase BCET, ACET, WCET
+ * @param cpurta the instance of CPURtaIA class that calls this method
+ * (to get the identified triggered GPU task in the model)
+ * (to access to the cumuAcTime Time variable that accumulate access latency)
+ * @return
+ * synchronous execution time of the observed set
+ */
+ private Time syncTypeOperation(final int indexforTrigger, final List<ActivityGraphItem> callSequenceList, final List<Runnable> runnableList,
+ final ProcessingUnit pu, final TimeType executionCase, final CPURta cpurta) {
+ log.debug("TYPE: SYNC");
+ /* set the default result time variable as 0s */
+ Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ /* Sum all the runnable ExecutionTime of the CPU Task */
+ for (final Runnable r : runnableList) {
+ result = result.add(getExecutionTimeForRTARunnable(r, pu, executionCase));
+ }
+ final InterProcessTrigger ipt = (InterProcessTrigger) callSequenceList.get(indexforTrigger);
+ final Task triggeredGPUTask = cpurta.getModel().getSwModel().getTasks().stream().filter(t -> t.getStimuli().get(0).equals(ipt.getStimulus())).iterator()
+ .next();
+ result = result.add(cpurta.getTRT().get(triggeredGPUTask));
+ return result;
+ }
+
+ /**
+ * Calculate execution time of the given runnableList in an asynchronous manner.
+ * (execution time of pre-processing) + (execution time of post-processing)
+ * @param runnableList the observed runnable List to calculate execution time in the asynchronous mode
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @param executionCase BCET, ACET, WCET
+ * @return
+ * asynchronous execution time of the observed runnable List
+ */
+ private Time asyncTypeOperation(final List<Runnable> runnableList, final ProcessingUnit pu, final TimeType executionCase) {
+ log.debug("TYPE: ASYNC");
+ /**
+ * <Asynchronous Task> et_t=sum_{runnable calls before GPU trigger
+ * event}et_r + et_{runnable calls after GPU trigger event};
+ */
+ /* set the default result time variable as 0s */
+ Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ /* Sum all the runnable ExecutionTime */
+ for (final Runnable r : runnableList) {
+ /* In case of Pre_Detection_Post task, the AsyncOffloading runnable is already taken into account here. */
+ result = result.add(getExecutionTimeForRTARunnable(r, pu, executionCase));
+ }
+ return result;
+ }
+
+ /**
+ * Identify whether or not the given task has the OffloadingAsyncCosts Runnable (that takes costs into account in the Asynchronous mode)
+ * which some triggering tasks do not have.
+ * Since this method is used by CPURtaIA, the visibility should be 'protected'
+ * @param task the observed task
+ * @param cpurta the instance of CPURtaIA class that calls this method
+ * (to access to the triggeringTaskList List<Task> variable that contains tasks with an InterProcessTrigger)
+ * @return
+ * boolean value of the result
+ */
+ protected static boolean doesTaskHaveAsyncRunnable(final Task task, final CPURta cpurta) {
+ boolean result = false;
+ if (cpurta.getTriggeringTaskList().contains(task)) {
+ final List<ActivityGraphItem> callList = SoftwareUtil.collectActivityGraphItems(task.getActivityGraph(), null, (call -> call instanceof RunnableCall
+ || call instanceof InterProcessTrigger || call instanceof ClearEvent || call instanceof SetEvent || call instanceof WaitEvent));
+ final int waitIndex = callList.indexOf(callList.stream().filter(s -> s instanceof WaitEvent).iterator().next());
+ final List<ActivityGraphItem> clearEvent = callList.stream().filter(s -> s instanceof ClearEvent).collect(Collectors.toList());
+ if (clearEvent.size() != 0) {
+ final int clearIndex = callList.indexOf(callList.stream().filter(s -> s instanceof ClearEvent).iterator().next());
+ if ((clearIndex - waitIndex) > 1) {
+ result = true;
+ }
+ }
+ } else {
+ log.debug("ERROR: This task is not a triggering task!!");
+ }
+ return result;
+ }
+
+ /**
+ * Calculate execution time of the given task which was originally designed for GPU but newly mapped to CPU by Generic Algorithm Mapping.
+ * It should ignore offloading runnables and take the required labels(read from pre-processing, write from post-processing) into account.
+ * The method follows Read / Compute(Ticks) / Write semantic.
+ * Read(Write)_Access_Time = Round_UP(Size_of_Read_Labels / 64.0 Bytes) * (Read_Latency / Frequency)
+ * @param task the observed task
+ * @param runnableList runnable list of the given task
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @param executionCase BCET, ACET, WCET
+ * @param cpurta the instance of CPURtaIA class that calls this method
+ * (to access to the gpuToCpuLabels HashMap variable that contains List<Label> of required read & write labels)
+ * @return
+ * execution time of the observed task
+ */
+ private Time getExecutionTimeForGPUTaskOnCPU(final Task task, final List<Runnable> runnableList, final ProcessingUnit pu,
+ final TimeType executionCase, final CPURta cpurta) {
+ log.debug("TYPE: GPUTaskOnCPU // " + "Task: " + task.getName());
+ Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Runnable funcRunnable = null;
+ for (final Runnable r : runnableList) {
+ final List<Ticks> thisTicksList = SoftwareUtil.getTicks(r, null);
+ if (thisTicksList.size() != 0) {
+ funcRunnable = r;
+ break;
+ }
+ }
+ final Time parameter = FactoryUtil.createTime(BigInteger.ONE, TimeUnit.S);
+ final double freq = AmaltheaServices.convertToHertz(pu.getFrequencyDomain().getDefaultValue()).longValue();
+ final HashMap<Task, List<List<Label>>> gtcl = cpurta.getGTCL();
+ final List<List<Label>> thisLabelList = gtcl.get(task);
+ final List<Label> readLabelList = thisLabelList.get(0);
+ final List<Label> writeLabelList = thisLabelList.get(1);
+ for (final Label l : readLabelList) {
+ log.debug("Label(Read): " + l.getName() + " // (" + task.getName() + ")");
+ }
+ for (final Label l : writeLabelList) {
+ log.debug("Label(Write): " + l.getName() + " // (" + task.getName() + ")");
+ }
+ double readLatency = 0;
+ double writeLatency = 0;
+ if (executionCase.equals(TimeType.WCET)) {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getUpperBound();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getUpperBound();
+ } else if (executionCase.equals(TimeType.BCET)) {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getLowerBound();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getLowerBound();
+ } else {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getAverage();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getAverage();
+ }
+ /* Read (LabelAccess): */
+ double readAccessParameter = 0;
+ double sizeofReadLabels = 0;
+ for (final Label rl : readLabelList) {
+ sizeofReadLabels += rl.getSize().getNumberBytes();
+ }
+ readAccessParameter = (Math.ceil(sizeofReadLabels / 64.0) * (readLatency / freq));
+ final Time readAccess = parameter.multiply(readAccessParameter);
+ result = result.add(readAccess); // LabelAccess(Read) added
+ /* Execution (Ticks): */
+ final List<Ticks> ticksList = SoftwareUtil.getTicks(funcRunnable, null);
+ for (final Ticks t : ticksList) {
+ final Time tickExecution = CommonUtils.getExecutionTimeForTicks(t, pu, executionCase); // 0.9.4
+ result = result.add(tickExecution); // Execution(Ticks) added
+ }
+ /* Write (LabelAccess): */
+ double writeAccessParameter = 0;
+ double sizeofWriteLabels = 0;
+ for (final Label wl : writeLabelList) {
+ sizeofWriteLabels += wl.getSize().getNumberBytes();
+ }
+ writeAccessParameter = (Math.ceil(sizeofWriteLabels / 64.0) * (writeLatency / freq));
+ final Time writeAccess = parameter.multiply(writeAccessParameter);
+ result = result.add(writeAccess); // LabelAccess(Write) added
+ return result;
+ }
+
+ /**
+ * Calculate execution time of the given runnable.
+ * The method consider Read / Compute(Ticks) / Write semantic.
+ * @param runnable the observed runnable
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @param executionCase BCET, ACET, WCET
+ * @return
+ * execution time of the observed runnable
+ */
+ private Time getExecutionTimeForRTARunnable(final Runnable runnable, final ProcessingUnit pu, final TimeType executionCase) {
+ log.debug(executionCase.toString());
+ Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ final double freq = AmaltheaServices.convertToHertz(pu.getFrequencyDomain().getDefaultValue()).longValue();
+ double readLatency = 0;
+ double writeLatency = 0;
+ if (pu.getAccessElements().size() == 0) {
+ readLatency = 30; // Default value will be assigned
+ writeLatency = 30; // Default value of will be assigned
+ } else {
+ if (executionCase.equals(TimeType.WCET)) {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getUpperBound();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getUpperBound();
+ } else if (executionCase.equals(TimeType.BCET)) {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getLowerBound();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getLowerBound();
+ } else {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getAverage();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getAverage();
+ }
+ }
+ /* Read & Write Memory Access Time */
+ result = result.add(getRunnableMemoryAccessTime(runnable, freq, readLatency, writeLatency));
+ /* Execution (Ticks): */
+ final List<Ticks> ticksList = SoftwareUtil.getTicks(runnable, null);
+ for (final Ticks t : ticksList) {
+ final Time tickExecution = RuntimeUtil.getExecutionTimeForTicks(t, pu, executionCase); // 0.9.5
+ result = result.add(tickExecution); // Execution(Ticks) added
+ }
+ return result;
+ }
+
+ /**
+ * Calculate memory access time of the observed task.
+ * Since this method is used by CPURta, the visibility should be 'public'
+ * @param task the observed task
+ * @param pu ProcessingUnit that would compute the given runnable (A57 or Denver)
+ * @param executionCase BCET, ACET, WCET
+ * @return
+ * memory access time of the observed task
+ */
+ public Time getTaskMemoryAccessTime(final Task task, final ProcessingUnit pu, final TimeType executionCase) {
+ Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ final double freq = AmaltheaServices.convertToHertz(pu.getFrequencyDomain().getDefaultValue()).longValue();
+ final List<Runnable> runnableList = SoftwareUtil.getRunnableList(task, null);
+ double readLatency = 0;
+ double writeLatency = 0;
+ if (pu.getAccessElements().size() == 0) {
+ readLatency = 30; // Default value will be assigned
+ writeLatency = 30; // Default value of will be assigned
+ } else {
+ if (executionCase.equals(TimeType.WCET)) {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getUpperBound();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getUpperBound();
+ } else if (executionCase.equals(TimeType.BCET)) {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getLowerBound();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getLowerBound();
+ } else {
+ readLatency = pu.getAccessElements().get(0).getReadLatency().getAverage();
+ writeLatency = pu.getAccessElements().get(0).getWriteLatency().getAverage();
+ }
+ }
+ for (final Runnable r : runnableList) {
+ result = result.add(getRunnableMemoryAccessTime(r, freq, readLatency, writeLatency));
+ }
+ return result;
+ }
+
+ /**
+ * Calculate memory access time of the observed runnable.
+ * The method follows Read / Compute(Ticks) / Write semantic.
+ * Read(Write)_Access_Time = Round_UP(Size_of_Read_Labels / 64.0 Bytes) * (Read_Latency / Frequency)
+ * @param runnable the observed runnable
+ * @param frequency frequency value of the Processing Unit
+ * @param readLatency readLatency value of the Processing Unit
+ * @param writeLatency writeLatency value of the Processing Unit
+ * @return
+ * memory access time of the observed runnable
+ */
+ public Time getRunnableMemoryAccessTime(final Runnable runnable, final double frequency, final double readLatency, final double writeLatency) {
+ Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ final Time parameter = FactoryUtil.createTime(BigInteger.ONE, TimeUnit.S);
+ final List<LabelAccess> thisLAList = SoftwareUtil.getLabelAccessList(runnable, null);
+ final List<LabelAccess> readList = thisLAList.stream().filter(x -> (x.getAccess()).equals(LabelAccessEnum.READ)).collect(Collectors.toList());
+ final List<LabelAccess> writeList = thisLAList.stream().filter(x -> (x.getAccess()).equals(LabelAccessEnum.WRITE)).collect(Collectors.toList());
+ /* Read (LabelAccess): */
+ double readAccessParameter = 0;
+ double sizeofReadLabels = 0;
+ for (final LabelAccess rl : readList) {
+ sizeofReadLabels += rl.getData().getSize().getNumberBytes();
+ }
+ readAccessParameter = (Math.ceil(sizeofReadLabels / 64.0) * (readLatency / frequency));
+ final Time readAccess = parameter.multiply(readAccessParameter);
+ result = result.add(readAccess); // LabelAccess(Read) added
+ /* Write (LabelAccess): */
+ double writeAccessParameter = 0;
+ double sizeofWriteLabels = 0;
+ for (final LabelAccess wl : writeList) {
+ sizeofWriteLabels += wl.getData().getSize().getNumberBytes();
+ }
+ writeAccessParameter = (Math.ceil(sizeofWriteLabels / 64.0) * (writeLatency / frequency));
+ final Time writeAccess = parameter.multiply(writeAccessParameter);
+ result = result.add(writeAccess); // LabelAccess(Write) added
+ return result;
+ }
+
+ /**
+ * Identify whether the given task has an InterProcessTrigger or not.
+ * @param task the observed task
+ * @return
+ * boolean value of the result
+ */
+ protected static boolean isTriggeringTask(final Task task) {
+ /* true: Triggering Task, false: Non-Triggering Task */
+ boolean result = false;
+ final List<ActivityGraphItem> callList = SoftwareUtil.collectActivityGraphItems(task.getActivityGraph(), null, (call -> call instanceof RunnableCall
+ || call instanceof InterProcessTrigger || call instanceof ClearEvent || call instanceof SetEvent || call instanceof WaitEvent));
+ final List<ActivityGraphItem> iptList = callList.stream().filter(s -> s instanceof InterProcessTrigger).collect(Collectors.toList());
+ if (iptList.size() != 0) {
+ result = true;
+ }
+ return result;
+ }
+
+ /******************************************* Implicit Communication Paradigm *************************************************/
+
+ /**
+ * For the implicit communication paradigm
+ * Time[0] = copy-in time for the observed task, Time[1] = copy-out time for the observed task
+ * if a GPU task mapped to CPU is passed here, we also need to consider its required labels from Pre-Pro processing runnables
+ * @param task the observed task
+ * @param pu the processing unit that the observed task is mapped to
+ * @param executionCase WCET, BCET, ACET
+ * @param cpurta the instance of CPURtaIA class that calls this method
+ * @return
+ * Time array that contains copy-in, copy-out time of the observed task
+ */
+ protected Time[] getLocalCopyTimeArray(final Task task, final ProcessingUnit pu, final TimeType executionCase, final CPURta cpurta) {
+ final Time[] ta = new Time[2];
+ Time readCopy = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ Time writeCopy = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ /* The observed task is a GPU task */
+ if (cpurta.getGpuTaskList().contains(task)) {
+ final HashMap<Task, List<List<Label>>> gtcl = cpurta.getGTCL();
+ final List<List<Label>> thisLabelList = gtcl.get(task);
+ final List<Label> readLabels = thisLabelList.get(0);
+ final List<Label> writeLabels = thisLabelList.get(1);
+ for (final Label rl : readLabels) {
+ readCopy = readCopy.add(this.getLocalCopyTime(rl, pu, executionCase, true));
+ }
+ ta[0] = readCopy;
+ for (final Label wl : writeLabels) {
+ writeCopy = writeCopy.add(this.getLocalCopyTime(wl, pu, executionCase, false));
+ }
+ ta[1] = writeCopy;
+ return ta;
+ }
+ /* The observed task is a CPU task */
+ final List<Runnable> runnableList = SoftwareUtil.getRunnableList(task, null);
+ final List<Label> readList = new ArrayList<Label>();
+ final List<Label> writeList = new ArrayList<Label>();
+ for (int i = 0; i < runnableList.size(); i++) {
+ final Runnable runnable = runnableList.get(i);
+ final List<LabelAccess> laList = SoftwareUtil.getLabelAccessList(runnable, null);
+ final List<Label> rList = laList.stream().filter(s -> (s.getAccess()).equals(LabelAccessEnum.READ))
+ .map(s -> s.getData()).collect(Collectors.toList());
+ rList.stream().forEach(s -> readList.add(s));
+ final List<Label> wList = laList.stream().filter(s -> (s.getAccess()).equals(LabelAccessEnum.WRITE))
+ .map(s -> s.getData()).collect(Collectors.toList());
+ wList.stream().forEach(s -> writeList.add(s));
+ }
+ final List<Label> readLabels = readList.stream().distinct().collect(Collectors.toList());
+ final List<Label> writeLabels = writeList.stream().distinct().collect(Collectors.toList());
+ for (final Label rl : readLabels) {
+ readCopy = readCopy.add(this.getLocalCopyTime(rl, pu, executionCase, true));
+ }
+ ta[0] = readCopy;
+ for (final Label wl : writeLabels) {
+ writeCopy = writeCopy.add(this.getLocalCopyTime(wl, pu, executionCase, false));
+ }
+ ta[1] = writeCopy;
+ return ta;
+ }
+
+ /**
+ * The method is used to calculate LocalCopy time for single label.
+ * @param label the observed label
+ * @param pu ProcessingUnit that would process the given label
+ * @param executionCase BCET, ACET, WCET
+ * @param readOrWrite when the given runnable is 'runnable_0'(the first callSquence of the task), it is read(true),
+ * when the given runnable is 'runnable_Last'(the last callSquence of the task), it is write(false).
+ * @return
+ * the given LocalCopy time
+ */
+ private Time getLocalCopyTime(final Label label, final ProcessingUnit pu, final TimeType executionCase, final boolean readOrWrite) {
+ Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ final Time parameter = FactoryUtil.createTime(BigInteger.ONE, TimeUnit.S);
+ final double freq = AmaltheaServices.convertToHertz(pu.getFrequencyDomain().getDefaultValue()).longValue();
+ double latency = 0;
+ /* Read */
+ if (readOrWrite) {
+ if (executionCase.equals(TimeType.BCET)) {
+ latency = pu.getAccessElements().get(0).getReadLatency().getLowerBound();
+ } else if (executionCase.equals(TimeType.ACET)) {
+ latency = pu.getAccessElements().get(0).getReadLatency().getAverage();
+ } else if (executionCase.equals(TimeType.WCET)) {
+ latency = pu.getAccessElements().get(0).getReadLatency().getUpperBound();
+ }
+ }
+ /* Write */
+ else {
+ if (executionCase.equals(TimeType.BCET)) {
+ latency = pu.getAccessElements().get(0).getWriteLatency().getLowerBound();
+ } else if (executionCase.equals(TimeType.ACET)) {
+ latency = pu.getAccessElements().get(0).getWriteLatency().getAverage();
+ } else if (executionCase.equals(TimeType.WCET)) {
+ latency = pu.getAccessElements().get(0).getWriteLatency().getUpperBound();
+ }
+ }
+ double labelAccessParameter = 0;
+ final double labelSize = label.getSize().getNumberBytes();
+ labelAccessParameter = (Math.ceil(labelSize / 64.0) * (latency / freq));
+ final Time labelAccess = parameter.multiply(labelAccessParameter);
+ result = result.add(labelAccess); // LabelAccess(Read) added
+ return result;
+ }
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/SharedConsts.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/SharedConsts.java
index 2ab3f29..ed04559 100644
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/SharedConsts.java
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/SharedConsts.java
@@ -16,23 +16,27 @@
import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
public class SharedConsts {
+
+ public static int RUNTIMESEC = 2 * 60 * 60;
+ public static final String SINGLE_CORE_MODEL = "model-input/SingleTCs/SingleTCs.amxmi";
+
/*-----------Measurement Configuration--------------–*/
public static TimeType timeType = TimeType.WCET;
public static boolean onlyWrittenLabelsCE = true;
public static boolean synchronousOffloading = false;
public static boolean useModelTimeSlices = false;
- public static boolean ignoreInfeasibility = true;
+ public static boolean ignoreInfeasibility = false;
public static int[] timeSlices;
public static long timeSliceLengthPS = 1000000000l;
- public static final boolean levelIBusyPeriod = false;
+ public static boolean levelIBusyPeriod = false;
public static TS_DERIV tsDeriv = TS_DERIV.TSxPrio;
public static OPT_TYPE optimize = OPT_TYPE.RESPONSETIMESUM;
- public static int comParadigm = 0;
+ public static final boolean considerGlobalBlocking = false;
+ public static final boolean considerLocalBlocking = false;
+ public static boolean offsetCPURTA = true;
+ public static final boolean zeroHigh = true;
/*-----------End Measur. Configuration--------------–*/
- /* Arbitrary Integer Array (GA scenario) */
- public static final int[] defaultIAMapping = new int[] { 4, 1, 1, 3, 4, 0, 1, 3, 3, 0, 6, 2, 5, 6 };
-
public enum OPT_TYPE {
TASKCHAINS, RESPONSETIMESUM, LOADBALANCING
}
@@ -41,7 +45,7 @@
TS, TSxPrio, TSxUtil, TSxUtilxNbTasks
}
- public enum MAPPINGS {
- EV, RTS, TCS, LB, RND
+ public enum ComParadigm {
+ DIRECT, IMPLICIT
}
-}
\ No newline at end of file
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/AllTests.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/AllTests.java
new file mode 100644
index 0000000..19509f3
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/AllTests.java
@@ -0,0 +1,12 @@
+package org.eclipse.app4mc.gsoc_rta.test;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({ CPURtaTest.class, E2ELatencyTest_Single.class, E2ELatencyTest_Multi.class })
+
+public class AllTests {
+ // empty class to start test suite
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/CPURtaTest.xtend b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/CPURtaTest.xtend
new file mode 100644
index 0000000..a73226d
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/CPURtaTest.xtend
@@ -0,0 +1,146 @@
+package org.eclipse.app4mc.gsoc_rta.test
+
+import java.math.BigInteger
+import org.eclipse.app4mc.amalthea.model.AmaltheaFactory
+import org.eclipse.app4mc.amalthea.model.DiscreteValueConstant
+import org.eclipse.app4mc.amalthea.model.FrequencyDomain
+import org.eclipse.app4mc.amalthea.model.FrequencyUnit
+import org.eclipse.app4mc.amalthea.model.ProcessingUnitDefinition
+import org.eclipse.app4mc.amalthea.model.Runnable
+import org.eclipse.app4mc.amalthea.model.TimeUnit
+import org.eclipse.app4mc.amalthea.model.builder.AmaltheaBuilder
+import org.eclipse.app4mc.amalthea.model.builder.HardwareBuilder
+import org.eclipse.app4mc.amalthea.model.builder.SoftwareBuilder
+import org.eclipse.app4mc.amalthea.model.builder.StimuliBuilder
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType
+import org.eclipse.app4mc.amalthea.model.PeriodicStimulus
+import org.eclipse.app4mc.gsoc_rta.CPURta
+import org.junit.Assert
+import org.junit.Test
+import org.eclipse.app4mc.amalthea.model.PuType
+
+class CPURtaTest {
+ extension AmaltheaBuilder b1 = new AmaltheaBuilder
+ extension SoftwareBuilder b2 = new SoftwareBuilder
+ extension HardwareBuilder b3 = new HardwareBuilder
+ extension StimuliBuilder b4 = new StimuliBuilder
+
+ @Test
+ def void CPURtaTest(){
+ org.apache.log4j.BasicConfigurator.configure();
+ val model = amalthea [
+ stimuliModel [
+ periodicStimulus [
+ name="periodic_03s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(3), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_05s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(5), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_06s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(6), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_10s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(10), TimeUnit.S)
+ ]
+ ]
+ softwareModel [
+ runnable [
+ name="r0"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r1"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r2"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r3"
+ activityGraph [
+ ticks [^default = createDVC(2l)]
+ ]
+ ]
+ task [
+ name="t0"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r0")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_03s"))
+ ]
+ task [
+ name="t1"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r1")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_05s"))
+ ]
+ task [
+ name="t2"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r2")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_06s"))
+ ]
+ task [
+ name="t3"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r3")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_10s"))
+ ]
+ ]
+ hardwareModel [
+ // ***** Definitions *****
+ definition_ProcessingUnit [
+ name = "ARM"
+ puType = PuType.CPU
+ ]
+
+ // ***** Domains *****
+ domain_Frequency [
+ name = "ARM_Domain"
+ defaultValue = FactoryUtil.createFrequency(1, FrequencyUnit::HZ)
+ ]
+
+ // ***** Structures *****
+ structure [
+ module_ProcessingUnit [
+ name = "ARM0"
+ definition = _find(ProcessingUnitDefinition, "ARM")
+ frequencyDomain = _find(FrequencyDomain, "ARM_Domain")
+ ]
+ ]
+ ]
+ ]
+ var CPURta cpurta = new CPURta(model)
+ var wcrtSum = cpurta.getRTSum(TimeType.WCET).adjustUnit().toString()
+ Assert.assertTrue(wcrtSum == "15 s")
+ }
+
+ private def DiscreteValueConstant createDVC(long upper) {
+ val ret = AmaltheaFactory.eINSTANCE.createDiscreteValueConstant
+ ret.value=upper
+ ret
+ }
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/E2ELatencyTest_Multi.xtend b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/E2ELatencyTest_Multi.xtend
new file mode 100644
index 0000000..d635baa
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/E2ELatencyTest_Multi.xtend
@@ -0,0 +1,389 @@
+package org.eclipse.app4mc.gsoc_rta.test
+
+import java.math.BigInteger
+import org.eclipse.app4mc.amalthea.model.AmaltheaFactory
+import org.eclipse.app4mc.amalthea.model.DiscreteValueConstant
+import org.eclipse.app4mc.amalthea.model.Runnable
+import org.eclipse.app4mc.amalthea.model.TimeUnit
+import org.eclipse.app4mc.amalthea.model.builder.AmaltheaBuilder
+import org.eclipse.app4mc.amalthea.model.builder.SoftwareBuilder
+import org.eclipse.app4mc.amalthea.model.builder.StimuliBuilder
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil
+import org.junit.Test
+import org.eclipse.app4mc.amalthea.model.PeriodicStimulus
+import org.eclipse.app4mc.amalthea.model.Task
+import org.eclipse.app4mc.amalthea.model.ProcessEvent
+import org.eclipse.app4mc.amalthea.model.EventChainItemType
+import org.eclipse.app4mc.amalthea.model.builder.ConstraintsBuilder
+import org.eclipse.app4mc.amalthea.model.builder.HardwareBuilder
+import org.eclipse.app4mc.amalthea.model.PuType
+import org.eclipse.app4mc.amalthea.model.FrequencyUnit
+import org.eclipse.app4mc.amalthea.model.ProcessingUnitDefinition
+import org.eclipse.app4mc.amalthea.model.FrequencyDomain
+import org.eclipse.app4mc.gsoc_rta.CPURta
+import org.eclipse.app4mc.gsoc_rta.E2ELatency
+import org.eclipse.app4mc.gsoc_rta.E2ELatency.MulticoreLatCase
+import org.junit.Assert
+
+class E2ELatencyTest_Multi {
+ extension AmaltheaBuilder b1 = new AmaltheaBuilder
+ extension HardwareBuilder b2 = new HardwareBuilder
+ extension StimuliBuilder b3 = new StimuliBuilder
+ extension SoftwareBuilder b4 = new SoftwareBuilder
+ extension ConstraintsBuilder b5 = new ConstraintsBuilder
+
+ @Test
+ def void E2ELatencyTest_Multi(){
+ org.apache.log4j.BasicConfigurator.configure();
+ val model = amalthea [
+ hardwareModel [
+ // ***** Definitions *****
+ definition_ProcessingUnit [
+ name = "ARM"
+ puType = PuType.CPU
+ ]
+
+ // ***** Domains *****
+ domain_Frequency [
+ name = "ARM_Domain"
+ defaultValue = FactoryUtil.createFrequency(1, FrequencyUnit::HZ)
+ ]
+
+ // ***** Structures *****
+ structure [
+ module_ProcessingUnit [
+ name = "ARM0"
+ definition = _find(ProcessingUnitDefinition, "ARM")
+ frequencyDomain = _find(FrequencyDomain, "ARM_Domain")
+ ]
+ module_ProcessingUnit [
+ name = "ARM1"
+ definition = _find(ProcessingUnitDefinition, "ARM")
+ frequencyDomain = _find(FrequencyDomain, "ARM_Domain")
+ ]
+ module_ProcessingUnit [
+ name = "ARM2"
+ definition = _find(ProcessingUnitDefinition, "ARM")
+ frequencyDomain = _find(FrequencyDomain, "ARM_Domain")
+ ]
+ ]
+ ]
+ stimuliModel [
+ periodicStimulus [
+ name="periodic_03s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(3), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_05s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(5), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_06s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(6), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_10s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(10), TimeUnit.S)
+ ]
+ ]
+ softwareModel [
+ runnable [
+ name="r0"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r1"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r2"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r3"
+ activityGraph [
+ ticks [^default = createDVC(2l)]
+ ]
+ ]
+ task [
+ name="t0"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r0")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_03s"))
+ ]
+ task [
+ name="t1"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r0")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_03s"))
+ ]
+ task [
+ name="t2"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r0")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_03s"))
+ ]
+ task [
+ name="t3"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r1")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_05s"))
+ ]
+ task [
+ name="t4"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r1")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_05s"))
+ ]
+ task [
+ name="t5"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r1")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_05s"))
+ ]
+ task [
+ name="t6"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r2")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_06s"))
+ ]
+ task [
+ name="t7"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r2")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_06s"))
+ ]
+ task [
+ name="t8"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r2")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_06s"))
+ ]
+ task [
+ name="t9"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r3")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_10s"))
+ ]
+ task [
+ name="t10"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r3")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_10s"))
+ ]
+ task [
+ name="t11"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r3")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_10s"))
+ ]
+ ]
+ eventModel [
+ val pe0 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe0.entity= _find(Task,"t0")
+ pe0.name = "pe0"
+ val pe1 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe1.entity= _find(Task,"t1")
+ pe1.name = "pe1"
+ val pe2 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe2.entity= _find(Task,"t2")
+ pe2.name = "pe2"
+ val pe3 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe3.entity= _find(Task,"t3")
+ pe3.name = "pe3"
+ val pe4 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe4.entity= _find(Task,"t4")
+ pe4.name = "pe4"
+ val pe5 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe5.entity= _find(Task,"t5")
+ pe5.name = "pe5"
+ val pe6 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe6.entity= _find(Task,"t6")
+ pe6.name = "pe6"
+ val pe7 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe7.entity= _find(Task,"t7")
+ pe7.name = "pe7"
+ val pe8 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe8.entity= _find(Task,"t8")
+ pe8.name = "pe8"
+ val pe9 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe9.entity= _find(Task,"t9")
+ pe9.name = "pe9"
+ val pe10 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe10.entity= _find(Task,"t10")
+ pe10.name = "pe10"
+ val pe11 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe11.entity= _find(Task,"t11")
+ pe11.name = "pe11"
+ events.add(pe0)
+ events.add(pe1)
+ events.add(pe2)
+ events.add(pe3)
+ events.add(pe4)
+ events.add(pe5)
+ events.add(pe6)
+ events.add(pe7)
+ events.add(pe8)
+ events.add(pe9)
+ events.add(pe10)
+ events.add(pe11)
+ ]
+ constraintsModel [
+ eventChain[
+ name = "ec0"
+ stimulus = _find(ProcessEvent,"pe0")
+ response = _find(ProcessEvent,"pe9")
+ subchain [
+ stimulus = _find(ProcessEvent,"pe0")
+ response = _find(ProcessEvent,"pe4")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe4")
+ response = _find(ProcessEvent,"pe8")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe8")
+ response = _find(ProcessEvent,"pe9")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ ]
+ eventChain[
+ name = "ec1"
+ stimulus = _find(ProcessEvent,"pe9")
+ response = _find(ProcessEvent,"pe0")
+ subchain [
+ stimulus = _find(ProcessEvent,"pe9")
+ response = _find(ProcessEvent,"pe7")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe7")
+ response = _find(ProcessEvent,"pe5")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe5")
+ response = _find(ProcessEvent,"pe0")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ ]
+ eventChain[
+ name = "ec2"
+ stimulus = _find(ProcessEvent,"pe0")
+ response = _find(ProcessEvent,"pe9")
+ subchain [
+ stimulus = _find(ProcessEvent,"pe0")
+ response = _find(ProcessEvent,"pe7")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe7")
+ response = _find(ProcessEvent,"pe5")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe5")
+ response = _find(ProcessEvent,"pe9")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ ]
+ eventChain[
+ name = "ec3"
+ stimulus = _find(ProcessEvent,"pe9")
+ response = _find(ProcessEvent,"pe0")
+ subchain [
+ stimulus = _find(ProcessEvent,"pe9")
+ response = _find(ProcessEvent,"pe4")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe4")
+ response = _find(ProcessEvent,"pe8")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe8")
+ response = _find(ProcessEvent,"pe0")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ ]
+ ]
+ ]
+ val ia = #[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]
+ var cpurta = new CPURta(false, model, ia);
+ var ecl = new E2ELatency();
+ var bcRctIm = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.BCRctIm).adjustUnit().toString();
+ var bcRctLET = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.BCRctLET).adjustUnit().toString();
+ var wcRctIm = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.WCRctIm).adjustUnit().toString();
+ var wcRctLET = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.WCRctLET).adjustUnit().toString();
+ var bcInitRctIm = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.BCInitRctIm).adjustUnit().toString();
+ var bcInitRctLET = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.BCInitRctLET).adjustUnit().toString();
+ var wcInitRctIm = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.WCInitRctIm).adjustUnit().toString();
+ var wcInitRctLET = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.WCInitRctLET).adjustUnit().toString();
+ var bcAgeIm = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.BCAgeIm).adjustUnit().toString();
+ var bcAgeLET = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.BCAgeLET).adjustUnit().toString();
+ var wcAgeIm = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.WCAgeIm).adjustUnit().toString();
+ var wcAgeLET = ecl.getMultiTCLsum(cpurta, MulticoreLatCase.WCAgeLET).adjustUnit().toString();
+ Assert.assertTrue(bcRctIm == "20 s")
+ Assert.assertTrue(bcRctLET == "96 s")
+ Assert.assertTrue(wcRctIm == "122 s")
+ Assert.assertTrue(wcRctLET == "166 s")
+ Assert.assertTrue(bcInitRctIm == "20 s")
+ Assert.assertTrue(bcInitRctLET == "96 s")
+ Assert.assertTrue(wcInitRctIm == "108 s")
+ Assert.assertTrue(wcInitRctLET == "150 s")
+ Assert.assertTrue(bcAgeIm == "12 s")
+ Assert.assertTrue(bcAgeLET == "26 s")
+ Assert.assertTrue(wcAgeIm == "114 s")
+ Assert.assertTrue(wcAgeLET == "69 s")
+ }
+ private def DiscreteValueConstant createDVC(long upper) {
+ val ret = AmaltheaFactory.eINSTANCE.createDiscreteValueConstant
+ ret.value=upper
+ ret
+ }
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/E2ELatencyTest_Single.xtend b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/E2ELatencyTest_Single.xtend
new file mode 100644
index 0000000..4f130e4
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/test/E2ELatencyTest_Single.xtend
@@ -0,0 +1,265 @@
+package org.eclipse.app4mc.gsoc_rta.test
+
+import org.eclipse.app4mc.amalthea.model.builder.AmaltheaBuilder
+import org.eclipse.app4mc.amalthea.model.builder.HardwareBuilder
+import org.eclipse.app4mc.amalthea.model.builder.StimuliBuilder
+import org.eclipse.app4mc.amalthea.model.builder.SoftwareBuilder
+import org.eclipse.app4mc.amalthea.model.builder.ConstraintsBuilder
+import org.junit.Test
+import org.eclipse.app4mc.amalthea.model.PuType
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil
+import org.eclipse.app4mc.amalthea.model.FrequencyUnit
+import org.eclipse.app4mc.amalthea.model.ProcessingUnitDefinition
+import org.eclipse.app4mc.amalthea.model.FrequencyDomain
+import java.math.BigInteger
+import org.eclipse.app4mc.amalthea.model.TimeUnit
+import org.eclipse.app4mc.amalthea.model.Runnable
+import org.eclipse.app4mc.amalthea.model.DiscreteValueConstant
+import org.eclipse.app4mc.amalthea.model.AmaltheaFactory
+import org.junit.Assert
+import org.eclipse.app4mc.gsoc_rta.CPURta
+import org.eclipse.app4mc.gsoc_rta.E2ELatency
+import org.eclipse.app4mc.amalthea.model.PeriodicStimulus
+import org.eclipse.app4mc.amalthea.model.Task
+import org.eclipse.app4mc.amalthea.model.ProcessEvent
+import org.eclipse.app4mc.amalthea.model.EventChainItemType
+import org.eclipse.app4mc.gsoc_rta.CommonUtils
+import org.eclipse.app4mc.gsoc_rta.E2ELatency.SinglecoreLatCase
+
+class E2ELatencyTest_Single {
+ extension AmaltheaBuilder b1 = new AmaltheaBuilder
+ extension HardwareBuilder b2 = new HardwareBuilder
+ extension StimuliBuilder b3 = new StimuliBuilder
+ extension SoftwareBuilder b4 = new SoftwareBuilder
+ extension ConstraintsBuilder b5 = new ConstraintsBuilder
+
+ @Test
+ def void E2ELatencyTest_Single(){
+ org.apache.log4j.BasicConfigurator.configure();
+ val model = amalthea [
+ hardwareModel [
+ // ***** Definitions *****
+ definition_ProcessingUnit [
+ name = "ARM"
+ puType = PuType.CPU
+ ]
+
+ // ***** Domains *****
+ domain_Frequency [
+ name = "ARM_Domain"
+ defaultValue = FactoryUtil.createFrequency(1, FrequencyUnit::HZ)
+ ]
+
+ // ***** Structures *****
+ structure [
+ module_ProcessingUnit [
+ name = "ARM0"
+ definition = _find(ProcessingUnitDefinition, "ARM")
+ frequencyDomain = _find(FrequencyDomain, "ARM_Domain")
+ ]
+ ]
+ ]
+ stimuliModel [
+ periodicStimulus [
+ name="periodic_03s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(3), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_05s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(5), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_06s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(6), TimeUnit.S)
+ ]
+ periodicStimulus [
+ name="periodic_10s"
+ recurrence=FactoryUtil.createTime(BigInteger.valueOf(10), TimeUnit.S)
+ ]
+ ]
+ softwareModel [
+ runnable [
+ name="r0"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r1"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r2"
+ activityGraph [
+ ticks [^default = createDVC(1l)]
+ ]
+ ]
+ runnable [
+ name="r3"
+ activityGraph [
+ ticks [^default = createDVC(2l)]
+ ]
+ ]
+ task [
+ name="t0"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r0")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_03s"))
+ ]
+ task [
+ name="t1"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r1")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_05s"))
+ ]
+ task [
+ name="t2"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r2")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_06s"))
+ ]
+ task [
+ name="t3"
+ activityGraph [
+ runnableCall [
+ runnable = _find(Runnable, "r3")
+ ]
+ ]
+ stimuli.add(_find(PeriodicStimulus, "periodic_10s"))
+ ]
+ ]
+ eventModel [
+ val pe0 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe0.entity= _find(Task,"t0")
+ pe0.name = "pe0"
+ val pe1 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe1.entity= _find(Task,"t1")
+ pe1.name = "pe1"
+ val pe2 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe2.entity= _find(Task,"t2")
+ pe2.name = "pe2"
+ val pe3 = AmaltheaFactory.eINSTANCE.createProcessEvent
+ pe3.entity= _find(Task,"t3")
+ pe3.name = "pe3"
+ events.add(pe0)
+ events.add(pe1)
+ events.add(pe2)
+ events.add(pe3)
+ ]
+ constraintsModel [
+ eventChain[
+ name = "ec0"
+ stimulus = _find(ProcessEvent,"pe0")
+ response = _find(ProcessEvent,"pe3")
+ subchain [
+ stimulus = _find(ProcessEvent,"pe0")
+ response = _find(ProcessEvent,"pe1")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe1")
+ response = _find(ProcessEvent,"pe2")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe2")
+ response = _find(ProcessEvent,"pe3")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ ]
+ eventChain[
+ name = "ec1"
+ stimulus = _find(ProcessEvent,"pe3")
+ response = _find(ProcessEvent,"pe0")
+ subchain [
+ stimulus = _find(ProcessEvent,"pe3")
+ response = _find(ProcessEvent,"pe2")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe2")
+ response = _find(ProcessEvent,"pe1")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe1")
+ response = _find(ProcessEvent,"pe0")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ ]
+ eventChain[
+ name = "ec2"
+ stimulus = _find(ProcessEvent,"pe0")
+ response = _find(ProcessEvent,"pe3")
+ subchain [
+ stimulus = _find(ProcessEvent,"pe0")
+ response = _find(ProcessEvent,"pe2")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe2")
+ response = _find(ProcessEvent,"pe1")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe1")
+ response = _find(ProcessEvent,"pe3")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ ]
+ eventChain[
+ name = "ec3"
+ stimulus = _find(ProcessEvent,"pe3")
+ response = _find(ProcessEvent,"pe0")
+ subchain [
+ stimulus = _find(ProcessEvent,"pe3")
+ response = _find(ProcessEvent,"pe1")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe1")
+ response = _find(ProcessEvent,"pe2")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ subchain [
+ stimulus = _find(ProcessEvent,"pe2")
+ response = _find(ProcessEvent,"pe0")
+ itemType = EventChainItemType.SEQUENCE
+ ]
+ ]
+ ]
+ ]
+ var cpurta = new CPURta(model);
+ var ama = cpurta.getModel();
+ var pu = CommonUtils.getPUs(ama).get(0)
+ var ecl = new E2ELatency();
+ var criInitRct = ecl.getSingleTCLsum(cpurta, pu, SinglecoreLatCase.CriInitRct).adjustUnit().toString();
+ var bcInitRct = ecl.getSingleTCLsum(cpurta, pu, SinglecoreLatCase.BCInitRct).adjustUnit().toString();
+ var wcInitRct = ecl.getSingleTCLsum(cpurta, pu, SinglecoreLatCase.WCInitRct).adjustUnit().toString();
+ var criWCRct = ecl.getSingleTCLsum(cpurta, pu, SinglecoreLatCase.CriWCRct).adjustUnit().toString();
+ var bcWCRct = ecl.getSingleTCLsum(cpurta, pu, SinglecoreLatCase.BCWCRct).adjustUnit().toString();
+ var wcWCRct = ecl.getSingleTCLsum(cpurta, pu, SinglecoreLatCase.WCWCRct).adjustUnit().toString();
+ Assert.assertTrue(criInitRct == "44 s")
+ Assert.assertTrue(bcInitRct == "35 s")
+ Assert.assertTrue(wcInitRct == "62 s")
+ Assert.assertTrue(criWCRct == "47 s")
+ Assert.assertTrue(bcWCRct == "49 s")
+ Assert.assertTrue(wcWCRct == "76 s")
+ }
+ private def DiscreteValueConstant createDVC(long upper) {
+ val ret = AmaltheaFactory.eINSTANCE.createDiscreteValueConstant
+ ret.value=upper
+ ret
+ }
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/ui/APP4RTA.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/ui/APP4RTA.java
new file mode 100644
index 0000000..8704d73
--- /dev/null
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/ui/APP4RTA.java
@@ -0,0 +1,1151 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors: Junhyung Ki - initial API and implementation
+ *
+ *******************************************************************************/
+package org.eclipse.app4mc.gsoc_rta.ui;
+
+import java.awt.Color;
+import java.awt.EventQueue;
+import java.awt.Font;
+import java.awt.List;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.stream.Collectors;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JRadioButton;
+import javax.swing.JTextField;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.eclipse.app4mc.amalthea.model.Amalthea;
+import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
+import org.eclipse.app4mc.amalthea.model.EventChain;
+import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
+import org.eclipse.app4mc.amalthea.model.PuType;
+import org.eclipse.app4mc.amalthea.model.Task;
+import org.eclipse.app4mc.amalthea.model.Time;
+import org.eclipse.app4mc.amalthea.model.TimeUnit;
+import org.eclipse.app4mc.amalthea.model.io.AmaltheaLoader;
+import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
+import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
+import org.eclipse.app4mc.gsoc_rta.*;
+import org.eclipse.app4mc.gsoc_rta.E2ELatency.SinglecoreLatCase;
+import org.eclipse.emf.common.util.EList;
+import javax.swing.SwingConstants;
+import javax.swing.filechooser.FileNameExtensionFilter;
+import javax.swing.JSeparator;
+
+/**
+ * Date: May 04, 2020
+ * @version 2.0
+ * The purpose of this class is to provide users a better visual and increase usability of Response Time Analysis.
+ */
+@SuppressWarnings("serial")
+public class APP4RTA extends JFrame {
+ private static JComboBox<String> ecComboBox = new JComboBox<String>();
+
+ private CPURta cpurta = new CPURta(false, AmaltheaLoader.loadFromFile(new File(SharedConsts.SINGLE_CORE_MODEL)), new int[] { 4, 1, 1, 3, 4, 0, 1, 3, 3, 0, 6, 2, 5, 6 });
+ private E2ELatency e2e = new E2ELatency();
+ private Amalthea currentModel = null;
+ private java.util.List<ProcessingUnit> currentPUList = null;
+ private int[] currentIA = null;
+ private EList<Task> allTaskList = null;
+ private EList<EventChain> currentECList = null;
+ private EventChain currentEC = null;
+ private java.util.List<Task> currentTaskChain = null;
+ private File currentFile = null;
+
+ private HashMap<Integer, java.util.List<Task>> puTaskListHM;
+ private JFrame frame;
+ private int selectedECIndex = -1;
+ private boolean schedulability_flag = false;
+ JFileChooser fileChooser;
+ JTextField selectedModelLbl;
+
+ private JLabel jl0, jl1, jl2, jl3, jl4, jl5, jl6, jl7, jl8, jl9, jl10,
+ jl11, jl12, jl13, jl14, jl15, jl16, jl17, jl18, jl19;
+ private JTextField tf0, tf1, tf2, tf3, tf4, tf5, tf6, tf7, tf8, tf9,
+ tf10, tf11, tf12, tf13, tf14, tf15, tf16, tf17, tf18, tf19;
+ private JLabel[] jLabelArray = {
+ jl0, jl1, jl2, jl3, jl4, jl5, jl6, jl7, jl8, jl9, jl10,
+ jl11, jl12, jl13, jl14, jl15, jl16, jl17, jl18, jl19
+ };
+ private JTextField[] jTextFieldArray= {
+ tf0, tf1, tf2, tf3, tf4, tf5, tf6, tf7, tf8, tf9,
+ tf10, tf11, tf12, tf13, tf14, tf15, tf16, tf17, tf18, tf19
+ };
+
+ private JLabel jl_0, jl_1, jl_2, jl_3, jl_4, jl_5, jl_6, jl_7;
+ private JLabel jl_a, jl_b, jl_c, jl_d, jl_e, jl_f, jl_g, jl_h;
+ private List l0, l1, l2, l3, l4, l5, l6, l7;
+ private List rtL0, rtL1, rtL2, rtL3, rtL4, rtL5, rtL6, rtL7;
+ private JLabel[] puLabelArray = {
+ jl_0, jl_1, jl_2, jl_3, jl_4, jl_5, jl_6, jl_7
+ };
+ private JLabel[] rtListLabelArray = {
+ jl_a, jl_b, jl_c, jl_d, jl_e, jl_f, jl_g, jl_h
+ };
+ private List[] puListArray = {
+ l0, l1, l2, l3, l4, l5, l6, l7
+ };
+ private List[] rtListArray = {
+ rtL0, rtL1, rtL2, rtL3, rtL4, rtL5, rtL6, rtL7
+ };
+
+ private JLabel ecL0, ecL1, ecL2, ecL3, ecL4, ecL5, ecL6,
+ ecL7, ecL8, ecL9, ecL10, ecL11, ecL12, ecL13;
+ private JTextField jtf0, jtf1, jtf2, jtf3, jtf4, jtf5, jtf6,
+ jtf7, jtf8, jtf9, jtf10, jtf11, jtf12, jtf13;
+ private JLabel[] ecLabelArray = {
+ ecL0, ecL1, ecL2, ecL3, ecL4, ecL5, ecL6,
+ ecL7, ecL8, ecL9, ecL10, ecL11, ecL12, ecL13
+ };
+ private JTextField[] ecJTPArray = {
+ jtf0, jtf1, jtf2, jtf3, jtf4, jtf5, jtf6,
+ jtf7, jtf8, jtf9, jtf10, jtf11, jtf12, jtf13
+ };
+
+ public static void main(String[] args) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ org.apache.log4j.BasicConfigurator.configure();
+ Logger.getRootLogger().setLevel(Level.ERROR);
+ final APP4RTA window = new APP4RTA();
+ window.frame.setVisible(true);
+ window.frame.setTitle("APP4RTA");
+ }
+ });
+ }
+
+ public APP4RTA() {
+ initialize();
+ }
+
+ private void initialize() {
+ frame = new JFrame();
+ frame.getContentPane().setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ frame.setBounds(0, 31, 1200, 1027);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().setLayout(null);
+
+ JLabel lblSelectTheModel = new JLabel("Amalthea Model");
+ lblSelectTheModel.setFont(new Font("Stencil BT", Font.PLAIN, 13));
+ lblSelectTheModel.setBounds(10, 13, 120, 22);
+ frame.getContentPane().add(lblSelectTheModel);
+
+ JLabel lblTaskName = new JLabel("Task Name");
+ lblTaskName.setForeground(new Color(139, 0, 0));
+ lblTaskName.setFont(new Font("Sitka Heading", Font.BOLD, 12));
+ lblTaskName.setHorizontalAlignment(SwingConstants.CENTER);
+ lblTaskName.setBounds(15, 43, 70, 16);
+ frame.getContentPane().add(lblTaskName);
+
+ JLabel lblPuNum = new JLabel("PU Num");
+ lblPuNum.setForeground(new Color(0, 0, 255));
+ lblPuNum.setHorizontalAlignment(SwingConstants.CENTER);
+ lblPuNum.setFont(new Font("Sitka Heading", Font.BOLD, 12));
+ lblPuNum.setBounds(92, 43, 70, 16);
+ frame.getContentPane().add(lblPuNum);
+
+ JButton btnDefualtIa = new JButton("Default IA");
+ btnDefualtIa.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ if (cpurta.getModel() == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: A model is not loaded.");
+ return ;
+ } else if (cpurta.getTRT() == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: TRT HashMap is not loaded.");
+ return ;
+ } else if (cpurta.getPUl().size() == 0) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Processing Unit List is not loaded.");
+ return ;
+ }
+ /* This is only for 'ChallengeModel_TCs.amxmi' */
+ /*
+ final int[] defaultIA = SharedConsts.defaultIAMapping;
+ if (cpurta.getModel().getSwModel().getTasks().size() == defaultIA.length) {
+ for (int i = 0; i < defaultIA.length; i++) {
+ jTextFieldArray[i].setText("" + defaultIA[i]);
+ }
+ return ;
+ }
+ String str = "";
+ for (int i = 0; i < currentPUList.size(); i++) {
+ if (i == currentPUList.size() - 1) {
+ str = str + i;
+ break;
+ }
+ str = str + i + ", ";
+ }
+ JOptionPane.showMessageDialog(frame, "ERROR: The length of the default integer array does not match with\n"
+ + "the number of tasks in the target model.\n\n" + "Please assign the number(s) manually.\n"
+ + "Available PU number(s): " + str);
+ */
+ if (currentPUList.size() < 1) {
+ JOptionPane.showMessageDialog(frame, "ERROR: There is no processing unit in this model.\n"
+ + "Please choose another model.");
+ } else if (currentPUList.size() == 1) {
+ final int numOfTasks = cpurta.getModel().getSwModel().getTasks().size();
+ for (int i = 0; i < numOfTasks; i++) {
+ jTextFieldArray[i].setText("0");
+ }
+ return ;
+ } else {
+ final int numOfTasks = cpurta.getModel().getSwModel().getTasks().size();
+ final int numOfPUs = currentPUList.size();
+ int x = 0;
+ for (int i = 0; i < numOfTasks; i++) {
+ if (x < numOfPUs) {
+ jTextFieldArray[i].setText("" + x);
+ } else {
+ x = 0;
+ jTextFieldArray[i].setText("" + x);
+ }
+ x++;
+ }
+ }
+ }
+ });
+
+ JButton btnEnterIA = new JButton("Enter IA");
+ btnEnterIA.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ currentIA = new int[cpurta.getModel().getSwModel().getTasks().size()];
+ for (int i = 0; i < allTaskList.size(); i++) {
+ if (jTextFieldArray[i].getText().length() == 0) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Fill the rest of the array!");
+ return ;
+ } else if (jTextFieldArray[i].getText().charAt(0) < 48 || jTextFieldArray[i].getText().charAt(0) > 54) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Wrong array value!");
+ return ;
+ } else if (i >= 0 && i <= 9 && Integer.parseInt(jTextFieldArray[i].getText()) == 6) {
+ JOptionPane.showMessageDialog(frame, "ERROR: CPU Tasks should not be mapped to GPU! \n\n"
+ + "Please assign different IA value for " + "(" + allTaskList.get(i).getName() + ")");
+ return ;
+ } else if (i == jTextFieldArray.length-1 && Integer.parseInt(jTextFieldArray[i].getText()) != 6) {
+ JOptionPane.showMessageDialog(frame, "ERROR: 'Detection' task can not be mapped to CPU!");
+ return ;
+ }
+ currentIA[i] = Integer.parseInt(jTextFieldArray[i].getText());
+ }
+ cpurta.setIA(currentIA);
+ cpurta.setContention(currentIA, currentModel);
+ puTaskListHM = cpurta.getPUTaskListHashMap(currentModel);
+ for (int i = 0; i < puTaskListHM.size(); i++) {
+ if (puListArray[i].getItemCount() == 0) {
+ for (int j = 0; j < puTaskListHM.get(i).size(); j++) {
+ puListArray[i].add((puTaskListHM.get(i).get(j)).getName());
+ }
+ }
+ }
+ }
+ });
+
+ JRadioButton rdbtnSynchronous = new JRadioButton("Synchronous");
+ rdbtnSynchronous.setForeground(new Color(139, 0, 0));
+ rdbtnSynchronous.setFont(new Font("Sitka Heading", Font.BOLD, 13));
+
+ JRadioButton rdbtnAsynchronous = new JRadioButton("Asynchronous");
+ rdbtnAsynchronous.setForeground(new Color(0, 0, 255));
+ rdbtnAsynchronous.setFont(new Font("Sitka Heading", Font.BOLD, 13));
+
+ ButtonGroup offloadingMode = new ButtonGroup();
+ offloadingMode.add(rdbtnSynchronous);
+ offloadingMode.add(rdbtnAsynchronous);
+
+ JRadioButton rdbtnWorstCase = new JRadioButton("Worst-Case");
+ rdbtnWorstCase.setFont(new Font("Sitka Heading", Font.BOLD, 13));
+ rdbtnWorstCase.setForeground(Color.DARK_GRAY);
+
+ JRadioButton rdbtnAverageCase = new JRadioButton("Average-Case");
+ rdbtnAverageCase.setFont(new Font("Sitka Heading", Font.BOLD, 13));
+ rdbtnAverageCase.setForeground(Color.DARK_GRAY);
+
+ JRadioButton rdbtnBestCase = new JRadioButton("Best-Case");
+ rdbtnBestCase.setFont(new Font("Sitka Heading", Font.BOLD, 13));
+ rdbtnBestCase.setForeground(Color.DARK_GRAY);
+
+ ButtonGroup executionMode = new ButtonGroup();
+ executionMode.add(rdbtnWorstCase);
+ executionMode.add(rdbtnAverageCase);
+ executionMode.add(rdbtnBestCase);
+
+ JLabel lblSchedulability = new JLabel("Schedulability");
+ JTextField schedulability = new JTextField();
+ schedulability.setHorizontalAlignment(SwingConstants.RIGHT);
+ schedulability.setEditable(false);
+
+ JLabel lblMemAccCost = new JLabel("Cumulated Memory-Access Cost");
+ JTextField memAccCost = new JTextField();
+ memAccCost.setHorizontalAlignment(SwingConstants.RIGHT);
+ memAccCost.setEditable(false);
+
+ JLabel lblCumulContention = new JLabel("Cumulated Contention");
+ JTextField cumulContention = new JTextField();
+ cumulContention.setHorizontalAlignment(SwingConstants.RIGHT);
+ cumulContention.setEditable(false);
+
+ JLabel lblComputation = new JLabel("Computation");
+ JTextField computation = new JTextField();
+ computation.setHorizontalAlignment(SwingConstants.RIGHT);
+ computation.setEditable(false);
+
+ JLabel lblResponseTimeSum = new JLabel("Response Time Sum");
+ JTextField rtSum = new JTextField();
+ rtSum.setHorizontalAlignment(SwingConstants.RIGHT);
+ rtSum.setEditable(false);
+
+ JButton btnCalculate = new JButton("Calculate");
+ btnCalculate.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
+ for (int i = 0; i < allTaskList.size(); i++) {
+ if (jTextFieldArray[i].getText().length() == 0) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Fill the array first!");
+ return ;
+ }
+ }
+ if (rdbtnSynchronous.isSelected()) {
+ SharedConsts.synchronousOffloading = true;
+ } else if (rdbtnAsynchronous.isSelected()) {
+ SharedConsts.synchronousOffloading = false;
+ } else {
+ JOptionPane.showMessageDialog(frame, "ERROR: You should choose an offloading mode! (Sync / Async)");
+ return ;
+ }
+ if (rdbtnWorstCase.isSelected()) {
+ SharedConsts.timeType = TimeType.WCET;
+ } else if (rdbtnAverageCase.isSelected()) {
+ SharedConsts.timeType = TimeType.ACET;
+ } else if (rdbtnBestCase.isSelected()) {
+ SharedConsts.timeType = TimeType.BCET;
+ } else {
+ JOptionPane.showMessageDialog(frame, "ERROR: You should choose an execution case! (Worst Case / Average Case / Best Case)");
+ return ;
+ }
+ if (currentIA == null || puTaskListHM.size() == 0) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Click the 'Enter IA' button.");
+ return ;
+ }
+ schedulability_flag = true;
+ Time pRtSum = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ for (int i = 0; i < puTaskListHM.size(); i++) {
+ final ProcessingUnit pu = cpurta.getPUl().get(i);
+ final java.util.List<Task> thisPUTaskList = puTaskListHM.get(i);
+ Time thisRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
+ if (rtListArray[i].getItemCount() == 0) {
+ if (pu.getDefinition().getPuType().equals(PuType.CPU)) {
+ for (Task t : thisPUTaskList) {
+ thisRT = cpurta.preciseTestCPURT(t, thisPUTaskList, SharedConsts.timeType, pu);
+ final Time thisPeriod = CommonUtils.getStimInTime(t);
+ final BigInteger period = AmaltheaServices.convertToPicoSeconds(thisPeriod);
+ if (AmaltheaServices.convertToPicoSeconds(thisRT).compareTo(period) > 0) {
+ rtListArray[i].add("Not Scheduleable! => MAX Value");
+ schedulability_flag = false;
+ } else if (AmaltheaServices.convertToPicoSeconds(thisRT).equals(BigInteger.ZERO)) {
+ rtListArray[i].add("0 ps (GPU Task on CPU)");
+ } else {
+ rtListArray[i].add(thisRT.toString());
+ }
+ pRtSum = pRtSum.add(thisRT);
+ }
+ } else {
+ for (Task t : thisPUTaskList) {
+ thisRT = cpurta.getTRT().get(t);
+ rtListArray[i].add(thisRT.toString());
+ pRtSum = pRtSum.add(thisRT);
+ }
+ }
+ }
+ }
+ if (schedulability_flag) {
+ schedulability.setText("Scheduleable! :)");
+ memAccCost.setText("" + cpurta.getCumulatedMemAccCosts());
+ cumulContention.setText("" + cpurta.getCumulatedContention());
+ computation.setText("" + (pRtSum.subtract(cpurta.getCumulatedMemAccCosts())).subtract(cpurta.getCumulatedContention()));
+ rtSum.setText(pRtSum.toString());
+ } else {
+ schedulability.setText("Non Scheduleable! :(");
+ memAccCost.setText("Not Available.");
+ cumulContention.setText("Not Available.");
+ computation.setText("Not Available.");
+ rtSum.setText("Not Available.");
+ JOptionPane.showMessageDialog(frame, "ERROR: This mapping is not schedulable.\n"
+ + "Please change the mapping.");
+ }
+ }
+ });
+
+ JButton btnReset = new JButton("Reset");
+ btnReset.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ currentIA = null;
+ cpurta.setIA(currentIA);
+ cpurta.setContention(currentIA, currentModel);
+ /* latency time initializing */
+ cpurta.initCumulatedMemAccCosts();
+ cpurta.initCumulatedContention();
+ for (int i = 0; i < allTaskList.size(); i++) {
+ jTextFieldArray[i].setText("");
+ }
+ for (int i = 0; i < currentPUList.size(); i++) {
+ puListArray[i].removeAll();
+ }
+ for (int i = 0; i < currentPUList.size(); i++) {
+ rtListArray[i].removeAll();
+ }
+ offloadingMode.setSelected(null, false);
+ executionMode.setSelected(null, false);
+ schedulability.setText(null);
+ memAccCost.setText(null);
+ cumulContention.setText(null);
+ computation.setText(null);
+ rtSum.setText(null);
+ currentIA = null;
+ puTaskListHM = null;
+ frame.revalidate();
+ frame.repaint();
+ }
+ });
+
+ selectedModelLbl = new JTextField();
+ selectedModelLbl.setEditable(false);
+ selectedModelLbl.setBounds(142, 13, 206, 22);
+ frame.getContentPane().add(selectedModelLbl);
+ selectedModelLbl.setColumns(10);
+
+ JButton amaltheaSchBtn = new JButton("Search Amalthea");
+ amaltheaSchBtn.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ final String userDirLocation = System.getProperty("user.dir");
+ File userDir = new File(userDirLocation);
+ fileChooser = new JFileChooser(userDir);
+ fileChooser.setAcceptAllFileFilterUsed(false);
+ FileNameExtensionFilter filter = new FileNameExtensionFilter("Amalthea models", "amxmi");
+ fileChooser.addChoosableFileFilter(filter);
+ fileChooser.setDialogTitle("Open File");
+ int result = fileChooser.showOpenDialog(null);
+ if (result == JFileChooser.APPROVE_OPTION) {
+ final Amalthea loadedModel = AmaltheaLoader.loadFromFile(fileChooser.getSelectedFile());
+ if (loadedModel.getVersion().compareTo("0.9.8") != 0) {
+ JOptionPane.showMessageDialog(frame, "Error: This model should be migrated to the version 0.9.8");
+ return ;
+ }
+ /* Something was selected before */
+ if (currentFile != null) {
+ /* The selected file is equal to the previous file => Do nothing */
+ if (fileChooser.getSelectedFile().equals(currentFile)) {
+ JOptionPane.showMessageDialog(frame, "Same Model");
+ return ;
+ }
+ /* If the selected file is different to the previous one => Remove and Do Normal. */
+ else {
+ schedulability.setText(null);
+ memAccCost.setText(null);
+ cumulContention.setText(null);
+ computation.setText(null);
+ rtSum.setText(null);
+ for (int i = 0; i < allTaskList.size(); i++) {
+ frame.remove(jLabelArray[i]);
+ frame.remove(jTextFieldArray[i]);
+ }
+ frame.remove(btnDefualtIa);
+ frame.remove(btnEnterIA);
+ frame.remove(rdbtnSynchronous);
+ frame.remove(rdbtnAsynchronous);
+ frame.remove(rdbtnWorstCase);
+ frame.remove(rdbtnAverageCase);
+ frame.remove(rdbtnBestCase);
+ frame.remove(btnCalculate);
+ frame.remove(btnReset);
+ frame.remove(lblSchedulability);
+ frame.remove(schedulability);
+ frame.remove(lblMemAccCost);
+ frame.remove(memAccCost);
+ frame.remove(lblCumulContention);
+ frame.remove(cumulContention);
+ frame.remove(lblComputation);
+ frame.remove(computation);
+ frame.remove(lblResponseTimeSum);
+ frame.remove(rtSum);
+ for (int i = 0; i < currentPUList.size(); i++) {
+ frame.remove(puLabelArray[i]);
+ frame.remove(rtListLabelArray[i]);
+ frame.remove(puListArray[i]);
+ frame.remove(rtListArray[i]);
+ }
+ frame.remove(ecComboBox);
+ }
+ }
+ /* Something was not selected before => Do normal */
+ currentFile = fileChooser.getSelectedFile();
+ selectedModelLbl.setText(currentFile.getName());
+ currentModel = loadedModel;
+ currentPUList = CommonUtils.getPUs(currentModel);
+ if (currentPUList.get(0).getAccessElements().size() == 0) {
+ JOptionPane.showMessageDialog(frame, "The selected model's processing unit(s) does(do) not have 'read & write Latency' values.\n\n"
+ + "Therefore, the default value of 30 will be assigned for them.\n"
+ + "This will affect the response time results.");
+ }
+ cpurta.setModel(currentModel);
+ cpurta.setTRT(cpurta.getDefaultTRT(currentModel));
+ cpurta.setPUl(currentPUList);
+ allTaskList = currentModel.getSwModel().getTasks();
+ if (allTaskList.size() > 20) {
+ JOptionPane.showMessageDialog(frame, "ERROR: The selected model has " + allTaskList.size() + " Tasks. (Limit: 20)\n"
+ + "Please choose a different model.");
+ return ;
+ } else if (currentPUList.size() > 8) {
+ JOptionPane.showMessageDialog(frame, "ERROR: The selected model has " + currentPUList.size() + " Processing Units. (Limit: 8)\n"
+ + "Please choose a different model.");
+ return ;
+ }
+ /* Task Indices */
+ for (int i = 0; i < allTaskList.size(); i++) {
+ jLabelArray[i] = new JLabel(allTaskList.get(i).getName());
+ jLabelArray[i].setBounds(12, (60+(i*24)), 97, 16);
+ frame.getContentPane().add(jLabelArray[i]);
+ jTextFieldArray[i] = new JTextField();
+ jTextFieldArray[i].setColumns(10);
+ jTextFieldArray[i].setBounds(118, (60+(i*24)), 22, 22);
+ frame.getContentPane().add(jTextFieldArray[i]);
+ }
+ /* DefaultIA Button */
+ btnDefualtIa.setBounds(155, 60, 97, 25);
+ frame.getContentPane().add(btnDefualtIa);
+ /* EnterIA Button */
+ btnEnterIA.setBounds(155, 90, 97, 25);
+ frame.getContentPane().add(btnEnterIA);
+ /* Sync Radio Button */
+ rdbtnSynchronous.setBounds(152, 125, 126, 25);
+ frame.getContentPane().add(rdbtnSynchronous);
+ /* Async Radio Button */
+ rdbtnAsynchronous.setBounds(152, 145, 126, 25);
+ frame.getContentPane().add(rdbtnAsynchronous);
+ /* WorstCase Radio Button */
+ rdbtnWorstCase.setBounds(152, 175, 107, 25);
+ frame.getContentPane().add(rdbtnWorstCase);
+ /* AverageCase Radio Button */
+ rdbtnAverageCase.setBounds(152, 195, 107, 25);
+ frame.getContentPane().add(rdbtnAverageCase);
+ /* BestCase Radio Button */
+ rdbtnBestCase.setBounds(152, 215, 107, 25);
+ frame.getContentPane().add(rdbtnBestCase);
+ /* Calculate Button */
+ btnCalculate.setBounds(155, 252, 97, 25);
+ frame.getContentPane().add(btnCalculate);
+ /* Reset Button */
+ btnReset.setBounds(155, 282, 97, 25);
+ frame.getContentPane().add(btnReset);
+ /* Schedulability Label & TextField */
+ lblSchedulability.setBounds(157, 323, 200, 16);
+ frame.getContentPane().add(lblSchedulability);
+ schedulability.setBounds(155, 343, 200, 22);
+ frame.getContentPane().add(schedulability);
+ /* MemAccCost Label & TextField */
+ lblMemAccCost.setBounds(157, 368, 200, 16);
+ frame.getContentPane().add(lblMemAccCost);
+ memAccCost.setBounds(155, 388, 200, 22);
+ frame.getContentPane().add(memAccCost);
+ /* CumulContention Label & TextField */
+ lblCumulContention.setBounds(157, 413, 200, 16);
+ frame.getContentPane().add(lblCumulContention);
+ cumulContention.setBounds(155, 433, 200, 22);
+ frame.getContentPane().add(cumulContention);
+ /* Computation */
+ lblComputation.setBounds(157, 458, 200, 16);
+ frame.getContentPane().add(lblComputation);
+ computation.setBounds(155, 478, 200, 22);
+ frame.getContentPane().add(computation);
+ /* ResponseTime Sum Label & TextField */
+ lblResponseTimeSum.setBounds(157, 503, 200, 16);
+ frame.getContentPane().add(lblResponseTimeSum);
+ rtSum.setBounds(155, 523, 200, 22);
+ frame.getContentPane().add(rtSum);
+ /* PU & RT Lists */
+ for (int i = 0; i < currentPUList.size(); i++) {
+ puLabelArray[i] = new JLabel(i +": " + currentPUList.get(i).getDefinition().getName());
+ rtListLabelArray[i] = new JLabel("Response Time");
+ puListArray[i] = new List();
+ rtListArray[i] = new List();
+ if (i >= 0 && i < 4) {
+ puLabelArray[i].setBounds((387+(i*200)), 50, 87, 22);
+ rtListLabelArray[i].setBounds((474+(i*200)), 50, 88, 22);
+ puListArray[i].setBounds((385+(i*200)), 75, 87, 145);
+ rtListArray[i].setBounds((475+(i*200)), 75, 87, 145);
+ } else if (i >= 4) {
+ puLabelArray[i].setBounds((387+((i-4)*200)), 225, 87, 22);
+ rtListLabelArray[i].setBounds((474+((i-4)*200)), 225, 88, 22);
+ puListArray[i].setBounds((385+((i-4)*200)), 250, 87, 145);
+ rtListArray[i].setBounds((475+((i-4)*200)), 250, 87, 145);
+ }
+ frame.getContentPane().add(puLabelArray[i]);
+ frame.getContentPane().add(rtListLabelArray[i]);
+ frame.getContentPane().add(puListArray[i]);
+ frame.getContentPane().add(rtListArray[i]);
+ }
+ /* E2ELatency Part */
+ currentECList = currentModel.getConstraintsModel().getEventChains();
+ if (currentECList.size() != 0) {
+ final String[] ecComboArray = new String[currentECList.size()];
+ for (int i = 0; i < currentECList.size(); i++) {
+ ecComboArray[i] = currentECList.get(i).getName();
+ }
+ ecComboBox = new JComboBox<String>(ecComboArray);
+ ecComboBox.setBounds(150, 570, 206, 22);
+ frame.getContentPane().add(ecComboBox);
+ ecComboBox.setSelectedItem(null);
+ } else {
+ JOptionPane.showMessageDialog(frame, "WARNING: The selected model has no Event-Chain.\n"
+ + "End-to-End Event-Chain Latency Calculation is impossible with this model.");
+ // TODO: Something needs to be done here to prevent E2ELatency calculation.
+ }
+ frame.revalidate();
+ frame.repaint();
+ }
+ }
+ });
+ amaltheaSchBtn.setBounds(348, 12, 133, 24);
+ frame.getContentPane().add(amaltheaSchBtn);
+
+ JLabel lblEventChainModel = new JLabel("EVENT CHAIN MODEL");
+ lblEventChainModel.setFont(new Font("Stencil BT", Font.PLAIN, 13));
+ lblEventChainModel.setBounds(10, 570, 136, 22);
+ frame.getContentPane().add(lblEventChainModel);
+
+ JLabel lblRI = new JLabel("Reaction (Implicit)");
+ lblRI.setFont(new Font("Sitka Text", Font.BOLD | Font.ITALIC, 13));
+ lblRI.setBounds(105, 605, 293, 16);
+ frame.getContentPane().add(lblRI);
+
+ JLabel lblBCRI = new JLabel("Best-Case");
+ lblBCRI.setHorizontalAlignment(SwingConstants.CENTER);
+ lblBCRI.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblBCRI.setBounds(10, 627, 90, 16);
+ frame.getContentPane().add(lblBCRI);
+
+ JTextField txtField0 = new JTextField();
+ txtField0.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField0.setBounds(103, 625, 200, 22);
+ txtField0.setEditable(false);
+ frame.getContentPane().add(txtField0);
+
+ JLabel lblWCRI = new JLabel("Worst-Case");
+ lblWCRI.setHorizontalAlignment(SwingConstants.CENTER);
+ lblWCRI.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblWCRI.setBounds(10, 656, 90, 16);
+ frame.getContentPane().add(lblWCRI);
+
+ JTextField txtField1 = new JTextField();
+ txtField1.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField1.setBounds(103, 654, 200, 22);
+ txtField1.setEditable(false);
+ frame.getContentPane().add(txtField1);
+
+ JLabel lblIRI = new JLabel("Initial Reaction (Implicit)");
+ lblIRI.setFont(new Font("Sitka Text", Font.BOLD | Font.ITALIC, 13));
+ lblIRI.setBounds(105, 688, 193, 16);
+ frame.getContentPane().add(lblIRI);
+
+ JLabel lblBCIRI = new JLabel("Best-Case");
+ lblBCIRI.setHorizontalAlignment(SwingConstants.CENTER);
+ lblBCIRI.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblBCIRI.setBounds(10, 710, 90, 16);
+ frame.getContentPane().add(lblBCIRI);
+
+ JTextField txtField2 = new JTextField();
+ txtField2.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField2.setBounds(103, 708, 200, 22);
+ txtField2.setEditable(false);
+ frame.getContentPane().add(txtField2);
+
+ JLabel lblWCIRI = new JLabel("Worst-Case");
+ lblWCIRI.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblWCIRI.setHorizontalAlignment(SwingConstants.CENTER);
+ lblWCIRI.setBounds(10, 739, 90, 16);
+ frame.getContentPane().add(lblWCIRI);
+
+ JTextField txtField3 = new JTextField();
+ txtField3.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField3.setBounds(103, 737, 200, 22);
+ txtField3.setEditable(false);
+ frame.getContentPane().add(txtField3);
+
+ JLabel lblRL = new JLabel("Reaction (LET)");
+ lblRL.setFont(new Font("Sitka Text", Font.BOLD | Font.ITALIC, 13));
+ lblRL.setBounds(415, 605, 222, 16);
+ frame.getContentPane().add(lblRL);
+
+ JLabel lblBCRL = new JLabel("Best-Case");
+ lblBCRL.setHorizontalAlignment(SwingConstants.CENTER);
+ lblBCRL.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblBCRL.setBounds(320, 627, 90, 16);
+ frame.getContentPane().add(lblBCRL);
+
+ JTextField txtField4 = new JTextField();
+ txtField4.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField4.setBounds(413, 625, 200, 22);
+ txtField4.setEditable(false);
+ frame.getContentPane().add(txtField4);
+
+ JLabel lblWCRL = new JLabel("Worst-Case");
+ lblWCRL.setHorizontalAlignment(SwingConstants.CENTER);
+ lblWCRL.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblWCRL.setBounds(320, 656, 90, 16);
+ frame.getContentPane().add(lblWCRL);
+
+ JTextField txtField5 = new JTextField();
+ txtField5.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField5.setBounds(413, 654, 200, 22);
+ txtField5.setEditable(false);
+ frame.getContentPane().add(txtField5);
+
+ JLabel lblIRL = new JLabel("Initial Reaction (LET)");
+ lblIRL.setFont(new Font("Sitka Text", Font.BOLD | Font.ITALIC, 13));
+ lblIRL.setBounds(415, 688, 232, 16);
+ frame.getContentPane().add(lblIRL);
+
+ JLabel lblBCIRL = new JLabel("Best-Case");
+ lblBCIRL.setHorizontalAlignment(SwingConstants.CENTER);
+ lblBCIRL.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblBCIRL.setBounds(320, 710, 90, 16);
+ frame.getContentPane().add(lblBCIRL);
+
+ JTextField txtField6 = new JTextField();
+ txtField6.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField6.setBounds(413, 708, 200, 22);
+ txtField6.setEditable(false);
+ frame.getContentPane().add(txtField6);
+
+ JLabel lblWCIRL = new JLabel("Worst-Case");
+ lblWCIRL.setHorizontalAlignment(SwingConstants.CENTER);
+ lblWCIRL.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblWCIRL.setBounds(320, 739, 90, 16);
+ frame.getContentPane().add(lblWCIRL);
+
+ JTextField txtField7 = new JTextField();
+ txtField7.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField7.setBounds(413, 737, 200, 22);
+ txtField7.setEditable(false);
+ frame.getContentPane().add(txtField7);
+
+ JLabel lblAI = new JLabel("Age (Implicit)");
+ lblAI.setFont(new Font("Sitka Text", Font.BOLD | Font.ITALIC, 13));
+ lblAI.setBounds(105, 771, 293, 16);
+ frame.getContentPane().add(lblAI);
+
+ JLabel lblBCAI = new JLabel("Best-Case");
+ lblBCAI.setHorizontalAlignment(SwingConstants.CENTER);
+ lblBCAI.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblBCAI.setBounds(10, 793, 90, 16);
+ frame.getContentPane().add(lblBCAI);
+
+ JTextField txtField8 = new JTextField();
+ txtField8.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField8.setBounds(103, 791, 200, 22);
+ txtField8.setEditable(false);
+ frame.getContentPane().add(txtField8);
+
+ JLabel lblWCAI = new JLabel("Worst-Case");
+ lblWCAI.setHorizontalAlignment(SwingConstants.CENTER);
+ lblWCAI.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblWCAI.setBounds(10, 822, 90, 16);
+ frame.getContentPane().add(lblWCAI);
+
+ JTextField txtField9 = new JTextField();
+ txtField9.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField9.setBounds(103, 820, 200, 22);
+ txtField9.setEditable(false);
+ frame.getContentPane().add(txtField9);
+
+ JLabel lblAL = new JLabel("Age (LET)");
+ lblAL.setFont(new Font("Sitka Text", Font.BOLD | Font.ITALIC, 13));
+ lblAL.setBounds(415, 771, 232, 16);
+ frame.getContentPane().add(lblAL);
+
+ JLabel lblBCAL = new JLabel("Best-Case");
+ lblBCAL.setHorizontalAlignment(SwingConstants.CENTER);
+ lblBCAL.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblBCAL.setBounds(320, 793, 90, 16);
+ frame.getContentPane().add(lblBCAL);
+
+ JTextField txtField10 = new JTextField();
+ txtField10.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField10.setBounds(413, 791, 200, 22);
+ txtField10.setEditable(false);
+ frame.getContentPane().add(txtField10);
+
+ JLabel lblWCAL = new JLabel("Worst-Case");
+ lblWCAL.setHorizontalAlignment(SwingConstants.CENTER);
+ lblWCAL.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblWCAL.setBounds(320, 822, 90, 16);
+ frame.getContentPane().add(lblWCAL);
+
+ JTextField txtField11 = new JTextField();
+ txtField11.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField11.setBounds(413, 820, 200, 22);
+ txtField11.setEditable(false);
+ frame.getContentPane().add(txtField11);
+
+ JLabel lblSIR = new JLabel("Single-core Initial Reaction");
+ lblSIR.setFont(new Font("Sitka Text", Font.BOLD | Font.ITALIC, 13));
+ lblSIR.setBounds(105, 865, 293, 16);
+ frame.getContentPane().add(lblSIR);
+
+ JLabel lblCRSIR = new JLabel("Critical-Case");
+ lblCRSIR.setHorizontalAlignment(SwingConstants.CENTER);
+ lblCRSIR.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblCRSIR.setBounds(10, 887, 90, 16);
+ frame.getContentPane().add(lblCRSIR);
+
+ JTextField txtField12 = new JTextField();
+ txtField12.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField12.setBounds(103, 885, 200, 22);
+ txtField12.setEditable(false);
+ frame.getContentPane().add(txtField12);
+
+ JLabel lblBCSIR = new JLabel("Best-Case");
+ lblBCSIR.setHorizontalAlignment(SwingConstants.CENTER);
+ lblBCSIR.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblBCSIR.setBounds(10, 916, 90, 16);
+ frame.getContentPane().add(lblBCSIR);
+
+ JTextField txtField13 = new JTextField();
+ txtField13.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField13.setBounds(103, 914, 200, 22);
+ txtField13.setEditable(false);
+ frame.getContentPane().add(txtField13);
+
+ JLabel lblWCSIR = new JLabel("Worst-Case");
+ lblWCSIR.setHorizontalAlignment(SwingConstants.CENTER);
+ lblWCSIR.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblWCSIR.setBounds(10, 945, 90, 16);
+ frame.getContentPane().add(lblWCSIR);
+
+ JTextField txtField14 = new JTextField();
+ txtField14.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField14.setBounds(103, 943, 200, 22);
+ txtField14.setEditable(false);
+ frame.getContentPane().add(txtField14);
+
+ JLabel lblSWCR = new JLabel("Single-core Worst-case Reaction");
+ lblSWCR.setFont(new Font("Sitka Text", Font.BOLD | Font.ITALIC, 13));
+ lblSWCR.setBounds(415, 865, 293, 16);
+ frame.getContentPane().add(lblSWCR);
+
+ JLabel lblCRSWCR = new JLabel("Critical-Case");
+ lblCRSWCR.setHorizontalAlignment(SwingConstants.CENTER);
+ lblCRSWCR.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblCRSWCR.setBounds(320, 887, 90, 16);
+ frame.getContentPane().add(lblCRSWCR);
+
+ JTextField txtField15 = new JTextField();
+ txtField15.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField15.setBounds(413, 885, 200, 22);
+ txtField15.setEditable(false);
+ frame.getContentPane().add(txtField15);
+
+ JLabel lblBCSWCR = new JLabel("Best-Case");
+ lblBCSWCR.setHorizontalAlignment(SwingConstants.CENTER);
+ lblBCSWCR.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblBCSWCR.setBounds(320, 916, 90, 16);
+ frame.getContentPane().add(lblBCSWCR);
+
+ JTextField txtField16 = new JTextField();
+ txtField16.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField16.setBounds(413, 914, 200, 22);
+ txtField16.setEditable(false);
+ frame.getContentPane().add(txtField16);
+
+ JLabel lblWCSWCR = new JLabel("Worst-Case");
+ lblWCSWCR.setHorizontalAlignment(SwingConstants.CENTER);
+ lblWCSWCR.setFont(new Font("Sitka Small", Font.PLAIN, 13));
+ lblWCSWCR.setBounds(320, 945, 90, 16);
+ frame.getContentPane().add(lblWCSWCR);
+
+ JTextField txtField17 = new JTextField();
+ txtField17.setHorizontalAlignment(SwingConstants.RIGHT);
+ txtField17.setBounds(413, 943, 200, 22);
+ txtField17.setEditable(false);
+ frame.getContentPane().add(txtField17);
+
+ JButton ecSelect = new JButton("Calculate");
+ ecSelect.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ if (currentModel == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Select an AMALTHEA model first.");
+ return ;
+ } else if (currentECList == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Event-Chain List is empty somehow.");
+ return ;
+ } else if (currentECList.size() == 0) {
+ JOptionPane.showMessageDialog(frame, "ERROR: There is no Event-Chain in this model.");
+ return ;
+ } else if (ecComboBox.getSelectedItem() == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Select an Event-Chain.");
+ return ;
+ } else if (puTaskListHM == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: IA(Integer Array) has not been assigned.");
+ return ;
+ } else if (offloadingMode.getSelection() == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Choose an offloading mode. (Sync / Async)");
+ return ;
+ } else if (schedulability_flag == false) {
+ String offMode = null;
+ if (SharedConsts.synchronousOffloading == true) {
+ offMode = "Sync";
+ } else if (SharedConsts.synchronousOffloading == false) {
+ offMode = "Aync";
+ }
+ String tType = null;
+ if (SharedConsts.timeType.equals(TimeType.WCET)) {
+ tType = "WC";
+ } else if (SharedConsts.timeType.equals(TimeType.ACET)) {
+ tType = "AC";
+ } else if (SharedConsts.timeType.equals(TimeType.BCET)) {
+ tType = "BC";
+ }
+ String iaFeedback = "";
+ for (int i = 0; i < currentIA.length; i++) {
+ if (i == currentIA.length - 1) {
+ iaFeedback = iaFeedback + currentIA[i];
+ } else {
+ iaFeedback = iaFeedback + currentIA[i] + ", ";
+ }
+ }
+ JOptionPane.showMessageDialog(frame, "ERROR: The entered IA value is not schedulable with the current configuration.\n\n"
+ + "Current Integer Arrary: { " + iaFeedback + " }\n\n"
+ + "Current Configuration: Offloading Mode(" + offMode + "), ExecutionCase(" + tType + ")");
+ return ;
+ }
+
+ /* If cpurta has only one core > single core mode, else > multicore mode (01/05/2020) */
+ final int thisIndex = ecComboBox.getSelectedIndex();
+ /* Something was selected before */
+ if (selectedECIndex != -1) {
+ /* If the selected Event-Chain is the same as before => Do Nothing */
+ if (selectedECIndex == thisIndex) {
+ return ;
+ }
+ /* If the selected Event-Chain is different to the previous one => Remove and Do Normal. */
+ if (selectedECIndex != thisIndex) {
+ for (int i = 0; i < currentTaskChain.size(); i++) {
+ frame.remove(ecLabelArray[i]);
+ frame.remove(ecJTPArray[i]);
+ }
+ selectedECIndex = thisIndex;
+ }
+ }
+ selectedECIndex = thisIndex;
+ currentEC = currentECList.get(thisIndex);
+ currentTaskChain = e2e.getECTaskList(currentEC);
+ if (currentTaskChain.size() == 0 ) {
+ JOptionPane.showMessageDialog(frame, "ERROR: The selected Event-Chain has no chain-element.");
+ txtField0.setText("Not Available.");
+ txtField1.setText("Not Available.");
+ txtField2.setText("Not Available.");
+ txtField3.setText("Not Available.");
+ txtField4.setText("Not Available.");
+ txtField5.setText("Not Available.");
+ txtField6.setText("Not Available.");
+ txtField7.setText("Not Available.");
+ return ;
+ }
+ else if (currentTaskChain.size() > 14) {
+ JOptionPane.showMessageDialog(frame, "ERROR: The selected Event-Chain has more than " + currentTaskChain.size() + " elements. (Limit: 14)\n");
+ txtField0.setText("Not Available.");
+ txtField1.setText("Not Available.");
+ txtField2.setText("Not Available.");
+ txtField3.setText("Not Available.");
+ txtField4.setText("Not Available.");
+ txtField5.setText("Not Available.");
+ txtField6.setText("Not Available.");
+ txtField7.setText("Not Available.");
+ return ;
+ }
+ for (int i = 0; i < currentTaskChain.size(); i++) {
+ final Task task = currentTaskChain.get(i);
+ for (int j = 0; j < puTaskListHM.size(); j++) {
+ java.util.List<Task> puTaskList = puTaskListHM.get(j);
+ if (puTaskList.stream().filter(s -> s.equals(task)).collect(Collectors.toList()).size() != 0) {
+ final ProcessingUnit pu = currentPUList.get(j);
+ ecLabelArray[i] = new JLabel((i+1) + ": " + pu.getName() + " (" + pu.getDefinition().getName() + ")");
+ ecJTPArray[i] = new JTextField();
+ ecJTPArray[i].setText(task.getName());
+ ecJTPArray[i].setEditable(false);
+ if (i < 7) {
+ ecLabelArray[i].setBounds(750, (604+(50*i)), 187, 16);
+ ecJTPArray[i].setBounds(750, (624+(50*i)), 187, 22);
+ } else {
+ ecLabelArray[i].setBounds(950, (604+(50*(i-7))), 187, 16);
+ ecJTPArray[i].setBounds(950, (624+(50*(i-7))), 187, 22);
+ }
+ frame.getContentPane().add(ecLabelArray[i]);
+ frame.getContentPane().add(ecJTPArray[i]);
+ break;
+ }
+ }
+ }
+
+ /* Calculation Part */
+ if (currentModel == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Select an AMALTHEA model first.");
+ return ;
+ } else if (ecComboBox.getSelectedItem() == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: Select an Event-Chain.");
+ return ;
+ } else if (currentIA == null) {
+ JOptionPane.showMessageDialog(frame, "ERROR: IA(Integer Array) has not been entered.");
+ return ;
+ }
+
+ /* To find out how many processing units are used by tasks */
+ ProcessingUnit pu = null;
+ int puCount = 0;
+ for (int i = 0; i < puTaskListHM.size(); i++) {
+ final java.util.List<Task> tasks = puTaskListHM.get(i);
+ if (tasks.size() > 0) {
+ pu = currentPUList.get(i);
+ puCount++;
+ }
+ }
+
+ if (puCount > 1) {
+ final Time bcRctIm = e2e.getBCReactionImplicit(currentEC, cpurta);
+ final Time wcRctIm = e2e.getWCReactionImplicit(currentEC, cpurta);
+ final Time bcInitRctIm = e2e.getBCInitialRctImplicit(currentEC, cpurta);
+ final Time wcInitRctIm = e2e.getWCInitialRctImplicit(currentEC, cpurta);
+ final Time bcRctLET = e2e.getBCReactionLET(currentEC, cpurta);
+ final Time wcRctLET = e2e.getWCReactionLET(currentEC, cpurta);
+ final Time bcInitRctLET = e2e.getBCInitialRctLET(currentEC, cpurta);
+ final Time wcInitRctLET = e2e.getWCInitialRctLET(currentEC, cpurta);
+ final Time bcAgeIm = e2e.getBCAgeImplicit(currentEC, cpurta);
+ final Time wcAgeIm = e2e.getWCAgeImplicit(currentEC, cpurta);
+ final Time bcAgeLET = e2e.getBCAgeLET(currentEC, cpurta);
+ final Time wcAgeLET = e2e.getWCAgeLET(currentEC, cpurta);
+
+ txtField0.setText("" + bcRctIm);
+ txtField1.setText("" + wcRctIm);
+ txtField2.setText("" + bcInitRctIm);
+ txtField3.setText("" + wcInitRctIm);
+ txtField4.setText("" + bcRctLET);
+ txtField5.setText("" + wcRctLET);
+ txtField6.setText("" + bcInitRctLET);
+ txtField7.setText("" + wcInitRctLET);
+ txtField8.setText("" + bcAgeIm);
+ txtField9.setText("" + wcAgeIm);
+ txtField10.setText("" + bcAgeLET);
+ txtField11.setText("" + wcAgeLET);
+
+ txtField12.setText("Not Single-Core.");
+ txtField13.setText("Not Single-Core.");
+ txtField14.setText("Not Single-Core.");
+ txtField15.setText("Not Single-Core.");
+ txtField16.setText("Not Single-Core.");
+ txtField17.setText("Not Single-Core.");
+ } else {
+ final Time crSingleInitRct = e2e.getSingleCoreInitialRct(currentEC, pu, SinglecoreLatCase.CriInitRct, cpurta);
+ final Time bcSingleInitRct = e2e.getSingleCoreInitialRct(currentEC, pu, SinglecoreLatCase.BCInitRct, cpurta);;
+ final Time wcSingleInitRct = e2e.getSingleCoreInitialRct(currentEC, pu, SinglecoreLatCase.WCInitRct, cpurta);;
+ final Time crSingleWCRct = e2e.getSingleCoreWCRct(currentEC, pu, SinglecoreLatCase.CriWCRct, cpurta);;
+ final Time bcSingleWCRct = e2e.getSingleCoreWCRct(currentEC, pu, SinglecoreLatCase.BCWCRct, cpurta);;
+ final Time wcSingleWCRct = e2e.getSingleCoreWCRct(currentEC, pu, SinglecoreLatCase.WCWCRct, cpurta);;
+
+ txtField0.setText("Not Multi-Core.");
+ txtField1.setText("Not Multi-Core.");
+ txtField2.setText("Not Multi-Core.");
+ txtField3.setText("Not Multi-Core.");
+ txtField4.setText("Not Multi-Core.");
+ txtField5.setText("Not Multi-Core.");
+ txtField6.setText("Not Multi-Core.");
+ txtField7.setText("Not Multi-Core.");
+ txtField8.setText("Not Multi-Core.");
+ txtField9.setText("Not Multi-Core.");
+ txtField10.setText("Not Multi-Core.");
+ txtField11.setText("Not Multi-Core.");
+
+ txtField12.setText("" + crSingleInitRct);
+ txtField13.setText("" + bcSingleInitRct);
+ txtField14.setText("" + wcSingleInitRct);
+ txtField15.setText("" + crSingleWCRct);
+ txtField16.setText("" + bcSingleWCRct);
+ txtField17.setText("" + wcSingleWCRct);
+ }
+
+ frame.revalidate();
+ frame.repaint();
+ }
+ });
+ ecSelect.setBounds(356, 569, 90, 25);
+ frame.getContentPane().add(ecSelect);
+
+ JButton btnNewButton_1 = new JButton("Reset");
+ btnNewButton_1.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ for (int i = 0; i < currentTaskChain.size(); i++) {
+ ecLabelArray[i].setText(null);
+ frame.remove(ecLabelArray[i]);
+ ecJTPArray[i].setText(null);
+ frame.remove(ecJTPArray[i]);
+ }
+ selectedECIndex = -1;
+ txtField0.setText("");
+ txtField1.setText("");
+ txtField2.setText("");
+ txtField3.setText("");
+ txtField4.setText("");
+ txtField5.setText("");
+ txtField6.setText("");
+ txtField7.setText("");
+ txtField8.setText("");
+ txtField9.setText("");
+ txtField10.setText("");
+ txtField11.setText("");
+ txtField12.setText("");
+ txtField13.setText("");
+ txtField14.setText("");
+ txtField15.setText("");
+ txtField16.setText("");
+ txtField17.setText("");
+
+ frame.revalidate();
+ frame.repaint();
+ }
+ });
+ btnNewButton_1.setBounds(445, 569, 70, 25);
+ frame.getContentPane().add(btnNewButton_1);
+
+ JLabel lblTaskChain_1 = new JLabel("Task Chain >");
+ lblTaskChain_1.setFont(new Font("Segoe UI Emoji", Font.BOLD, 13));
+ lblTaskChain_1.setBounds(646, 605, 90, 16);
+ frame.getContentPane().add(lblTaskChain_1);
+
+ JLabel lblApprta = new JLabel("APP4RTA");
+ lblApprta.setForeground(Color.DARK_GRAY);
+ lblApprta.setFont(new Font("Snap ITC", Font.ITALIC, 20));
+ lblApprta.setBounds(1050, 1, 120, 34);
+ frame.getContentPane().add(lblApprta);
+
+ JSeparator separator = new JSeparator();
+ separator.setBounds(10, 557, 1160, 2);
+ frame.getContentPane().add(separator);
+ }
+}
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/ui/RTApp_WATERS19.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/ui/RTApp_WATERS19.java
deleted file mode 100644
index 4df858e..0000000
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/ui/RTApp_WATERS19.java
+++ /dev/null
@@ -1,561 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2019 Dortmund University of Applied Sciences and Arts.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors: Junhyung Ki - initial API and implementation
- *
- *******************************************************************************/
-package org.eclipse.app4mc.gsoc_rta.ui;
-
-import java.awt.Color;
-import java.awt.EventQueue;
-import java.awt.Font;
-import java.awt.List;
-import java.awt.TextArea;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.HashMap;
-import javax.swing.ButtonGroup;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JRadioButton;
-import javax.swing.JTextField;
-
-import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
-import org.eclipse.app4mc.amalthea.model.PuType;
-import org.eclipse.app4mc.amalthea.model.Task;
-import org.eclipse.app4mc.amalthea.model.Time;
-import org.eclipse.app4mc.amalthea.model.TimeUnit;
-import org.eclipse.app4mc.amalthea.model.io.AmaltheaLoader;
-import org.eclipse.app4mc.amalthea.model.util.FactoryUtil;
-import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
-import org.eclipse.app4mc.gsoc_rta.*;
-
-/**
- * Date: Jun 20-2019
- * @author Junhyung Ki
- * @version 1.0
- * The purpose of this class is to provide users a better visual and increase usability of Response Time Analysis.
- */
-@SuppressWarnings("serial")
-public class RTApp_WATERS19 extends JFrame {
- private HashMap<Integer, java.util.List<Task>> puTaskListHM;
- private JFrame frame;
- private boolean iaEntered = false;
-
- /**
- * Launch the application.
- */
- public static void main(String[] args) {
- EventQueue.invokeLater(new Runnable() {
- public void run() {
- org.apache.log4j.BasicConfigurator.configure();
- final RTApp_WATERS19 window = new RTApp_WATERS19();
- window.frame.setVisible(true);
- window.frame.setTitle("APP4RTA");
- }
- });
- }
-
- /**
- * Create the frame.
- */
- public RTApp_WATERS19() {
- initialize();
- }
-
- private void initialize() {
- final CpuRTA cpurta = new CpuRTA();
- final ArrayList<JTextField> jTextFieldList = new ArrayList<JTextField>();
- final ArrayList<List> tListList = new ArrayList<List>();
- final ArrayList<List> rtListList = new ArrayList<List>();
-
- frame = new JFrame();
- frame.setBounds(100, 100, 864, 690);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.getContentPane().setLayout(null);
-
- JLabel lblEnterIa = new JLabel("Enter IA");
- lblEnterIa.setBounds(32, 13, 56, 16);
- frame.getContentPane().add(lblEnterIa);
-
- JButton btnDefualtIa = new JButton("Defualt IA");
- btnDefualtIa.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent arg0) {
- cpurta.setModel(AmaltheaLoader.loadFromFile(cpurta.inputFile));
- cpurta.setTRT(cpurta.getDefaultTRT(cpurta.getModel()));
- cpurta.setIA(cpurta.getDefaultIAMapping());
- cpurta.setPUl(CommonUtils.getPUs(cpurta.getModel()));
- final int[] defaultIA = cpurta.getIA();
- for (int i = 0; i < defaultIA.length; i++) {
- jTextFieldList.get(i).setText(""+defaultIA[i]);
- }
- }
- });
- btnDefualtIa.setBounds(12, 28, 97, 25);
- frame.getContentPane().add(btnDefualtIa);
-
- JRadioButton rdbtnSynchronous = new JRadioButton("Synchronous");
- rdbtnSynchronous.setBounds(157, 58, 107, 25);
- frame.getContentPane().add(rdbtnSynchronous);
-
- JRadioButton rdbtnAsynchronous = new JRadioButton("Asynchronous");
- rdbtnAsynchronous.setBounds(157, 79, 107, 25);
- frame.getContentPane().add(rdbtnAsynchronous);
-
- ButtonGroup group_0 = new ButtonGroup();
- group_0.add(rdbtnSynchronous);
- group_0.add(rdbtnAsynchronous);
-
- JRadioButton rdbtnWorstCase = new JRadioButton("Worst Case");
- rdbtnWorstCase.setBounds(268, 58, 107, 25);
- frame.getContentPane().add(rdbtnWorstCase);
-
- JRadioButton rdbtnAverageCase = new JRadioButton("Average Case");
- rdbtnAverageCase.setBounds(268, 79, 107, 25);
- frame.getContentPane().add(rdbtnAverageCase);
-
- JRadioButton rdbtnBestCase = new JRadioButton("Best Case");
- rdbtnBestCase.setBounds(268, 100, 107, 25);
- frame.getContentPane().add(rdbtnBestCase);
-
- ButtonGroup group_1 = new ButtonGroup();
- group_1.add(rdbtnWorstCase);
- group_1.add(rdbtnAverageCase);
- group_1.add(rdbtnBestCase);
-
- JButton btnEnterIA = new JButton("Enter IA");
- btnEnterIA.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- cpurta.setModel(AmaltheaLoader.loadFromFile(cpurta.inputFile));
- cpurta.setTRT(cpurta.getDefaultTRT(cpurta.getModel()));
- int[] tpumap = new int[cpurta.getModel().getSwModel().getTasks().size()];
- for (int i = 0; i < jTextFieldList.size(); i++) {
- if ((jTextFieldList.get(i)).getText().length() == 0) {
- JOptionPane.showMessageDialog(frame, "ERROR: Fill the rest of the array!");
- return ;
- }
- else if ((jTextFieldList.get(i)).getText().charAt(0) < 48 || (jTextFieldList.get(i)).getText().charAt(0) > 54) {
- JOptionPane.showMessageDialog(frame, "ERROR: Wrong array value!");
- return ;
- }
- // TODO: should be more generic
- else if (i >= 0 && i <= 9 && Integer.parseInt(((jTextFieldList.get(i)).getText())) == 6) {
- JOptionPane.showMessageDialog(frame, "ERROR: CPU Tasks should not be mapped to GPU!");
- return ;
- }
- // TODO: should be more generic
- else if (i == jTextFieldList.size()-1 && Integer.parseInt(((jTextFieldList.get(i)).getText())) != 6) {
- JOptionPane.showMessageDialog(frame, "ERROR: 'Detection' task can not be mapped to CPU!");
- return ;
- }
- tpumap[i] = Integer.parseInt(((jTextFieldList.get(i)).getText()));
- }
- cpurta.setIA(tpumap);
- cpurta.setPUl(CommonUtils.getPUs(cpurta.getModel()));
- puTaskListHM = cpurta.be_getPUTaskListHashMap(cpurta.getModel());
- for (int i = 0; i < puTaskListHM.size(); i++) {
- if (tListList.get(i).getItemCount() == 0) {
- for (int j = 0; j < puTaskListHM.get(i).size(); j++) {
- tListList.get(i).add((puTaskListHM.get(i).get(j)).getName());
- }
- }
- }
- iaEntered = true;
- }
- });
- btnEnterIA.setBounds(616, 28, 97, 25);
- frame.getContentPane().add(btnEnterIA);
-
- JLabel lblResponseTimeSum = new JLabel("Response Time Sum");
- lblResponseTimeSum.setBounds(616, 359, 145, 16);
- frame.getContentPane().add(lblResponseTimeSum);
-
- TextArea rtSum = new TextArea();
- rtSum.setBounds(616, 381, 218, 50);
- frame.getContentPane().add(rtSum);
-
- JButton btnCalculate = new JButton("Calculate");
- btnCalculate.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent arg0) {
- for (int i = 0; i < jTextFieldList.size(); i++) {
- if ((jTextFieldList.get(i)).getText().length() == 0) {
- JOptionPane.showMessageDialog(frame, "ERROR: Fill the array first!");
- return ;
- }
- }
- if (rdbtnSynchronous.isSelected()) {
- SharedConsts.synchronousOffloading = true;
- }
- else if (rdbtnAsynchronous.isSelected()) {
- SharedConsts.synchronousOffloading = false;
- }
- else {
- JOptionPane.showMessageDialog(frame, "ERROR: You should choose an offloading mode! (Sync / Async)");
- return ;
- }
- if (rdbtnWorstCase.isSelected()) {
- SharedConsts.timeType = TimeType.WCET;
- }
- else if (rdbtnAverageCase.isSelected()) {
- SharedConsts.timeType = TimeType.ACET;
- }
- else if (rdbtnBestCase.isSelected()) {
- SharedConsts.timeType = TimeType.BCET;
- }
- else {
- JOptionPane.showMessageDialog(frame, "ERROR: You should choose an execution case! (Worst Case / Average Case / Best Case)");
- return ;
- }
- if (iaEntered == false) {
- JOptionPane.showMessageDialog(frame, "ERROR: Click the 'Enter IA' button!");
- return ;
- }
- boolean flag = false;
- Time pRtSum = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- for (int i = 0; i < puTaskListHM.size(); i++) {
- final ProcessingUnit pu = cpurta.getPUl().get(i);
- final java.util.List<Task> thisPUTaskList = puTaskListHM.get(i);
- Time thisRT = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);
- if (rtListList.get(i).getItemCount() == 0) {
- if (pu.getDefinition().getPuType().equals(PuType.CPU)) {
- for (Task t : thisPUTaskList) {
- thisRT = cpurta.preciseTestCPURT(t, thisPUTaskList, SharedConsts.timeType, pu);
- if (thisRT.getValue().equals(BigInteger.valueOf(Long.MAX_VALUE))) {
- rtListList.get(i).add("Non Scheduleable! => MAX Value");
- flag = true;
- }
- else {
- rtListList.get(i).add(thisRT.toString());
- }
- pRtSum = pRtSum.add(thisRT);
- }
- }
- else {
- // TODO: TRT 0s!
- for (Task t : thisPUTaskList) {
- thisRT = cpurta.getTRT().get(t);
- rtListList.get(i).add(thisRT.toString());
- pRtSum = pRtSum.add(thisRT);
- }
- }
- }
- }
- if (flag) {
- rtSum.setText("Non Scheduleable!: " + pRtSum.toString());
- }
- else {
- rtSum.setText(pRtSum.toString());
- }
- }
- });
- btnCalculate.setBounds(616, 58, 97, 25);
- frame.getContentPane().add(btnCalculate);
-
- JButton btnReset = new JButton("Reset");
- btnReset.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- cpurta.setModel(null);
- cpurta.setTRT(null);
- cpurta.setIA(null);
- cpurta.setPUl(null);
- puTaskListHM = null;
- for (int i = 0; i < jTextFieldList.size(); i++) {
- jTextFieldList.get(i).setText("");
- }
- for (List tList : tListList) {
- tList.removeAll();
- }
- for (List rtList : rtListList) {
- rtList.removeAll();
- }
- rtSum.setText(null);
- iaEntered = false;
- }
- });
- btnReset.setBounds(616, 86, 97, 25);
- frame.getContentPane().add(btnReset);
-
- JLabel lblT0 = new JLabel("T0");
- lblT0.setBounds(124, 13, 15, 16);
- frame.getContentPane().add(lblT0);
-
- JTextField txtInput0 = new JTextField();
- txtInput0.setBounds(124, 29, 23, 22);
- txtInput0.setColumns(10);
- frame.getContentPane().add(txtInput0);
- jTextFieldList.add(txtInput0);
-
- JLabel lblT1 = new JLabel("T1");
- lblT1.setBounds(159, 13, 15, 16);
- frame.getContentPane().add(lblT1);
-
- JTextField txtInput1 = new JTextField();
- txtInput1.setColumns(10);
- txtInput1.setBounds(159, 29, 23, 22);
- frame.getContentPane().add(txtInput1);
- jTextFieldList.add(txtInput1);
-
- JLabel lblT2 = new JLabel("T2");
- lblT2.setBounds(194, 13, 15, 16);
- frame.getContentPane().add(lblT2);
-
- JTextField txtInput2 = new JTextField();
- txtInput2.setColumns(10);
- txtInput2.setBounds(194, 29, 23, 22);
- frame.getContentPane().add(txtInput2);
- jTextFieldList.add(txtInput2);
-
- JLabel lblT3 = new JLabel("T3");
- lblT3.setBounds(229, 13, 15, 16);
- frame.getContentPane().add(lblT3);
-
- JTextField txtInput3 = new JTextField();
- txtInput3.setColumns(10);
- txtInput3.setBounds(229, 29, 23, 22);
- frame.getContentPane().add(txtInput3);
- jTextFieldList.add(txtInput3);
-
- JLabel lblT4 = new JLabel("T4");
- lblT4.setBounds(264, 13, 15, 16);
- frame.getContentPane().add(lblT4);
-
- JTextField txtInput4 = new JTextField();
- txtInput4.setColumns(10);
- txtInput4.setBounds(264, 29, 23, 22);
- frame.getContentPane().add(txtInput4);
- jTextFieldList.add(txtInput4);
-
- JLabel lblT5 = new JLabel("T5");
- lblT5.setBounds(299, 13, 15, 16);
- frame.getContentPane().add(lblT5);
-
- JTextField txtInput5 = new JTextField();
- txtInput5.setColumns(10);
- txtInput5.setBounds(299, 29, 23, 22);
- frame.getContentPane().add(txtInput5);
- jTextFieldList.add(txtInput5);
-
- JLabel lblT6 = new JLabel("T6");
- lblT6.setBounds(334, 13, 15, 16);
- frame.getContentPane().add(lblT6);
-
- JTextField txtInput6 = new JTextField();
- txtInput6.setColumns(10);
- txtInput6.setBounds(334, 29, 23, 22);
- frame.getContentPane().add(txtInput6);
- jTextFieldList.add(txtInput6);
-
- JLabel lblT7 = new JLabel("T7");
- lblT7.setBounds(369, 13, 15, 16);
- frame.getContentPane().add(lblT7);
-
- JTextField txtInput7 = new JTextField();
- txtInput7.setColumns(10);
- txtInput7.setBounds(369, 29, 23, 22);
- frame.getContentPane().add(txtInput7);
- jTextFieldList.add(txtInput7);
-
- JLabel lblT8 = new JLabel("T8");
- lblT8.setBounds(404, 13, 15, 16);
- frame.getContentPane().add(lblT8);
-
- JTextField txtInput8 = new JTextField();
- txtInput8.setColumns(10);
- txtInput8.setBounds(404, 29, 23, 22);
- frame.getContentPane().add(txtInput8);
- jTextFieldList.add(txtInput8);
-
- JLabel lblT9 = new JLabel("T9");
- lblT9.setBounds(439, 13, 15, 16);
- frame.getContentPane().add(lblT9);
-
- JTextField txtInput9 = new JTextField();
- txtInput9.setColumns(10);
- txtInput9.setBounds(439, 29, 23, 22);
- frame.getContentPane().add(txtInput9);
- jTextFieldList.add(txtInput9);
-
- JLabel lblT10 = new JLabel("T10");
- lblT10.setBounds(474, 13, 23, 16);
- frame.getContentPane().add(lblT10);
-
- JTextField txtInput10 = new JTextField();
- txtInput10.setColumns(10);
- txtInput10.setBounds(474, 29, 23, 22);
- frame.getContentPane().add(txtInput10);
- jTextFieldList.add(txtInput10);
-
- JLabel lblT11 = new JLabel("T11");
- lblT11.setBounds(509, 13, 23, 16);
- frame.getContentPane().add(lblT11);
-
- JTextField txtInput11 = new JTextField();
- txtInput11.setColumns(10);
- txtInput11.setBounds(509, 29, 23, 22);
- frame.getContentPane().add(txtInput11);
- jTextFieldList.add(txtInput11);
-
- JLabel lblT12 = new JLabel("T12");
- lblT12.setBounds(544, 13, 23, 16);
- frame.getContentPane().add(lblT12);
-
- JTextField txtInput12 = new JTextField();
- txtInput12.setColumns(10);
- txtInput12.setBounds(544, 29, 23, 22);
- frame.getContentPane().add(txtInput12);
- jTextFieldList.add(txtInput12);
-
- JLabel lblT13 = new JLabel("T13");
- lblT13.setBounds(579, 13, 23, 16);
- frame.getContentPane().add(lblT13);
-
- JTextField txtInput13 = new JTextField();
- txtInput13.setColumns(10);
- txtInput13.setBounds(579, 29, 23, 22);
- frame.getContentPane().add(txtInput13);
- jTextFieldList.add(txtInput13);
-
- JLabel txtArm_0 = new JLabel("ARM0");
- txtArm_0.setBounds(86, 154, 42, 22);
- frame.getContentPane().add(txtArm_0);
-
- List arm0_list = new List();
- arm0_list.setBounds(10, 180, 87, 145);
- frame.getContentPane().add(arm0_list);
- tListList.add(arm0_list);
-
- List arm0_rtList = new List();
- arm0_rtList.setBounds(108, 180, 87, 145);
- frame.getContentPane().add(arm0_rtList);
- rtListList.add(arm0_rtList);
-
- JLabel txtArm_1 = new JLabel("ARM1");
- txtArm_1.setBounds(288, 154, 42, 22);
- frame.getContentPane().add(txtArm_1);
-
- List arm1_list = new List();
- arm1_list.setBounds(212, 180, 87, 145);
- frame.getContentPane().add(arm1_list);
- tListList.add(arm1_list);
-
- List arm1_rtList = new List();
- arm1_rtList.setBounds(309, 180, 87, 145);
- frame.getContentPane().add(arm1_rtList);
- rtListList.add(arm1_rtList);
-
- JLabel txtArm_2 = new JLabel("ARM2");
- txtArm_2.setBounds(489, 154, 42, 22);
- frame.getContentPane().add(txtArm_2);
-
- List arm2_list = new List();
- arm2_list.setBounds(414, 180, 87, 145);
- frame.getContentPane().add(arm2_list);
- tListList.add(arm2_list);
-
- List arm2_rtList = new List();
- arm2_rtList.setBounds(510, 180, 87, 145);
- frame.getContentPane().add(arm2_rtList);
- rtListList.add(arm2_rtList);
-
- JLabel txtArm_3 = new JLabel("ARM3");
- txtArm_3.setBounds(691, 154, 42, 22);
- frame.getContentPane().add(txtArm_3);
-
- List arm3_list = new List();
- arm3_list.setBounds(616, 180, 87, 145);
- frame.getContentPane().add(arm3_list);
- tListList.add(arm3_list);
-
- List arm3_rtList = new List();
- arm3_rtList.setBounds(711, 180, 87, 145);
- frame.getContentPane().add(arm3_rtList);
- rtListList.add(arm3_rtList);
-
- JLabel txtDenver_0 = new JLabel("Denver0");
- txtDenver_0.setBounds(82, 335, 56, 22);
- frame.getContentPane().add(txtDenver_0);
-
- List denver0_list = new List();
- denver0_list.setBounds(10, 359, 87, 145);
- frame.getContentPane().add(denver0_list);
- tListList.add(denver0_list);
-
- List denver0_rtList = new List();
- denver0_rtList.setBounds(108, 359, 87, 145);
- frame.getContentPane().add(denver0_rtList);
- rtListList.add(denver0_rtList);
-
- JLabel txtDenver_1 = new JLabel("Denver1");
- txtDenver_1.setBounds(284, 335, 56, 22);
- frame.getContentPane().add(txtDenver_1);
-
- List denver1_list = new List();
- denver1_list.setBounds(212, 359, 87, 145);
- frame.getContentPane().add(denver1_list);
- tListList.add(denver1_list);
-
- List denver1_rtList = new List();
- denver1_rtList.setBounds(309, 359, 87, 145);
- frame.getContentPane().add(denver1_rtList);
- rtListList.add(denver1_rtList);
-
- JLabel txtGpu = new JLabel("GPU");
- txtGpu.setBounds(489, 335, 42, 22);
- frame.getContentPane().add(txtGpu);
-
- List gpu_list = new List();
- gpu_list.setBounds(414, 359, 87, 145);
- frame.getContentPane().add(gpu_list);
- tListList.add(gpu_list);
-
- List gpu_rtList = new List();
- gpu_rtList.setBounds(510, 359, 87, 145);
- frame.getContentPane().add(gpu_rtList);
- rtListList.add(gpu_rtList);
-
- JLabel lblArm = new JLabel("0: ARM0");
- lblArm.setBounds(12, 62, 56, 16);
- frame.getContentPane().add(lblArm);
-
- JLabel lblArm_1 = new JLabel("1: ARM1");
- lblArm_1.setBounds(12, 79, 56, 16);
- frame.getContentPane().add(lblArm_1);
-
- JLabel lblArm_2 = new JLabel("2: ARM2");
- lblArm_2.setBounds(12, 98, 56, 16);
- frame.getContentPane().add(lblArm_2);
-
- JLabel lblArm_3 = new JLabel("3: ARM3");
- lblArm_3.setBounds(12, 117, 56, 16);
- frame.getContentPane().add(lblArm_3);
-
- JLabel lblDenver = new JLabel("4: Denver0");
- lblDenver.setBounds(77, 62, 72, 16);
- frame.getContentPane().add(lblDenver);
-
- JLabel lblDenver_1 = new JLabel("5: Denver1");
- lblDenver_1.setBounds(77, 79, 72, 16);
- frame.getContentPane().add(lblDenver_1);
-
- JLabel lblGpu = new JLabel("6: GPU");
- lblGpu.setBounds(77, 96, 56, 16);
- frame.getContentPane().add(lblGpu);
-
- JLabel lblApprta = new JLabel("APP4RTA");
- lblApprta.setForeground(Color.BLUE);
- lblApprta.setFont(new Font("Tahoma", Font.ITALIC, 20));
- lblApprta.setBounds(747, 1, 87, 34);
- frame.getContentPane().add(lblApprta);
- }
-}
\ No newline at end of file