source: rtems/testsuites/sptests/spedfsched04/init.c @ 166a9f67

5
Last change on this file since 166a9f67 was 166a9f67, checked in by Kuan-Hsun Chen <c0066c@…>, on 01/30/17 at 18:34:28

sprmsched01/spedfsched04: Revise

Instead of using the target time and console driver, both tests now use
assertions and rtems_rate_monotonic_get_status() to verify the count of
postponed jobs. The setting of spedfsched04 is slightly changed.

Close #2795.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/**
2 * @brief A heuristic example to demonstrate how the postponed jobs are handled in EDF.
3 *
4 * Given two tasks with implicit deadline under EDF policy.
5 * Task 1 has (400, 500) and task 2 has (450, 550), where (required ticks, period/deadline).
6 * For the simplicity, we only execute the first task three times.
7 * In the original implementation in v4.11, no matter how many periods are
8 * expired, only one job will be released with a shifted deadline assignment.
9 *
10 * In this example, task 2 will be blocked by the second and third jobs
11 * of task 1, so that there are two jobs are postponed.
12 * Due to the domino effects, the following jobs of task 2 will be postponed until Job 9.
13 *
14 * If the overrun handling is correct, the period of task 2 changes back to
15 * normal status at Job 9.
16 * Otherwise, the release time of job 3 is no longer periodic
17 * and there is no more postponed jobs.
18 *
19 */
20
21/*
22 *  COPYRIGHT (c) 2016-2017 Kuan-Hsun Chen.
23 *
24 *  The license and distribution terms for this file may be
25 *  found in the file LICENSE in this distribution or at
26 *  http://www.rtems.com/license/LICENSE.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <rtems/cpuuse.h>
34#include <tmacros.h>
35#include "test_support.h"
36
37const char rtems_test_name[] = "SPEDFSCHED 4";
38
39static const uint32_t Periods[] = { 500, 550 };
40static const uint32_t Iterations[] = { 400, 450 };
41static const rtems_name Task_name[] = {
42  rtems_build_name( 'T', 'A', '1', ' ' ),
43  rtems_build_name( 'T', 'A', '2', ' ' )
44};
45static const rtems_task_priority Prio[3] = { 2, 5 };
46static const uint32_t testnumber = 9; /* stop condition */
47
48static uint32_t tsk_counter[] = { 0, 0 };
49static rtems_id   Task_id[ 2 ];
50
51/**
52 * @brief Task body
53 */
54static rtems_task Task(
55  rtems_task_argument argument
56)
57{
58  rtems_status_code                         status;
59  rtems_id                                  RM_period;
60  rtems_id                                  selfid=rtems_task_self();
61  rtems_rate_monotonic_period_status        period_status;
62  uint32_t                                  flag=0;
63
64  /* create period */
65  status = rtems_rate_monotonic_create( Task_name[ argument ], &RM_period );
66  directive_failed( status, "rtems_rate_monotonic_create" );
67
68  while ( FOREVER ) {
69    status = rtems_rate_monotonic_period( RM_period, Periods[ argument ] );
70
71    /* Do some work */
72    rtems_test_spin_for_ticks( Iterations[ argument ] );
73
74    if( argument == 1 ){
75      if( status == RTEMS_TIMEOUT ){
76        if( flag == 0 ){
77          puts( "First time RTEMS_TIMEOUT" );
78          puts( "Task 2 should have 2 postponed job due to preemption." );
79          rtems_test_assert( period_status.postponed_jobs_count == 2 );
80          flag = 1;
81        }
82      } else if ( flag == 1 && status == RTEMS_SUCCESSFUL ) {
83        puts( "RTEMS_SUCCESSFUL" );
84        puts( "Overrun handling is finished, now Task 2 becomes normal." );
85        rtems_test_assert( period_status.postponed_jobs_count == 0 );
86        flag = 0;
87      }
88
89      /* Check the status */
90      status = rtems_rate_monotonic_get_status( RM_period, &period_status );
91      directive_failed( status, "rate_monotonic_get_status" );
92
93      if( tsk_counter[ argument ] == testnumber ){
94        TEST_END();
95        status = rtems_rate_monotonic_delete( RM_period );
96        directive_failed( status, "rtems_rate_monotonic_delete" );
97        rtems_test_exit( 0 );
98      }
99    }
100
101    tsk_counter[ argument ]+=1;
102    if ( argument == 0 ){
103      if( tsk_counter[ argument ] == 3 ){
104        puts("Task 1 has released 3 jobs and finished.");
105        status = rtems_rate_monotonic_delete( RM_period );
106        directive_failed( status, "rtems_rate_monotonic_delete" );
107        status = rtems_task_delete( selfid );
108        directive_failed( status, "rtems_task_delete" );
109      }
110    }
111  }
112}
113
114static rtems_task Init(
115        rtems_task_argument argument
116)
117{
118  uint32_t     index;
119  rtems_status_code status;
120
121  TEST_BEGIN();
122
123
124  /* Create two tasks */
125  for ( index = 0; index < RTEMS_ARRAY_SIZE(Task_name); ++index ){
126    status = rtems_task_create(
127      Task_name[ index ], Prio[index], RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES,
128      RTEMS_DEFAULT_ATTRIBUTES, &Task_id[ index ]
129    );
130    directive_failed( status, "rtems_task_create loop" );
131  }
132
133  /* After creating the periods for tasks, start to run them sequencially. */
134  for ( index = 0; index < RTEMS_ARRAY_SIZE(Task_name); ++index ){
135    status = rtems_task_start( Task_id[ index ], Task, index);
136    directive_failed( status, "rtems_task_start loop");
137  }
138  status = rtems_task_delete( RTEMS_SELF );
139  directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
140}
141
142#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
143#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
144#define CONFIGURE_MICROSECONDS_PER_TICK     1000
145#define CONFIGURE_MAXIMUM_TASKS             3
146#define CONFIGURE_MAXIMUM_PERIODS           2
147
148#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
149
150#define CONFIGURE_SCHEDULER_EDF
151
152#define CONFIGURE_INITIAL_EXTENSIONS \
153  RTEMS_TEST_INITIAL_EXTENSION
154
155#define CONFIGURE_INIT
156
157#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.