source: rtems/testsuites/tmtests/tm26/task1.c @ 2ead50a

4.11
Last change on this file since 2ead50a was 2ead50a, checked in by bjorn larsson <bjornlarsson@…>, on Mar 21, 2014 at 3:48:01 PM

tmtests: convert to test.h

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