| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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 |