Bug 562792: Add response time level-i function. (part 2)

Change-Id: Ib53667cfbf5911ae079c9426d743f1d7459abb69
Signed-off-by: The Bao Bui <Zerovnb@gmail.com>
diff --git a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/NPandPRTA.java b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/NPandPRTA.java
index e9479b7..d8f26d9 100644
--- a/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/NPandPRTA.java
+++ b/eclipse-tools/responseTime-analyzer/plugins/org.eclipse.app4mc.gsoc_rta/src/org/eclipse/app4mc/gsoc_rta/NPandPRTA.java
@@ -81,8 +81,7 @@
 	}

 

 	/**

-	 * Calculate classic RTA of task using this formula

-	 * Ri = Ci + Sum j among HP(i)[Ri/Tj]*Cj

+	 * Calculate classic RTA of task using this formula  Ri = Ci + Sum j among HP(i)[Ri/Tj]*Cj

 	 * https://www.it.uu.se/edu/course/homepage/realtid/ht10/schedule/Scheduling-periodic.pdf

 	 * @param thisTask

 	 * @param thisIA

@@ -178,6 +177,125 @@
 	}

 

 	/**

+	 * Calculate RT of thisTask using busy window technique (level-i busy period)

+	 * No blocking time is present here. This function is used for just simple preemptive environment case

+	 * @param thisTask

+	 * @param ia

+	 * @param executionCase

+	 * @return Time responseTime

+	 */

+	public Time getResponseTimeViaLvI(Task thisTask, int[] ia, TimeType executionCase) {

+		Time responseTime = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);

+

+		int[] thisIA = ia.clone();

+		CPURta rtaia = new CPURta(this.model);

+		List<Task> groupTaskList = groupTask(thisTask, thisIA);

+		List<Task> sortedTaskList = rtaia.taskSorting(groupTaskList);

+

+

+		/* Check ultilization value here, if ultiValue > 100% then ultiCheck = false*/

+		boolean ultiCheck = getUltilizationCheck(sortedTaskList, thisIA, executionCase);

+		if (!ultiCheck) {

+			//result is 0

+			return responseTime;

+		}

+

+		int taskIndex = sortedTaskList.indexOf(thisTask);

+		Time iPeriodTime = CommonUtils.getStimInTime(thisTask);

+		BigInteger iPeriodInPs = AmaltheaServices.convertToPicoSeconds(iPeriodTime);

+		Time iExecutionTime = getExecutionTime(thisTask, thisIA, executionCase);

+

+		/* ----- Get LEVEL - I for each task ------ */

+		BigDecimal lv0 = BigDecimal.ZERO;

+		BigDecimal currentLv = BigDecimal.ONE;

+

+		BigDecimal iPeriod = new BigDecimal(iPeriodInPs);

+		BigDecimal iExe = new BigDecimal(iExecutionTime.getValue());

+		BigDecimal iResponseTime = BigDecimal.ZERO;

+		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 < taskIndex + 1; entry++) {

+				Task entryTask = sortedTaskList.get(entry);

+				BigInteger entryPeriodInPs = AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(entryTask));

+				BigDecimal entryPeriod = new BigDecimal(entryPeriodInPs);

+				BigDecimal entryExe = new BigDecimal(getExecutionTime(entryTask, thisIA, executionCase).getValue());

+

+				BigDecimal roundUp = currentLv.divide(entryPeriod, 0, RoundingMode.CEILING);

+				BigDecimal entryValue = roundUp.multiply(entryExe);

+				log.debug(df.format(roundUp) + " round up x " + df.format(entryValue) + " entryValue");

+

+				iterationValue = iterationValue.add(entryValue);

+			}

+			currentLv = iterationValue;

+		}

+		log.debug(df.format(lv0) + " ps - level-i ");

+

+		/* ----- Get K (total task iteration) ------ */

+		int bigK = lv0.divide(iPeriod, 0, 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;

+			BigDecimal kCi = iExe.multiply(BigDecimal.valueOf(smallK));

+			int smallK1 = smallK - 1;

+			int counter = 0;

+

+			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 < taskIndex; entry++) {

+					Task entryTask = sortedTaskList.get(entry);

+					BigInteger entryPeriodInPs = AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(entryTask));

+					BigDecimal entryPeriod = new BigDecimal(entryPeriodInPs);

+					BigDecimal entryExe = new BigDecimal(getExecutionTime(entryTask, thisIA, executionCase).getValue());

+

+					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;

+				kLv = kLv.add(kCi); //add k*Ci at the end of iteration

+				log.debug("finishTime = iterationValue + k*Ci: ");

+				log.debug(df.format(iterationValue) + " + " + df.format(kCi) + " = " + df.format(kLv));

+			}

+			/* ----- Get response time for each task (k) ------ */

+			BigDecimal taskStartTime = iPeriod.multiply(BigDecimal.valueOf(smallK1));

+			log.debug("start time (k*period): " + df.format(taskStartTime) + " - finishing time " + df.format(kLv));

+			BigDecimal taskResponseTime = kLv.subtract(taskStartTime);

+			log.debug(df.format(taskResponseTime) + " - this k instance response time");

+			if (taskResponseTime.compareTo(iResponseTime) >= 0) {

+				iResponseTime = taskResponseTime;

+			}

+			log.info(df.format(iResponseTime) + " - biggest response time so far ");

+		}

+		log.info(df.format(iResponseTime) + "  ps - Task [" + thisTask.getName() + "] level-i response time");

+

+		//Check schedulability

+		if (iResponseTime.compareTo(iPeriod) > 0 && this.schedubilityCheck) {

+			log.error("!!! UNSCHEDULABLE !!!");

+			log.error("Response time of task [" + thisTask.getName() + "] is bigger than its period, return 0 for RT ");

+			log.error(df.format(iResponseTime) + " > " + df.format(iPeriod));

+			//result is 0

+			return responseTime;

+		}

+		//Set response time value after all calculation above

+		responseTime.setValue(iResponseTime.toBigInteger());

+

+		return responseTime;

+

+	}

+	/**

 	 * Calculate task's response time with C-P mixed environment (Cooperative + Preemptive)

 	 * Formula = classic RTA + max_{k of type C and in lp(i)} c_k.

 	 * In easy explaination: classic response time + blocking time caused by lower priority task,