mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-23 16:23:52 +08:00
rtems: Avoid Giant lock for partitions
Use an ISR lock to protect the partition state changes. Update #2555.
This commit is contained in:
@@ -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. */
|
||||
|
||||
@@ -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( &_Partition_Information, id, location );
|
||||
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
|
||||
)
|
||||
{
|
||||
_ISR_lock_Release_and_ISR_enable( &the_partition->Lock, lock_context );
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user