[PATCH 10/10] rtems: Avoid Giant lock for dual ported memory

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Apr 21 07:20:14 UTC 2016


There is no need for an ISR lock since the Dual_ported_memory_Control is
immutable after initialization.  ISR disable is enough for deletion
safety on uni-processor configurations.

Update #2555.
---
 cpukit/rtems/include/rtems/rtems/dpmemimpl.h | 18 +++--------
 cpukit/rtems/src/dpmemdelete.c               | 33 ++++++-------------
 cpukit/rtems/src/dpmemexternal2internal.c    | 47 ++++++++++++---------------
 cpukit/rtems/src/dpmeminternal2external.c    | 48 ++++++++++++----------------
 4 files changed, 54 insertions(+), 92 deletions(-)

diff --git a/cpukit/rtems/include/rtems/rtems/dpmemimpl.h b/cpukit/rtems/include/rtems/rtems/dpmemimpl.h
index 213856d..1e96722 100644
--- a/cpukit/rtems/include/rtems/rtems/dpmemimpl.h
+++ b/cpukit/rtems/include/rtems/rtems/dpmemimpl.h
@@ -66,23 +66,13 @@ RTEMS_INLINE_ROUTINE void _Dual_ported_memory_Free (
   _Objects_Free( &_Dual_ported_memory_Information, &the_port->Object );
 }
 
-/**
- *  @brief Maps port IDs to port control blocks.
- *
- *  This function maps port IDs to port control blocks.  If ID
- *  corresponds to a local port, then it returns the_port control
- *  pointer which maps to ID and location is set to OBJECTS_LOCAL.
- *  Global ports are not supported, thus if ID  does not map to a
- *  local port, location is set to OBJECTS_ERROR and the_port is
- *  undefined.
- */
-RTEMS_INLINE_ROUTINE Dual_ported_memory_Control *_Dual_ported_memory_Get (
-  Objects_Id         id,
-  Objects_Locations *location
+RTEMS_INLINE_ROUTINE Dual_ported_memory_Control *_Dual_ported_memory_Get(
+  Objects_Id        id,
+  ISR_lock_Context *lock_context
 )
 {
   return (Dual_ported_memory_Control *)
-     _Objects_Get( &_Dual_ported_memory_Information, id, location );
+    _Objects_Get_local( id, &_Dual_ported_memory_Information, lock_context );
 }
 
 /**@}*/
diff --git a/cpukit/rtems/src/dpmemdelete.c b/cpukit/rtems/src/dpmemdelete.c
index 6f11a53..f303629 100644
--- a/cpukit/rtems/src/dpmemdelete.c
+++ b/cpukit/rtems/src/dpmemdelete.c
@@ -18,39 +18,26 @@
 #include "config.h"
 #endif
 
-#include <rtems/system.h>
-#include <rtems/rtems/status.h>
-#include <rtems/rtems/support.h>
-#include <rtems/score/address.h>
 #include <rtems/rtems/dpmemimpl.h>
-#include <rtems/score/thread.h>
 
 rtems_status_code rtems_port_delete(
   rtems_id id
 )
 {
-  Dual_ported_memory_Control          *the_port;
-  Objects_Locations                    location;
+  Dual_ported_memory_Control *the_port;
+  ISR_lock_Context            lock_context;
 
   _Objects_Allocator_lock();
-  the_port = _Dual_ported_memory_Get( id, &location );
-  switch ( location ) {
+  the_port = _Dual_ported_memory_Get( id, &lock_context );
 
-    case OBJECTS_LOCAL:
-      _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object );
-      _Objects_Put( &the_port->Object );
-      _Dual_ported_memory_Free( the_port );
-      _Objects_Allocator_unlock();
-      return RTEMS_SUCCESSFUL;
-
-#if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:        /* this error cannot be returned */
-#endif
-    case OBJECTS_ERROR:
-      break;
+  if ( the_port == NULL ) {
+    _Objects_Allocator_unlock();
+    return RTEMS_INVALID_ID;
   }
 
+  _Objects_Close( &_Dual_ported_memory_Information, &the_port->Object );
+  _ISR_lock_ISR_enable( &lock_context );
+  _Dual_ported_memory_Free( the_port );
   _Objects_Allocator_unlock();
-
-  return RTEMS_INVALID_ID;
+  return RTEMS_SUCCESSFUL;
 }
diff --git a/cpukit/rtems/src/dpmemexternal2internal.c b/cpukit/rtems/src/dpmemexternal2internal.c
index 237d5c4..0456010 100644
--- a/cpukit/rtems/src/dpmemexternal2internal.c
+++ b/cpukit/rtems/src/dpmemexternal2internal.c
@@ -18,12 +18,8 @@
 #include "config.h"
 #endif
 
-#include <rtems/system.h>
-#include <rtems/rtems/status.h>
-#include <rtems/rtems/support.h>
-#include <rtems/score/address.h>
 #include <rtems/rtems/dpmemimpl.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/address.h>
 
 rtems_status_code rtems_port_external_to_internal(
   rtems_id   id,
@@ -31,31 +27,28 @@ rtems_status_code rtems_port_external_to_internal(
   void     **internal
 )
 {
-  Dual_ported_memory_Control          *the_port;
-  Objects_Locations                    location;
-  uint32_t                             ending;
+  Dual_ported_memory_Control *the_port;
+  ISR_lock_Context            lock_context;
+  uint32_t                    ending;
 
-  if ( !internal )
+  if ( internal == NULL ) {
     return RTEMS_INVALID_ADDRESS;
+  }
 
-  the_port = _Dual_ported_memory_Get( id, &location );
-  switch ( location ) {
-    case OBJECTS_LOCAL:
-      ending = _Addresses_Subtract( external, the_port->external_base );
-      if ( ending > the_port->length )
-        *internal = external;
-      else
-        *internal = _Addresses_Add_offset( the_port->internal_base,
-                                           ending );
-      _Objects_Put( &the_port->Object );
-      return RTEMS_SUCCESSFUL;
-
-#if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:        /* this error cannot be returned */
-#endif
-    case OBJECTS_ERROR:
-      break;
+  the_port = _Dual_ported_memory_Get( id, &lock_context );
+
+  if ( the_port == NULL ) {
+    return RTEMS_INVALID_ID;
+  }
+
+  ending = _Addresses_Subtract( external, the_port->external_base );
+
+  if ( ending > the_port->length ) {
+    *internal = external;
+  } else {
+    *internal = _Addresses_Add_offset( the_port->internal_base, ending );
   }
 
-  return RTEMS_INVALID_ID;
+  _ISR_lock_ISR_enable( &lock_context );
+  return RTEMS_SUCCESSFUL;
 }
diff --git a/cpukit/rtems/src/dpmeminternal2external.c b/cpukit/rtems/src/dpmeminternal2external.c
index e048d8a..bd66ee4 100644
--- a/cpukit/rtems/src/dpmeminternal2external.c
+++ b/cpukit/rtems/src/dpmeminternal2external.c
@@ -18,12 +18,8 @@
 #include "config.h"
 #endif
 
-#include <rtems/system.h>
-#include <rtems/rtems/status.h>
-#include <rtems/rtems/support.h>
-#include <rtems/score/address.h>
 #include <rtems/rtems/dpmemimpl.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/address.h>
 
 rtems_status_code rtems_port_internal_to_external(
   rtems_id   id,
@@ -31,32 +27,28 @@ rtems_status_code rtems_port_internal_to_external(
   void     **external
 )
 {
-  Dual_ported_memory_Control          *the_port;
-  Objects_Locations                    location;
-  uint32_t                             ending;
+  Dual_ported_memory_Control *the_port;
+  ISR_lock_Context            lock_context;
+  uint32_t                    ending;
 
-  if ( !external )
+  if ( external == NULL ) {
     return RTEMS_INVALID_ADDRESS;
+  }
 
-  the_port = _Dual_ported_memory_Get( id, &location );
-  switch ( location ) {
-
-    case OBJECTS_LOCAL:
-      ending = _Addresses_Subtract( internal, the_port->internal_base );
-      if ( ending > the_port->length )
-        *external = internal;
-      else
-        *external = _Addresses_Add_offset( the_port->external_base,
-                                           ending );
-      _Objects_Put( &the_port->Object );
-      return RTEMS_SUCCESSFUL;
-
-#if defined(RTEMS_MULTIPROCESSING)
-    case OBJECTS_REMOTE:        /* this error cannot be returned */
-#endif
-    case OBJECTS_ERROR:
-      break;
+  the_port = _Dual_ported_memory_Get( id, &lock_context );
+
+  if ( the_port == NULL ) {
+    return RTEMS_INVALID_ID;
+  }
+
+  ending = _Addresses_Subtract( internal, the_port->internal_base );
+
+  if ( ending > the_port->length ) {
+    *external = internal;
+  } else {
+    *external = _Addresses_Add_offset( the_port->external_base, ending );
   }
 
-  return RTEMS_INVALID_ID;
+  _ISR_lock_ISR_enable( &lock_context );
+  return RTEMS_SUCCESSFUL;
 }
-- 
1.8.4.5




More information about the devel mailing list