[rtems commit] score: Avoid Giant lock _Scheduler_Get_affinity()

Sebastian Huber sebh at rtems.org
Thu May 12 11:34:58 UTC 2016


Module:    rtems
Branch:    master
Commit:    d99529999451043166c6dbf3ef22be42463e16f3
Changeset: http://git.rtems.org/rtems/commit/?id=d99529999451043166c6dbf3ef22be42463e16f3

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed May 11 11:06:51 2016 +0200

score: Avoid Giant lock _Scheduler_Get_affinity()

Update #2555.

---

 cpukit/posix/src/pthreadgetaffinitynp.c | 49 +++++++++++++++----------------
 cpukit/rtems/src/taskgetaffinity.c      | 51 +++++++++++++++++----------------
 cpukit/score/src/schedulergetaffinity.c | 13 +++++++--
 3 files changed, 62 insertions(+), 51 deletions(-)

diff --git a/cpukit/posix/src/pthreadgetaffinitynp.c b/cpukit/posix/src/pthreadgetaffinitynp.c
index 7636954..7e0c32e 100644
--- a/cpukit/posix/src/pthreadgetaffinitynp.c
+++ b/cpukit/posix/src/pthreadgetaffinitynp.c
@@ -31,37 +31,38 @@
 #include <rtems/score/schedulerimpl.h>
 
 int pthread_getaffinity_np(
-  const pthread_t       id,
-  size_t                cpusetsize,
-  cpu_set_t            *cpuset
+  pthread_t  thread,
+  size_t     cpusetsize,
+  cpu_set_t *cpuset
 )
 {
-  Objects_Locations        location;
-  Thread_Control          *the_thread;
-  bool                     ok;
+  Thread_Control   *the_thread;
+  ISR_lock_Context  lock_context;
+  Per_CPU_Control  *cpu_self;
+  bool              ok;
 
-  if ( !cpuset )
+  if ( cpuset == NULL ) {
     return EFAULT;
+  }
 
-  the_thread = _Thread_Get( id, &location );
-  switch ( location ) {
-
-    case OBJECTS_LOCAL:
-      ok = _Scheduler_Get_affinity(
-        the_thread,
-        cpusetsize,
-        cpuset
-      );
-      _Objects_Put( &the_thread->Object );
-      return ok ? 0 : EINVAL;
+  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;
+
+  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+  _Thread_State_acquire_critical( the_thread, &lock_context );
+
+  ok = _Scheduler_Get_affinity(
+    the_thread,
+    cpusetsize,
+    cpuset
+  );
+
+  _Thread_State_release( the_thread, &lock_context );
+  _Thread_Dispatch_enable( cpu_self );
+  return ok ? 0 : EINVAL;
 }
 
 #endif
diff --git a/cpukit/rtems/src/taskgetaffinity.c b/cpukit/rtems/src/taskgetaffinity.c
index 25339b4..27c21db 100644
--- a/cpukit/rtems/src/taskgetaffinity.c
+++ b/cpukit/rtems/src/taskgetaffinity.c
@@ -25,41 +25,44 @@
 #include <rtems/score/cpusetimpl.h>
 #include <rtems/score/schedulerimpl.h>
 
-
 rtems_status_code rtems_task_get_affinity(
-  rtems_id             id,
-  size_t               cpusetsize,
-  cpu_set_t           *cpuset
+  rtems_id   id,
+  size_t     cpusetsize,
+  cpu_set_t *cpuset
 )
 {
-  Thread_Control        *the_thread;
-  Objects_Locations      location;
-  bool                   ok;
+  Thread_Control   *the_thread;
+  ISR_lock_Context  lock_context;
+  Per_CPU_Control  *cpu_self;
+  bool              ok;
 
-  if ( !cpuset )
+  if ( cpuset == NULL ) {
     return RTEMS_INVALID_ADDRESS;
+  }
 
-  the_thread = _Thread_Get( id, &location );
-
-  switch ( location ) {
-
-    case OBJECTS_LOCAL:
-      ok = _Scheduler_Get_affinity(
-        the_thread,
-        cpusetsize,
-        cpuset
-      );
-      _Objects_Put( &the_thread->Object );
-      return ok ? RTEMS_SUCCESSFUL : RTEMS_INVALID_NUMBER;
+  the_thread = _Thread_Get_interrupt_disable( id, &lock_context );
 
+  if ( the_thread == NULL ) {
 #if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:
+    if ( _Thread_MP_Is_remote( id ) ) {
+      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+    }
 #endif
 
-    case OBJECTS_ERROR:
-      break;
+    return RTEMS_INVALID_ID;
   }
 
-  return RTEMS_INVALID_ID;
+  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+  _Thread_State_acquire_critical( the_thread, &lock_context );
+
+  ok = _Scheduler_Get_affinity(
+    the_thread,
+    cpusetsize,
+    cpuset
+  );
+
+  _Thread_State_release( the_thread, &lock_context );
+  _Thread_Dispatch_enable( cpu_self );
+  return ok ? RTEMS_SUCCESSFUL : RTEMS_INVALID_NUMBER;
 }
 #endif
diff --git a/cpukit/score/src/schedulergetaffinity.c b/cpukit/score/src/schedulergetaffinity.c
index 06ebfbe..c910a75 100644
--- a/cpukit/score/src/schedulergetaffinity.c
+++ b/cpukit/score/src/schedulergetaffinity.c
@@ -26,28 +26,35 @@ bool _Scheduler_Get_affinity(
   cpu_set_t      *cpuset
 )
 {
-  const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
+  const Scheduler_Control *scheduler;
+  ISR_lock_Context         lock_context;
+  bool                     ok;
 
   if ( !_CPU_set_Is_large_enough( cpusetsize ) ) {
     return false;
   }
 
+  scheduler = _Scheduler_Get( the_thread );
+  _Scheduler_Acquire_critical( scheduler, &lock_context );
 
 #if defined(RTEMS_SMP)
-  return ( *scheduler->Operations.get_affinity )(
+  ok = ( *scheduler->Operations.get_affinity )(
     scheduler,
     the_thread,
     cpusetsize,
     cpuset
   );
 #else
-  return _Scheduler_default_Get_affinity_body(
+  ok = _Scheduler_default_Get_affinity_body(
     scheduler,
     the_thread,
     cpusetsize,
     cpuset
   );
 #endif
+
+  _Scheduler_Release_critical( scheduler, &lock_context );
+  return ok;
 }
 
 #endif /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */




More information about the vc mailing list