source: rtems/testsuites/tmtests/tm27/task1.c @ b331f40

Last change on this file since b331f40 was b331f40, checked in by Joel Sherrill <joel@…>, on 04/01/22 at 19:05:19

testsuites/tmtests/*: Change license to BSD-2

Updates #3053.

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 *  COPYRIGHT (c) 1989-2013.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 *  WARNING!!!!!!!!!
31 *
32 *  THIS TEST USES INTERNAL RTEMS VARIABLES!!!
33 */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#define CONFIGURE_INIT
40#include "system.h"
41
42#include <bsp.h>
43#include <rtems/btimer.h>
44#include <rtems/score/schedulerpriorityimpl.h>
45
46#define _RTEMS_TMTEST27
47#include <tm27.h>
48
49const char rtems_test_name[] = "TIME TEST 27";
50
51rtems_task Task_1(
52  rtems_task_argument argument
53);
54
55rtems_task Task_2(
56  rtems_task_argument argument
57);
58
59volatile uint32_t   Interrupt_occurred;
60volatile uint32_t   Interrupt_enter_time, Interrupt_enter_nested_time;
61volatile uint32_t   Interrupt_return_time, Interrupt_return_nested_time;
62uint32_t   Interrupt_nest;
63uint32_t   timer_overhead;
64
65rtems_isr Isr_handler(
66  rtems_vector_number vector
67);
68
69static void set_thread_executing( Thread_Control *thread )
70{
71  _Per_CPU_Get_snapshot()->executing = thread;
72}
73
74rtems_task Init(
75  rtems_task_argument argument
76)
77{
78  rtems_status_code status;
79
80  Print_Warning();
81
82  TEST_BEGIN();
83
84  if (
85    _Scheduler_Table[ 0 ].Operations.initialize
86      != _Scheduler_priority_Initialize
87  ) {
88    puts("  Error ==> " );
89    puts("Test only supported for deterministic priority scheduler\n" );
90    TEST_END();
91    rtems_test_exit( 0 );
92  }
93
94#define LOW_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 1u)
95  status = rtems_task_create(
96    rtems_build_name( 'T', 'A', '1', ' ' ),
97    LOW_PRIORITY,
98    RTEMS_MINIMUM_STACK_SIZE,
99    RTEMS_DEFAULT_MODES,
100    RTEMS_DEFAULT_ATTRIBUTES,
101    &Task_id[ 1 ]
102  );
103  directive_failed( status, "rtems_task_create Task_1" );
104
105  status = rtems_task_start( Task_id[ 1 ], Task_1, 0 );
106  directive_failed( status, "rtems_task_start Task_1" );
107
108  status = rtems_task_create(
109    rtems_build_name( 'T', 'A', '2', ' ' ),
110    LOW_PRIORITY,
111    RTEMS_MINIMUM_STACK_SIZE,
112    RTEMS_DEFAULT_MODES,
113    RTEMS_DEFAULT_ATTRIBUTES,
114    &Task_id[ 2 ]
115  );
116  directive_failed( status, "rtems_task_create of Task_2" );
117
118  status = rtems_task_start( Task_id[ 2 ], Task_2, 0 );
119  directive_failed( status, "rtems_task_start of Task_2" );
120
121  benchmark_timer_initialize();
122  benchmark_timer_read();
123  benchmark_timer_initialize();
124  timer_overhead = benchmark_timer_read();
125
126  rtems_task_exit();
127}
128
129rtems_task Task_1(
130  rtems_task_argument argument
131)
132{
133  Scheduler_priority_Context *scheduler_context =
134    _Scheduler_priority_Get_context( _Thread_Scheduler_get_home( _Thread_Get_executing() ) );
135#if defined(RTEMS_SMP)
136  rtems_interrupt_level level;
137#endif
138
139  Install_tm27_vector( Isr_handler );
140
141  /*
142   *  No preempt .. no nesting
143   */
144
145  Interrupt_nest = 0;
146
147  Interrupt_occurred = 0;
148
149  benchmark_timer_initialize();
150  Cause_tm27_intr();
151  /* goes to Isr_handler */
152
153#if (MUST_WAIT_FOR_INTERRUPT == 1)
154  while ( Interrupt_occurred == 0 );
155#endif
156  Interrupt_return_time = benchmark_timer_read();
157
158  put_time(
159    "rtems interrupt: entry overhead returns to interrupted task",
160    Interrupt_enter_time,
161    1,
162    0,
163    timer_overhead
164  );
165
166  put_time(
167    "rtems interrupt: exit overhead returns to interrupted task",
168    Interrupt_return_time,
169    1,
170    0,
171    timer_overhead
172  );
173
174  /*
175   *  No preempt .. nested
176   */
177
178  _Thread_Dispatch_disable();
179
180  Interrupt_nest = 1;
181
182  Interrupt_occurred = 0;
183  benchmark_timer_initialize();
184  Cause_tm27_intr();
185  /* goes to Isr_handler */
186
187#if (MUST_WAIT_FOR_INTERRUPT == 1)
188  while ( Interrupt_occurred == 0 );
189#endif
190  Interrupt_return_time = benchmark_timer_read();
191
192  _Thread_Dispatch_enable( _Per_CPU_Get() );
193
194  put_time(
195    "rtems interrupt: entry overhead returns to nested interrupt",
196    Interrupt_enter_nested_time,
197    1,
198    0,
199    0
200  );
201
202  put_time(
203    "rtems interrupt: exit overhead returns to nested interrupt",
204    Interrupt_return_nested_time,
205    1,
206    0,
207    0
208  );
209
210  /*
211   *  Does a preempt .. not nested
212   */
213
214#if defined(RTEMS_SMP)
215  _ISR_Local_disable(level);
216#endif
217
218  set_thread_executing(
219    (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY])
220  );
221
222  _Thread_Dispatch_necessary = 1;
223
224#if defined(RTEMS_SMP)
225  _ISR_Local_enable(level);
226#endif
227
228  Interrupt_occurred = 0;
229  benchmark_timer_initialize();
230  Cause_tm27_intr();
231
232  /*
233   *  goes to Isr_handler and then returns
234   */
235
236  TEST_END();
237  rtems_test_exit( 0 );
238}
239
240/*
241 *  NOTE:  When this task is executing, some of the assumptions made
242 *         regarding the placement of the currently executing task's TCB
243 *         on the ready chains have been violated.  At least the assumption
244 *         that this task is at the head of the chain for its priority
245 *         has been violated.
246 */
247
248rtems_task Task_2(
249  rtems_task_argument argument
250)
251{
252  Thread_Control *executing = _Thread_Get_executing();
253  const Scheduler_Control    *scheduler;
254  Scheduler_priority_Context *scheduler_context;
255  ISR_lock_Context state_lock_context;
256  ISR_lock_Context scheduler_lock_context;
257
258  _Thread_State_acquire( executing, &state_lock_context );
259  scheduler = _Thread_Scheduler_get_home( executing );
260  scheduler_context = _Scheduler_priority_Get_context( scheduler );
261  _Thread_State_release( executing, &state_lock_context );
262
263#if (MUST_WAIT_FOR_INTERRUPT == 1)
264  while ( Interrupt_occurred == 0 );
265#endif
266  end_time = benchmark_timer_read();
267
268  put_time(
269    "rtems interrupt: entry overhead returns to preempting task",
270    Interrupt_enter_time,
271    1,
272    0,
273    timer_overhead
274  );
275
276  put_time(
277    "rtems interrupt: exit overhead returns to preempting task",
278    end_time,
279    1,
280    0,
281    0
282  );
283
284  fflush( stdout );
285
286  /*
287   *  Switch back to the other task to exit the test.
288   */
289
290  _Thread_State_acquire( executing, &state_lock_context );
291  _Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
292
293  set_thread_executing(
294    (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY])
295  );
296
297  _Thread_Dispatch_necessary = 1;
298
299  _Scheduler_Release_critical( scheduler, &scheduler_lock_context );
300  _Thread_State_release( executing, &state_lock_context );
301
302  _Thread_Dispatch();
303
304}
305
306/*  The Isr_handler() and Isr_handler_inner() routines are structured
307 *  so that there will be as little entry overhead as possible included
308 *  in the interrupt entry time.
309 */
310
311void Isr_handler_inner( void );
312
313rtems_isr Isr_handler(
314  rtems_vector_number vector
315)
316{
317  end_time = benchmark_timer_read();
318
319  Interrupt_occurred = 1;
320  Isr_handler_inner();
321}
322
323void Isr_handler_inner( void )
324{
325
326  /*enable_tracing();*/
327  Clear_tm27_intr();
328  switch ( Interrupt_nest ) {
329    case 0:
330      Interrupt_enter_time = end_time;
331      break;
332    case 1:
333      Interrupt_enter_time = end_time;
334      Interrupt_nest = 2;
335      Interrupt_occurred = 0;
336      Lower_tm27_intr();
337      benchmark_timer_initialize();
338      Cause_tm27_intr();
339      /* goes to a nested copy of Isr_handler */
340#if (MUST_WAIT_FOR_INTERRUPT == 1)
341       while ( Interrupt_occurred == 0 );
342#endif
343      Interrupt_return_nested_time = benchmark_timer_read();
344      break;
345    case 2:
346      Interrupt_enter_nested_time = end_time;
347      break;
348  }
349
350  benchmark_timer_initialize();
351}
Note: See TracBrowser for help on using the repository browser.