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

4.115
Last change on this file since e1598a6 was e1598a6, checked in by Sebastian Huber <sebastian.huber@…>, on 04/04/14 at 08:56:36

score: Static scheduler configuration

Do not allocate the scheduler control structures from the workspace.
This is a preparation step for configuration of clustered/partitioned
schedulers on SMP.

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