rtems_task Floating_point_task_2( rtems_task_argument argument ) { Scheduler_priority_Context *scheduler_context = _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) ); Thread_Control *executing; FP_DECLARE; context_switch_save_restore_idle_time = benchmark_timer_read(); executing = _Thread_Get_executing(); set_thread_executing( (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP1_PRIORITY]) ); FP_LOAD( 1.0 ); benchmark_timer_initialize(); #if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1) _Context_Save_fp( &executing->fp_context ); _Context_Restore_fp( &_Thread_Get_executing()->fp_context ); #endif _Context_Switch( &executing->Registers, &_Thread_Get_executing()->Registers ); /* switch to Floating_point_task_1 */ context_switch_save_restore_initted_time = benchmark_timer_read(); complete_test(); }
rtems_task Middle_task( rtems_task_argument argument ) { Scheduler_priority_Context *scheduler_context = _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) ); thread_dispatch_no_fp_time = benchmark_timer_read(); _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED ); Middle_tcb = _Thread_Get_executing(); set_thread_executing( (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY]) ); /* do not force context switch */ set_thread_dispatch_necessary( false ); _Thread_Dispatch_disable(); benchmark_timer_initialize(); _Context_Switch( &Middle_tcb->Registers, &_Thread_Get_executing()->Registers ); benchmark_timer_initialize(); _Context_Switch(&Middle_tcb->Registers, &Low_tcb->Registers); }
Scheduler_Void_or_thread _Scheduler_priority_Update_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread ) { Scheduler_priority_Context *context; Scheduler_priority_Node *node; unsigned int priority; bool prepend_it; if ( !_Thread_Is_ready( the_thread ) ) { /* Nothing to do */ SCHEDULER_RETURN_VOID_OR_NULL; } node = _Scheduler_priority_Thread_get_node( the_thread ); priority = (unsigned int ) _Scheduler_Node_get_priority( &node->Base, &prepend_it ); if ( priority == node->Ready_queue.current_priority ) { /* Nothing to do */ SCHEDULER_RETURN_VOID_OR_NULL; } context = _Scheduler_priority_Get_context( scheduler ); _Scheduler_priority_Ready_queue_extract( &the_thread->Object.Node, &node->Ready_queue, &context->Bit_map ); _Scheduler_priority_Ready_queue_update( &node->Ready_queue, priority, &context->Bit_map, &context->Ready[ 0 ] ); if ( prepend_it ) { _Scheduler_priority_Ready_queue_enqueue_first( &the_thread->Object.Node, &node->Ready_queue, &context->Bit_map ); } else { _Scheduler_priority_Ready_queue_enqueue( &the_thread->Object.Node, &node->Ready_queue, &context->Bit_map ); } _Scheduler_priority_Schedule_body( scheduler, the_thread, false ); SCHEDULER_RETURN_VOID_OR_NULL; }
Scheduler_Void_or_thread _Scheduler_priority_Unblock ( const Scheduler_Control *scheduler, Thread_Control *the_thread ) { Scheduler_priority_Context *context; Scheduler_priority_Node *node; unsigned int priority; bool prepend_it; context = _Scheduler_priority_Get_context( scheduler ); node = _Scheduler_priority_Thread_get_node( the_thread ); priority = (unsigned int ) _Scheduler_Node_get_priority( &node->Base, &prepend_it ); (void) prepend_it; if ( priority != node->Ready_queue.current_priority ) { _Scheduler_priority_Ready_queue_update( &node->Ready_queue, priority, &context->Bit_map, &context->Ready[ 0 ] ); } _Scheduler_priority_Ready_queue_enqueue( &the_thread->Object.Node, &node->Ready_queue, &context->Bit_map ); /* TODO: flash critical section? */ /* * If the thread that was unblocked is more important than the heir, * then we have a new heir. This may or may not result in a * context switch. * * Normal case: * If the current thread is preemptible, then we need to do * a context switch. * Pseudo-ISR case: * Even if the thread isn't preemptible, if the new heir is * a pseudo-ISR system task, we need to do a context switch. */ if ( priority < _Thread_Get_priority( _Thread_Heir ) ) { _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR ); } SCHEDULER_RETURN_VOID_OR_NULL; }
rtems_task Task_2( rtems_task_argument argument ) { Thread_Control *executing = _Thread_Get_executing(); Scheduler_priority_Context *scheduler_context = _Scheduler_priority_Get_context( _Scheduler_Get( executing ) ); ISR_lock_Context lock_context; #if (MUST_WAIT_FOR_INTERRUPT == 1) while ( Interrupt_occurred == 0 ); #endif end_time = benchmark_timer_read(); put_time( "rtems interrupt: entry overhead returns to preempting task", Interrupt_enter_time, 1, 0, timer_overhead ); put_time( "rtems interrupt: exit overhead returns to preempting task", end_time, 1, 0, 0 ); fflush( stdout ); /* * Switch back to the other task to exit the test. */ _Scheduler_Acquire( executing, &lock_context ); _Thread_Executing = (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY]); _Thread_Dispatch_necessary = 1; _Scheduler_Release( executing, &lock_context ); _Thread_Dispatch(); }
rtems_task Low_task( rtems_task_argument argument ) { Scheduler_priority_Context *scheduler_context = _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) ); Thread_Control *executing; context_switch_no_fp_time = benchmark_timer_read(); executing = _Thread_Get_executing(); Low_tcb = executing; benchmark_timer_initialize(); _Context_Switch( &executing->Registers, &executing->Registers ); context_switch_self_time = benchmark_timer_read(); _Context_Switch(&executing->Registers, &Middle_tcb->Registers); context_switch_another_task_time = benchmark_timer_read(); set_thread_executing( (Thread_Control *) _Chain_First(&scheduler_context->Ready[FP1_PRIORITY]) ); /* do not force context switch */ set_thread_dispatch_necessary( false ); thread_disable_dispatch(); benchmark_timer_initialize(); #if (CPU_HARDWARE_FP == 1) || (CPU_SOFTWARE_FP == 1) _Context_Restore_fp( &_Thread_Get_executing()->fp_context ); #endif _Context_Switch( &executing->Registers, &_Thread_Get_executing()->Registers ); }
Scheduler_Void_or_thread _Scheduler_priority_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, bool prepend_it ) { Scheduler_priority_Context *context = _Scheduler_priority_Get_context( scheduler ); Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread ); _Scheduler_priority_Ready_queue_extract( &the_thread->Object.Node, &node->Ready_queue, &context->Bit_map ); _Scheduler_priority_Ready_queue_update( &node->Ready_queue, new_priority, &context->Bit_map, &context->Ready[ 0 ] ); if ( prepend_it ) { _Scheduler_priority_Ready_queue_enqueue_first( &the_thread->Object.Node, &node->Ready_queue, &context->Bit_map ); } else { _Scheduler_priority_Ready_queue_enqueue( &the_thread->Object.Node, &node->Ready_queue, &context->Bit_map ); } SCHEDULER_RETURN_VOID_OR_NULL; }
rtems_task Task_1( rtems_task_argument argument ) { Scheduler_priority_Context *scheduler_context = _Scheduler_priority_Get_context( _Scheduler_Get( _Thread_Get_executing() ) ); #if defined(RTEMS_SMP) rtems_interrupt_level level; #endif Install_tm27_vector( Isr_handler ); /* * No preempt .. no nesting */ Interrupt_nest = 0; Interrupt_occurred = 0; benchmark_timer_initialize(); Cause_tm27_intr(); /* goes to Isr_handler */ #if (MUST_WAIT_FOR_INTERRUPT == 1) while ( Interrupt_occurred == 0 ); #endif Interrupt_return_time = benchmark_timer_read(); put_time( "rtems interrupt: entry overhead returns to interrupted task", Interrupt_enter_time, 1, 0, timer_overhead ); put_time( "rtems interrupt: exit overhead returns to interrupted task", Interrupt_return_time, 1, 0, timer_overhead ); /* * No preempt .. nested */ _Thread_Disable_dispatch(); Interrupt_nest = 1; Interrupt_occurred = 0; benchmark_timer_initialize(); Cause_tm27_intr(); /* goes to Isr_handler */ #if (MUST_WAIT_FOR_INTERRUPT == 1) while ( Interrupt_occurred == 0 ); #endif Interrupt_return_time = benchmark_timer_read(); _Thread_Unnest_dispatch(); put_time( "rtems interrupt: entry overhead returns to nested interrupt", Interrupt_enter_nested_time, 1, 0, 0 ); put_time( "rtems interrupt: exit overhead returns to nested interrupt", Interrupt_return_nested_time, 1, 0, 0 ); /* * Does a preempt .. not nested */ #if defined(RTEMS_SMP) _ISR_Disable_without_giant(level); #endif _Thread_Executing = (Thread_Control *) _Chain_First(&scheduler_context->Ready[LOW_PRIORITY]); _Thread_Dispatch_necessary = 1; #if defined(RTEMS_SMP) _ISR_Enable_without_giant(level); #endif Interrupt_occurred = 0; benchmark_timer_initialize(); Cause_tm27_intr(); /* * goes to Isr_handler and then returns */ TEST_END(); rtems_test_exit( 0 ); }