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:
Sebastian Huber
2015-03-20 13:41:27 +01:00
parent 3134eb8267
commit 4054c91646
9 changed files with 67 additions and 32 deletions

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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 );
}

View File

@@ -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 );
}

View File

@@ -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 );
}

View File

@@ -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 );
}

View File

@@ -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 );
}