Use an ISR lock to protect the partition state changes. Update #2555. --- cpukit/rtems/include/rtems/rtems/part.h | 3 ++ cpukit/rtems/include/rtems/rtems/partimpl.h | 73 ++++++++++++++++++++++------- cpukit/rtems/src/partcreate.c | 15 +++--- cpukit/rtems/src/partdelete.c | 16 ++++--- cpukit/rtems/src/partgetbuffer.c | 23 +++++---- cpukit/rtems/src/partreturnbuffer.c | 34 ++++---------- 6 files changed, 97 insertions(+), 67 deletions(-)
diff --git a/cpukit/rtems/include/rtems/rtems/part.h b/cpukit/rtems/include/rtems/rtems/part.h index 7dd90a9..5b840cc 100644 --- a/cpukit/rtems/include/rtems/rtems/part.h +++ b/cpukit/rtems/include/rtems/rtems/part.h @@ -34,6 +34,7 @@ #include <rtems/rtems/attr.h> #include <rtems/rtems/status.h> #include <rtems/rtems/types.h> +#include <rtems/score/isrlock.h> #ifdef __cplusplus extern "C" { @@ -55,6 +56,8 @@ extern "C" { typedef struct { /** This field is the object management portion of a Partition instance. */ Objects_Control Object; + /** This field is the lock of the Partition. */ + ISR_LOCK_MEMBER( Lock ) /** This field is the physical starting address of the Partition. */ void *starting_address; /** This field is the size of the Partition in bytes. */ diff --git a/cpukit/rtems/include/rtems/rtems/partimpl.h b/cpukit/rtems/include/rtems/rtems/partimpl.h index 472e06f..0ce7622 100644 --- a/cpukit/rtems/include/rtems/rtems/partimpl.h +++ b/cpukit/rtems/include/rtems/rtems/partimpl.h @@ -50,7 +50,7 @@ RTEMS_INLINE_ROUTINE void *_Partition_Allocate_buffer ( Partition_Control *the_partition ) { - return _Chain_Get( &the_partition->Memory ); + return _Chain_Get_unprotected( &the_partition->Memory ); } /** @@ -63,7 +63,7 @@ RTEMS_INLINE_ROUTINE void _Partition_Free_buffer ( Chain_Node *the_buffer ) { - _Chain_Append( &the_partition->Memory, the_buffer ); + _Chain_Append_unprotected( &the_partition->Memory, the_buffer ); } /** @@ -136,6 +136,37 @@ RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Allocate ( void ) return (Partition_Control *) _Objects_Allocate( &_Partition_Information ); } +RTEMS_INLINE_ROUTINE void _Partition_Initialize( + Partition_Control *the_partition, + void *starting_address, + uint32_t length, + uint32_t buffer_size, + rtems_attribute attribute_set +) +{ + the_partition->starting_address = starting_address; + the_partition->length = length; + the_partition->buffer_size = buffer_size; + the_partition->attribute_set = attribute_set; + the_partition->number_of_used_blocks = 0; + + _Chain_Initialize( + &the_partition->Memory, + starting_address, + length / buffer_size, + buffer_size + ); + + _ISR_lock_Initialize( &the_partition->Lock, "Partition" ); +} + +RTEMS_INLINE_ROUTINE void _Partition_Destroy( + Partition_Control *the_partition +) +{ + _ISR_lock_Destroy( &the_partition->Lock ); +} + /** * @brief Frees a partition control block to the * inactive chain of free partition control blocks. @@ -150,24 +181,34 @@ RTEMS_INLINE_ROUTINE void _Partition_Free ( _Objects_Free( &_Partition_Information, &the_partition->Object ); } -/** - * @brief Maps partition IDs to partition control blocks. - * - * This function maps partition IDs to partition control blocks. - * If ID corresponds to a local partition, then it returns - * the_partition control pointer which maps to ID and location - * is set to OBJECTS_LOCAL. If the partition ID is global and - * resides on a remote node, then location is set to OBJECTS_REMOTE, - * and the_partition is undefined. Otherwise, location is set - * to OBJECTS_ERROR and the_partition is undefined. - */ RTEMS_INLINE_ROUTINE Partition_Control *_Partition_Get ( Objects_Id id, - Objects_Locations *location + Objects_Locations *location, + ISR_lock_Context *lock_context +) +{ + return (Partition_Control *) _Objects_Get_isr_disable( + &_Partition_Information, + id, + location, + lock_context + ); +} + +RTEMS_INLINE_ROUTINE void _Partition_Acquire_critical( + Partition_Control *the_partition, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Acquire( &the_partition->Lock, lock_context ); +} + +RTEMS_INLINE_ROUTINE void _Partition_Release( + Partition_Control *the_partition, + ISR_lock_Context *lock_context ) { - return (Partition_Control *) - _Objects_Get( &_Partition_Information, id, location ); + _ISR_lock_Release_and_ISR_enable( &the_partition->Lock, lock_context ); } /**@}*/ diff --git a/cpukit/rtems/src/partcreate.c b/cpukit/rtems/src/partcreate.c index e3544e7..c058adf 100644 --- a/cpukit/rtems/src/partcreate.c +++ b/cpukit/rtems/src/partcreate.c @@ -94,14 +94,13 @@ rtems_status_code rtems_partition_create( } #endif - the_partition->starting_address = starting_address; - the_partition->length = length; - the_partition->buffer_size = buffer_size; - the_partition->attribute_set = attribute_set; - the_partition->number_of_used_blocks = 0; - - _Chain_Initialize( &the_partition->Memory, starting_address, - length / buffer_size, buffer_size ); + _Partition_Initialize( + the_partition, + starting_address, + length, + buffer_size, + attribute_set + ); _Objects_Open( &_Partition_Information, diff --git a/cpukit/rtems/src/partdelete.c b/cpukit/rtems/src/partdelete.c index 032f73d..2df3893 100644 --- a/cpukit/rtems/src/partdelete.c +++ b/cpukit/rtems/src/partdelete.c @@ -20,20 +20,22 @@ #include <rtems/rtems/partimpl.h> #include <rtems/rtems/attrimpl.h> -#include <rtems/score/threaddispatch.h> rtems_status_code rtems_partition_delete( rtems_id id ) { - Partition_Control *the_partition; - Objects_Locations location; + Partition_Control *the_partition; + Objects_Locations location; + ISR_lock_Context lock_context; _Objects_Allocator_lock(); - the_partition = _Partition_Get( id, &location ); + the_partition = _Partition_Get( id, &location, &lock_context ); switch ( location ) { case OBJECTS_LOCAL: + _Partition_Acquire_critical( the_partition, &lock_context ); + if ( the_partition->number_of_used_blocks == 0 ) { _Objects_Close( &_Partition_Information, &the_partition->Object ); #if defined(RTEMS_MULTIPROCESSING) @@ -53,12 +55,14 @@ rtems_status_code rtems_partition_delete( } #endif - _Objects_Put( &the_partition->Object ); + _Partition_Release( the_partition, &lock_context ); + _Partition_Destroy( the_partition ); _Partition_Free( the_partition ); _Objects_Allocator_unlock(); return RTEMS_SUCCESSFUL; } - _Objects_Put( &the_partition->Object ); + + _Partition_Release( the_partition, &lock_context ); _Objects_Allocator_unlock(); return RTEMS_RESOURCE_IN_USE; diff --git a/cpukit/rtems/src/partgetbuffer.c b/cpukit/rtems/src/partgetbuffer.c index 3a7e8bf..39cac5e 100644 --- a/cpukit/rtems/src/partgetbuffer.c +++ b/cpukit/rtems/src/partgetbuffer.c @@ -18,37 +18,36 @@ #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/partimpl.h> -#include <rtems/score/thread.h> rtems_status_code rtems_partition_get_buffer( rtems_id id, void **buffer ) { - Partition_Control *the_partition; - Objects_Locations location; - void *the_buffer; + Partition_Control *the_partition; + Objects_Locations location; + ISR_lock_Context lock_context; + void *the_buffer; if ( !buffer ) return RTEMS_INVALID_ADDRESS; - the_partition = _Partition_Get( id, &location ); + the_partition = _Partition_Get( id, &location, &lock_context ); switch ( location ) { case OBJECTS_LOCAL: + _Partition_Acquire_critical( the_partition, &lock_context ); + the_buffer = _Partition_Allocate_buffer( the_partition ); - if ( the_buffer ) { + if ( the_buffer != NULL ) { the_partition->number_of_used_blocks += 1; - _Objects_Put( &the_partition->Object ); + _Partition_Release( the_partition, &lock_context ); *buffer = the_buffer; return RTEMS_SUCCESSFUL; } - _Objects_Put( &the_partition->Object ); + + _Partition_Release( the_partition, &lock_context ); return RTEMS_UNSATISFIED; #if defined(RTEMS_MULTIPROCESSING) diff --git a/cpukit/rtems/src/partreturnbuffer.c b/cpukit/rtems/src/partreturnbuffer.c index 2cccc3c..641abed 100644 --- a/cpukit/rtems/src/partreturnbuffer.c +++ b/cpukit/rtems/src/partreturnbuffer.c @@ -14,47 +14,31 @@ #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/partimpl.h> -#include <rtems/score/thread.h> - -/* - * rtems_partition_return_buffer - * - * This directive will return the given buffer to the specified - * buffer partition. - * - * Input parameters: - * id - partition id - * buffer - pointer to buffer address - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ rtems_status_code rtems_partition_return_buffer( rtems_id id, void *buffer ) { - Partition_Control *the_partition; - Objects_Locations location; + Partition_Control *the_partition; + Objects_Locations location; + ISR_lock_Context lock_context; - the_partition = _Partition_Get( id, &location ); + the_partition = _Partition_Get( id, &location, &lock_context ); switch ( location ) { case OBJECTS_LOCAL: + _Partition_Acquire_critical( the_partition, &lock_context ); + if ( _Partition_Is_buffer_valid( buffer, the_partition ) ) { _Partition_Free_buffer( the_partition, buffer ); the_partition->number_of_used_blocks -= 1; - _Objects_Put( &the_partition->Object ); + _Partition_Release( the_partition, &lock_context ); return RTEMS_SUCCESSFUL; } - _Objects_Put( &the_partition->Object ); + + _Partition_Release( the_partition, &lock_context ); return RTEMS_INVALID_ADDRESS; #if defined(RTEMS_MULTIPROCESSING) -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel