| /** |
| ******************************************************************************** |
| * 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; |
| } |
| } |