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 ) { if ( preempt_enabled || needs_asr_dispatching ) {
ISR_Level level; ISR_lock_Context lock_context;
_Thread_Disable_dispatch(); _Thread_Disable_dispatch();
_ISR_Disable( level ); _Scheduler_Acquire( executing, &lock_context );
_Scheduler_Schedule( executing ); _Scheduler_Schedule( executing );
_ISR_Enable( level ); _Scheduler_Release( executing, &lock_context );
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
} }

View File

@@ -1374,6 +1374,38 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Ask_blocked_node_for_help(
} }
#endif #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 #ifdef __cplusplus

View File

@@ -20,6 +20,8 @@
#include <rtems/score/schedulerimpl.h> #include <rtems/score/schedulerimpl.h>
ISR_LOCK_DEFINE( , _Scheduler_Lock, "Scheduler" )
void _Scheduler_Handler_initialization(void) void _Scheduler_Handler_initialization(void)
{ {
size_t n = _Scheduler_Count; 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 ) { if ( deadline*budget_left > budget*deadline_left ) {
/* Put late unblocked task to background until the end of period. */ /* Put late unblocked task to background until the end of period. */
new_priority = the_thread->Start.initial_priority; new_priority = the_thread->Start.initial_priority;
if ( the_thread->real_priority != new_priority )
the_thread->real_priority = new_priority; the_thread->real_priority = new_priority;
if ( the_thread->current_priority != new_priority ) if ( the_thread->current_priority != new_priority ) {
_Thread_Change_priority(the_thread, new_priority, true); the_thread->current_priority = new_priority;
_Scheduler_Change_priority(the_thread, new_priority, true);
}
} }
} }

View File

@@ -40,7 +40,6 @@ void _Thread_Change_priority(
*/ */
if ( the_thread->current_priority != new_priority ) { if ( the_thread->current_priority != new_priority ) {
uint32_t my_generation; uint32_t my_generation;
ISR_Level level;
my_generation = the_thread->Priority.generation + 1; my_generation = the_thread->Priority.generation + 1;
the_thread->current_priority = new_priority; the_thread->current_priority = new_priority;
@@ -54,7 +53,7 @@ void _Thread_Change_priority(
_Thread_Lock_release( lock, &lock_context ); _Thread_Lock_release( lock, &lock_context );
_ISR_Disable( level ); _Scheduler_Acquire( the_thread, &lock_context );
if ( the_thread->Priority.generation == my_generation ) { if ( the_thread->Priority.generation == my_generation ) {
if ( _States_Is_ready( the_thread->current_state ) ) { 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 { } else {
_Thread_Lock_release( lock, &lock_context ); _Thread_Lock_release( lock, &lock_context );
} }

View File

@@ -26,12 +26,12 @@ void _Thread_Clear_state(
States_Control state States_Control state
) )
{ {
ISR_Level level; ISR_lock_Context lock_context;
States_Control current_state; States_Control current_state;
_ISR_Disable( level ); _Scheduler_Acquire( the_thread, &lock_context );
current_state = the_thread->current_state;
current_state = the_thread->current_state;
if ( current_state & state ) { if ( current_state & state ) {
current_state = current_state =
the_thread->current_state = _States_Clear( state, current_state ); the_thread->current_state = _States_Clear( state, current_state );
@@ -40,5 +40,6 @@ void _Thread_Clear_state(
_Scheduler_Unblock( the_thread ); _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 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; the_thread->current_state = STATES_READY;
_Scheduler_Unblock( the_thread ); _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 States_Control state
) )
{ {
ISR_Level level; ISR_lock_Context lock_context;
States_Control current_state; States_Control current_state;
_ISR_Disable( level ); _Scheduler_Acquire( the_thread, &lock_context );
current_state = the_thread->current_state; current_state = the_thread->current_state;
if ( _States_Is_ready( 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); 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 ) 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 ) ) { if ( _States_Is_ready( executing->current_state ) ) {
_Scheduler_Yield( executing ); _Scheduler_Yield( executing );
} }
_ISR_Enable( level ); _Scheduler_Release( executing, &lock_context );
} }