source: rtems/testsuites/tmtests/tm26/task1.c @ e41308ea

5
Last change on this file since e41308ea was e41308ea, checked in by Sebastian Huber <sebastian.huber@…>, on 08/22/16 at 08:58:34

score: Introduce Thread_queue_Lock_context

Introduce Thread_queue_Lock_context to contain the context necessary for
thread queue lock and thread wait lock acquire/release operations to
reduce the Thread_Control size.

  • Property mode set to 100644
File size: 16.3 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2013.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#define CONFIGURE_INIT
15#include <rtems.h>
16#include "system.h"
17#include "fptest.h"
18#include <coverhd.h>
19#include <tmacros.h>
20#include <timesys.h>
21
22#include <rtems/score/schedulerpriorityimpl.h>
23#include <rtems/rtems/semimpl.h>
24
25#if defined( RTEMS_SMP ) && defined( RTEMS_DEBUG )
26  #define PREVENT_SMP_ASSERT_FAILURES
27#endif
28
29const char rtems_test_name[] = "TIME TEST 26";
30
31/* TEST DATA */
32rtems_id Semaphore_id;
33
34Thread_Control *Middle_tcb;   /* uses internal RTEMS type */
35
36Thread_Control *Low_tcb;      /* uses internal RTEMS type */
37
38/*
39 *  Variables to hold execution times until they are printed
40 *  at the end of the test.
41 */
42
43uint32_t   isr_disable_time;
44uint32_t   isr_flash_time;
45uint32_t   isr_enable_time;
46uint32_t   thread_disable_dispatch_time;
47uint32_t   thread_enable_dispatch_time;
48uint32_t   thread_set_state_time;
49uint32_t   thread_dispatch_no_fp_time;
50uint32_t   context_switch_no_fp_time;
51uint32_t   context_switch_self_time;
52uint32_t   context_switch_another_task_time;
53uint32_t   context_switch_restore_1st_fp_time;
54uint32_t   context_switch_save_idle_restore_initted_time;
55uint32_t   context_switch_save_restore_idle_time;
56uint32_t   context_switch_save_restore_initted_time;
57uint32_t   thread_resume_time;
58uint32_t   thread_unblock_time;
59uint32_t   thread_ready_time;
60uint32_t   thread_get_time;
61uint32_t   semaphore_get_time;
62uint32_t   thread_get_invalid_time;
63
64rtems_task null_task(
65  rtems_task_argument argument
66);
67
68rtems_task High_task(
69  rtems_task_argument argument
70);
71
72rtems_task Middle_task(
73  rtems_task_argument argument
74);
75
76rtems_task Low_task(
77  rtems_task_argument argument
78);
79
80rtems_task Floating_point_task_1(
81  rtems_task_argument argument
82);
83
84rtems_task Floating_point_task_2(
85  rtems_task_argument argument
86);
87
88void complete_test( void );
89
90static void set_thread_dispatch_necessary( bool dispatch_necessary )
91{
92#if defined( PREVENT_SMP_ASSERT_FAILURES )
93  ISR_Level level;
94
95  _ISR_Local_disable( level );
96#endif
97
98  _Thread_Dispatch_necessary = dispatch_necessary;
99
100  if ( !dispatch_necessary ) {
101    _Thread_Heir = _Thread_Executing;
102  }
103
104#if defined( PREVENT_SMP_ASSERT_FAILURES )
105  _ISR_Local_enable( level );
106#endif
107}
108
109static void set_thread_heir( Thread_Control *thread )
110{
111#if defined( PREVENT_SMP_ASSERT_FAILURES )
112  ISR_Level level;
113
114  _ISR_Local_disable( level );
115#endif
116
117  _Thread_Heir = thread;
118
119#if defined( PREVENT_SMP_ASSERT_FAILURES )
120  _ISR_Local_enable( level );
121#endif
122}
123
124static void set_thread_executing( Thread_Control *thread )
125{
126#if defined( PREVENT_SMP_ASSERT_FAILURES )
127  ISR_Level level;
128
129  _ISR_Local_disable( level );
130#endif
131
132  _Thread_Executing = thread;
133
134#if defined( PREVENT_SMP_ASSERT_FAILURES )
135  _ISR_Local_enable( level );
136#endif
137}
138
139static void thread_resume( Thread_Control *thread )
140{
141  _Thread_Clear_state( thread, STATES_SUSPENDED );
142}
143
144rtems_task null_task(
145  rtems_task_argument argument
146)
147{
148}
149
150rtems_task Init(
151  rtems_task_argument argument
152)
153{
154  uint32_t    index;
155  rtems_id          task_id;
156  rtems_status_code status;
157
158  Print_Warning();
159
160  TEST_BEGIN();
161
162  if (
163    _Scheduler_Table[ 0 ].Operations.initialize
164      != _Scheduler_priority_Initialize
165  ) {
166    puts("  Error ==> " );
167    puts("Test only supported for deterministic priority scheduler\n" );
168    TEST_END();
169    rtems_test_exit( 0 );
170  }
171
172#define FP1_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 3u)      /* 201, */
173  status = rtems_task_create(
174    rtems_build_name( 'F', 'P', '1', ' ' ),
175    FP1_PRIORITY,
176    RTEMS_MINIMUM_STACK_SIZE,
177    RTEMS_DEFAULT_MODES,
178    RTEMS_FLOATING_POINT,
179    &task_id
180  );
181  directive_failed( status, "rtems_task_create of FP1" );
182
183  status = rtems_task_start( task_id, Floating_point_task_1, 0 );
184  directive_failed( status, "rtems_task_start of FP1" );
185
186#define FP2_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 2u)      /* 202, */
187  status = rtems_task_create(
188    rtems_build_name( 'F', 'P', '2', ' ' ),
189    FP2_PRIORITY,
190    RTEMS_MINIMUM_STACK_SIZE,
191    RTEMS_DEFAULT_MODES,
192    RTEMS_FLOATING_POINT,
193    &task_id
194  );
195  directive_failed( status, "rtems_task_create of FP2" );
196
197  status = rtems_task_start( task_id, Floating_point_task_2, 0 );
198  directive_failed( status, "rtems_task_start of FP2" );
199
200#define LOW_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 4u)   /*  200, */
201  status = rtems_task_create(
202    rtems_build_name( 'L', 'O', 'W', ' ' ),
203    LOW_PRIORITY,
204    RTEMS_MINIMUM_STACK_SIZE,
205    RTEMS_DEFAULT_MODES,
206    RTEMS_DEFAULT_ATTRIBUTES,
207    &task_id
208  );
209  directive_failed( status, "rtems_task_create of LOW" );
210
211  status = rtems_task_start( task_id, Low_task, 0 );
212  directive_failed( status, "rtems_task_start of LOW" );
213
214#define MIDDLE_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 5u)   /*  128, */
215  status = rtems_task_create(
216    rtems_build_name( 'M', 'I', 'D', ' ' ),
217    MIDDLE_PRIORITY,
218    RTEMS_MINIMUM_STACK_SIZE,
219    RTEMS_DEFAULT_MODES,
220    RTEMS_DEFAULT_ATTRIBUTES,
221    &task_id
222  );
223  directive_failed( status, "rtems_task_create of MIDDLE" );
224
225  status = rtems_task_start( task_id, Middle_task, 0 );
226  directive_failed( status, "rtems_task_start of MIDDLE" );
227
228  status = rtems_task_create(
229    rtems_build_name( 'H', 'I', 'G', 'H' ),
230    5,
231    RTEMS_MINIMUM_STACK_SIZE,
232    RTEMS_DEFAULT_MODES,
233    RTEMS_DEFAULT_ATTRIBUTES,
234    &task_id
235  );
236  directive_failed( status, "rtems_task_create of HIGH" );
237
238  status = rtems_task_start( task_id, High_task, 0 );
239  directive_failed( status, "rtems_task_start of HIGH" );
240
241  status = rtems_semaphore_create(
242    rtems_build_name( 'S', 'E', 'M', '1' ),
243    OPERATION_COUNT,
244    RTEMS_DEFAULT_ATTRIBUTES,
245    RTEMS_NO_PRIORITY,
246    &Semaphore_id
247  );
248  directive_failed( status, "rtems_semaphore_create" );
249
250  for ( index = 1 ; index <= OPERATION_COUNT ; index++ ) {
251    status = rtems_task_create(
252      rtems_build_name( 'N', 'U', 'L', 'L' ),
253      RTEMS_MAXIMUM_PRIORITY - 1u,      /* 254, */
254      RTEMS_MINIMUM_STACK_SIZE,
255      RTEMS_DEFAULT_MODES,
256      RTEMS_DEFAULT_ATTRIBUTES,
257      &task_id
258    );
259    directive_failed( status, "rtems_task_create LOOP" );
260
261    status = rtems_task_start( task_id, null_task, 0 );
262    directive_failed( status, "rtems_task_start LOOP" );
263  }
264
265  status = rtems_task_delete( RTEMS_SELF );
266  directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
267}
268
269rtems_task High_task(
270  rtems_task_argument argument
271)
272{
273  rtems_interrupt_level level;
274
275  _Thread_Dispatch_disable();
276
277  benchmark_timer_initialize();
278    rtems_interrupt_local_disable( level );
279  isr_disable_time = benchmark_timer_read();
280
281  benchmark_timer_initialize();
282#if defined(RTEMS_SMP)
283    rtems_interrupt_local_enable( level );
284    rtems_interrupt_local_disable( level );
285#else
286    rtems_interrupt_flash( level );
287#endif
288  isr_flash_time = benchmark_timer_read();
289
290  benchmark_timer_initialize();
291    rtems_interrupt_local_enable( level );
292  isr_enable_time = benchmark_timer_read();
293
294  _Thread_Dispatch_enable( _Per_CPU_Get() );
295
296  benchmark_timer_initialize();
297    _Thread_Dispatch_disable();
298  thread_disable_dispatch_time = benchmark_timer_read();
299
300  benchmark_timer_initialize();
301    _Thread_Dispatch_enable( _Per_CPU_Get() );
302  thread_enable_dispatch_time = benchmark_timer_read();
303
304  benchmark_timer_initialize();
305    _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED );
306  thread_set_state_time = benchmark_timer_read();
307
308  set_thread_dispatch_necessary( true );
309
310  benchmark_timer_initialize();
311    _Thread_Dispatch();           /* dispatches Middle_task */
312}
313
314rtems_task Middle_task(
315  rtems_task_argument argument
316)
317{
318  Scheduler_priority_Context *scheduler_context =
319    _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) );
320
321  thread_dispatch_no_fp_time = benchmark_timer_read();
322
323  _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED );
324
325  Middle_tcb   = _Thread_Get_executing();
326
327  set_thread_executing(
328    (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY])
329  );
330
331  /* do not force context switch */
332
333  set_thread_dispatch_necessary( false );
334
335  _Thread_Dispatch_disable();
336
337  benchmark_timer_initialize();
338    _Context_Switch(
339      &Middle_tcb->Registers,
340      &_Thread_Get_executing()->Registers
341    );
342
343  benchmark_timer_initialize();
344    _Context_Switch(&Middle_tcb->Registers, &Low_tcb->Registers);
345}
346
347rtems_task Low_task(
348  rtems_task_argument argument
349)
350{
351  Scheduler_priority_Context *scheduler_context =
352    _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) );
353  Thread_Control             *executing;
354
355  context_switch_no_fp_time = benchmark_timer_read();
356
357  executing    = _Thread_Get_executing();
358
359  Low_tcb = executing;
360
361  benchmark_timer_initialize();
362    _Context_Switch( &executing->Registers, &executing->Registers );
363
364  context_switch_self_time = benchmark_timer_read();
365
366  _Context_Switch(&executing->Registers, &Middle_tcb->Registers);
367
368  context_switch_another_task_time = benchmark_timer_read();
369
370  set_thread_executing(
371    (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP1_PRIORITY])
372  );
373
374  /* do not force context switch */
375
376  set_thread_dispatch_necessary( false );
377
378  _Thread_Dispatch_disable();
379
380  benchmark_timer_initialize();
381    _Context_Switch(
382      &executing->Registers,
383      &_Thread_Get_executing()->Registers
384    );
385}
386
387rtems_task Floating_point_task_1(
388  rtems_task_argument argument
389)
390{
391  Scheduler_priority_Context *scheduler_context =
392    _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) );
393  Thread_Control             *executing;
394  FP_DECLARE;
395
396  context_switch_restore_1st_fp_time = benchmark_timer_read();
397
398  executing = _Thread_Get_executing();
399
400  set_thread_executing(
401    (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP2_PRIORITY])
402  );
403
404  /* do not force context switch */
405
406  set_thread_dispatch_necessary( false );
407
408  _Thread_Dispatch_disable();
409
410  benchmark_timer_initialize();
411#if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
412    _Context_Save_fp( &executing->fp_context );
413    _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
414#endif
415    _Context_Switch(
416      &executing->Registers,
417      &_Thread_Get_executing()->Registers
418    );
419  /* switch to Floating_point_task_2 */
420
421  context_switch_save_idle_restore_initted_time = benchmark_timer_read();
422
423  FP_LOAD( 1.0 );
424
425  executing = _Thread_Get_executing();
426
427  set_thread_executing(
428    (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP2_PRIORITY])
429  );
430
431  benchmark_timer_initialize();
432#if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
433    _Context_Save_fp( &executing->fp_context );
434    _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
435#endif
436    _Context_Switch(
437      &executing->Registers,
438      &_Thread_Get_executing()->Registers
439    );
440  /* switch to Floating_point_task_2 */
441}
442
443rtems_task Floating_point_task_2(
444  rtems_task_argument argument
445)
446{
447  Scheduler_priority_Context *scheduler_context =
448    _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) );
449  Thread_Control             *executing;
450  FP_DECLARE;
451
452  context_switch_save_restore_idle_time = benchmark_timer_read();
453
454  executing = _Thread_Get_executing();
455
456  set_thread_executing(
457    (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP1_PRIORITY])
458  );
459
460  FP_LOAD( 1.0 );
461
462  benchmark_timer_initialize();
463#if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
464    _Context_Save_fp( &executing->fp_context );
465    _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
466#endif
467    _Context_Switch(
468      &executing->Registers,
469      &_Thread_Get_executing()->Registers
470    );
471  /* switch to Floating_point_task_1 */
472
473  context_switch_save_restore_initted_time = benchmark_timer_read();
474
475  complete_test();
476}
477
478void complete_test( void )
479{
480  uint32_t             index;
481  rtems_id             task_id;
482  ISR_lock_Context     lock_context;
483  Thread_queue_Context queue_context;
484
485  benchmark_timer_initialize();
486    thread_resume( Middle_tcb );
487  thread_resume_time = benchmark_timer_read();
488
489  _Thread_Set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
490
491  benchmark_timer_initialize();
492    _Thread_Unblock( Middle_tcb );
493  thread_unblock_time = benchmark_timer_read();
494
495  _Thread_Set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
496
497  benchmark_timer_initialize();
498    _Thread_Clear_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
499  thread_ready_time = benchmark_timer_read();
500
501  benchmark_timer_initialize();
502    for ( index=1 ; index <= OPERATION_COUNT ; index++ )
503      (void) benchmark_timer_empty_function();
504  overhead = benchmark_timer_read();
505
506  task_id = Middle_tcb->Object.id;
507
508  benchmark_timer_initialize();
509    for ( index=1 ; index <= OPERATION_COUNT ; index++ ) {
510      (void) _Thread_Get( task_id, &lock_context );
511      _ISR_lock_ISR_enable( &lock_context );
512    }
513  thread_get_time = benchmark_timer_read();
514
515  benchmark_timer_initialize();
516    for ( index=1 ; index <= OPERATION_COUNT ; index++ ) {
517      (void) _Semaphore_Get( Semaphore_id, &queue_context );
518      _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
519    }
520  semaphore_get_time = benchmark_timer_read();
521
522  benchmark_timer_initialize();
523    for ( index=1 ; index <= OPERATION_COUNT ; index++ ) {
524      (void) _Thread_Get( 0x3, &lock_context );
525      _ISR_lock_ISR_enable( &lock_context );
526    }
527  thread_get_invalid_time = benchmark_timer_read();
528
529  /*
530   *  This is the running task and we have tricked RTEMS out enough where
531   *  we need to set some internal tracking information to match this.
532   */
533
534  set_thread_heir( _Thread_Get_executing() );
535  set_thread_dispatch_necessary( false );
536
537  /*
538   *  Now dump all the times
539   */
540
541  put_time(
542    "rtems interrupt: _ISR_Local_disable",
543    isr_disable_time,
544    1,
545    0,
546    0
547  );
548
549  put_time(
550    "rtems interrupt: _ISR_Local_flash",
551    isr_flash_time,
552    1,
553    0,
554    0
555  );
556
557  put_time(
558    "rtems interrupt: _ISR_Local_enable",
559    isr_enable_time,
560    1,
561    0,
562    0
563  );
564
565  put_time(
566    "rtems internal: _Thread_Dispatch_disable",
567    thread_disable_dispatch_time,
568    1,
569    0,
570    0
571  );
572
573  put_time(
574    "rtems internal: _Thread_Dispatch_enable",
575    thread_enable_dispatch_time,
576    1,
577    0,
578    0
579  );
580
581  put_time(
582    "rtems internal: _Thread_Set_state",
583    thread_set_state_time,
584    1,
585    0,
586    0
587  );
588
589  put_time(
590    "rtems internal: _Thread_Dispatch NO FP",
591    thread_dispatch_no_fp_time,
592    1,
593    0,
594    0
595  );
596
597  put_time(
598    "rtems internal: context switch: no floating point contexts",
599    context_switch_no_fp_time,
600    1,
601    0,
602    0
603  );
604
605  put_time(
606    "rtems internal: context switch: self",
607    context_switch_self_time,
608    1,
609    0,
610    0
611  );
612
613  put_time(
614    "rtems internal: context switch to another task",
615    context_switch_another_task_time,
616    1,
617    0,
618    0
619  );
620
621#if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
622  put_time(
623    "rtems internal: fp context switch restore 1st FP task",
624    context_switch_restore_1st_fp_time,
625    1,
626    0,
627    0
628  );
629
630  put_time(
631    "rtems internal: fp context switch save idle and restore initialized",
632    context_switch_save_idle_restore_initted_time,
633    1,
634    0,
635    0
636  );
637
638  put_time(
639    "rtems internal: fp context switch save idle, restore idle",
640    context_switch_save_restore_idle_time,
641    1,
642    0,
643    0
644  );
645
646  put_time(
647    "rtems internal: fp context switch save initialized, restore initialized",
648    context_switch_save_restore_initted_time,
649    1,
650    0,
651    0
652  );
653#else
654    puts(
655     "rtems internal: fp context switch restore 1st FP task - NA\n"
656     "rtems internal: fp context switch save idle restore initialized - NA\n"
657     "rtems internal: fp context switch save idle restore idle - NA\n"
658     "rtems internal: fp context switch save initialized\n"
659                      " restore initialized - NA"
660   );
661#endif
662
663  put_time(
664    "rtems internal: _Thread_Resume",
665    thread_resume_time,
666    1,
667    0,
668    0
669  );
670
671  put_time(
672    "rtems internal: _Thread_Unblock",
673    thread_unblock_time,
674    1,
675    0,
676    0
677  );
678
679  put_time(
680    "rtems internal: _Thread_Ready",
681    thread_ready_time,
682    1,
683    0,
684    0
685  );
686
687  put_time(
688    "rtems internal: _Thread_Get",
689    thread_get_time,
690    OPERATION_COUNT,
691    0,
692    0
693  );
694
695  put_time(
696    "rtems internal: _Semaphore_Get",
697    semaphore_get_time,
698    OPERATION_COUNT,
699    0,
700    0
701  );
702
703  put_time(
704    "rtems internal: _Thread_Get: invalid id",
705    thread_get_invalid_time,
706    OPERATION_COUNT,
707    0,
708    0
709  );
710
711  TEST_END();
712  rtems_test_exit( 0 );
713}
Note: See TracBrowser for help on using the repository browser.