[PATCH 3/3] score: Add scheduler acquire/release
Sebastian Huber
sebastian.huber at embedded-brains.de
Mon Mar 23 14:51:47 UTC 2015
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.
---
cpukit/rtems/src/taskmode.c | 6 ++---
cpukit/score/include/rtems/score/schedulerimpl.h | 32 ++++++++++++++++++++++++
cpukit/score/src/scheduler.c | 2 ++
cpukit/score/src/threadchangepriority.c | 7 +++---
cpukit/score/src/threadclearstate.c | 23 +++++++++--------
cpukit/score/src/threadready.c | 6 ++---
cpukit/score/src/threadsetstate.c | 8 +++---
cpukit/score/src/threadyield.c | 6 ++---
8 files changed, 62 insertions(+), 28 deletions(-)
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c
index 1056c6b..de30806 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 43257c4..d11b2c5 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 ef5a0a9..c0da70b 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 Lock" )
+
void _Scheduler_Handler_initialization(void)
{
size_t n = _Scheduler_Count;
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index 2baa9d2..a011a8f 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 19e41df..c60fb8f 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 b79d8db..5375294 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 a8cd38e..02ee70e 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 fc796da..7f1c175 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 );
}
--
1.8.4.5
More information about the devel
mailing list