source: rtems/testsuites/tmtests/tm26/task1.c @ 6c0301d

4.115
Last change on this file since 6c0301d was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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