[PATCH 04/12] posix: Use a dedicated lock for scheduler changes

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Apr 8 06:49:19 UTC 2016


Update #2555.
---
 cpukit/posix/include/rtems/posix/pthreadimpl.h | 17 +++++++
 cpukit/posix/include/rtems/posix/threadsup.h   |  3 ++
 cpukit/posix/src/pthread.c                     | 65 ++++++++++++++++----------
 cpukit/posix/src/pthreadcreate.c               |  4 +-
 cpukit/posix/src/pthreadsetschedparam.c        | 34 ++++++++------
 5 files changed, 83 insertions(+), 40 deletions(-)

diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h
index 42f10b0..ef5821e 100644
--- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
+++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
@@ -223,6 +223,23 @@ RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Join_dequeue(
   );
 }
 
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Scheduler_acquire(
+  POSIX_API_Control *api,
+  ISR_lock_Context  *lock_context
+)
+{
+  _ISR_lock_ISR_disable_and_acquire( &api->Scheduler_lock, lock_context );
+}
+
+RTEMS_INLINE_ROUTINE void _POSIX_Threads_Scheduler_release(
+  POSIX_API_Control *api,
+  ISR_lock_Context  *lock_context
+)
+{
+  _ISR_lock_Release_and_ISR_enable( &api->Scheduler_lock, lock_context );
+}
+
+
 /** @} */
 
 #ifdef __cplusplus
diff --git a/cpukit/posix/include/rtems/posix/threadsup.h b/cpukit/posix/include/rtems/posix/threadsup.h
index 7cd2354..93ba2c1 100644
--- a/cpukit/posix/include/rtems/posix/threadsup.h
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -19,6 +19,7 @@
 #define _RTEMS_POSIX_THREADSUP_H
 
 #include <rtems/score/coresem.h>
+#include <rtems/score/isrlock.h>
 #include <rtems/score/thread.h>
 #include <rtems/score/threadq.h>
 #include <rtems/score/watchdog.h>
@@ -51,6 +52,8 @@ typedef struct {
   /** This is the set of threads waiting for the thread to exit. */
   Thread_queue_Control    Join_List;
   /** This is the thread's current scheduling policy. */
+  ISR_LOCK_MEMBER(        Scheduler_lock )
+  /** This is the thread's current scheduling policy. */
   int                     schedpolicy;
   /** This is the thread's current set of scheduling parameters. */
   struct sched_param      schedparam;
diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index 12f02df..f3d45c9 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -106,39 +106,37 @@ static bool _POSIX_Threads_Sporadic_budget_TSR_filter(
  */
 void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
 {
-  uint32_t            ticks;
   POSIX_API_Control  *api;
   Thread_Control     *the_thread;
-  ISR_Level           level;
+  ISR_lock_Context    lock_context;
+  Priority_Control    new_priority;
 
   api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic_timer );
   the_thread = api->thread;
 
-  /* ticks is guaranteed to be at least one */
-  ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget );
+  _POSIX_Threads_Scheduler_acquire( api, &lock_context );
 
-  the_thread->cpu_time_budget = ticks;
+  the_thread->cpu_time_budget =
+    _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget );
+
+  _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+  _Watchdog_Per_CPU_insert_relative(
+    &api->Sporadic_timer,
+    _Per_CPU_Get(),
+    _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period )
+  );
+
+  new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority );
+
+  _POSIX_Threads_Scheduler_acquire( api, &lock_context );
 
   _Thread_Change_priority(
     the_thread,
-    _POSIX_Priority_To_core( api->schedparam.sched_priority ),
+    new_priority,
     NULL,
     _POSIX_Threads_Sporadic_budget_TSR_filter,
     true
   );
-
-  /* ticks is guaranteed to be at least one */
-  ticks = _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period );
-
-  _Thread_Disable_dispatch();
-  _ISR_Disable( level );
-  _Watchdog_Per_CPU_insert_relative(
-    &api->Sporadic_timer,
-    _Per_CPU_Get(),
-    ticks
-  );
-  _ISR_Enable( level );
-  _Thread_Unnest_dispatch();
 }
 
 static bool _POSIX_Threads_Sporadic_budget_callout_filter(
@@ -202,6 +200,8 @@ static bool _POSIX_Threads_Create_extension(
 
   api = created->API_Extensions[ THREAD_API_POSIX ];
 
+  _ISR_lock_Initialize( &api->Scheduler_lock, "POSIX Threads Scheduler" );
+
   /* XXX check all fields are touched */
   api->thread = created;
   _POSIX_Threads_Initialize_attributes( &api->Attributes );
@@ -244,12 +244,26 @@ static bool _POSIX_Threads_Create_extension(
   return true;
 }
 
+static void _POSIX_Threads_Delete_extension(
+  Thread_Control *executing,
+  Thread_Control *deleted
+)
+{
+  POSIX_API_Control *api;
+
+  api = deleted->API_Extensions[ THREAD_API_POSIX ];
+
+  _ISR_lock_Destroy( &api->Scheduler_lock );
+  _Thread_queue_Destroy( &api->Join_List );
+}
+
 static void _POSIX_Threads_Terminate_extension(
   Thread_Control *executing
 )
 {
   Thread_Control     *the_thread;
   POSIX_API_Control  *api;
+  ISR_lock_Context    lock_context;
   void              **value_ptr;
 
   api = executing->API_Extensions[ THREAD_API_POSIX ];
@@ -265,12 +279,15 @@ static void _POSIX_Threads_Terminate_extension(
     *(void **)the_thread->Wait.return_argument = value_ptr;
   }
 
-  if ( api->schedpolicy == SCHED_SPORADIC )
-    _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+  _Thread_Enable_dispatch();
 
-  _Thread_queue_Destroy( &api->Join_List );
+  _POSIX_Threads_Scheduler_acquire( api, &lock_context );
 
-  _Thread_Enable_dispatch();
+  if ( api->schedpolicy == SCHED_SPORADIC ) {
+    _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+  }
+
+  _POSIX_Threads_Scheduler_release( api, &lock_context );
 }
 
 /*
@@ -296,7 +313,7 @@ User_extensions_Control _POSIX_Threads_User_extensions = {
   { _POSIX_Threads_Create_extension,          /* create */
     NULL,                                     /* start */
     NULL,                                     /* restart */
-    NULL,                                     /* delete */
+    _POSIX_Threads_Delete_extension,          /* delete */
     NULL,                                     /* switch */
     NULL,                                     /* begin */
     _POSIX_Threads_Exitted_extension,         /* exitted */
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index fc07b1f..2533345 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -247,13 +247,13 @@ int pthread_create(
   #endif
 
   if ( schedpolicy == SCHED_SPORADIC ) {
-    _ISR_Disable( level );
+    _ISR_Disable_without_giant( level );
     _Watchdog_Per_CPU_insert_relative(
       &api->Sporadic_timer,
       _Per_CPU_Get(),
       _Timespec_To_ticks( &api->schedparam.sched_ss_repl_period )
     );
-    _ISR_Enable( level );
+    _ISR_Enable_without_giant( level );
   }
 
   _Thread_Enable_dispatch();
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
index c9560f5..57a2bc8 100644
--- a/cpukit/posix/src/pthreadsetschedparam.c
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -44,7 +44,8 @@ int pthread_setschedparam(
   Objects_Locations                    location;
   int                                  rc;
   Priority_Control                     unused;
-  ISR_Level                            level;
+  ISR_lock_Context                     lock_context;
+  Priority_Control                     new_priority;
 
   /*
    *  Check all the parameters
@@ -70,10 +71,10 @@ int pthread_setschedparam(
     case OBJECTS_LOCAL:
       api = the_thread->API_Extensions[ THREAD_API_POSIX ];
 
+      _POSIX_Threads_Scheduler_acquire( api, &lock_context );
+
       if ( api->schedpolicy == SCHED_SPORADIC ) {
-        _ISR_Disable( level );
         _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
-        _ISR_Enable( level );
       }
 
       api->schedpolicy = policy;
@@ -84,26 +85,31 @@ int pthread_setschedparam(
       the_thread->budget_algorithm = budget_algorithm;
       the_thread->budget_callout   = budget_callout;
 
-      switch ( api->schedpolicy ) {
+      switch ( policy ) {
         case SCHED_OTHER:
         case SCHED_FIFO:
         case SCHED_RR:
           the_thread->cpu_time_budget =
             rtems_configuration_get_ticks_per_timeslice();
-
-          _Thread_Set_priority(
-            the_thread,
-            _POSIX_Priority_To_core( api->schedparam.sched_priority ),
-            &unused,
-            true
-          );
+	  new_priority =
+            _POSIX_Priority_To_core( api->schedparam.sched_priority );
           break;
 
         case SCHED_SPORADIC:
           api->ss_high_priority = api->schedparam.sched_priority;
-          _ISR_Disable( level );
-          _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
-          _ISR_Enable( level );
+          break;
+      }
+
+      _POSIX_Threads_Scheduler_release( api, &lock_context );
+
+      switch ( policy ) {
+        case SCHED_OTHER:
+        case SCHED_FIFO:
+        case SCHED_RR:
+          _Thread_Set_priority( the_thread, new_priority, &unused, true );
+          break;
+
+        case SCHED_SPORADIC:
           _POSIX_Threads_Sporadic_budget_TSR( &api->Sporadic_timer );
           break;
       }
-- 
1.8.4.5




More information about the devel mailing list