source: rtems/c/src/tests/tmtests/tm27/task1.c @ f3dc8e6

Last change on this file since f3dc8e6 was 21766bd6, checked in by Joel Sherrill <joel.sherrill@…>, on 11/08/01 at 14:15:47

2001-11-08 Jiri Gaisler <jiri@…>

This fix is in response to test results reported by Jerry Needell
<jerry.needell@…> for the SPARC/ERC32 and tracked as PR80.

  • erc32/include/bsp.h: TM27 was not running properly because the ERC32 and LEON cannot nest interrupts at the same level. The BSP test support had to be modified to support using two different interrupt sources.
  • tm27/task1.c: Account for overhead in starting and stopping the timer.
  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 *
3 *  COPYRIGHT (c) 1989-1999.
4 *  On-Line Applications Research Corporation (OAR).
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.OARcorp.com/rtems/license.html.
9 *
10 *  $Id$
11 */
12
13/*
14 *  WARNING!!!!!!!!!   
15 *
16 *  THIS TEST USES INTERNAL RTEMS VARIABLES!!!
17 */
18
19#define TEST_INIT
20#define RTEMS_TM27
21#include "system.h"
22
23#include <bsp.h>
24
25rtems_task Task_1(
26  rtems_task_argument argument
27);
28
29rtems_task Task_2(
30  rtems_task_argument argument
31);
32
33volatile rtems_unsigned32 Interrupt_occurred;
34volatile rtems_unsigned32 Interrupt_enter_time, Interrupt_enter_nested_time;
35volatile rtems_unsigned32 Interrupt_return_time, Interrupt_return_nested_time;
36rtems_unsigned32 Interrupt_nest;
37rtems_unsigned32 timer_overhead;
38
39rtems_isr Isr_handler(
40  rtems_vector_number vector
41);
42
43rtems_task Init(
44  rtems_task_argument argument
45)
46{
47  rtems_status_code status;
48
49  Print_Warning();
50
51  puts( "\n\n*** TIME TEST 27 ***" );
52
53  status = rtems_task_create(
54    rtems_build_name( 'T', 'A', '1', ' ' ),
55    254,
56    RTEMS_MINIMUM_STACK_SIZE,
57    RTEMS_DEFAULT_MODES,
58    RTEMS_DEFAULT_ATTRIBUTES,
59    &Task_id[ 1 ]
60  );
61  directive_failed( status, "rtems_task_create Task_1" );
62
63  status = rtems_task_start( Task_id[ 1 ], Task_1, 0 );
64  directive_failed( status, "rtems_task_start Task_1" );
65
66  status = rtems_task_create(
67    rtems_build_name( 'T', 'A', '2', ' ' ),
68    254,
69    RTEMS_MINIMUM_STACK_SIZE,
70    RTEMS_DEFAULT_MODES,
71    RTEMS_DEFAULT_ATTRIBUTES,
72    &Task_id[ 2 ]
73  );
74  directive_failed( status, "rtems_task_create of Task_2" );
75
76  status = rtems_task_start( Task_id[ 2 ], Task_2, 0 );
77  directive_failed( status, "rtems_task_start of Task_2" );
78
79  Timer_initialize();
80  Read_timer();
81  Timer_initialize();
82  timer_overhead = Read_timer();
83
84  status = rtems_task_delete( RTEMS_SELF );
85  directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
86}
87
88rtems_task Task_1(
89  rtems_task_argument argument
90)
91{
92  Install_tm27_vector( Isr_handler );
93
94  /*
95   *  No preempt .. no nesting
96   */
97
98  Interrupt_nest = 0;
99
100  _Thread_Dispatch_disable_level = 0;
101
102  Interrupt_occurred = 0;
103
104  Timer_initialize();
105  Cause_tm27_intr();
106  /* goes to Isr_handler */
107
108#if (MUST_WAIT_FOR_INTERRUPT == 1)
109  while ( Interrupt_occurred == 0 );
110#endif
111  Interrupt_return_time = Read_timer();
112
113  put_time(
114    "interrupt entry overhead: returns to interrupted task",
115    Interrupt_enter_time,
116    1,
117    0,
118    timer_overhead
119  );
120
121  put_time(
122    "interrupt exit overhead: returns to interrupted task",
123    Interrupt_return_time,
124    1,
125    0,
126    timer_overhead
127  );
128
129  /*
130   *  No preempt .. nested
131   */
132
133  _Thread_Dispatch_disable_level = 1;
134
135  Interrupt_nest = 1;
136
137  Interrupt_occurred = 0;
138  Timer_initialize();
139  Cause_tm27_intr();
140  /* goes to Isr_handler */
141
142#if (MUST_WAIT_FOR_INTERRUPT == 1)
143  while ( Interrupt_occurred == 0 );
144#endif
145  Interrupt_return_time = Read_timer();
146
147  put_time(
148    "interrupt entry overhead: returns to nested interrupt",
149    Interrupt_enter_nested_time,
150    1,
151    0,
152    0
153  );
154
155  put_time(
156    "interrupt exit overhead: returns to nested interrupt",
157    Interrupt_return_nested_time,
158    1,
159    0,
160    0
161  );
162
163  /*
164   *  Does a preempt .. not nested
165   */
166
167  _Thread_Dispatch_disable_level = 0;
168
169  _Thread_Heir = (rtems_tcb *) _Thread_Ready_chain[254].last;
170
171  _Context_Switch_necessary = 1;
172
173  Interrupt_occurred = 0;
174  Timer_initialize();
175  Cause_tm27_intr();
176
177  /*
178   *  goes to Isr_handler and then returns
179   */
180
181  puts( "*** END OF TEST 27 ***" );
182  exit( 0 );
183}
184
185/*
186 *  NOTE:  When this task is executing, some of the assumptions made
187 *         regarding the placement of the currently executing task's TCB
188 *         on the ready chains have been violated.  At least the assumption
189 *         that this task is at the head of the chain for its priority
190 *         has been violated.
191 */
192
193rtems_task Task_2(
194  rtems_task_argument argument
195)
196{
197#if (MUST_WAIT_FOR_INTERRUPT == 1)
198  while ( Interrupt_occurred == 0 );
199#endif
200  end_time = Read_timer();
201
202  put_time(
203    "interrupt entry overhead: returns to preempting task",
204    Interrupt_enter_time,
205    1,
206    0,
207    timer_overhead
208  );
209
210  put_time(
211    "interrupt exit overhead: returns to preempting task",
212    end_time,
213    1,
214    0,
215    0
216  );
217
218  fflush( stdout );
219
220  /*
221   *  Switch back to the other task to exit the test.
222   */
223
224  _Thread_Dispatch_disable_level = 0;
225 
226  _Thread_Heir = (rtems_tcb *) _Thread_Ready_chain[254].first;
227 
228  _Context_Switch_necessary = 1;
229
230  _Thread_Dispatch();
231
232}
233
234/*  The Isr_handler() and Isr_handler_inner() routines are structured
235 *  so that there will be as little entry overhead as possible included
236 *  in the interrupt entry time.
237 */
238
239void Isr_handler_inner( void );
240
241rtems_isr Isr_handler(
242  rtems_vector_number vector
243)
244{
245  end_time = Read_timer();
246
247  Interrupt_occurred = 1;
248  Isr_handler_inner();
249}
250
251void Isr_handler_inner( void )
252{
253
254  /*enable_tracing();*/
255  Clear_tm27_intr();
256  switch ( Interrupt_nest ) {
257    case 0:
258      Interrupt_enter_time = end_time;
259      break;
260    case 1:
261      Interrupt_enter_time = end_time;
262      Interrupt_nest = 2;
263      Interrupt_occurred = 0;
264      Lower_tm27_intr();
265      Timer_initialize();
266      Cause_tm27_intr();
267      /* goes to a nested copy of Isr_handler */
268#if (MUST_WAIT_FOR_INTERRUPT == 1)
269       while ( Interrupt_occurred == 0 );
270#endif
271      Interrupt_return_nested_time = Read_timer();
272      break;
273    case 2:
274      Interrupt_enter_nested_time = end_time;
275      break;
276  }
277
278  Timer_initialize();
279}
Note: See TracBrowser for help on using the repository browser.