Bug 562792: Add option to disable schedule check, rename function(part1)

Change-Id: I8274ff0740910da0b92ba54ea0e012ff80e334ce
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 4d3dc9d..e9479b7 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
@@ -8,7 +8,7 @@
  *

  * SPDX-License-Identifier: EPL-2.0

  *

- * Contributors:

+ * Contributors: The Bao Bui

  *     FH Dortmund - initial API and implementation

  *******************************************************************************/

 package org.eclipse.app4mc.gsoc_rta;

@@ -39,6 +39,11 @@
 	private final int[] ia;

 	private final Amalthea model;

 	private final int[] preemptionTypeArray;

+	private boolean schedubilityCheck = true;

+	//Adding decimal Format for better visual checking when debugging

+	//ie 6000000000 ps -> 6,000,000,000 ps 

+	private DecimalFormat df = new DecimalFormat("#,###.##");

+	final Logger log = Logger.getLogger(NPandPRTA.class);

 

 	/*

 	 * PreemptionTypeArray will have the same length with mapping indexArray (ia), just with different value

@@ -51,6 +56,23 @@
 	 *	pta = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,} - the preemption type array

 	 *	this mean the first and second task of the model have non-preemption mode, the rest are preemptive

 	 */

+	

+	

+

+	public boolean isSchedubilityCheck() {

+		return schedubilityCheck;

+	}

+

+	/**Default = true.

+	 * 

+	 * True = return result after comparing task's blocking time and period.

+	 * False = return result as long as ultilization value is less than 100 percent.

+	 * @param schedubilityCheck

+	 */

+	public void setSchedubilityCheck(boolean schedubilityCheck) {

+		this.schedubilityCheck = schedubilityCheck;

+	}

+	

 	public NPandPRTA(final Amalthea modelp, final int[] iap) {

 		this.ia = iap;

 		this.model = modelp;

@@ -63,30 +85,34 @@
 	 * 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 ia

+	 * @param thisIA

 	 * @return

 	 */

-	public Time getClassicRTA(Task thisTask, int[] ia, final TimeType executionCase) {

-		//Adding decimal Format for better visual checking when debugging

-		//ie 6000000000 ps -> 6,000,000,000 ps 

-		DecimalFormat df = new DecimalFormat("#,###.##");

-		final Logger log = Logger.getLogger(NPandPRTA.class);

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

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

 		/*Initialize variable to compare previous and current iteration in the formula*/

 		BigDecimal temp = BigDecimal.valueOf(2.0);

 

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

 		CPURta rtaia = new CPURta(this.model);

-		List<Task> groupTaskList = groupTask(thisTask, ia);

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

+		}

+		

 		int taskIndex = sortedTaskList.indexOf(thisTask);

 		//Loop through all task inside the list (until thisTask)

 		for (int i = 0; i < taskIndex + 1; i++) {

 			//Highest priority -> get executed first all the damn time

 			if (taskIndex == 0) {

 				log.debug(

-						df.format(getExecutionTime(thisTask, ia, executionCase).getValue()) + " ps - Task [" + thisTask.getName() + "] classic response time");

-				return getExecutionTime(thisTask, ia, executionCase);

+						df.format(getExecutionTime(thisTask, thisIA, executionCase).getValue()) + " ps - Task [" + thisTask.getName() + "] recurrence response time");

+				return getExecutionTime(thisTask, thisIA, executionCase);

 			}

 

 			//Calculate rta by looping until the result of the previous and current are the same

@@ -95,7 +121,7 @@
 				/*Set up r_0 for the calculation*/

 				for (int j = 0; j < i + 1; j++) {

 					Task jTask = sortedTaskList.get(j);

-					Time jTaskExecutionTime = getExecutionTime(jTask, ia, executionCase);

+					Time jTaskExecutionTime = getExecutionTime(jTask, thisIA, executionCase);

 					BigDecimal bigDecVal = new BigDecimal(jTaskExecutionTime.getValue());

 					rZero = rZero.add(bigDecVal);

 				}

@@ -114,7 +140,7 @@
 					BigDecimal iteration = BigDecimal.ZERO;

 					for (int k = 0; k < i; k++) {

 						Task kTask = sortedTaskList.get(k);

-						Time kTaskExecutionTime = getExecutionTime(kTask, ia, executionCase);

+						Time kTaskExecutionTime = getExecutionTime(kTask, thisIA, executionCase);

 						Time kTaskPeriod = CommonUtils.getStimInTime(kTask);

 						//Need to change all time value to PS for calculation

 						BigInteger kTaskPeriodInPs = AmaltheaServices.convertToPicoSeconds(kTaskPeriod);

@@ -131,11 +157,11 @@
 					}

 					//Adding Ci after the iteration

 					Task iTask = sortedTaskList.get(i);

-					BigDecimal iTaskExecutionTimeDec = new BigDecimal(getExecutionTime(iTask, ia, executionCase).getValue());

+					BigDecimal iTaskExecutionTimeDec = new BigDecimal(getExecutionTime(iTask, thisIA, executionCase).getValue());

 					currentVal = iteration.add(iTaskExecutionTimeDec);

 				}

 				BigDecimal thisTaskPeriodInBigDec = new BigDecimal(AmaltheaServices.convertToPicoSeconds(CommonUtils.getStimInTime(thisTask)));

-				if (currentVal.compareTo(thisTaskPeriodInBigDec) > 0) {

+				if (currentVal.compareTo(thisTaskPeriodInBigDec) > 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(currentVal) + " > " + df.format(thisTaskPeriodInBigDec));

@@ -169,7 +195,7 @@
 		EList<Task> listTask = this.model.getSwModel().getTasks();

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

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

-		Time taskClassicRTA = getClassicRTA(thisTask, ia, executionCase);

+		Time taskClassicRTA = getResponseTimeViaRecurrenceRelation(thisTask, ia, executionCase);

 		CPURta rtaia = new CPURta(this.model);

 

 		List<Task> sortedTaskList = rtaia.taskSorting(groupTask(thisTask, ia));

@@ -293,7 +319,7 @@
 		EList<Task> listTask = this.model.getSwModel().getTasks();

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

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

-		Time taskClassicRTA = getClassicRTA(thisTask, ia, executionCase);

+		Time taskClassicRTA = getResponseTimeViaRecurrenceRelation(thisTask, ia, executionCase);

 		CPURta rtaia = new CPURta(this.model);

 

 		List<Task> sortedTaskList = rtaia.taskSorting(groupTask(thisTask, ia));

@@ -381,7 +407,7 @@
 		Time result = FactoryUtil.createTime(BigInteger.ZERO, TimeUnit.PS);

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

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

-		Time taskClassicRTA = getClassicRTA(thisTask, ia, executionCase);

+		Time taskClassicRTA = getResponseTimeViaRecurrenceRelation(thisTask, ia, executionCase);

 		CPURta rtaia = new CPURta(this.model);

 

 		List<Task> sortedTaskList = rtaia.taskSorting(groupTask(thisTask, ia));

@@ -531,6 +557,41 @@
 		 */

 		return result;

 	}

+	

+	/**

+	 * Get core ultilization percentage by Sum all [Ci/Ti] (i = tasks in the same core)

+	 * return false If [Ci/Ti] > 1 or ulti percentage > 100% 

+	 * groupTask = List<Task> that in the same core

+	 * @param groupTask

+	 * @param ia

+	 * @param executionCase

+	 * @return

+	 */

+

+	public boolean getUltilizationCheck(List<Task> groupTask, int[] ia, TimeType executionCase) {

+		boolean checkValue = true;

+		BigDecimal ultiValue = BigDecimal.ZERO;

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

+		for (Task task : groupTask) {

+			Time taskPeriod = CommonUtils.getStimInTime(task);

+			Time taskExe = getExecutionTime(task, thisIA, executionCase);

+			BigDecimal numerator = new BigDecimal(taskExe.getValue());

+			BigDecimal denominator = new BigDecimal(AmaltheaServices.convertToPicoSeconds(taskPeriod));

+			//scale = 9 here means 9 digit after the damn commaaaaa, why scale 9? because feng shui my dude.

+			BigDecimal division = numerator.divide(denominator, 9, RoundingMode.HALF_UP);

+			ultiValue = ultiValue.add(division);

+		}

+		log.debug(ultiValue.multiply(BigDecimal.valueOf(100)) + " % - core ultilization Value ");

+

+		//if ultilization percentage > 100% then core exceed it maximum workable ability, should never happen

+		if (ultiValue.compareTo(BigDecimal.ONE) > 0) {

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

+			log.error("Ultilization value :" + ultiValue.multiply(BigDecimal.valueOf(100)) + " exceed 100% ");

+			checkValue = false;

+		}

+

+		return checkValue;

+	}

 

 	/**

 	 * Initialize preemptive array.