forked from Imagelibrary/rtems
score: Add scheduler acquire/release
This is currently a global lock for all scheduler instances. It should get replaced with one lock per scheduler instance in the future. Update #2273.
This commit is contained in:
@@ -110,12 +110,12 @@ rtems_status_code rtems_task_mode(
|
||||
}
|
||||
|
||||
if ( preempt_enabled || needs_asr_dispatching ) {
|
||||
ISR_Level level;
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
_ISR_Disable( level );
|
||||
_Scheduler_Acquire( executing, &lock_context );
|
||||
_Scheduler_Schedule( executing );
|
||||
_ISR_Enable( level );
|
||||
_Scheduler_Release( executing, &lock_context );
|
||||
_Thread_Enable_dispatch();
|
||||
}
|
||||
|
||||
|
||||
@@ -1374,6 +1374,38 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Ask_blocked_node_for_help(
|
||||
}
|
||||
#endif
|
||||
|
||||
ISR_LOCK_DECLARE( extern, _Scheduler_Lock )
|
||||
|
||||
/**
|
||||
* @brief Acquires the scheduler instance of the thread.
|
||||
*
|
||||
* @param[in] the_thread The thread.
|
||||
* @param[in] lock_context The lock context for _Scheduler_Release().
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _Scheduler_Acquire(
|
||||
Thread_Control *the_thread,
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
(void) the_thread;
|
||||
_ISR_lock_ISR_disable_and_acquire( &_Scheduler_Lock, lock_context );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases the scheduler instance of the thread.
|
||||
*
|
||||
* @param[in] the_thread The thread.
|
||||
* @param[in] lock_context The lock context used for _Scheduler_Acquire().
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _Scheduler_Release(
|
||||
Thread_Control *the_thread,
|
||||
ISR_lock_Context *lock_context
|
||||
)
|
||||
{
|
||||
(void) the_thread;
|
||||
_ISR_lock_Release_and_ISR_enable( &_Scheduler_Lock, lock_context );
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include <rtems/score/schedulerimpl.h>
|
||||
|
||||
ISR_LOCK_DEFINE( , _Scheduler_Lock, "Scheduler" )
|
||||
|
||||
void _Scheduler_Handler_initialization(void)
|
||||
{
|
||||
size_t n = _Scheduler_Count;
|
||||
|
||||
@@ -53,10 +53,11 @@ Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
|
||||
if ( deadline*budget_left > budget*deadline_left ) {
|
||||
/* Put late unblocked task to background until the end of period. */
|
||||
new_priority = the_thread->Start.initial_priority;
|
||||
if ( the_thread->real_priority != new_priority )
|
||||
the_thread->real_priority = new_priority;
|
||||
if ( the_thread->current_priority != new_priority )
|
||||
_Thread_Change_priority(the_thread, new_priority, true);
|
||||
the_thread->real_priority = new_priority;
|
||||
if ( the_thread->current_priority != new_priority ) {
|
||||
the_thread->current_priority = new_priority;
|
||||
_Scheduler_Change_priority(the_thread, new_priority, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,7 @@ void _Thread_Change_priority(
|
||||
* we are not REALLY changing priority.
|
||||
*/
|
||||
if ( the_thread->current_priority != new_priority ) {
|
||||
uint32_t my_generation;
|
||||
ISR_Level level;
|
||||
uint32_t my_generation;
|
||||
|
||||
my_generation = the_thread->Priority.generation + 1;
|
||||
the_thread->current_priority = new_priority;
|
||||
@@ -54,7 +53,7 @@ void _Thread_Change_priority(
|
||||
|
||||
_Thread_Lock_release( lock, &lock_context );
|
||||
|
||||
_ISR_Disable( level );
|
||||
_Scheduler_Acquire( the_thread, &lock_context );
|
||||
|
||||
if ( the_thread->Priority.generation == my_generation ) {
|
||||
if ( _States_Is_ready( the_thread->current_state ) ) {
|
||||
@@ -68,7 +67,7 @@ void _Thread_Change_priority(
|
||||
}
|
||||
}
|
||||
|
||||
_ISR_Enable( level );
|
||||
_Scheduler_Release( the_thread, &lock_context );
|
||||
} else {
|
||||
_Thread_Lock_release( lock, &lock_context );
|
||||
}
|
||||
|
||||
@@ -26,19 +26,20 @@ void _Thread_Clear_state(
|
||||
States_Control state
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
States_Control current_state;
|
||||
ISR_lock_Context lock_context;
|
||||
States_Control current_state;
|
||||
|
||||
_ISR_Disable( level );
|
||||
current_state = the_thread->current_state;
|
||||
_Scheduler_Acquire( the_thread, &lock_context );
|
||||
|
||||
if ( current_state & state ) {
|
||||
current_state =
|
||||
the_thread->current_state = _States_Clear( state, current_state );
|
||||
current_state = the_thread->current_state;
|
||||
if ( current_state & state ) {
|
||||
current_state =
|
||||
the_thread->current_state = _States_Clear( state, current_state );
|
||||
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
_Scheduler_Unblock( the_thread );
|
||||
}
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
_Scheduler_Unblock( the_thread );
|
||||
}
|
||||
}
|
||||
_ISR_Enable( level );
|
||||
|
||||
_Scheduler_Release( the_thread, &lock_context );
|
||||
}
|
||||
|
||||
@@ -26,13 +26,13 @@ void _Thread_Ready(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_ISR_Disable( level );
|
||||
_Scheduler_Acquire( the_thread, &lock_context );
|
||||
|
||||
the_thread->current_state = STATES_READY;
|
||||
|
||||
_Scheduler_Unblock( the_thread );
|
||||
|
||||
_ISR_Enable( level );
|
||||
_Scheduler_Release( the_thread, &lock_context );
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ void _Thread_Set_state(
|
||||
States_Control state
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
States_Control current_state;
|
||||
ISR_lock_Context lock_context;
|
||||
States_Control current_state;
|
||||
|
||||
_ISR_Disable( level );
|
||||
_Scheduler_Acquire( the_thread, &lock_context );
|
||||
|
||||
current_state = the_thread->current_state;
|
||||
if ( _States_Is_ready( current_state ) ) {
|
||||
@@ -44,5 +44,5 @@ void _Thread_Set_state(
|
||||
the_thread->current_state = _States_Set( state, current_state);
|
||||
}
|
||||
|
||||
_ISR_Enable( level );
|
||||
_Scheduler_Release( the_thread, &lock_context );
|
||||
}
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
|
||||
void _Thread_Yield( Thread_Control *executing )
|
||||
{
|
||||
ISR_Level level;
|
||||
ISR_lock_Context lock_context;
|
||||
|
||||
_ISR_Disable( level );
|
||||
_Scheduler_Acquire( executing, &lock_context );
|
||||
|
||||
if ( _States_Is_ready( executing->current_state ) ) {
|
||||
_Scheduler_Yield( executing );
|
||||
}
|
||||
|
||||
_ISR_Enable( level );
|
||||
_Scheduler_Release( executing, &lock_context );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user