[PATCH 11/19] rtems: Avoid Giant lock for semaphores

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Apr 29 09:13:11 UTC 2016


Update #2555.
---
 cpukit/libnetworking/rtems/rtems_glue.c    |  7 ++-----
 cpukit/rtems/include/rtems/rtems/semimpl.h | 20 --------------------
 cpukit/rtems/src/semsetpriority.c          | 26 ++++++++++++++++++++------
 testsuites/tmtests/tm26/task1.c            | 14 +++++++++++---
 4 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c
index f079a67..b360b07 100644
--- a/cpukit/libnetworking/rtems/rtems_glue.c
+++ b/cpukit/libnetworking/rtems/rtems_glue.c
@@ -330,11 +330,8 @@ rtems_bsdnet_initialize (void)
 		return -1;
 	}
 #ifdef RTEMS_FAST_MUTEX
-	{
-	Objects_Locations location;
-	the_networkSemaphore = _Semaphore_Get( networkSemaphore, &location );
-	_Thread_Enable_dispatch();
-	}
+	the_networkSemaphore = (Semaphore_Control *)
+		_Objects_Get_no_protection(networkSemaphore, &_Semaphore_Information);
 #endif
 
 	/*
diff --git a/cpukit/rtems/include/rtems/rtems/semimpl.h b/cpukit/rtems/include/rtems/rtems/semimpl.h
index 68eac6f..b67b415 100644
--- a/cpukit/rtems/include/rtems/rtems/semimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/semimpl.h
@@ -145,26 +145,6 @@ RTEMS_INLINE_ROUTINE void _Semaphore_Free (
  *  and the_semaphore is undefined.  Otherwise, location is set
  *  to OBJECTS_ERROR and the_semaphore is undefined.
  */
-RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get (
-  Objects_Id         id,
-  Objects_Locations *location
-)
-{
-  return (Semaphore_Control *)
-    _Objects_Get( &_Semaphore_Information, id, location );
-}
-
-/**
- *  @brief Maps semaphore IDs to semaphore control blocks.
- *
- *  This function maps semaphore IDs to semaphore control blocks.
- *  If ID corresponds to a local semaphore, then it returns
- *  the_semaphore control pointer which maps to ID and location
- *  is set to OBJECTS_LOCAL.  if the semaphore ID is global and
- *  resides on a remote node, then location is set to OBJECTS_REMOTE,
- *  and the_semaphore is undefined.  Otherwise, location is set
- *  to OBJECTS_ERROR and the_semaphore is undefined.
- */
 RTEMS_INLINE_ROUTINE Semaphore_Control *_Semaphore_Get_interrupt_disable (
   Objects_Id         id,
   Objects_Locations *location,
diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c
index b5dd1db..1073a56 100644
--- a/cpukit/rtems/src/semsetpriority.c
+++ b/cpukit/rtems/src/semsetpriority.c
@@ -25,7 +25,8 @@ static rtems_status_code _Semaphore_Set_priority(
   Semaphore_Control   *the_semaphore,
   rtems_id             scheduler_id,
   rtems_task_priority  new_priority,
-  rtems_task_priority *old_priority_p
+  rtems_task_priority *old_priority_p,
+  ISR_lock_Context    *lock_context
 )
 {
   rtems_status_code   sc;
@@ -39,26 +40,36 @@ static rtems_status_code _Semaphore_Set_priority(
     MRSP_Control *mrsp = &the_semaphore->Core_control.mrsp;
     uint32_t scheduler_index = _Scheduler_Get_index_by_id( scheduler_id );
 
+    _MRSP_Acquire_critical( mrsp, lock_context );
+
     old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index );
 
     if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
       _MRSP_Set_ceiling_priority( mrsp, scheduler_index, new_priority );
     }
 
+    _MRSP_Release( mrsp, lock_context );
+
     sc = RTEMS_SUCCESSFUL;
   } else
 #endif
   if ( _Attributes_Is_priority_ceiling( attribute_set ) ) {
     CORE_mutex_Control *mutex = &the_semaphore->Core_control.mutex;
 
+    _CORE_mutex_Acquire_critical( mutex, lock_context );
+
     old_priority = mutex->Attributes.priority_ceiling;
 
     if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
       mutex->Attributes.priority_ceiling = new_priority;
     }
 
+    _CORE_mutex_Release( mutex, lock_context );
+
     sc = RTEMS_SUCCESSFUL;
   } else {
+    _ISR_lock_ISR_enable( lock_context );
+
     old_priority = 0;
 
     sc = RTEMS_NOT_DEFINED;
@@ -66,8 +77,6 @@ static rtems_status_code _Semaphore_Set_priority(
 
   *old_priority_p = _RTEMS_tasks_Priority_from_Core( old_priority );
 
-  _Objects_Put( &the_semaphore->Object );
-
   return sc;
 }
 
@@ -80,6 +89,7 @@ rtems_status_code rtems_semaphore_set_priority(
 {
   Semaphore_Control *the_semaphore;
   Objects_Locations  location;
+  ISR_lock_Context   lock_context;
 
   if ( new_priority != RTEMS_CURRENT_PRIORITY &&
        !_RTEMS_tasks_Priority_is_valid( new_priority ) ) {
@@ -94,18 +104,22 @@ rtems_status_code rtems_semaphore_set_priority(
     return RTEMS_INVALID_ID;
   }
 
-  the_semaphore = _Semaphore_Get( semaphore_id, &location );
+  the_semaphore = _Semaphore_Get_interrupt_disable(
+    semaphore_id,
+    &location,
+    &lock_context
+  );
   switch ( location ) {
     case OBJECTS_LOCAL:
       return _Semaphore_Set_priority(
         the_semaphore,
         scheduler_id,
         new_priority,
-        old_priority
+        old_priority,
+        &lock_context
       );
 #if defined(RTEMS_MULTIPROCESSING)
     case OBJECTS_REMOTE:
-      _Thread_Dispatch();
       return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
 #endif
     case OBJECTS_ERROR:
diff --git a/testsuites/tmtests/tm26/task1.c b/testsuites/tmtests/tm26/task1.c
index 5b19c3d..a46f042 100644
--- a/testsuites/tmtests/tm26/task1.c
+++ b/testsuites/tmtests/tm26/task1.c
@@ -575,8 +575,16 @@ void complete_test( void )
   thread_get_time = benchmark_timer_read();
 
   benchmark_timer_initialize();
-    for ( index=1 ; index <= OPERATION_COUNT ; index++ )
-      (void) _Semaphore_Get( Semaphore_id, &location );
+    for ( index=1 ; index <= OPERATION_COUNT ; index++ ) {
+      ISR_lock_Context lock_context;
+
+      (void) _Semaphore_Get_interrupt_disable(
+        Semaphore_id,
+        &location,
+        &lock_context
+      );
+      _ISR_lock_ISR_enable( &lock_context );
+    }
   semaphore_get_time = benchmark_timer_read();
 
   benchmark_timer_initialize();
@@ -592,7 +600,7 @@ void complete_test( void )
   set_thread_heir( _Thread_Get_executing() );
   set_thread_dispatch_necessary( false );
 
-  for (index = 0; index < 2 * OPERATION_COUNT; ++index) {
+  for (index = 0; index < OPERATION_COUNT; ++index) {
     _Thread_Unnest_dispatch();
   }
 
-- 
1.8.4.5



More information about the devel mailing list