[PATCH 13/14] posix: Avoid Giant lock for some pthread functions

Sebastian Huber sebastian.huber at embedded-brains.de
Wed May 11 13:23:40 UTC 2016


Avoid Giant lock for pthread_getattr_np(), pthread_setschedparam() and
pthread_getschedparam().  Replace POSIX threads scheduler lock with
thread state lock.

Update #2555.
---
 cpukit/posix/include/rtems/posix/pthreadimpl.h |  17 ----
 cpukit/posix/include/rtems/posix/threadsup.h   |   2 -
 cpukit/posix/src/pthread.c                     |  11 +--
 cpukit/posix/src/pthreadgetattrnp.c            |  35 ++++---
 cpukit/posix/src/pthreadgetschedparam.c        |  42 ++++-----
 cpukit/posix/src/pthreadsetschedparam.c        | 123 ++++++++++++-------------
 cpukit/score/include/rtems/score/thread.h      |   5 +
 7 files changed, 103 insertions(+), 132 deletions(-)

diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h
index ef5821e..42f10b0 100644
--- a/cpukit/posix/include/rtems/posix/pthreadimpl.h
+++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h
@@ -223,23 +223,6 @@ 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 93ba2c1..8109921 100644
--- a/cpukit/posix/include/rtems/posix/threadsup.h
+++ b/cpukit/posix/include/rtems/posix/threadsup.h
@@ -52,8 +52,6 @@ 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 61e498b..5c5cff7 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -114,7 +114,7 @@ void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
   api = RTEMS_CONTAINER_OF( watchdog, POSIX_API_Control, Sporadic_timer );
   the_thread = api->thread;
 
-  _POSIX_Threads_Scheduler_acquire( api, &lock_context );
+  _Thread_State_acquire( the_thread, &lock_context );
 
   the_thread->cpu_time_budget =
     _Timespec_To_ticks( &api->schedparam.sched_ss_init_budget );
@@ -128,7 +128,7 @@ void _POSIX_Threads_Sporadic_budget_TSR( Watchdog_Control *watchdog )
 
   new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority );
 
-  _POSIX_Threads_Scheduler_release( api, &lock_context );
+  _Thread_State_release( the_thread, &lock_context );
 
   _Thread_Change_priority(
     the_thread,
@@ -200,8 +200,6 @@ 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 );
@@ -253,7 +251,6 @@ static void _POSIX_Threads_Delete_extension(
 
   api = deleted->API_Extensions[ THREAD_API_POSIX ];
 
-  _ISR_lock_Destroy( &api->Scheduler_lock );
   _Thread_queue_Destroy( &api->Join_List );
 }
 
@@ -281,13 +278,13 @@ static void _POSIX_Threads_Terminate_extension(
 
   _Thread_Enable_dispatch();
 
-  _POSIX_Threads_Scheduler_acquire( api, &lock_context );
+  _Thread_State_acquire( executing, &lock_context );
 
   if ( api->schedpolicy == SCHED_SPORADIC ) {
     _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
   }
 
-  _POSIX_Threads_Scheduler_release( api, &lock_context );
+  _Thread_State_release( executing, &lock_context );
 }
 
 /*
diff --git a/cpukit/posix/src/pthreadgetattrnp.c b/cpukit/posix/src/pthreadgetattrnp.c
index f71819f..57c5318 100644
--- a/cpukit/posix/src/pthreadgetattrnp.c
+++ b/cpukit/posix/src/pthreadgetattrnp.c
@@ -26,32 +26,29 @@
 #include <rtems/score/threadimpl.h>
 
 int pthread_getattr_np(
-  pthread_t       id,
+  pthread_t       thread,
   pthread_attr_t *attr
 )
 {
-  Objects_Locations        location;
-  POSIX_API_Control       *api;
-  Thread_Control          *the_thread;
+  Thread_Control    *the_thread;
+  ISR_lock_Context   lock_context;
+  POSIX_API_Control *api;
 
-  if ( !attr )
+  if ( attr == NULL ) {
     return EINVAL;
+  }
 
-  the_thread = _Thread_Get( id, &location );
-  switch ( location ) {
-
-    case OBJECTS_LOCAL:
-      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
-      _POSIX_Threads_Copy_attributes( attr, &api->Attributes);
-      _Objects_Put( &the_thread->Object );
-      return 0;
+  the_thread = _Thread_Get_interrupt_disable( thread, &lock_context );
 
-#if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:
-#endif
-    case OBJECTS_ERROR:
-      break;
+  if ( the_thread == NULL ) {
+    return ESRCH;
   }
 
-  return ESRCH;
+  _Thread_State_acquire_critical( the_thread, &lock_context );
+
+  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+  _POSIX_Threads_Copy_attributes( attr, &api->Attributes);
+
+  _Thread_State_release( the_thread, &lock_context );
+  return 0;
 }
diff --git a/cpukit/posix/src/pthreadgetschedparam.c b/cpukit/posix/src/pthreadgetschedparam.c
index d3fa9d4..d769d8a 100644
--- a/cpukit/posix/src/pthreadgetschedparam.c
+++ b/cpukit/posix/src/pthreadgetschedparam.c
@@ -34,35 +34,29 @@ int pthread_getschedparam(
   struct sched_param *param
 )
 {
-  Objects_Locations        location;
-  POSIX_API_Control       *api;
-  Thread_Control          *the_thread;
+  Thread_Control    *the_thread;
+  ISR_lock_Context   lock_context;
+  POSIX_API_Control *api;
 
-  if ( !policy || !param  )
+  if ( policy == NULL || param == NULL ) {
     return EINVAL;
+  }
 
-  the_thread = _Thread_Get( thread, &location );
-  switch ( location ) {
-
-    case OBJECTS_LOCAL:
-      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
-      if ( policy )
-        *policy = api->schedpolicy;
-      if ( param ) {
-        *param  = api->schedparam;
-        param->sched_priority =
-          _POSIX_Priority_From_core( the_thread->current_priority );
-      }
-      _Objects_Put( &the_thread->Object );
-      return 0;
+  the_thread = _Thread_Get_interrupt_disable( thread, &lock_context );
 
-#if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:
-#endif
-    case OBJECTS_ERROR:
-      break;
+  if ( the_thread == NULL ) {
+    return ESRCH;
   }
 
-  return ESRCH;
+  _Thread_State_acquire_critical( the_thread, &lock_context );
+
+  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+  *policy = api->schedpolicy;
+  *param  = api->schedparam;
+  param->sched_priority = _POSIX_Priority_From_core(
+    the_thread->current_priority
+  );
 
+  _Thread_State_release( the_thread, &lock_context );
+  return 0;
 }
diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c
index 57a2bc8..8f3cc20 100644
--- a/cpukit/posix/src/pthreadsetschedparam.c
+++ b/cpukit/posix/src/pthreadsetschedparam.c
@@ -38,11 +38,11 @@ int pthread_setschedparam(
 )
 {
   Thread_Control                      *the_thread;
+  Per_CPU_Control                     *cpu_self;
   POSIX_API_Control                   *api;
   Thread_CPU_budget_algorithms         budget_algorithm;
   Thread_CPU_budget_algorithm_callout  budget_callout;
-  Objects_Locations                    location;
-  int                                  rc;
+  int                                  eno;
   Priority_Control                     unused;
   ISR_lock_Context                     lock_context;
   Priority_Control                     new_priority;
@@ -50,79 +50,76 @@ int pthread_setschedparam(
   /*
    *  Check all the parameters
    */
-  if ( !param )
+
+  if ( param == NULL ) {
     return EINVAL;
+  }
 
-  rc = _POSIX_Thread_Translate_sched_param(
+  eno = _POSIX_Thread_Translate_sched_param(
     policy,
     param,
     &budget_algorithm,
     &budget_callout
   );
-  if ( rc )
-    return rc;
+  if ( eno != 0 ) {
+    return eno;
+  }
+
+  the_thread = _Thread_Get_interrupt_disable( thread, &lock_context );
+
+  if ( the_thread == NULL ) {
+    return ESRCH;
+  }
 
   /*
    *  Actually change the scheduling policy and parameters
    */
-  the_thread = _Thread_Get( thread, &location );
-  switch ( location ) {
-
-    case OBJECTS_LOCAL:
-      api = the_thread->API_Extensions[ THREAD_API_POSIX ];
-
-      _POSIX_Threads_Scheduler_acquire( api, &lock_context );
-
-      if ( api->schedpolicy == SCHED_SPORADIC ) {
-        _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
-      }
-
-      api->schedpolicy = policy;
-      api->schedparam  = *param;
-      api->Attributes.schedpolicy = policy;
-      api->Attributes.schedparam  = *param;
-
-      the_thread->budget_algorithm = budget_algorithm;
-      the_thread->budget_callout   = budget_callout;
-
-      switch ( policy ) {
-        case SCHED_OTHER:
-        case SCHED_FIFO:
-        case SCHED_RR:
-          the_thread->cpu_time_budget =
-            rtems_configuration_get_ticks_per_timeslice();
-	  new_priority =
-            _POSIX_Priority_To_core( api->schedparam.sched_priority );
-          break;
-
-        case SCHED_SPORADIC:
-          api->ss_high_priority = api->schedparam.sched_priority;
-          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;
-      }
-
-      _Objects_Put( &the_thread->Object );
-      return 0;
-
-#if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:
-#endif
-    case OBJECTS_ERROR:
+
+  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+  _Thread_State_acquire_critical( the_thread, &lock_context );
+
+  api = the_thread->API_Extensions[ THREAD_API_POSIX ];
+
+  if ( api->schedpolicy == SCHED_SPORADIC ) {
+    _Watchdog_Per_CPU_remove_relative( &api->Sporadic_timer );
+  }
+
+  api->schedpolicy = policy;
+  api->schedparam  = *param;
+  api->Attributes.schedpolicy = policy;
+  api->Attributes.schedparam  = *param;
+
+  the_thread->budget_algorithm = budget_algorithm;
+  the_thread->budget_callout   = budget_callout;
+
+  switch ( policy ) {
+    case SCHED_OTHER:
+    case SCHED_FIFO:
+    case SCHED_RR:
+      the_thread->cpu_time_budget =
+        rtems_configuration_get_ticks_per_timeslice();
+      new_priority = _POSIX_Priority_To_core( api->schedparam.sched_priority );
+      break;
+
+    case SCHED_SPORADIC:
+      api->ss_high_priority = api->schedparam.sched_priority;
+      break;
+  }
+
+  _Thread_State_release( the_thread, &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;
   }
 
-  return ESRCH;
+  _Thread_Dispatch_enable( cpu_self );
+  return 0;
 }
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 18e0f54..b8e0e00 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -719,7 +719,12 @@ struct _Thread_Control {
    * the following fields
    *
    * - POSIX_API_Control::Attributes,
+   * - POSIX_API_Control::schedparam,
+   * - POSIX_API_Control::schedpolicy,
    * - RTEMS_API_Control::Signal,
+   * - Thread_Control::budget_algorithm,
+   * - Thread_Control::budget_callout,
+   * - Thread_Control::cpu_time_budget,
    * - Thread_Control::current_state,
    * - Thread_Control::Post_switch_actions,
    * - Thread_Control::Scheduler::control, and
-- 
1.8.4.5



More information about the devel mailing list