blob: 2422d55fa59f870cc64fbc6d62cc575e33db13ec [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2019 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v2.0 //
// which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_Scheduler_Test_Functions
//
// Purpose:
// This module provides definitions for testing EPTF_CLL_Scheduler
//
// Module depends on:
// -
//
// Current Owner:
// Attila Jenö Balaskó (ETHBAAT)
//
// Last Review Date:
// -
//
// Detailed Comments:
// Provide definitions to test
//
//
///////////////////////////////////////////////////////////////
module EPTF_Scheduler_Test_Functions {
//import from EPTF_CLL_FBQScheduler_Definitions all;
//import from EPTF_CLL_FBQScheduler_Functions all;
// to use Red-black tree scheduler, comment the FBQ lines and uncomment these lines:
//import from EPTF_CLL_RBTScheduler_Definitions all;
import from EPTF_CLL_RBTScheduler_Functions all;
import from EPTF_CLL_Scheduler_Definitions all;
import from EPTF_Scheduler_Test_Definitions all;
import from EPTF_CLL_Common_Definitions all;
import from EPTF_CLL_Base_Functions all;
//============================================================
// Name: Group DemoFunctions
// Purpose: Functions created for tc_EPTF_Scheduler_Test_demo
//============================================================
group DemoFunctions {
// eventid: [0] : type (0,1)
// if eventId[0] == 0 (event 0): eventId[1]: number of execution times
// if eventId[0] == 1 (event 1): eventId[1]: number of execution times
// Event0: logs periodically how many times it is executed from start.
// event1: if event0 is executing stops it, if not starts it.
// handles my scheduler events
function f_myEventHandler(in EPTF_ScheduledAction pl_action, in integer pl_eventIndex) runs on EPTF_Scheduler_Test_CT return boolean {
if (pl_action.actionId[0] == 0) {
f_handleEvent0(pl_action.when,pl_action.actionId[1]);
return true;
} else if(pl_action.actionId[0] == 1) {
f_handleEvent1(pl_action.when,pl_action.actionId[1]);
return true;
} else if( pl_action.actionId[0] == 2) {
f_EPTF_Scheduler_Test_handleEvent2ListElement(pl_action.when, pl_action.actionId[1],pl_eventIndex);
return true;
}
return false;
}
//initialises my component
function f_EPTF_Scheduler_Test_init_CT() runs on EPTF_Scheduler_Test_CT {
f_EPTF_Scheduler_init_CT("SchedulerTest");
v_myEventHandler := refers(f_myEventHandler);
}
//////////////////////////
// Event 0 functions
//////////////////////////
// activates event0
function f_startEvent0(in float pl_period, in integer pl_maxExecutionNum) runs on EPTF_Scheduler_Test_CT {
v_event0Data.period := pl_period;
v_event0Data.maxExecutionNum := pl_maxExecutionNum;
f_EPTF_SchedulerComp_refreshSnapshotTime();
f_handleEvent0(f_EPTF_SchedulerComp_snapshotTime(),0);
}
function f_scheduleEvent0(in float pl_when, in integer pl_action) runs on EPTF_Scheduler_Test_CT {
f_EPTF_SchedulerComp_scheduleAction(
pl_when + v_event0Data.period,
v_myEventHandler,
{0,pl_action},
v_event0Data.eventIdx
);
}
function f_handleEvent0(in float pl_when, in integer pl_action) runs on EPTF_Scheduler_Test_CT {
log("Event 0 executed ", pl_action, " times.");
v_event0Data.eventCounter := v_event0Data.eventCounter+1;
log("Event 0 executed ", v_event0Data.eventCounter, " times since start.");
if (pl_action==v_event0Data.maxExecutionNum) {
v_event0Data.eventIdx := -1;
return; // do not schedule more
}
f_scheduleEvent0(pl_when,pl_action+1);
}
function f_stopEvent0() runs on EPTF_Scheduler_Test_CT {
if (v_event0Data.eventIdx==-1) {
return; // already stopped
}
f_EPTF_SchedulerComp_CancelEvent(v_event0Data.eventIdx);
v_event0Data.eventIdx := -1;
log("Event 0 stopped.");
}
//////////////////////////
// Event 1 functions
//////////////////////////
// activates event1
function f_startEvent1(in float pl_delay, in float pl_period, in integer pl_maxExecutionNum) runs on EPTF_Scheduler_Test_CT {
v_event1Data.period := pl_period;
v_event1Data.maxExecutionNum := pl_maxExecutionNum;
f_EPTF_SchedulerComp_refreshSnapshotTime();
f_scheduleEvent1(f_EPTF_SchedulerComp_snapshotTime()+pl_delay,0);
}
function f_scheduleEvent1(in float pl_when, in integer pl_action) runs on EPTF_Scheduler_Test_CT {
f_EPTF_SchedulerComp_scheduleAction(
pl_when + v_event1Data.period,v_myEventHandler,{1,pl_action},
v_event1Data.eventIdx
);
}
function f_handleEvent1(in float pl_when, in integer pl_action) runs on EPTF_Scheduler_Test_CT {
log("Event 1 executed ", pl_action, " times.");
v_event1Data.eventCounter := v_event1Data.eventCounter+1;
log("Event 1 executed ", v_event1Data.eventCounter, " times since start.");
if (pl_action==v_event1Data.maxExecutionNum) {
v_event1Data.eventIdx := -1;
return; // do not schedule more
}
// if event running: stop, else start:
if (v_event0Data.eventIdx != -1 ) {
f_stopEvent0();
} else {
f_startEvent0(v_event0Data.period, v_event0Data.maxExecutionNum);
// increase Event 1 period:
v_event1Data.period := v_event1Data.period * 2.0;
}
f_scheduleEvent1(pl_when,pl_action+1);
}
function f_stopEvent1() runs on EPTF_Scheduler_Test_CT {
if (v_event1Data.eventIdx==-1) {
return; // already stopped
}
f_EPTF_SchedulerComp_CancelEvent(v_event1Data.eventIdx);
v_event1Data.eventIdx := -1;
log("Event 1 stopped.");
}
}//DemoFunctions
group ParallelTestFuncions {
// handles my scheduler events
function f_EPTF_Scheduler_ParallelTest_myEventHandler(in EPTF_ScheduledAction pl_action, in integer pl_eventIndex) runs on EPTF_Scheduler_ParallelTest_CT return boolean {
var float vl_relTime := f_EPTF_Base_getRelTimeInSecs();
var integer pl_eventNo := pl_action.actionId[0];
if (v_tLastEvent < 0.0) { // first event
//action("Event ", pl_eventIndex, " executed at ", vl_relTime);
v_tLastEvent := vl_relTime;
} else {
var float vl_tElapsed := vl_relTime-v_tLastEvent;
v_tLastEvent := vl_relTime;
//action("Event ", pl_eventIndex, " executed at ", vl_relTime, " s (", vl_tElapsed, " s after previous event)");
// fail if absolute time elapsed since last event is >10% larger than the scheduled time difference
if (vl_tElapsed*vl_tElapsed > v_dt*1.1*v_dt*1.1) { // use squares instead of absolute values
setverdict(fail, "Scheduled event was processed too late. Elapsed time since last event: ", vl_tElapsed, "s. Should be: ", v_dt, "s.");
}
}
if (pl_eventNo+1 == v_nEvents) {
v_allEventsProcessed := true;
}
// block for 1.0 second
timer t_wait := 1.0;
t_wait.start;
t_wait.timeout;
return true;
}
//initialize my component
function f_EPTF_Scheduler_ParallelTest_init_CT() runs on EPTF_Scheduler_ParallelTest_CT {
f_EPTF_Scheduler_init_CT("SchedulerParallelTest");
v_tLastEvent := -1.0;
v_allEventsProcessed := false;
}
// schedule the event sequence (the first at initDelay, then one every dt seconds, in total nEvents)
function f_EPTF_Scheduler_ParallelTest_startEvents(in float pl_initDelay, in float pl_dt, in integer pl_nEvents) runs on EPTF_Scheduler_ParallelTest_CT {
v_dt := pl_dt;
v_nEvents := pl_nEvents;
v_testcaseDuration := pl_initDelay + int2float(pl_nEvents)*pl_dt; // note: allows pl_dt extra time for the events
f_EPTF_SchedulerComp_refreshSnapshotTime();
var float vl_tFirstEvent := f_EPTF_SchedulerComp_snapshotTime()+pl_initDelay;
var integer i;
for(i:=0; i<pl_nEvents; i:=i+1) {
f_EPTF_Scheduler_ParallelTest_scheduleEvent(vl_tFirstEvent+int2float(i)*pl_dt,i);
}
}
// schedule one event
function f_EPTF_Scheduler_ParallelTest_scheduleEvent(in float pl_when, in integer pl_action) runs on EPTF_Scheduler_ParallelTest_CT {
var integer vl_eventIdx;
f_EPTF_SchedulerComp_scheduleAction(
pl_when,
refers(f_EPTF_Scheduler_ParallelTest_myEventHandler),
{pl_action},
vl_eventIdx
);
//action("Event ", vl_eventIdx, " scheduled to ", pl_when);
}
}//group ParallelTestFunctions
//******************** General Functions **************************************
////////////////////////////////////////////////////
//Function: f_EPTF_Scheduler_Test_ScheduleEvent2ListElement
//
//Purpose:
// Schedules an event of the v_event2DataList
//
//Parameters:
// - pl_when - *in* *float* - timestamp when the event should be generated
// - pl_index - *in* *integer* - index in v_event2DataList
//
//Return value:
// -
//Errors:
//
//Detailed comments:
//
////////////////////////////////////////////////////
function f_EPTF_Scheduler_Test_ScheduleEvent2ListElement(in float pl_when, in integer pl_index)
runs on EPTF_Scheduler_Test_CT {
//if(tsp_EPTF_Scheduler_Test_debug){ log(">>>Init index ",pl_index);}
f_EPTF_SchedulerComp_scheduleAction( pl_when,v_myEventHandler, {2,pl_index},v_event2DataList[pl_index].eventIdx);
}
////////////////////////////////////////////////////
//Function: f_EPTF_Scheduler_Test_handleEvent2ListElement
//
//Purpose:
// This function will be executed when event of type event2 occures
//
//Parameters:
// - pl_when *in* *float* - the timestamp of the event under procession. Not used.
// - pl_listIndex *in* *integer* - the index of the event in the list of types event2
// - pl_eventIndex *in* *integer* - the index of the event in the event queue of the Scheduler. Not used.
//
//Return value:
// *boolean* - true if the get was successful
//
//Errors: -
//
//Detailed comments: It counts the occurance of an event2, cancel it in the Sch Database (i.e removes it),
// cancel it in the component database, i. e in v_event2DataList
//
////////////////////////////////////////////////////
function f_EPTF_Scheduler_Test_handleEvent2ListElement(in float pl_when, in integer pl_listIndex, in integer pl_eventIndex)
runs on EPTF_Scheduler_Test_CT {
v_eventCounter:=v_eventCounter+1;
if(v_eventCounter==1) { v_firstEventExecTime:=f_EPTF_Base_getRelTimeInSecs(); }
v_lastEventExecTime:= f_EPTF_Base_getRelTimeInSecs();
if((v_eventCounter==v_maxExecutionNum) or (v_eventCounter mod 10==0)) {
v_lastEventExecTime:= f_EPTF_Base_getRelTimeInSecs();
}
if(tsp_EPTF_Scheduler_Test_debug) {
log(">>>Event ",
"\n scheduled at ", pl_when, " listIndex: ",pl_listIndex, " event index :",pl_eventIndex,
"\n generated at ", f_EPTF_SchedulerComp_snapshotTime(),
"\n counter: ", v_eventCounter)
}
//cancel event:
if( v_event2DataList[pl_listIndex].eventIdx != -1) {
v_event2DataList[pl_listIndex].eventIdx := -1;
}
}
////////////////////////////////////////////////////
//Function: f_EPTF_Scheduler_Test_StartEvent2List
//
//Purpose:
// Initializes the list, schedules all elements in incremental order with a given timegap
//
//Parameters:
// - pl_noOfEvents - *in* *integer* - number of elements/events
// - pl_eventGap - *inout* *float* - time between two event
// - pl_delayBetweenSchAndGen: - *in* *float* -the difference between the time of the first writing (=scheduling) and the least timestamp of events scheduled
// - pl_mode - *in* <WritingMode> - incr, decr or rand
// - pl_eventGap - *inout* *float* - time between two event
//
//Return value:
// *boolean* - true if the get was successful
//
//Errors:
//
//Detailed comments:
//
////////////////////////////////////////////////////
function f_EPTF_Scheduler_Test_StartEvent2List(
in integer pl_noOfEvents, in float pl_eventGap, in float pl_delayBetweenSchAndGen, in WritingMode pl_mode)
runs on EPTF_Scheduler_Test_CT
{
v_eventCounter:= 0;
v_maxExecutionNum:= pl_noOfEvents;
v_firstEventExecTime:=0.0;
v_lastEventExecTime :=0.0;
//init the list:
v_event2DataList := {}
for(var integer i:=0; i<pl_noOfEvents; i:=i+1) {
v_event2DataList[i].eventIdx:= -1;
}//for
f_EPTF_SchedulerComp_initEventQueue(); // empties the q but not restart the sch clock and the does not redefine the default altstep.
v_firstEventExecTime:=f_EPTF_Base_getRelTimeInSecs(); //Measuring clock Clock starts
//schedule:
f_EPTF_SchedulerComp_refreshSnapshotTime();
var float vl_actTimeStamp := f_EPTF_SchedulerComp_snapshotTime()+pl_delayBetweenSchAndGen;
select(pl_mode) {
case(incr) {
for(var integer i:=0; i<pl_noOfEvents; i:=i+1) {
f_EPTF_Scheduler_Test_ScheduleEvent2ListElement(vl_actTimeStamp,i)
vl_actTimeStamp:= vl_actTimeStamp+pl_eventGap;
}
}
case(decr) {
vl_actTimeStamp:= vl_actTimeStamp+int2float(pl_noOfEvents)*pl_eventGap;
for(var integer i:=0; i<pl_noOfEvents; i:=i+1) {
f_EPTF_Scheduler_Test_ScheduleEvent2ListElement(vl_actTimeStamp,i)
vl_actTimeStamp:= vl_actTimeStamp-pl_eventGap;
}
}
case(rand) {
var float vl_interval:=int2float(pl_noOfEvents)*pl_eventGap;
//log("Time Interval:",vl_interval);
var float vl_actTimeStamp0:=vl_actTimeStamp;
for(var integer i:=0; i<pl_noOfEvents; i:=i+1) {
f_EPTF_Scheduler_Test_ScheduleEvent2ListElement(vl_actTimeStamp,i)
vl_actTimeStamp:= vl_actTimeStamp0+rnd()*vl_interval;
}
}
}//select
v_lastEventExecTime:=f_EPTF_Base_getRelTimeInSecs();
//log("Scheduler init ready");
}
////////////////////////////////////////////////////
//Function: f_EPTF_Scheduler_Test_StartAndGenerateEvent2List
//
//Purpose:
// Initializes the list, schedules all elements in increasing, decreasing or random order with a given timegap,
// (only once) executes these events and returns the results
//
//Parameters:
// - pl_noOfEvents - *in* *integer* - number of elements/events
// - pl_eventGap - *inout* *float* - time between two event
// - pl_delayBetweenSchAndGen: - *in* *float* -the difference between the time of the first writing (=scheduling) and the least timestamp of events scheduled
// - pl_mode - *in* <WritingMode> - incr, decr or rand
//
//Return value: <EPTF_FloatList> - the total execution time of writing and reading
//Errors: -
//
//Detailed comments:-
//
//Precondition: f_EPTF_Scheduler_Test_init_CT executed,
////////////////////////////////////////////////////
function f_EPTF_Scheduler_Test_StartAndGenerateEvent2List(
in integer pl_noOfEvents,
in float pl_eventGap,
in float pl_delayBetweenSchAndGen,
in WritingMode pl_mode)
runs on EPTF_Scheduler_Test_CT
return EPTF_FloatList
{
var float vl_necessaryTime := int2float(pl_noOfEvents)*pl_eventGap+1.0;
var float vl_wrTime:=0.0, vl_readingTime:=0.0
f_EPTF_Scheduler_Test_StartEvent2List( pl_noOfEvents, pl_eventGap, pl_delayBetweenSchAndGen, pl_mode);
vl_wrTime:=v_lastEventExecTime-v_firstEventExecTime;
if(vl_necessaryTime<tsp_executionTime) { vl_necessaryTime:=tsp_executionTime }
timer t_wait := vl_necessaryTime;
//===Generates events====
v_lastEventExecTime:=0.0;
v_firstEventExecTime:=0.0;
t_wait.start;
alt {
[] t_wait.timeout {}
}
vl_readingTime:= v_lastEventExecTime-v_firstEventExecTime;
return {vl_wrTime, vl_readingTime}
}
////////////////////////////////////////////////////
//Function: f_EPTF_Scheduler_Test_WriteReadHandleEvents_fixedTimes
//
//Purpose: Measures writing and reading times for different number of elements
//
//Parameters:
// - pl_repeatNo - *in* *integer* - number of repetition
// - pl_noOfEvents - *in* *integer* - number of elements/events
// - pl_eventGap - *inout* *float* - time between two event
// - pl_delayBetweenSchAndGen: - *in* *float* -the difference between the time of the first writing (=scheduling) and the least timestamp of events scheduled
// - pl_mode - *in* <WritingMode> - incr, decr or rand
//
//Return value: *verdicttype* - pass if all
//Errors:
//
//Detailed comments:
// 1.Repeats these steps pl_repeatNo times for different number of elements:
// Initializes the list, schedules all elements in increasing, decreasing or random timestamp with a given timegap,
// executes these events.
// 2.Then logs the execution time statistics, i.e.
// - the number of elements
// - the averaged total elapsed writing time (for each number of elements),
// - the averaged total elapsed writing time divided by the number of elements
// - the averaged total elapsed reading time (for each number of elements),
// - the averaged total elapsed reading time divided by the number of elements
//
//Precondition: f_EPTF_Scheduler_Test_init_CT executed,
////////////////////////////////////////////////////
function f_EPTF_Scheduler_Test_WriteReadHandleEvents_fixedTimes(
in integer pl_repeatNo,
in integer pl_noOfEvents,
in float pl_eventGap,
in float pl_delayBetweenSchAndGen,
in WritingMode pl_mode)
runs on EPTF_Scheduler_Test_CT
return verdicttype
{
var verdicttype vl_verdict:=pass;
var float vl_execTime :=0.0;
var EPTF_FloatList vl_execTimes :={}
var float vl_wrTime:=0.0, vl_readingTime:=0.0;
f_EPTF_Scheduler_Test_init_CT();
var integer vl_repeatNo:=pl_repeatNo;
if(pl_noOfEvents>10000) { //Too big numbers should be measured only once
vl_repeatNo:=1;
}
for(var integer vl_n:=0;vl_n< vl_repeatNo; vl_n:=vl_n+1) {
//log("Rep:", vl_n);
vl_execTimes:=
f_EPTF_Scheduler_Test_StartAndGenerateEvent2List(pl_noOfEvents , pl_eventGap, pl_delayBetweenSchAndGen, pl_mode);
vl_wrTime:=vl_wrTime+vl_execTimes[0];
vl_readingTime:=vl_readingTime+vl_execTimes[1];
if(v_eventCounter!= pl_noOfEvents) {
log(%definitionId&": v_eventCounter=",v_eventCounter,", pl_noOfEvents=",pl_noOfEvents);
vl_verdict:= fail;
}
}//for
vl_wrTime:=vl_wrTime/int2float(vl_repeatNo);
vl_readingTime:= vl_readingTime/int2float(vl_repeatNo);
vl_execTime:=(vl_wrTime+vl_readingTime)/int2float(pl_noOfEvents);
if(vl_execTime>0.0005) {
log(%definitionId&": vl_execTime=", vl_execTime);
vl_verdict:= fail;
}
log("==>>>Avg times:NrOfEvents/AvgTotalTime/AvgTimePerEvent/AvgReadingTime/AvgReadingTimePerEvent: ",
pl_noOfEvents," ",
vl_wrTime ," ",vl_wrTime/int2float(pl_noOfEvents)," ",
vl_readingTime," ",vl_readingTime/int2float(pl_noOfEvents));
return vl_verdict
}
////////////////////////////////////////////////////
//Function: f_EPTF_Scheduler_Test_WriteReadHandleEvents_Average
//
//Purpose:
// For different sequence of elements: schedules all elements in incremental, decremental or random order with a given timegap,
// and logs the results
//
//Parameters:
// - pl_noOfEvents - *in* *integer* - number of elements in the v_event0List
// - pl_eventGap - *inout* *float* - time between two event
//
//Return value:
// *boolean* - true if the get was successful
//
//Errors:
//
//Detailed comments:
//
//Precondition: f_EPTF_Scheduler_Test_init_CT executed,
function f_EPTF_Scheduler_Test_WriteReadHandleEvents_Average(
in integer pl_repeatNo,
in integer pl_noOfEvents,
in integer pl_deltaNoOfEvents,
in float pl_eventGap,
in float pl_delayBetweenSchAndGen,
in WritingMode pl_mode,
in IncrMode pl_iMode:=lin)
runs on EPTF_Scheduler_Test_CT
return verdicttype
{
var verdicttype vl_verdict:=pass;
if(pl_iMode==lin) {
for(var integer vl_n:= pl_deltaNoOfEvents;vl_n<= pl_noOfEvents; vl_n:=vl_n+pl_deltaNoOfEvents) {
vl_verdict:=f_EPTF_Scheduler_Test_WriteReadHandleEvents_fixedTimes(pl_repeatNo,vl_n,pl_eventGap,pl_delayBetweenSchAndGen,pl_mode)
}
}
else if(pl_iMode==exp) {
for(var integer vl_n:= pl_deltaNoOfEvents ;vl_n<= pl_noOfEvents; vl_n:=vl_n*pl_deltaNoOfEvents) {
vl_verdict:=f_EPTF_Scheduler_Test_WriteReadHandleEvents_fixedTimes(pl_repeatNo,vl_n,pl_eventGap,pl_delayBetweenSchAndGen,pl_mode)
}
}
return vl_verdict;
}//f_
////////////////////////////////////////////////////
//Function: f_EPTF_Scheduler_Test_StartEvent2List_Average
//
//Purpose:
// For different sequence of elements: schedules all elements in incremental, decremental or random order with a given timegap,
// and logs the results
//
//Parameters:
// - pl_noOfEvents - *in* *integer* - number of elements in the v_event0List
// - pl_eventGap - *inout* *float* - time between two event
//
//Return value:
// *boolean* - true if the get was successful
//
//Errors:
//
//Detailed comments:
//
//Precondition: f_EPTF_Scheduler_Test_init_CT executed,
////////////////////////////////////////////////////
function f_EPTF_Scheduler_Test_StartEvent2List_Average(
in integer pl_noOfEvents, in integer pl_deltaNoOfEvents, in float pl_eventGap,
in float pl_delayBetweenSchAndGen, in WritingMode pl_mode, in IncrMode pl_iMode:=lin)
runs on EPTF_Scheduler_Test_CT
return float
{
var EPTF_FloatList vl_avgExecTimes:={}, vl_totalAvgExecTimes:={}
var float vl_t:=0.0;
var integer j:=0, index:=0;
if(pl_iMode==lin) {
for(var integer vl_n:= pl_deltaNoOfEvents;vl_n<= pl_noOfEvents; vl_n:=vl_n+pl_deltaNoOfEvents) {
vl_avgExecTimes:={};
vl_totalAvgExecTimes[index]:=0.0;
for(j:=0;j<tsp_repeatNo;j:=j+1) {
f_EPTF_Scheduler_Test_StartEvent2List( vl_n , pl_eventGap, pl_delayBetweenSchAndGen, pl_mode);
vl_avgExecTimes[j]:=(v_lastEventExecTime-v_firstEventExecTime); //int2float(vl_n);
vl_totalAvgExecTimes[index]:=vl_totalAvgExecTimes[index]+vl_avgExecTimes[j];
}//j
vl_totalAvgExecTimes[index] := vl_totalAvgExecTimes[index] / int2float(tsp_repeatNo);
vl_t:=vl_totalAvgExecTimes[index]/int2float(vl_n);
log(">>>Scheduler writing speed: NrOfEvents/Elapsed time/Time/TimePerNr: ",
vl_n," ",vl_totalAvgExecTimes[index]," ", vl_t);
vl_totalAvgExecTimes[index]:=vl_t;
index:=index+1;
}//vl_n
} else if(pl_iMode==exp) {
for(var integer vl_n:= pl_deltaNoOfEvents;vl_n<= pl_noOfEvents; vl_n:=vl_n*pl_deltaNoOfEvents) {
vl_avgExecTimes:={};
vl_totalAvgExecTimes[index]:=0.0;
for(j:=0;j<tsp_repeatNo;j:=j+1) {
f_EPTF_Scheduler_Test_StartEvent2List( vl_n , pl_eventGap, pl_delayBetweenSchAndGen, pl_mode);
vl_avgExecTimes[j]:=(v_lastEventExecTime-v_firstEventExecTime);
vl_totalAvgExecTimes[index]:=vl_totalAvgExecTimes[index]+vl_avgExecTimes[j];
}//j
vl_totalAvgExecTimes[index]:=vl_totalAvgExecTimes[index]/int2float(tsp_repeatNo);
vl_t:=vl_totalAvgExecTimes[index]/int2float(vl_n);
log(">>>Scheduler writing speed: NrOfEvents/Elapsed time/Time/TimePerNr: ",
vl_n," ",vl_totalAvgExecTimes[index]," ", vl_t);
vl_totalAvgExecTimes[index]:=vl_t;
index:=index+1;
}//vl_n
}
var integer vl_size:=sizeof(vl_totalAvgExecTimes);
var float vl_totalAvgTime:=0.0
log("vl_totalAvgExecTimes :",vl_totalAvgExecTimes);
for(var integer i:=0;i< vl_size;i:=i+1) { vl_totalAvgTime:= vl_totalAvgTime+ vl_totalAvgExecTimes[i]}
return vl_totalAvgTime/int2float(vl_size);
}
group Scheduler_Test_dte_handler {
function f_EPTF_Scheduler_Test_generateDTEActionHandler(
in EPTF_ScheduledAction pl_action, in integer pl_eventIndex) runs on EPTF_Scheduler_Test_CT
return boolean {
v_actualNofSchEvents := v_actualNofSchEvents + 1;
// generate DTE (divison by zero) if pl_action[0] == 1:
if (sizeof(pl_action.actionId)>0 and pl_action.actionId[0]==1) {
var float vl_i:=0.0;
vl_i := 1.0/vl_i;
}
return true;
}
function f_EPTF_Scheduler_Test_dteHandler(
in EPTF_ScheduledAction pl_action, in integer pl_eventIndex, in charstring pl_dte_str) runs on EPTF_Scheduler_Test_CT {
v_eventCounter := v_eventCounter + 1;
action("Executing DTE handler for action ",pl_action," Error: ", pl_dte_str);
// generate DTE (divison by zero) if pl_action[1] == 1:
if (sizeof(pl_action.actionId)>1 and pl_action.actionId[1]==1) {
var float vl_i:=0.0;
vl_i := 1.0/vl_i;
}
}
function f_EPTF_Scheduler_Test_checkWarning_DTE_preamble_FN(in charstring pl_message) runs on EPTF_Scheduler_Test_CT {
if (match(pl_message,pattern "*Dynamic test case error occured during executing scheduled action*")) {
setverdict(pass,"Expected warning received");
}
}
} // group Scheduler_Test_dte_handler
group OverloadDetection {
type component BurnCPU_CT {
private timer t_clock;
private timer t_cpu;
private var float lastEventTime := 0.0;
private var float deltaT := 0.02;
private var integer loadCyclesFor10Percent := 40000;
private var integer loadCycles := 0;
private var float targetLoad := 0.5;
private var default v_default := null
}
type component EPTF_Scheduler_OverloadTest_CT extends EPTF_Scheduler_Test_CT, BurnCPU_CT {
var float v_readLoadPeriod := 10.0;
}
public function f_EPTF_Scheduler_OverloadTest_init(in charstring pl_selfname) runs on EPTF_Scheduler_OverloadTest_CT {
f_EPTF_Scheduler_init_CT(pl_selfname);
//f_EPTF_Scheduler_enableLoadMeasurement(true);
f_BurnCPU_init_CT();
var integer vl_eventId;
f_EPTF_SchedulerComp_scheduleAction(
pl_when := f_EPTF_SchedulerComp_snapshotTime() + 1.0,
pl_actionHandler := refers(f_EPTF_Scheduler_generateOverloadHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
f_EPTF_SchedulerComp_scheduleAction(
pl_when := f_EPTF_SchedulerComp_snapshotTime() + 1.0,
pl_actionHandler := refers(f_EPTF_Scheduler_generateBackgroundEventsHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
f_EPTF_SchedulerComp_scheduleAction(
pl_when := f_EPTF_SchedulerComp_snapshotTime() + 1.0,
pl_actionHandler := refers(f_EPTF_Scheduler_readLoadHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
}
private altstep as_BurnCPU_generateLoad() runs on BurnCPU_CT {
var float currentTime;
var float nextTime;
[] t_cpu.timeout {
// calculate next event time:
currentTime := t_clock.read;
nextTime := lastEventTime+deltaT;
lastEventTime := nextTime;
var float vl_interval := nextTime-currentTime;
if (vl_interval<0.0) {
vl_interval := 0.0;
}
t_cpu.start(vl_interval);
// generate load:
f_BurnCPU_generateLoad();
repeat;
}
}
private function f_BurnCPU_generateLoad() runs on BurnCPU_CT {
// generate load:
var float vl_var;
for(var integer i:=0; i<loadCycles; i:=i+1) {
vl_var := 12.34;
vl_var := vl_var*vl_var; // just do something to generate CPU load
}
}
private function f_BurnCPU_getDeltaT() runs on BurnCPU_CT return float {
return deltaT;
}
private function f_EPTF_Scheduler_generateOverloadHandler(
in EPTF_ScheduledAction pl_action,
in integer pl_eventIndex
) runs on EPTF_Scheduler_OverloadTest_CT return boolean {
f_BurnCPU_generateLoad();
var integer vl_eventId;
f_EPTF_SchedulerComp_scheduleAction(
pl_when := pl_action.when + f_BurnCPU_getDeltaT(),
pl_actionHandler := refers(f_EPTF_Scheduler_generateOverloadHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
return true;
}
private function f_EPTF_Scheduler_generateBackgroundEventsHandler(
in EPTF_ScheduledAction pl_action,
in integer pl_eventIndex
) runs on EPTF_Scheduler_OverloadTest_CT return boolean {
var integer vl_eventId;
f_EPTF_SchedulerComp_scheduleAction(
pl_when := pl_action.when + 0.01,
pl_actionHandler := refers(f_EPTF_Scheduler_generateBackgroundEventsHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
return true;
}
private function f_EPTF_Scheduler_readLoadHandler(
in EPTF_ScheduledAction pl_action,
in integer pl_eventIndex
) runs on EPTF_Scheduler_OverloadTest_CT return boolean {
action("load: ", f_EPTF_Scheduler_getLoad(), " period: ", f_EPTF_Scheduler_getLoadMeasurementInterval());
var integer vl_eventId;
f_EPTF_SchedulerComp_scheduleAction(
pl_when := pl_action.when + v_readLoadPeriod,
pl_actionHandler := refers(f_EPTF_Scheduler_readLoadHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
return true;
}
public function f_BurnCPU_init_CT(
in float pl_deltaT := 0.02,
in integer pl_loadCyclesFor10Percent := 40000,
in float pl_targetLoad := 0.5,
in float pl_startDelay := 1.0
) runs on BurnCPU_CT {
deltaT := pl_deltaT;
loadCyclesFor10Percent := pl_loadCyclesFor10Percent;
targetLoad := pl_targetLoad;
loadCycles := float2int(int2float(loadCyclesFor10Percent)*targetLoad*10.0);
lastEventTime := pl_startDelay;
t_clock.start(1000.0);
t_cpu.start(lastEventTime);
// v_default := activate(as_BurnCPU_generateLoad());
}
// changes deltaT so that load remains the same
public function f_BurnCPU_setDeltaT(
in float pl_deltaT := 0.1
) runs on BurnCPU_CT {
loadCyclesFor10Percent := float2int(int2float(loadCyclesFor10Percent)*pl_deltaT/deltaT);
deltaT := pl_deltaT;
f_BurnCPU_setTargetLoad(targetLoad);
}
// changes load so that deltaT remains the same
public function f_BurnCPU_setTargetLoad(
in float pl_targetLoad
) runs on BurnCPU_CT {
targetLoad := pl_targetLoad;
loadCycles := float2int(int2float(loadCyclesFor10Percent)*targetLoad*10.0);
}
} // group OverloadDetection
}//module