sptests: EDF scheduler overrun handling

Update #2795.
This commit is contained in:
Kuan-Hsun Chen
2016-12-21 17:42:41 +01:00
committed by Gedare Bloom
parent 86aa124806
commit ad40220f80
8 changed files with 316 additions and 1 deletions

View File

@@ -37,7 +37,7 @@ _SUBDIRS += spfatal29
_SUBDIRS += spmutex01
_SUBDIRS += spextensions01
_SUBDIRS += spsysinit01
_SUBDIRS += sprmsched01
_SUBDIRS += sprmsched01 spedfsched04
if HAS_SMP
else
_SUBDIRS += sp29

View File

@@ -156,6 +156,7 @@ spcoverage/Makefile
spedfsched01/Makefile
spedfsched02/Makefile
spedfsched03/Makefile
spedfsched04/Makefile
sperror01/Makefile
sperror02/Makefile
sperror03/Makefile

View File

@@ -0,0 +1,21 @@
rtems_tests_PROGRAMS = spedfsched04
spedfsched04_SOURCES = init.c tasks.c system.h
dist_rtems_tests_DATA = spedfsched04.scn
dist_rtems_tests_DATA += spedfsched04.doc
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../automake/compile.am
include $(top_srcdir)/../automake/leaf.am
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
LINK_OBJS = $(spedfsched04_OBJECTS)
LINK_LIBS = $(spedfsched04_LDLIBS)
spedfsched04$(EXEEXT): $(spedfsched04_OBJECTS) $(spedfsched04_DEPENDENCIES)
@rm -f spedfsched04$(EXEEXT)
$(make-exe)
include $(top_srcdir)/../automake/local.am

View File

@@ -0,0 +1,70 @@
/**
* @file spedfsched04/init.c
*
* @brief A init task body for spedfsched04 example.
*
*/
/*
* COPYRIGHT (c) 2016 Kuan-Hsun Chen.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define CONFIGURE_INIT
#include "system.h"
#include <rtems/rtems/tasksimpl.h>
#include <rtems/test.h>
#include <rtems/status-checks.h>
const char rtems_test_name[] = "SPEDFSCHED 4 - Overrun Test";
/* Global variables */
rtems_id Task_id[ 2 ]; /* array of task ids */
rtems_name Task_name[ 2 ]; /* array of task names */
uint32_t tick_per_second; /* time reference */
int testnumber = 5; /* stop condition */
rtems_task_priority Prio[ 3 ] = { 0, 2, 5 };
rtems_task Init(
rtems_task_argument argument
)
{
uint32_t index;
TEST_BEGIN();
rtems_status_code status;
tick_per_second = rtems_clock_get_ticks_per_second();
printf( "\nTicks per second in your system: %" PRIu32 "\n", tick_per_second );
Task_name[ 1 ] = rtems_build_name( 'T', 'A', '1', ' ' );
Task_name[ 2 ] = rtems_build_name( 'T', 'A', '2', ' ' );
/* Create two tasks */
for ( index = 1; index <= 2; index++ ){
status = rtems_task_create(
Task_name[ index ], Prio[ index ], RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES, &Task_id[ index ]
);
directive_failed( status, "rtems_task_create loop" );
}
/* After creating the periods for tasks, start to run them sequencially. */
for ( index = 1; index <= 2; index++ ){
status = rtems_task_start( Task_id[ index ], Task, index);
directive_failed( status, "rtems_task_start loop" );
}
status = rtems_task_delete( RTEMS_SELF );
directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
}

View File

@@ -0,0 +1,34 @@
#
# COPYRIGHT (c) 2016 Kuan-Hsun Chen.
#
# The license and distribution terms for this file may be
# found in the file LICENSE in this distribution or at
# http://www.rtems.com/license/LICENSE.
#
This file describes the directives and concepts tested by this test set.
The adopted scheduling here is EDF. For fixed-priority scheduling, the corresponding testing can be found in sprmsched01.
test set name: spedfsched04
directives:
- rtems_rate_monotonic_report_statistics()
- rtems_rate_monotonic_period()
- rtems_rate_monotonic_Postponed_num()
- _Rate_monotonic_Timeout()
- _Rate_monotonic_Renew_deadline()
- _Rate_monotonic_Release_postponedjob()
- _Rate_monotonic_Block_while_expired()
concepts:
- Verify that watchdog deadline is renewed on time without shift via
_Rate_monotonic_Renew_deadline().
- Verify that postponed jobs are released with a correct number via
_Rate_monotonic_Release_postponedjob().
- Verify that rtems_rate_monotonic_report_statistics() reports correct number
of deadline misses.
- Verify that rtems_rate_monotonic_period() and
_Rate_monotonic_Block_while_expired() are operational.

View File

@@ -0,0 +1,24 @@
*** BEGIN OF TEST SPEDFSCHED 4 ***
Ticks per second in your system: 1000
Job 1 Task 1 starts at tick 14.
Job 1 Task 1 ends at tick 4023.
Job 1 Task 2 starts at tick 4025.
Job 2 Task 1 starts at tick 5013.
Job 2 Task 1 ends at tick 9023.
Job 1 Task 2 ends at tick 12045.
System TIMEOUT
Job 2 Task 2 starts at tick 12045.
Job 2 Task 2 ends at tick 16054.
Job 3 Task 2 starts at tick 16054.
Job 3 Task 2 ends at tick 20061.
System SUCCESSFUL
Job 4 Task 2 starts at tick 22025.
Job 4 Task 2 ends at tick 26033.
Job 5 Task 2 starts at tick 28025.
Job 5 Task 2 ends at tick 32033.
Job 6 Task 2 starts at tick 34025.
Job 6 Task 2 ends at tick 38033.
*** END OF TEST SPEDFSCHED 4 ***

View File

@@ -0,0 +1,62 @@
/**
* @file spedfsched04/system.h
*
* @brief spedfsched04 example header
*/
/*
* COPYRIGHT (c) 1989-2007.
* On-Line Applications Research Corporation (OAR).
*
* COPYRIGHT (c) 2016 Kuan-Hsun Chen.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#include <inttypes.h>
#include <rtems.h>
#include <tmacros.h>
/* function prototypes */
rtems_task Init(
rtems_task_argument argument
);
rtems_task Task(
rtems_task_argument argument
);
/*
* Keep the names and IDs in global variables so another task can use them.
*/
extern rtems_id Task_id[ 2 ]; /* array of task ids */
extern rtems_name Task_name[ 2 ]; /* array of task names */
extern uint32_t tick_per_second; /* time reference */
extern int testnumber; /* stop condition */
/* configuration information */
#include <bsp.h> /* for device driver prototypes */
#define CONFIGURE_SCHEDULER_EDF
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
#define CONFIGURE_MICROSECONDS_PER_TICK 1000 // NB: 10 and lower gives system failure for erc32 simulator
#define CONFIGURE_MAXIMUM_TASKS 3
#define CONFIGURE_MAXIMUM_PRIORITY 15
#define CONFIGURE_EXTRA_TASK_STACKS (20 * RTEMS_MINIMUM_STACK_SIZE)
#define CONFIGURE_MAXIMUM_PERIODS 3
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#include <rtems/confdefs.h>
/* end of include file */

View File

@@ -0,0 +1,103 @@
/**
* @file sprmsched04/tasks.c
*
* @brief A heuristic example to demonstrate how the postponed jobs are handled.
*
* Given two tasks with implicit deadline under EDF policy.
* Task 1 has (4, 5) and task 2 has (4, 6), where (execution time, period/deadline).
* For the simplicity, we only execute the first task twice.
* In the original implementation in v4.11, no matter how many periods are
* expired, only one job will be released with a shifted deadline assignment.
*
* In this example, the first job of task 2 will be blocked by the second job
* of task 1, so that there at least one following job is postponed.
* Due to overhead/delay, the second following job will be postponed as well.
*
* If the overrun handling is correct, the period of task 2 changes back to
* normal status at time 22.
* Otherwise, the release time of job 3 is no longer periodic.
*
*/
/*
* COPYRIGHT (c) 2016 Kuan-Hsun Chen.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "system.h"
#include <rtems/score/watchdogimpl.h>
/* CPU usage and Rate monotonic manger statistics */
#include "rtems/cpuuse.h"
#include "rtems/counter.h"
uint32_t Periods[ 3 ] = { 0, 5000, 6000 };
uint32_t Iterations[ 3 ] = { 0, 4000, 4000 };
uint32_t tsk_counter[ 3 ] = { 0, 0, 0 };
/**
* @brief Task body
*/
rtems_task Task(
rtems_task_argument argument
)
{
rtems_status_code status;
rtems_id RM_period;
rtems_id selfid=rtems_task_self();
uint32_t start, end, index, flag = 0;
rtems_counter_ticks t0 = rtems_counter_nanoseconds_to_ticks( 1000000 );
/*create period*/
status = rtems_rate_monotonic_create( argument, &RM_period );
directive_failed( status, "rtems_rate_monotonic_create" );
switch ( argument ) {
case 1:
case 2:
while ( FOREVER ) {
status = rtems_rate_monotonic_period( RM_period, Periods[ argument ]);
if ( flag == 0 && status == RTEMS_TIMEOUT ){
printf( "System TIMEOUT \n" );
flag = 1;
}else if ( flag == 1 && status == RTEMS_SUCCESSFUL ){
printf( "System SUCCESSFUL \n" );
flag = 0;
}
start = rtems_clock_get_ticks_since_boot();
printf( "Job %d Task %d starts at tick %d.\n", tsk_counter[ argument ]+1, argument, start );
for( index = 0; index < Iterations[ argument ]; index++ ){
rtems_counter_delay_ticks( t0 );
}
end = rtems_clock_get_ticks_since_boot();
printf( " Job %d Task %d ends at tick %d.\n", tsk_counter[ argument ]+1, argument, end );
if( argument == 2 ){
if( tsk_counter[ argument ] == testnumber ){
TEST_END();
status = rtems_rate_monotonic_delete( RM_period );
directive_failed( status, "rtems_rate_monotonic_delete" );
rtems_test_exit( 0 );
}
}
tsk_counter[ argument ]+=1;
if ( argument == 1 ){
if( tsk_counter[ argument ] == 2 ){
status = rtems_rate_monotonic_delete( RM_period );
directive_failed( status, "rtems_rate_monotonic_delete" );
status = rtems_task_delete( selfid );
directive_failed( status, "rtems_task_delete" );
}
}
}
break;
}
}