blob: 3b33c74d0bc7b6e2a0d3f497d0304b3b7cfe2e87 [file] [log] [blame]
/**
********************************************************************************
* Copyright (c) 2022 Dortmund University of Applied Sciences and Arts and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dortmund University of Applied Sciences and Arts - initial API and implementation
********************************************************************************
*/
package org.eclipse.app4mc.amalthea.model.util.stimuli;
import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
import org.eclipse.app4mc.amalthea.model.ModeLabel;
import org.eclipse.app4mc.amalthea.model.Process;
import org.eclipse.app4mc.amalthea.model.Time;
import org.eclipse.app4mc.amalthea.model.VariableRateStimulus;
import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil;
import org.eclipse.app4mc.amalthea.model.util.RuntimeUtil.TimeType;
import org.eclipse.emf.common.util.EMap;
/**
* Event Model functions for APP4MC's {@link VariableRateStimulus}.
*/
public class EMVariableRate implements IEventModel {
private Time tStep;
private double dLowerBoundOccurrences;
private double dUpperBoundOccurrences;
private double dAverageBoundOccurrences;
public EMVariableRate() {
// Empty on purpose
}
@Override
public long etaPlus(final Time dt) {
// Return 0 on dt=0
if (EventModelFactory.isNullOrZero(dt)) {
// For dt = 0, the upper and lower bound functions return 0
return 0;
}
final double result = dt.multiply(this.dUpperBoundOccurrences).divide(this.tStep);
return (long) Math.ceil(result);
}
@Override
public long etaMinus(final Time dt) {
// Return 0 on dt=0
if (EventModelFactory.isNullOrZero(dt)) {
// For dt = 0, the upper and lower bound functions return 0
return 0;
}
final double result = dt.multiply(this.dLowerBoundOccurrences).divide(this.tStep);
// Equivalent to Math.floor
return (long) result;
}
@Override
public Time deltaPlus(final long n) {
// Function is only valid for n >= 2, return null on invalid parameter
if (n < 2) {
return null;
}
final double scale = (n - 1) / this.dUpperBoundOccurrences;
final Time tDistance = this.tStep.multiply(scale);
if (tDistance == null) {
return null;
}
return AmaltheaServices.adjustTimeUnit(tDistance);
}
@Override
public Time deltaMinus(final long n) {
// Function is only valid for n >= 2, return null on invalid parameter
if (n < 2) {
return null;
}
final double scale = (n - 1) / this.dLowerBoundOccurrences;
final Time tDistance = this.tStep.multiply(scale);
if (tDistance == null) {
return null;
}
return AmaltheaServices.adjustTimeUnit(tDistance);
}
@Override
public double getUtilization(Process process, TimeType tt, EMap<ModeLabel, String> modes) {
final Time executionTime = RuntimeUtil.getExecutionTimeForProcess(process, modes, tt);
if (tt.equals(TimeType.BCET)) {
// Minimum load occurs when the minimum of activation events occurs per step
return executionTime.multiply(dLowerBoundOccurrences).divide(getStep());
} else if (tt.equals(TimeType.WCET)) {
// Maximum load occurs when the maximum of activation events occurs per step
return executionTime.multiply(dUpperBoundOccurrences).divide(getStep());
} else if (tt.equals(TimeType.ACET)) {
return executionTime.multiply(dAverageBoundOccurrences).divide(getStep());
}
// Unsupported configuration
return -1;
}
public Time getStep() {
return tStep;
}
public void setStep(Time step) {
this.tStep = step;
}
public double getLowerBoundOccurrences() {
return dLowerBoundOccurrences;
}
public void setLowerBoundOccurrences(double dLowerBoundOccurrences) {
this.dLowerBoundOccurrences = dLowerBoundOccurrences;
}
public double getAverageBoundOccurrences() {
return dAverageBoundOccurrences;
}
public void setAverageBoundOccurrences(double dAverageBoundOccurrences) {
this.dAverageBoundOccurrences = dAverageBoundOccurrences;
}
public double getUpperBoundOccurrences() {
return dUpperBoundOccurrences;
}
public void setUpperBoundOccurrences(double dUpperBoundOccurrences) {
this.dUpperBoundOccurrences = dUpperBoundOccurrences;
}
}