/******************************************************************************* | |
* 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: The Bao Bui | |
* FH Dortmund - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.app4mc.gsoc_rta.test; | |
import java.math.BigDecimal; | |
import java.math.RoundingMode; | |
import java.text.DecimalFormat; | |
import org.apache.log4j.Level; | |
import org.apache.log4j.Logger; | |
/** | |
* This class is a numerical example of NPandPRTA functions, used to trace/debug the data flow and understand how each equations work. | |
* Include: recurrence rta, level-i rta, level-i non preempt, level-i cooperative. | |
* Hope this will help everybody understand better on how level-i busy window technique work in response time analysis. | |
* @author The Bao Bui (Zero) | |
*/ | |
public class NPandPRTANumerical { | |
public static void main(final String[] args) { | |
org.apache.log4j.BasicConfigurator.configure(); | |
Logger.getRootLogger().setLevel(Level.DEBUG); | |
//Just uncomment the class you want to run, but remember to edit input value if you have others input values. | |
//All of the equation used in this class can be found in my documentation (readthedocs) | |
final NPandPRTANumerical test = new NPandPRTANumerical(); | |
// test.levelI(); | |
// test.classicRTA(); | |
// test.levelIforNonPreemptive(); | |
// test.levelIforMixedNPandP(); | |
test.levelIforCooperative(); | |
} | |
private static long roundUp(final long num, final long divisor) { | |
return (num + divisor - 1) / divisor; | |
} | |
/** | |
* This function is a numerical example of how recurrence response time analysis work. | |
* It's the implementation of equation 1, if you don't know where is equation 1, it's in my readthedocs. | |
* To understand how equation work, just put a debug pointer in the function and trace the data flow | |
* | |
* Credit: | |
* The input number are derived from the paper "Fixed Priority Scheduling of Periodic Task Sets with Arbitrary Deadlines" by Lehoczky (1990) | |
* I just use the number for confirmation. | |
*/ | |
private void recurrenceRTA() { | |
System.out.println("Testing classicRTA here"); | |
//Exe = excution time, p = period | |
final int[] exe = { 20, 20, 35 }; | |
final int[] p = { 70, 80, 200 }; | |
//r0 and temp is just variable to spot whether the iteration has come to an end or not. | |
//Iteration ended when previous and current iteration value is the same. | |
int r0 = 0; | |
int temp = 1; | |
//Iterate from the highest priority task to the lowest. Task is already ordered. | |
//Calculate response time of all task | |
for (int i = 0; i < exe.length; i++) { | |
r0 = 0; | |
final int taskNo = i + 1; | |
System.out.println("Task number " + taskNo); | |
//getting r0. | |
for (int j = 0; j < i + 1; j++) { | |
r0 = r0 + exe[j]; | |
} | |
System.out.println("r0 = " + r0); | |
int current = r0; | |
//Iteration loop for each task, response time will be found when this is ended. | |
while (temp != current) { | |
temp = current; | |
//Because there will be lots of \frac {R_{i-1}^+} {T_j} if we have several higher priority task, hence the iteration value | |
//Iteration value here is the big sum of all \frac {R_{i-1}^+} {T_j} | |
int iteration = 0; | |
//Sum all \frac {R_{i-1}^+} {T_j} | |
for (int k = 0; k < i; k++) { | |
//This is | |
final long num = roundUp(current, p[k]); | |
final long div = exe[k]; | |
iteration = iteration + (int) (num * div); | |
} | |
current = iteration + exe[i]; | |
} | |
} | |
} | |
/** | |
* calculate level-i busy period. Preemptive | |
* | |
* Credit: | |
* The input number are derived from the paper "Fixed Priority Scheduling of Periodic Task Sets with Arbitrary Deadlines" by Lehoczky (1990) | |
* I just use the number for confirmation. | |
*/ | |
private void levelI() { | |
final Logger log = Logger.getLogger(this.getClass().getName()); | |
final DecimalFormat df = new DecimalFormat("#,###.##"); | |
//Exe = excution time, p = period | |
// final int[] exe = { 20, 20, 35 }; | |
// final int[] p = { 70, 80, 200 }; | |
// | |
final int[] exe = { 20, 50, 60, 80 }; | |
final int[] p = { 100, 180, 250, 300 }; | |
for (int i = 0; i < exe.length; i++) { | |
log.debug("for task " + i); | |
/* ----- Get LEVEL - I for each task ------ */ | |
BigDecimal lv0 = BigDecimal.ZERO; | |
BigDecimal currentLv = BigDecimal.ONE; | |
final BigDecimal iPeriod = BigDecimal.valueOf(p[i]); | |
final BigDecimal iExe = BigDecimal.valueOf(exe[i]); | |
BigDecimal iResponseTime = BigDecimal.ZERO; | |
while (!currentLv.equals(lv0)) { | |
lv0 = currentLv; | |
//entry = each small sum of [Li/Tj]Cj, p_j >= p_i | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i + 1; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
final BigDecimal roundUp = currentLv.divide(entryPeriod, RoundingMode.CEILING); | |
final BigDecimal entryValue = roundUp.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
} | |
/* -- Add blocking for nonpreemptive here-- current lv plus blocking*/ | |
currentLv = iterationValue; | |
} | |
log.debug("level-" + i + ": " + lv0); | |
/* ----- Get K (total task iteration) ------ */ | |
final int bigK = lv0.divide(iPeriod, RoundingMode.CEILING).intValue(); | |
/* ----- Get finishing time for each task ------ */ | |
for (int smallK = 1; smallK <= bigK; smallK++) { | |
log.debug(" --- k instance : " + smallK + "/" + bigK + " --------------------------------------------"); | |
BigDecimal kLv = BigDecimal.ZERO; | |
BigDecimal currentKLv = BigDecimal.ONE; | |
final BigDecimal kCi = iExe.multiply(BigDecimal.valueOf(smallK)); | |
int counter = 0; | |
while (!kLv.equals(currentKLv)) { | |
currentKLv = kLv; | |
//entry = each small sum of [Li/Tj]Cj, j > i, not >= | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
final BigDecimal roundUp = currentKLv.divide(entryPeriod, RoundingMode.CEILING); | |
final BigDecimal entryValue = roundUp.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
if (counter == 0) { | |
iterationValue = BigDecimal.ZERO; | |
counter++; | |
break; | |
} | |
} | |
kLv = iterationValue; | |
kLv = kLv.add(kCi); //add k*Ci at the end of iteration | |
} | |
/* ----- Get response time for each task (k) ------ */ | |
final BigDecimal taskStartTime = iPeriod.multiply(BigDecimal.valueOf(smallK - 1)); | |
log.debug("start time " + df.format(taskStartTime) + " - finishing time " + df.format(kLv)); | |
final BigDecimal taskResponseTime = kLv.subtract(taskStartTime); | |
if (taskResponseTime.compareTo(iResponseTime) >= 0) { | |
iResponseTime = taskResponseTime; | |
} | |
log.info(df.format(iResponseTime) + " current RT "); | |
} | |
log.info(df.format(iResponseTime) + " - responseTime of task "); | |
System.out.println(); | |
} | |
} | |
/** | |
* calculate level-i busy period for non-preemptive type | |
* add Blocking time = max blocking time from lower priority taskssssss | |
*/ | |
private void levelIforNonPreemptive() { | |
final Logger log = Logger.getLogger(this.getClass().getName()); | |
final DecimalFormat df = new DecimalFormat("#,###.##"); | |
log.debug("level-i for non-preemptive here"); | |
final int[] exe = { 20, 20, 35 }; | |
final int[] p = { 70, 80, 200 }; | |
//rt = 55 - 75 - 75, | |
for (int i = 0; i < exe.length; i++) { | |
BigDecimal blockingTime = BigDecimal.valueOf(35); | |
if (i == 2) { | |
blockingTime = BigDecimal.ZERO; | |
} | |
log.debug("for task " + i); | |
/* ----- Get LEVEL - I for each task ------ */ | |
BigDecimal lv0 = BigDecimal.ZERO; | |
BigDecimal currentLv = BigDecimal.ONE; | |
final BigDecimal iPeriod = BigDecimal.valueOf(p[i]); | |
final BigDecimal iExe = BigDecimal.valueOf(exe[i]); | |
BigDecimal iResponseTime = BigDecimal.ZERO; | |
//sum of execution time of all tasks with higher prio not including this task (in TU Dortmund say included, they are imbecile ) | |
BigDecimal hpCiSum = BigDecimal.ZERO; | |
int iterationCounterLvI = 0; | |
while (!currentLv.equals(lv0)) { | |
lv0 = currentLv; | |
//entry = each small sum of [Li/Tj]Cj, p_j >= p_i ( i = taskIndex) | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i + 1; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
final BigDecimal roundUp = currentLv.divide(entryPeriod, RoundingMode.CEILING); | |
final BigDecimal entryValue = roundUp.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
} | |
//First entry of level-i = Bi + Ci, the sum above doesn't exist | |
//check non-premptive scheduler from TUDortmund pdf, google that shit | |
if (iterationCounterLvI == 0) { | |
iterationValue = iExe; | |
} | |
iterationCounterLvI++; | |
/* -- Add blocking for nonpreemptive here-- current lv plus blocking*/ | |
iterationValue = iterationValue.add(blockingTime); | |
currentLv = iterationValue; | |
} | |
log.debug("level-" + i + ": " + lv0); | |
/* ----- Get K (total task iteration) ------ */ | |
final int bigK = lv0.divide(iPeriod, RoundingMode.CEILING).intValue(); | |
/** | |
* Things get more complicated from here, we get preemption from higher prio, blocking from lower prio | |
* so we have to calculate the START TIMEEEE with blocking, my man | |
*/ | |
for (int smallK = 1; smallK <= bigK; smallK++) { | |
log.debug(" --- k instance : " + smallK + "/" + bigK + " --------------------------------------------"); | |
BigDecimal kLv = BigDecimal.ZERO; | |
BigDecimal currentKLv = BigDecimal.ONE; | |
final int smallK1 = smallK - 1; | |
final BigDecimal kCi1 = iExe.multiply(BigDecimal.valueOf(smallK1)); | |
//Equation from Tu Dortmund for this is wrong, it's <i, not <=i. | |
for (int entry = 0; entry < i; entry++) { | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
hpCiSum = hpCiSum.add(entryExe); | |
} | |
int iterationCounterK = 0; | |
while (!kLv.equals(currentKLv)) { | |
currentKLv = kLv; | |
//entry = each small sum of [Li/Tj]Cj (rown down), j > i, not >= | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
final BigDecimal roundDown = currentKLv.divide(entryPeriod, RoundingMode.FLOOR); | |
final BigDecimal roundDownPlusOne = roundDown.add(BigDecimal.ONE); | |
final BigDecimal entryValue = roundDownPlusOne.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
} | |
kLv = iterationValue; | |
log.debug(kLv + " + " + kCi1 + " + " + blockingTime); | |
kLv = kLv.add(kCi1); //add k*Ci at the end of iteration | |
//first iteration = Bi + hpCiSum | |
if (iterationCounterK == 0) { | |
log.debug("hpCiSum - " + hpCiSum + " blocking " + blockingTime); | |
kLv = hpCiSum; | |
//reseti this for next task | |
hpCiSum = BigDecimal.ZERO; | |
} | |
kLv = kLv.add(blockingTime); // add blocking time here | |
log.debug(kLv); | |
iterationCounterK++; | |
} | |
/* ----- Get response time for each task (k) ------ */ | |
final BigDecimal taskStartTime = kLv; | |
final BigDecimal taskFinishingTime = taskStartTime.add(iExe); | |
final BigDecimal taskStartPeriod = iPeriod.multiply(BigDecimal.valueOf(smallK1)); | |
log.debug("start time " + df.format(taskStartTime) + " - finishing time " + df.format(taskFinishingTime) + " - period " | |
+ df.format(taskStartPeriod)); | |
final BigDecimal taskResponseTime = taskFinishingTime.subtract(taskStartPeriod); | |
if (taskResponseTime.compareTo(iResponseTime) >= 0) { | |
iResponseTime = taskResponseTime; | |
} | |
log.info(df.format(iResponseTime) + " current RT "); | |
} | |
log.info(df.format(iResponseTime) + " - responseTime of task "); | |
System.out.println(); | |
/* ----- Get finishing time for each task ------ */ | |
} | |
} | |
/* | |
* calculate level-i busy period for mixed preemptive with non-preemptive type | |
* add Blocking time = max blocking time from lower priority taskssssss to level-i for the busy window | |
* add inteference from higher priority task when calculate finishing time (if task is preemptive type) | |
*/ | |
private void levelIforMixedNPandP() { | |
final Logger log = Logger.getLogger(this.getClass().getName()); | |
final DecimalFormat df = new DecimalFormat("#,###.##"); | |
log.debug("level-i for non-preemptive here"); | |
final int[] exe = { 20, 20, 35, 40 }; | |
final int[] p = { 70, 80, 200, 250 }; | |
final int[] pType = { 0, 0, 0, 1 }; | |
// 0 - preemptive, 1 - non-preemptive, 2 - cooperative | |
//rt = 55 - 75 - 75, | |
for (int i = 0; i < exe.length; i++) { | |
BigDecimal blockingTime = BigDecimal.valueOf(40); | |
if (i == 3) { | |
blockingTime = BigDecimal.ZERO; | |
} | |
log.debug("for task " + i + " preemptive type :" + pType[i]); | |
/* ----- Get LEVEL - I for each task ------ */ | |
BigDecimal lv0 = BigDecimal.ZERO; | |
BigDecimal currentLv = BigDecimal.ONE; | |
final BigDecimal iPeriod = BigDecimal.valueOf(p[i]); | |
final BigDecimal iExe = BigDecimal.valueOf(exe[i]); | |
BigDecimal iResponseTime = BigDecimal.ZERO; | |
//sum of execution time of all tasks with higher prio not including this task (in TU Dortmund say included, they are imbecile ) | |
BigDecimal hpCiSum = BigDecimal.ZERO; | |
int iterationCounterLvI = 0; | |
while (!currentLv.equals(lv0)) { | |
lv0 = currentLv; | |
//entry = each small sum of [Li/Tj]Cj, j >= i | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i + 1; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
final BigDecimal roundUp = currentLv.divide(entryPeriod, RoundingMode.CEILING); | |
final BigDecimal entryValue = roundUp.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
} | |
//First entry of level-i = Bi + Ci, the sum above doesn't exist | |
//check non-premptive scheduler from TUDortmund pdf, google that shit | |
if (iterationCounterLvI == 0) { | |
iterationValue = iExe; | |
} | |
iterationCounterLvI++; | |
/* -- Add blocking for nonpreemptive here-- current lv plus blocking*/ | |
iterationValue = iterationValue.add(blockingTime); | |
currentLv = iterationValue; | |
} | |
log.debug("level-" + i + ": " + lv0); | |
/* ----- Get K (total task iteration) ------ */ | |
final int bigK = lv0.divide(iPeriod, RoundingMode.CEILING).intValue(); | |
/** | |
* Things get more complicated from here, we get preemption from higher prio, blocking from lower prio | |
* so we have to calculate the START TIMEEEE with blocking time. | |
*/ | |
for (int smallK = 1; smallK <= bigK; smallK++) { | |
log.debug(" --- k instance : " + smallK + "/" + bigK + " --------------------------------------------"); | |
BigDecimal kTaskStart = BigDecimal.ZERO; | |
BigDecimal currentKLv = BigDecimal.ONE; | |
final int smallK1 = smallK - 1; | |
/*starting time = Bi + sum([Si,Tj]+1)*Cj + (k-1)*Ci | |
calculating (k-1)*Ci here, Bi got from above via looping lower priority task execution time */ | |
final BigDecimal kCi1 = iExe.multiply(BigDecimal.valueOf(smallK1)); | |
//Equation from Tu Dortmund for this is wrong, so stick with mine | |
for (int entry = 0; entry < i; entry++) { | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
hpCiSum = hpCiSum.add(entryExe); | |
} | |
int iterationCounterK = 0; | |
while (!kTaskStart.equals(currentKLv)) { | |
currentKLv = kTaskStart; | |
//entry = each small sum of [Li/Tj]Cj (rown down), j > i, not >= | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
final BigDecimal roundDown = currentKLv.divide(entryPeriod, RoundingMode.FLOOR); | |
final BigDecimal roundDownPlusOne = roundDown.add(BigDecimal.ONE); | |
final BigDecimal entryValue = roundDownPlusOne.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
} | |
kTaskStart = iterationValue; | |
kTaskStart = kTaskStart.add(kCi1); //add k*Ci at the end of iteration | |
//first iteration = Bi + hpCiSum | |
if (iterationCounterK == 0) { | |
log.debug("hpCiSum - " + hpCiSum + " blocking " + blockingTime); | |
kTaskStart = hpCiSum; | |
//reseti this for next task | |
hpCiSum = BigDecimal.ZERO; | |
} | |
kTaskStart = kTaskStart.add(blockingTime); // add blocking time here | |
iterationCounterK++; | |
} | |
/* ----- Get finishing time for each task (k) ------ */ | |
final BigDecimal taskStartTime = kTaskStart; | |
final BigDecimal taskStartPeriod = iPeriod.multiply(BigDecimal.valueOf(smallK1)); | |
BigDecimal taskFinishingTime = BigDecimal.ZERO; | |
final int iPreemptiveType = pType[i]; // 0 - preemptive, 1 - non-preemptive, 2 - cooperative | |
/* if task is non-preemptive then startTime + Ci = finishing time */ | |
if (iPreemptiveType == 1) { | |
taskFinishingTime = taskStartTime.add(iExe); | |
log.debug("start time " + df.format(taskStartTime) + " - finishing time " + df.format(taskFinishingTime) + " - period " | |
+ df.format(taskStartPeriod)); | |
} | |
/* if task is not non-preemptive (coop-preemptive) then | |
* finishingTime = startTime + Ci + hp_task's preemptive time | |
* challenge here is to calculate the preemption from higher priority task*/ | |
else if (iPreemptiveType == 2 || iPreemptiveType == 0) { | |
BigDecimal kTaskFinishingTime = BigDecimal.ONE; | |
BigDecimal currentFinishingTime = BigDecimal.ZERO; | |
while (!kTaskFinishingTime.equals(currentFinishingTime)) { | |
currentFinishingTime = kTaskFinishingTime; | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
final BigDecimal roundUp = currentFinishingTime.divide(entryPeriod, RoundingMode.CEILING); | |
final BigDecimal roundDown = kTaskStart.divide(entryPeriod, RoundingMode.FLOOR); | |
final BigDecimal roundDownPlusOne = roundDown.add(BigDecimal.ONE); | |
final BigDecimal bigSum = roundUp.subtract(roundDownPlusOne); | |
final BigDecimal entryValue = bigSum.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
log.debug("([fi/tj]up - ([si/tj]down + 1)) : " + roundUp + " - " + roundDownPlusOne); | |
log.debug("Sum*Ci= " + entryValue + " = " + bigSum + " x " + entryExe); | |
} | |
log.debug("Finishing time = s + Ci + preemp (Sum*Ci) : " + kTaskStart + " + " + iExe + " + " + iterationValue); | |
iterationValue = iterationValue.add(kTaskStart).add(iExe); | |
kTaskFinishingTime = iterationValue; | |
} | |
taskFinishingTime = kTaskFinishingTime; | |
log.debug("start time " + df.format(taskStartTime) + " - finishing time " + df.format(taskFinishingTime) + " - period " | |
+ df.format(taskStartPeriod)); | |
} | |
/* ----- Get response time for each task (k) ------ */ | |
final BigDecimal taskResponseTime = taskFinishingTime.subtract(taskStartPeriod); | |
if (taskResponseTime.compareTo(iResponseTime) >= 0) { | |
iResponseTime = taskResponseTime; | |
} | |
log.info(df.format(iResponseTime) + " current RT "); | |
} | |
log.info(df.format(iResponseTime) + " - responseTime of task "); | |
System.out.println(); | |
} | |
} | |
/** | |
* calculate level-i busy period for cooperative tasks type. Assume all task is cooperative | |
* | |
* Credit: not me, I just implement his research, the work is from Ignacio. His paper is below | |
* Ignacio Sanudo, Paolo Burgio and Marko Bertogna "Schedulability and Timing Analysis of Mixed Preemptive-Cooperative Tasks on a Partitioned Multi-Core System". | |
*/ | |
private void levelIforCooperative() { | |
//Adding decimal Format for better visual checking when debugging | |
//ie 6000000000 ps -> 6,000,000,000 ps | |
final Logger log = Logger.getLogger(this.getClass().getName()); | |
final DecimalFormat df = new DecimalFormat("#,###.##"); | |
//Exe = execution time, p = period, | |
final int[] exe = { 20, 50, 60, 80 }; | |
final int[] p = { 100, 180, 250, 300 }; | |
//bl = blocking time (time that the task will be blocked by lower priority task) | |
final int[] bl = { 40, 40, 30, 0 }; | |
for (int i = 0; i < exe.length; i++) { | |
/* ----- Get LEVEL - I for each task ------ */ | |
BigDecimal lv0 = BigDecimal.ZERO; | |
BigDecimal currentLv = BigDecimal.ONE; | |
BigDecimal iPeriod = BigDecimal.valueOf(p[i]); | |
BigDecimal iExe = BigDecimal.valueOf(exe[i]); | |
BigDecimal blockingTime = BigDecimal.valueOf(bl[i]); | |
BigDecimal iResponseTime = BigDecimal.ZERO; | |
log.debug("for task " + i); | |
//sum of execution time of all tasks with higher prio not including this task (in TU Dortmund say included, they are imbecile ) | |
BigDecimal hpCiSum = BigDecimal.ZERO; | |
/*------Calculating level-i busy window-----*/ | |
int iterationCounterLvI = 0; | |
while (!currentLv.equals(lv0)) { | |
lv0 = currentLv; | |
//entry = each small sum of [Li/Tj]Cj, p_j >= p_i ( i = taskIndex) | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i + 1; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
BigDecimal roundUp = currentLv.divide(entryPeriod, 0, RoundingMode.CEILING); | |
BigDecimal entryValue = roundUp.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
} | |
//First entry of level-i = Bi + Ci, the sum above doesn't exist (or maybe 1, not gonna risk it hence the code below) | |
//check non-premptive scheduler from TUDortmund pdf, google that shit | |
if (iterationCounterLvI == 0) { | |
iterationValue = iExe; | |
} | |
iterationCounterLvI++; | |
/* -- Add blocking if there is non-preemptive or cooperative in the set ---- | |
* iteration = current lv + blocking*/ | |
iterationValue = iterationValue.add(blockingTime); | |
currentLv = iterationValue; | |
} | |
log.debug("level-" + i + ": " + lv0); | |
/*-----------------------------Level-i finished-----------------*/ | |
/* ----- Get K (total task iteration) ------ */ | |
int bigK = lv0.divide(iPeriod, 0, RoundingMode.CEILING).intValue(); | |
/* --------- get Task finishing time --------- */ | |
/* ----- Get finishing time for each task ------ */ | |
for (int smallK = 1; smallK <= bigK; smallK++) { | |
log.debug(" --- k instance : " + smallK + "/" + bigK + " --------------------------------------------"); | |
BigDecimal kLv = BigDecimal.ZERO; | |
BigDecimal currentKLv = BigDecimal.ONE; | |
int smallK1 = smallK - 1; | |
int counter = 0; | |
BigDecimal kCi = iExe.multiply(BigDecimal.valueOf(smallK)); | |
while (!kLv.equals(currentKLv)) { | |
currentKLv = kLv; | |
//entry = each small sum of [Li/Tj]Cj, p_j > p_i, not >= | |
BigDecimal iterationValue = BigDecimal.ZERO; | |
for (int entry = 0; entry < i; entry++) { | |
final BigDecimal entryPeriod = BigDecimal.valueOf(p[entry]); | |
final BigDecimal entryExe = BigDecimal.valueOf(exe[entry]); | |
BigDecimal roundUp = currentKLv.divide(entryPeriod, 0, RoundingMode.CEILING); | |
BigDecimal entryValue = roundUp.multiply(entryExe); | |
iterationValue = iterationValue.add(entryValue); | |
if (counter == 0) { | |
iterationValue = BigDecimal.ZERO; | |
counter++; | |
break; | |
} | |
} | |
kLv = iterationValue; | |
/*--------------Bi + iteration + (k-1)Ci------------ */ | |
kLv = kLv.add(kCi).add(blockingTime); //add k*Ci at the end of iteration | |
log.debug("finishTime = iterationValue + k*Ci: "); | |
String s1 = df.format(iterationValue); | |
String s2 = df.format(kCi); | |
String s3 = df.format(kLv); | |
String s4 = df.format(blockingTime); | |
log.debug("iteration ,(k-1)Ci, kLv, blocking time"); | |
log.debug(s1 + ", " + s2 + ", " + s3 + ", " + s4); | |
} | |
/* ----- Get response time for each task (k) ------ */ | |
BigDecimal taskStartTime = iPeriod.multiply(BigDecimal.valueOf(smallK1)); | |
String s1 = df.format(taskStartTime); | |
String s2 = df.format(kLv); | |
log.debug("start time (k*period): " + s1 + " - finishing time " + s2); | |
BigDecimal taskResponseTime = kLv.subtract(taskStartTime); | |
String s3 = df.format(taskResponseTime); | |
log.debug(s3 + " - this k instance response time"); | |
if (taskResponseTime.compareTo(iResponseTime) >= 0) { | |
iResponseTime = taskResponseTime; | |
} | |
log.debug(iResponseTime + " - biggest response time so far "); | |
} | |
String s1 = df.format(iResponseTime); | |
log.info(s1 + " task " + i + " response time"); | |
System.out.println(); | |
} | |
} | |
} |