[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