rtems: Avoid Giant lock for dual ported memory

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.
This commit is contained in:
Sebastian Huber
2016-04-21 07:52:19 +02:00
parent 84a5398853
commit 9c3bae11b3
4 changed files with 56 additions and 94 deletions

View File

@@ -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 );
}
/**@}*/

View File

@@ -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;
}

View File

@@ -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;
}
return RTEMS_INVALID_ID;
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 );
}
_ISR_lock_ISR_enable( &lock_context );
return RTEMS_SUCCESSFUL;
}

View File

@@ -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;
}
return RTEMS_INVALID_ID;
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 );
}
_ISR_lock_ISR_enable( &lock_context );
return RTEMS_SUCCESSFUL;
}