File indexing completed on 2025-05-11 08:24:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #if !defined(OPERATION_COUNT)
0030 #define OPERATION_COUNT 100
0031 #endif
0032
0033 #ifdef HAVE_CONFIG_H
0034 #include "config.h"
0035 #endif
0036
0037 #define CONFIGURE_INIT
0038 #include <rtems.h>
0039 #include <rtems/btimer.h>
0040 #include "system.h"
0041 #include "fptest.h"
0042 #include <tmacros.h>
0043 #include <timesys.h>
0044
0045 #include <rtems/score/schedulerpriorityimpl.h>
0046 #include <rtems/rtems/semimpl.h>
0047
0048 #if defined( RTEMS_SMP ) && defined( RTEMS_DEBUG )
0049 #define PREVENT_SMP_ASSERT_FAILURES
0050 #endif
0051
0052 const char rtems_test_name[] = "TIME TEST 26";
0053
0054
0055 rtems_id Semaphore_id;
0056
0057 Thread_Control *Middle_tcb;
0058
0059 Thread_Control *Low_tcb;
0060
0061
0062
0063
0064
0065
0066 uint32_t isr_disable_time;
0067 uint32_t isr_flash_time;
0068 uint32_t isr_enable_time;
0069 uint32_t thread_disable_dispatch_time;
0070 uint32_t thread_enable_dispatch_time;
0071 uint32_t thread_set_state_time;
0072 uint32_t thread_dispatch_no_fp_time;
0073 uint32_t context_switch_no_fp_time;
0074 uint32_t context_switch_self_time;
0075 uint32_t context_switch_another_task_time;
0076 uint32_t context_switch_restore_1st_fp_time;
0077 uint32_t context_switch_save_idle_restore_initted_time;
0078 uint32_t context_switch_save_restore_idle_time;
0079 uint32_t context_switch_save_restore_initted_time;
0080 uint32_t thread_resume_time;
0081 uint32_t thread_unblock_time;
0082 uint32_t thread_ready_time;
0083 uint32_t thread_get_time;
0084 uint32_t semaphore_get_time;
0085 uint32_t thread_get_invalid_time;
0086
0087 rtems_task null_task(
0088 rtems_task_argument argument
0089 );
0090
0091 rtems_task High_task(
0092 rtems_task_argument argument
0093 );
0094
0095 rtems_task Middle_task(
0096 rtems_task_argument argument
0097 );
0098
0099 rtems_task Low_task(
0100 rtems_task_argument argument
0101 );
0102
0103 rtems_task Floating_point_task_1(
0104 rtems_task_argument argument
0105 );
0106
0107 rtems_task Floating_point_task_2(
0108 rtems_task_argument argument
0109 );
0110
0111 void complete_test( void );
0112
0113 static void set_thread_dispatch_necessary( bool dispatch_necessary )
0114 {
0115 #if defined( PREVENT_SMP_ASSERT_FAILURES )
0116 ISR_Level level;
0117
0118 _ISR_Local_disable( level );
0119 #endif
0120
0121 _Thread_Dispatch_necessary = dispatch_necessary;
0122
0123 if ( !dispatch_necessary ) {
0124 _Thread_Heir = _Thread_Executing;
0125 }
0126
0127 #if defined( PREVENT_SMP_ASSERT_FAILURES )
0128 _ISR_Local_enable( level );
0129 #endif
0130 }
0131
0132 static void set_thread_heir( Thread_Control *thread )
0133 {
0134 #if defined( PREVENT_SMP_ASSERT_FAILURES )
0135 ISR_Level level;
0136
0137 _ISR_Local_disable( level );
0138 #endif
0139
0140 _Thread_Heir = thread;
0141
0142 #if defined( PREVENT_SMP_ASSERT_FAILURES )
0143 _ISR_Local_enable( level );
0144 #endif
0145 }
0146
0147 static void set_thread_executing( Thread_Control *thread )
0148 {
0149 _Per_CPU_Get_snapshot()->executing = thread;
0150 }
0151
0152 static void thread_resume( Thread_Control *thread )
0153 {
0154 _Thread_Clear_state( thread, STATES_SUSPENDED );
0155 }
0156
0157 rtems_task null_task(
0158 rtems_task_argument argument
0159 )
0160 {
0161 }
0162
0163 rtems_task Init(
0164 rtems_task_argument argument
0165 )
0166 {
0167 uint32_t index;
0168 rtems_id task_id;
0169 rtems_status_code status;
0170
0171 rtems_print_printer_fprintf_putc(&rtems_test_printer);
0172 Print_Warning();
0173
0174 TEST_BEGIN();
0175
0176 if (
0177 _Scheduler_Table[ 0 ].Operations.initialize
0178 != _Scheduler_priority_Initialize
0179 ) {
0180 puts(" Error ==> " );
0181 puts("Test only supported for deterministic priority scheduler\n" );
0182 TEST_END();
0183 rtems_test_exit( 0 );
0184 }
0185
0186 #define FP1_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 3u)
0187 status = rtems_task_create(
0188 rtems_build_name( 'F', 'P', '1', ' ' ),
0189 FP1_PRIORITY,
0190 RTEMS_MINIMUM_STACK_SIZE,
0191 RTEMS_DEFAULT_MODES,
0192 RTEMS_FLOATING_POINT,
0193 &task_id
0194 );
0195 directive_failed( status, "rtems_task_create of FP1" );
0196
0197 status = rtems_task_start( task_id, Floating_point_task_1, 0 );
0198 directive_failed( status, "rtems_task_start of FP1" );
0199
0200 #define FP2_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 2u)
0201 status = rtems_task_create(
0202 rtems_build_name( 'F', 'P', '2', ' ' ),
0203 FP2_PRIORITY,
0204 RTEMS_MINIMUM_STACK_SIZE,
0205 RTEMS_DEFAULT_MODES,
0206 RTEMS_FLOATING_POINT,
0207 &task_id
0208 );
0209 directive_failed( status, "rtems_task_create of FP2" );
0210
0211 status = rtems_task_start( task_id, Floating_point_task_2, 0 );
0212 directive_failed( status, "rtems_task_start of FP2" );
0213
0214 #define LOW_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 4u)
0215 status = rtems_task_create(
0216 rtems_build_name( 'L', 'O', 'W', ' ' ),
0217 LOW_PRIORITY,
0218 RTEMS_MINIMUM_STACK_SIZE,
0219 RTEMS_DEFAULT_MODES,
0220 RTEMS_DEFAULT_ATTRIBUTES,
0221 &task_id
0222 );
0223 directive_failed( status, "rtems_task_create of LOW" );
0224
0225 status = rtems_task_start( task_id, Low_task, 0 );
0226 directive_failed( status, "rtems_task_start of LOW" );
0227
0228 #define MIDDLE_PRIORITY (RTEMS_MAXIMUM_PRIORITY - 5u)
0229 status = rtems_task_create(
0230 rtems_build_name( 'M', 'I', 'D', ' ' ),
0231 MIDDLE_PRIORITY,
0232 RTEMS_MINIMUM_STACK_SIZE,
0233 RTEMS_DEFAULT_MODES,
0234 RTEMS_DEFAULT_ATTRIBUTES,
0235 &task_id
0236 );
0237 directive_failed( status, "rtems_task_create of MIDDLE" );
0238
0239 status = rtems_task_start( task_id, Middle_task, 0 );
0240 directive_failed( status, "rtems_task_start of MIDDLE" );
0241
0242 status = rtems_task_create(
0243 rtems_build_name( 'H', 'I', 'G', 'H' ),
0244 5,
0245 RTEMS_MINIMUM_STACK_SIZE,
0246 RTEMS_DEFAULT_MODES,
0247 RTEMS_DEFAULT_ATTRIBUTES,
0248 &task_id
0249 );
0250 directive_failed( status, "rtems_task_create of HIGH" );
0251
0252 status = rtems_task_start( task_id, High_task, 0 );
0253 directive_failed( status, "rtems_task_start of HIGH" );
0254
0255 status = rtems_semaphore_create(
0256 rtems_build_name( 'S', 'E', 'M', '1' ),
0257 OPERATION_COUNT,
0258 RTEMS_DEFAULT_ATTRIBUTES,
0259 RTEMS_NO_PRIORITY,
0260 &Semaphore_id
0261 );
0262 directive_failed( status, "rtems_semaphore_create" );
0263
0264 for ( index = 1 ; index <= OPERATION_COUNT ; index++ ) {
0265 status = rtems_task_create(
0266 rtems_build_name( 'N', 'U', 'L', 'L' ),
0267 RTEMS_MAXIMUM_PRIORITY - 1u,
0268 RTEMS_MINIMUM_STACK_SIZE,
0269 RTEMS_DEFAULT_MODES,
0270 RTEMS_DEFAULT_ATTRIBUTES,
0271 &task_id
0272 );
0273 directive_failed( status, "rtems_task_create LOOP" );
0274
0275 status = rtems_task_start( task_id, null_task, 0 );
0276 directive_failed( status, "rtems_task_start LOOP" );
0277 }
0278
0279 rtems_task_exit();
0280 }
0281
0282 rtems_task High_task(
0283 rtems_task_argument argument
0284 )
0285 {
0286 rtems_interrupt_level level;
0287
0288 _Thread_Dispatch_disable();
0289
0290 benchmark_timer_initialize();
0291 rtems_interrupt_local_disable( level );
0292 isr_disable_time = benchmark_timer_read();
0293
0294 benchmark_timer_initialize();
0295 #if defined(RTEMS_SMP)
0296 rtems_interrupt_local_enable( level );
0297 rtems_interrupt_local_disable( level );
0298 #else
0299 rtems_interrupt_flash( level );
0300 #endif
0301 isr_flash_time = benchmark_timer_read();
0302
0303 benchmark_timer_initialize();
0304 rtems_interrupt_local_enable( level );
0305 isr_enable_time = benchmark_timer_read();
0306
0307 _Thread_Dispatch_enable( _Per_CPU_Get() );
0308
0309 benchmark_timer_initialize();
0310 _Thread_Dispatch_disable();
0311 thread_disable_dispatch_time = benchmark_timer_read();
0312
0313 benchmark_timer_initialize();
0314 _Thread_Dispatch_enable( _Per_CPU_Get() );
0315 thread_enable_dispatch_time = benchmark_timer_read();
0316
0317 benchmark_timer_initialize();
0318 _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED );
0319 thread_set_state_time = benchmark_timer_read();
0320
0321 set_thread_dispatch_necessary( true );
0322
0323 benchmark_timer_initialize();
0324 _Thread_Dispatch();
0325 }
0326
0327 rtems_task Middle_task(
0328 rtems_task_argument argument
0329 )
0330 {
0331 Scheduler_priority_Context *scheduler_context =
0332 _Scheduler_priority_Get_context( _Thread_Scheduler_get_home( _Thread_Get_executing() ) );
0333
0334 thread_dispatch_no_fp_time = benchmark_timer_read();
0335
0336 _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED );
0337
0338 Middle_tcb = _Thread_Get_executing();
0339
0340 set_thread_executing(
0341 (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY])
0342 );
0343
0344
0345
0346 set_thread_dispatch_necessary( false );
0347
0348 _Thread_Dispatch_disable();
0349
0350 benchmark_timer_initialize();
0351 _Context_Switch(
0352 &Middle_tcb->Registers,
0353 &_Thread_Get_executing()->Registers
0354 );
0355
0356 benchmark_timer_initialize();
0357 _Context_Switch(&Middle_tcb->Registers, &Low_tcb->Registers);
0358 }
0359
0360 rtems_task Low_task(
0361 rtems_task_argument argument
0362 )
0363 {
0364 Scheduler_priority_Context *scheduler_context =
0365 _Scheduler_priority_Get_context( _Thread_Scheduler_get_home( _Thread_Get_executing() ) );
0366 Thread_Control *executing;
0367
0368 context_switch_no_fp_time = benchmark_timer_read();
0369
0370 executing = _Thread_Get_executing();
0371
0372 Low_tcb = executing;
0373
0374 benchmark_timer_initialize();
0375 _Context_Switch( &executing->Registers, &executing->Registers );
0376
0377 context_switch_self_time = benchmark_timer_read();
0378
0379 _Context_Switch(&executing->Registers, &Middle_tcb->Registers);
0380
0381 context_switch_another_task_time = benchmark_timer_read();
0382
0383 set_thread_executing(
0384 (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP1_PRIORITY])
0385 );
0386
0387
0388
0389 set_thread_dispatch_necessary( false );
0390
0391 _Thread_Dispatch_disable();
0392
0393 benchmark_timer_initialize();
0394 _Context_Switch(
0395 &executing->Registers,
0396 &_Thread_Get_executing()->Registers
0397 );
0398 }
0399
0400 rtems_task Floating_point_task_1(
0401 rtems_task_argument argument
0402 )
0403 {
0404 Scheduler_priority_Context *scheduler_context =
0405 _Scheduler_priority_Get_context( _Thread_Scheduler_get_home( _Thread_Get_executing() ) );
0406 Thread_Control *executing;
0407 FP_DECLARE;
0408
0409 context_switch_restore_1st_fp_time = benchmark_timer_read();
0410
0411 executing = _Thread_Get_executing();
0412
0413 set_thread_executing(
0414 (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP2_PRIORITY])
0415 );
0416
0417
0418
0419 set_thread_dispatch_necessary( false );
0420
0421 _Thread_Dispatch_disable();
0422
0423 benchmark_timer_initialize();
0424 #if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
0425 _Context_Save_fp( &executing->fp_context );
0426 _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
0427 #endif
0428 _Context_Switch(
0429 &executing->Registers,
0430 &_Thread_Get_executing()->Registers
0431 );
0432
0433
0434 context_switch_save_idle_restore_initted_time = benchmark_timer_read();
0435
0436 FP_LOAD( 1.0 );
0437
0438 executing = _Thread_Get_executing();
0439
0440 set_thread_executing(
0441 (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP2_PRIORITY])
0442 );
0443
0444 benchmark_timer_initialize();
0445 #if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
0446 _Context_Save_fp( &executing->fp_context );
0447 _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
0448 #endif
0449 _Context_Switch(
0450 &executing->Registers,
0451 &_Thread_Get_executing()->Registers
0452 );
0453
0454 }
0455
0456 rtems_task Floating_point_task_2(
0457 rtems_task_argument argument
0458 )
0459 {
0460 Scheduler_priority_Context *scheduler_context =
0461 _Scheduler_priority_Get_context( _Thread_Scheduler_get_home( _Thread_Get_executing() ) );
0462 Thread_Control *executing;
0463 FP_DECLARE;
0464
0465 context_switch_save_restore_idle_time = benchmark_timer_read();
0466
0467 executing = _Thread_Get_executing();
0468
0469 set_thread_executing(
0470 (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP1_PRIORITY])
0471 );
0472
0473 FP_LOAD( 1.0 );
0474
0475 benchmark_timer_initialize();
0476 #if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
0477 _Context_Save_fp( &executing->fp_context );
0478 _Context_Restore_fp( &_Thread_Get_executing()->fp_context );
0479 #endif
0480 _Context_Switch(
0481 &executing->Registers,
0482 &_Thread_Get_executing()->Registers
0483 );
0484
0485
0486 context_switch_save_restore_initted_time = benchmark_timer_read();
0487
0488 complete_test();
0489 }
0490
0491 void complete_test( void )
0492 {
0493 uint32_t index;
0494 rtems_id task_id;
0495 ISR_lock_Context lock_context;
0496 Thread_queue_Context queue_context;
0497
0498 benchmark_timer_initialize();
0499 thread_resume( Middle_tcb );
0500 thread_resume_time = benchmark_timer_read();
0501
0502 _Thread_Set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
0503
0504 benchmark_timer_initialize();
0505 _Thread_Unblock( Middle_tcb );
0506 thread_unblock_time = benchmark_timer_read();
0507
0508 _Thread_Set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
0509
0510 benchmark_timer_initialize();
0511 _Thread_Clear_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
0512 thread_ready_time = benchmark_timer_read();
0513
0514 benchmark_timer_initialize();
0515 for ( index=1 ; index <= OPERATION_COUNT ; index++ )
0516 (void) benchmark_timer_empty_function();
0517 overhead = benchmark_timer_read();
0518
0519 task_id = Middle_tcb->Object.id;
0520
0521 benchmark_timer_initialize();
0522 for ( index=1 ; index <= OPERATION_COUNT ; index++ ) {
0523 (void) _Thread_Get( task_id, &lock_context );
0524 _ISR_lock_ISR_enable( &lock_context );
0525 }
0526 thread_get_time = benchmark_timer_read();
0527
0528 benchmark_timer_initialize();
0529 for ( index=1 ; index <= OPERATION_COUNT ; index++ ) {
0530 (void) _Semaphore_Get( Semaphore_id, &queue_context );
0531 _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
0532 }
0533 semaphore_get_time = benchmark_timer_read();
0534
0535 benchmark_timer_initialize();
0536 for ( index=1 ; index <= OPERATION_COUNT ; index++ ) {
0537 (void) _Thread_Get( 0x3, &lock_context );
0538 _ISR_lock_ISR_enable( &lock_context );
0539 }
0540 thread_get_invalid_time = benchmark_timer_read();
0541
0542
0543
0544
0545
0546
0547 set_thread_heir( _Thread_Get_executing() );
0548 set_thread_dispatch_necessary( false );
0549
0550
0551
0552
0553
0554 put_time(
0555 "rtems interrupt: _ISR_Local_disable",
0556 isr_disable_time,
0557 1,
0558 0,
0559 0
0560 );
0561
0562 put_time(
0563 "rtems interrupt: _ISR_Local_flash",
0564 isr_flash_time,
0565 1,
0566 0,
0567 0
0568 );
0569
0570 put_time(
0571 "rtems interrupt: _ISR_Local_enable",
0572 isr_enable_time,
0573 1,
0574 0,
0575 0
0576 );
0577
0578 put_time(
0579 "rtems internal: _Thread_Dispatch_disable",
0580 thread_disable_dispatch_time,
0581 1,
0582 0,
0583 0
0584 );
0585
0586 put_time(
0587 "rtems internal: _Thread_Dispatch_enable",
0588 thread_enable_dispatch_time,
0589 1,
0590 0,
0591 0
0592 );
0593
0594 put_time(
0595 "rtems internal: _Thread_Set_state",
0596 thread_set_state_time,
0597 1,
0598 0,
0599 0
0600 );
0601
0602 put_time(
0603 "rtems internal: _Thread_Dispatch NO FP",
0604 thread_dispatch_no_fp_time,
0605 1,
0606 0,
0607 0
0608 );
0609
0610 put_time(
0611 "rtems internal: context switch: no floating point contexts",
0612 context_switch_no_fp_time,
0613 1,
0614 0,
0615 0
0616 );
0617
0618 put_time(
0619 "rtems internal: context switch: self",
0620 context_switch_self_time,
0621 1,
0622 0,
0623 0
0624 );
0625
0626 put_time(
0627 "rtems internal: context switch to another task",
0628 context_switch_another_task_time,
0629 1,
0630 0,
0631 0
0632 );
0633
0634 #if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1)
0635 put_time(
0636 "rtems internal: fp context switch restore 1st FP task",
0637 context_switch_restore_1st_fp_time,
0638 1,
0639 0,
0640 0
0641 );
0642
0643 put_time(
0644 "rtems internal: fp context switch save idle and restore initialized",
0645 context_switch_save_idle_restore_initted_time,
0646 1,
0647 0,
0648 0
0649 );
0650
0651 put_time(
0652 "rtems internal: fp context switch save idle, restore idle",
0653 context_switch_save_restore_idle_time,
0654 1,
0655 0,
0656 0
0657 );
0658
0659 put_time(
0660 "rtems internal: fp context switch save initialized, restore initialized",
0661 context_switch_save_restore_initted_time,
0662 1,
0663 0,
0664 0
0665 );
0666 #else
0667 puts(
0668 "rtems internal: fp context switch restore 1st FP task - NA\n"
0669 "rtems internal: fp context switch save idle restore initialized - NA\n"
0670 "rtems internal: fp context switch save idle restore idle - NA\n"
0671 "rtems internal: fp context switch save initialized\n"
0672 " restore initialized - NA"
0673 );
0674 #endif
0675
0676 put_time(
0677 "rtems internal: _Thread_Resume",
0678 thread_resume_time,
0679 1,
0680 0,
0681 0
0682 );
0683
0684 put_time(
0685 "rtems internal: _Thread_Unblock",
0686 thread_unblock_time,
0687 1,
0688 0,
0689 0
0690 );
0691
0692 put_time(
0693 "rtems internal: _Thread_Ready",
0694 thread_ready_time,
0695 1,
0696 0,
0697 0
0698 );
0699
0700 put_time(
0701 "rtems internal: _Thread_Get",
0702 thread_get_time,
0703 OPERATION_COUNT,
0704 0,
0705 0
0706 );
0707
0708 put_time(
0709 "rtems internal: _Semaphore_Get",
0710 semaphore_get_time,
0711 OPERATION_COUNT,
0712 0,
0713 0
0714 );
0715
0716 put_time(
0717 "rtems internal: _Thread_Get: invalid id",
0718 thread_get_invalid_time,
0719 OPERATION_COUNT,
0720 0,
0721 0
0722 );
0723
0724 TEST_END();
0725 rtems_test_exit( 0 );
0726 }