forked from Imagelibrary/rtems
rtems: Add and use _Region_Get_and_lock()
Get region and lock allocator in _Region_Get_and_lock() in case the region exists and unlock it in _Region_Unlock().
This commit is contained in:
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <rtems/rtems/region.h>
|
||||
#include <rtems/score/apimutex.h>
|
||||
#include <rtems/score/assert.h>
|
||||
#include <rtems/score/heapimpl.h>
|
||||
#include <rtems/score/objectimpl.h>
|
||||
#include <rtems/score/threadqimpl.h>
|
||||
@@ -67,11 +66,28 @@ RTEMS_INLINE_ROUTINE void _Region_Free (
|
||||
_Objects_Free( &_Region_Information, &the_region->Object );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE Region_Control *_Region_Get( Objects_Id id )
|
||||
RTEMS_INLINE_ROUTINE Region_Control *_Region_Get_and_lock( Objects_Id id )
|
||||
{
|
||||
_Assert( _RTEMS_Allocator_is_owner() );
|
||||
return (Region_Control *)
|
||||
Region_Control *the_region;
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
|
||||
the_region = (Region_Control *)
|
||||
_Objects_Get_no_protection( &_Region_Information, id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
/* Keep allocator lock */
|
||||
return the_region;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Region_Unlock( Region_Control *the_region )
|
||||
{
|
||||
(void) the_region;
|
||||
_RTEMS_Unlock_allocator();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,23 +28,23 @@ rtems_status_code rtems_region_delete(
|
||||
Region_Control *the_region;
|
||||
|
||||
_Objects_Allocator_lock();
|
||||
_RTEMS_Lock_allocator();
|
||||
|
||||
the_region = _Region_Get( id );
|
||||
the_region = _Region_Get_and_lock( id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
if ( the_region->number_of_used_blocks != 0 ) {
|
||||
status = RTEMS_RESOURCE_IN_USE;
|
||||
} else {
|
||||
_Objects_Close( &_Region_Information, &the_region->Object );
|
||||
_Region_Free( the_region );
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
}
|
||||
} else {
|
||||
status = RTEMS_INVALID_ID;
|
||||
if ( the_region == NULL ) {
|
||||
_Objects_Allocator_unlock();
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
if ( the_region->number_of_used_blocks != 0 ) {
|
||||
status = RTEMS_RESOURCE_IN_USE;
|
||||
} else {
|
||||
_Objects_Close( &_Region_Information, &the_region->Object );
|
||||
_Region_Free( the_region );
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
_Region_Unlock( the_region );
|
||||
_Objects_Allocator_unlock();
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -34,29 +34,27 @@ rtems_status_code rtems_region_extend(
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
the_region = _Region_Get_and_lock( id );
|
||||
|
||||
the_region = _Region_Get( id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
amount_extended = _Heap_Extend(
|
||||
&the_region->Memory,
|
||||
starting_address,
|
||||
length,
|
||||
0
|
||||
);
|
||||
|
||||
if ( amount_extended > 0 ) {
|
||||
the_region->length += amount_extended;
|
||||
the_region->maximum_segment_size += amount_extended;
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
status = RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
} else {
|
||||
status = RTEMS_INVALID_ID;
|
||||
if ( the_region == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
amount_extended = _Heap_Extend(
|
||||
&the_region->Memory,
|
||||
starting_address,
|
||||
length,
|
||||
0
|
||||
);
|
||||
|
||||
if ( amount_extended > 0 ) {
|
||||
the_region->length += amount_extended;
|
||||
the_region->maximum_segment_size += amount_extended;
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
status = RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
_Region_Unlock( the_region );
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -27,25 +27,21 @@ rtems_status_code rtems_region_get_free_information(
|
||||
Heap_Information_block *the_info
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
Region_Control *the_region;
|
||||
Region_Control *the_region;
|
||||
|
||||
if ( the_info == NULL ) {
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
the_region = _Region_Get_and_lock( id );
|
||||
|
||||
the_region = _Region_Get( id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
memset( &the_info->Used, 0, sizeof( the_info->Used ) );
|
||||
_Heap_Get_free_information( &the_region->Memory, &the_info->Free );
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
status = RTEMS_INVALID_ID;
|
||||
if ( the_region == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
return status;
|
||||
memset( &the_info->Used, 0, sizeof( the_info->Used ) );
|
||||
_Heap_Get_free_information( &the_region->Memory, &the_info->Free );
|
||||
|
||||
_Region_Unlock( the_region );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -25,24 +25,20 @@ rtems_status_code rtems_region_get_information(
|
||||
Heap_Information_block *the_info
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
Region_Control *the_region;
|
||||
Region_Control *the_region;
|
||||
|
||||
if ( the_info == NULL ) {
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
the_region = _Region_Get_and_lock( id );
|
||||
|
||||
the_region = _Region_Get( id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
_Heap_Get_information( &the_region->Memory, the_info );
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
status = RTEMS_INVALID_ID;
|
||||
if ( the_region == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
return status;
|
||||
_Heap_Get_information( &the_region->Memory, the_info );
|
||||
|
||||
_Region_Unlock( the_region );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -44,60 +44,58 @@ rtems_status_code rtems_region_get_segment(
|
||||
return RTEMS_INVALID_SIZE;
|
||||
}
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
the_region = _Region_Get_and_lock( id );
|
||||
|
||||
the_region = _Region_Get( id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
if ( size > the_region->maximum_segment_size ) {
|
||||
status = RTEMS_INVALID_SIZE;
|
||||
} else {
|
||||
void *the_segment;
|
||||
|
||||
the_segment = _Region_Allocate_segment( the_region, size );
|
||||
|
||||
if ( the_segment != NULL ) {
|
||||
the_region->number_of_used_blocks += 1;
|
||||
*segment = the_segment;
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
} else if ( _Options_Is_no_wait( option_set ) ) {
|
||||
status = RTEMS_UNSATISFIED;
|
||||
} else {
|
||||
Per_CPU_Control *cpu_self;
|
||||
Thread_Control *executing;
|
||||
|
||||
/*
|
||||
* Switch from using the memory allocation mutex to using a
|
||||
* dispatching disabled critical section. We have to do this
|
||||
* because this thread is going to block.
|
||||
*/
|
||||
/* FIXME: This is a home grown condition variable */
|
||||
cpu_self = _Thread_Dispatch_disable();
|
||||
_RTEMS_Unlock_allocator();
|
||||
|
||||
executing = _Per_CPU_Get_executing( cpu_self );
|
||||
|
||||
executing->Wait.count = size;
|
||||
executing->Wait.return_argument = segment;
|
||||
|
||||
_Thread_queue_Enqueue(
|
||||
&the_region->Wait_queue,
|
||||
the_region->wait_operations,
|
||||
executing,
|
||||
STATES_WAITING_FOR_SEGMENT,
|
||||
timeout,
|
||||
RTEMS_TIMEOUT
|
||||
);
|
||||
|
||||
_Thread_Dispatch_enable( cpu_self );
|
||||
|
||||
return (rtems_status_code) executing->Wait.return_code;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = RTEMS_INVALID_ID;
|
||||
if ( the_region == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
if ( size > the_region->maximum_segment_size ) {
|
||||
status = RTEMS_INVALID_SIZE;
|
||||
} else {
|
||||
void *the_segment;
|
||||
|
||||
the_segment = _Region_Allocate_segment( the_region, size );
|
||||
|
||||
if ( the_segment != NULL ) {
|
||||
the_region->number_of_used_blocks += 1;
|
||||
*segment = the_segment;
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
} else if ( _Options_Is_no_wait( option_set ) ) {
|
||||
status = RTEMS_UNSATISFIED;
|
||||
} else {
|
||||
Per_CPU_Control *cpu_self;
|
||||
Thread_Control *executing;
|
||||
|
||||
/*
|
||||
* Switch from using the memory allocation mutex to using a
|
||||
* dispatching disabled critical section. We have to do this
|
||||
* because this thread is going to block.
|
||||
*/
|
||||
/* FIXME: This is a home grown condition variable */
|
||||
cpu_self = _Thread_Dispatch_disable();
|
||||
_Region_Unlock( the_region );
|
||||
|
||||
executing = _Per_CPU_Get_executing( cpu_self );
|
||||
|
||||
executing->Wait.count = size;
|
||||
executing->Wait.return_argument = segment;
|
||||
|
||||
_Thread_queue_Enqueue(
|
||||
&the_region->Wait_queue,
|
||||
the_region->wait_operations,
|
||||
executing,
|
||||
STATES_WAITING_FOR_SEGMENT,
|
||||
timeout,
|
||||
RTEMS_TIMEOUT
|
||||
);
|
||||
|
||||
_Thread_Dispatch_enable( cpu_self );
|
||||
|
||||
return (rtems_status_code) executing->Wait.return_code;
|
||||
}
|
||||
}
|
||||
|
||||
_Region_Unlock( the_region );
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -37,20 +37,18 @@ rtems_status_code rtems_region_get_segment_size(
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
the_region = _Region_Get_and_lock( id );
|
||||
|
||||
the_region = _Region_Get( id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
if ( _Heap_Size_of_alloc_area( &the_region->Memory, segment, size ) ) {
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
status = RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
} else {
|
||||
status = RTEMS_INVALID_ID;
|
||||
if ( the_region == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
if ( _Heap_Size_of_alloc_area( &the_region->Memory, segment, size ) ) {
|
||||
status = RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
status = RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
_Region_Unlock( the_region );
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ void _Region_Process_queue(
|
||||
* switch could occur.
|
||||
*/
|
||||
cpu_self = _Thread_Dispatch_disable();
|
||||
_RTEMS_Unlock_allocator();
|
||||
_Region_Unlock( the_region );
|
||||
|
||||
/*
|
||||
* NOTE: The following loop is O(n) where n is the number of
|
||||
|
||||
@@ -37,38 +37,36 @@ rtems_status_code rtems_region_resize_segment(
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
the_region = _Region_Get_and_lock( id );
|
||||
|
||||
the_region = _Region_Get( id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
resize_status = _Heap_Resize_block(
|
||||
&the_region->Memory,
|
||||
segment,
|
||||
(uint32_t) size,
|
||||
&osize,
|
||||
&avail_size
|
||||
);
|
||||
*old_size = (uint32_t) osize;
|
||||
|
||||
switch ( resize_status ) {
|
||||
case HEAP_RESIZE_SUCCESSFUL:
|
||||
/* Unlocks allocator */
|
||||
_Region_Process_queue( the_region );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
case HEAP_RESIZE_UNSATISFIED:
|
||||
status = RTEMS_UNSATISFIED;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = RTEMS_INVALID_ADDRESS;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
status = RTEMS_INVALID_ID;
|
||||
if ( the_region == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
resize_status = _Heap_Resize_block(
|
||||
&the_region->Memory,
|
||||
segment,
|
||||
(uint32_t) size,
|
||||
&osize,
|
||||
&avail_size
|
||||
);
|
||||
*old_size = (uint32_t) osize;
|
||||
|
||||
switch ( resize_status ) {
|
||||
case HEAP_RESIZE_SUCCESSFUL:
|
||||
/* Unlocks allocator */
|
||||
_Region_Process_queue( the_region );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
|
||||
case HEAP_RESIZE_UNSATISFIED:
|
||||
status = RTEMS_UNSATISFIED;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = RTEMS_INVALID_ADDRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
_Region_Unlock( the_region );
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -25,27 +25,22 @@ rtems_status_code rtems_region_return_segment(
|
||||
void *segment
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
Region_Control *the_region;
|
||||
Region_Control *the_region;
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
the_region = _Region_Get_and_lock( id );
|
||||
|
||||
the_region = _Region_Get( id );
|
||||
|
||||
if ( the_region != NULL ) {
|
||||
if ( _Region_Free_segment( the_region, segment ) ) {
|
||||
the_region->number_of_used_blocks -= 1;
|
||||
|
||||
/* Unlocks allocator */
|
||||
_Region_Process_queue( the_region );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
} else {
|
||||
status = RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
} else {
|
||||
status = RTEMS_INVALID_ID;
|
||||
if ( the_region == NULL ) {
|
||||
return RTEMS_INVALID_ID;
|
||||
}
|
||||
|
||||
_RTEMS_Unlock_allocator();
|
||||
return status;
|
||||
if ( _Region_Free_segment( the_region, segment ) ) {
|
||||
the_region->number_of_used_blocks -= 1;
|
||||
|
||||
/* Unlocks allocator */
|
||||
_Region_Process_queue( the_region );
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
_Region_Unlock( the_region );
|
||||
return RTEMS_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user