source: rtems/testsuites/sptests/spedfsched04/init.c @ 03e86553

5
Last change on this file since 03e86553 was 03e86553, checked in by Sebastian Huber <sebastian.huber@…>, on 12/05/18 at 07:05:54

tests: Fix rtems_test_spin_until_next_tick()

This bug surfaced due to sporadic failures in sptimecounter02. Adjust
rtems_test_spin_for_ticks() to include the partial tick in the argument
value.

  • Property mode set to 100644
File size: 4.9 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  rtems_test_spin_until_next_tick();
69
70  while ( FOREVER ) {
71    status = rtems_rate_monotonic_period( RM_period, Periods[ argument ] );
72
73    /* Do some work */
74    rtems_test_spin_for_ticks( Iterations[ argument ] );
75
76    if( argument == 1 ){
77      if( status == RTEMS_TIMEOUT ){
78        if( flag == 0 ){
79          puts( "First time RTEMS_TIMEOUT" );
80          puts( "Task 2 should have 2 postponed job due to preemption." );
81          rtems_test_assert( period_status.postponed_jobs_count == 2 );
82          flag = 1;
83        }
84      } else if ( flag == 1 && status == RTEMS_SUCCESSFUL ) {
85        puts( "RTEMS_SUCCESSFUL" );
86        puts( "Overrun handling is finished, now Task 2 becomes normal." );
87        rtems_test_assert( period_status.postponed_jobs_count == 0 );
88        flag = 0;
89      }
90
91      /* Check the status */
92      status = rtems_rate_monotonic_get_status( RM_period, &period_status );
93      directive_failed( status, "rate_monotonic_get_status" );
94
95      if( tsk_counter[ argument ] == testnumber ){
96        TEST_END();
97        status = rtems_rate_monotonic_delete( RM_period );
98        directive_failed( status, "rtems_rate_monotonic_delete" );
99        rtems_test_exit( 0 );
100      }
101    }
102
103    tsk_counter[ argument ]+=1;
104    if ( argument == 0 ){
105      if( tsk_counter[ argument ] == 3 ){
106        puts("Task 1 has released 3 jobs and finished.");
107        status = rtems_rate_monotonic_delete( RM_period );
108        directive_failed( status, "rtems_rate_monotonic_delete" );
109        status = rtems_task_delete( selfid );
110        directive_failed( status, "rtems_task_delete" );
111      }
112    }
113  }
114}
115
116static rtems_task Init(
117        rtems_task_argument argument
118)
119{
120  uint32_t     index;
121  rtems_status_code status;
122
123  TEST_BEGIN();
124
125
126  /* Create two tasks */
127  for ( index = 0; index < RTEMS_ARRAY_SIZE(Task_name); ++index ){
128    status = rtems_task_create(
129      Task_name[ index ], Prio[index], RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES,
130      RTEMS_DEFAULT_ATTRIBUTES, &Task_id[ index ]
131    );
132    directive_failed( status, "rtems_task_create loop" );
133  }
134
135  /* After creating the periods for tasks, start to run them sequencially. */
136  for ( index = 0; index < RTEMS_ARRAY_SIZE(Task_name); ++index ){
137    status = rtems_task_start( Task_id[ index ], Task, index);
138    directive_failed( status, "rtems_task_start loop");
139  }
140  rtems_task_exit();
141}
142
143#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
144#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
145#define CONFIGURE_MICROSECONDS_PER_TICK     1000
146#define CONFIGURE_MAXIMUM_TASKS             3
147#define CONFIGURE_MAXIMUM_PERIODS           2
148
149#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
150
151#define CONFIGURE_SCHEDULER_EDF
152
153#define CONFIGURE_INITIAL_EXTENSIONS \
154  RTEMS_TEST_INITIAL_EXTENSION
155
156#define CONFIGURE_INIT
157
158#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.