summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-03-20 13:41:27 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-03-24 14:35:05 +0100
commit4054c9164601830c7ead74be612d33c4717d8ea6 (patch)
tree10b417daff4d9013a3fda4ee6f42895129259984
parentscore: Use a dedicated ISR lock for thread queues (diff)
downloadrtems-4054c9164601830c7ead74be612d33c4717d8ea6.tar.bz2
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.
-rw-r--r--cpukit/rtems/src/taskmode.c6
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h32
-rw-r--r--cpukit/score/src/scheduler.c2
-rw-r--r--cpukit/score/src/schedulercbsunblock.c9
-rw-r--r--cpukit/score/src/threadchangepriority.c7
-rw-r--r--cpukit/score/src/threadclearstate.c23
-rw-r--r--cpukit/score/src/threadready.c6
-rw-r--r--cpukit/score/src/threadsetstate.c8
-rw-r--r--cpukit/score/src/threadyield.c6
9 files changed, 67 insertions, 32 deletions
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c
index 1056c6b11e..de30806186 100644
--- a/cpukit/rtems/src/taskmode.c
+++ b/cpukit/rtems/src/taskmode.c
@@ -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();
}
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 43257c4a7a..d11b2c55c8 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -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
diff --git a/cpukit/score/src/scheduler.c b/cpukit/score/src/scheduler.c
index ef5a0a9c00..e7854e1361 100644
--- a/cpukit/score/src/scheduler.c
+++ b/cpukit/score/src/scheduler.c
@@ -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;
diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c
index 56b35de8b9..9170889491 100644
--- a/cpukit/score/src/schedulercbsunblock.c
+++ b/cpukit/score/src/schedulercbsunblock.c
@@ -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);
+ }
}
}
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index 2baa9d2774..a011a8f5e5 100644
--- a/cpukit/score/src/threadchangepriority.c
+++ b/cpukit/score/src/threadchangepriority.c
@@ -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 );
}
diff --git a/cpukit/score/src/threadclearstate.c b/cpukit/score/src/threadclearstate.c
index 19e41df593..c60fb8fc41 100644
--- a/cpukit/score/src/threadclearstate.c
+++ b/cpukit/score/src/threadclearstate.c
@@ -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 );
}
diff --git a/cpukit/score/src/threadready.c b/cpukit/score/src/threadready.c
index b79d8db84d..5375294fe9 100644
--- a/cpukit/score/src/threadready.c
+++ b/cpukit/score/src/threadready.c
@@ -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 );
}
diff --git a/cpukit/score/src/threadsetstate.c b/cpukit/score/src/threadsetstate.c
index a8cd38efc7..02ee70ed9b 100644
--- a/cpukit/score/src/threadsetstate.c
+++ b/cpukit/score/src/threadsetstate.c
@@ -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 );
}
diff --git a/cpukit/score/src/threadyield.c b/cpukit/score/src/threadyield.c
index fc796dabea..7f1c175b4a 100644
--- a/cpukit/score/src/threadyield.c
+++ b/cpukit/score/src/threadyield.c
@@ -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 );
}