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/rtems/region.h>
|
||||||
#include <rtems/score/apimutex.h>
|
#include <rtems/score/apimutex.h>
|
||||||
#include <rtems/score/assert.h>
|
|
||||||
#include <rtems/score/heapimpl.h>
|
#include <rtems/score/heapimpl.h>
|
||||||
#include <rtems/score/objectimpl.h>
|
#include <rtems/score/objectimpl.h>
|
||||||
#include <rtems/score/threadqimpl.h>
|
#include <rtems/score/threadqimpl.h>
|
||||||
@@ -67,11 +66,28 @@ RTEMS_INLINE_ROUTINE void _Region_Free (
|
|||||||
_Objects_Free( &_Region_Information, &the_region->Object );
|
_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() );
|
Region_Control *the_region;
|
||||||
return (Region_Control *)
|
|
||||||
|
_RTEMS_Lock_allocator();
|
||||||
|
|
||||||
|
the_region = (Region_Control *)
|
||||||
_Objects_Get_no_protection( &_Region_Information, id );
|
_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;
|
Region_Control *the_region;
|
||||||
|
|
||||||
_Objects_Allocator_lock();
|
_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 == NULL ) {
|
||||||
if ( the_region->number_of_used_blocks != 0 ) {
|
_Objects_Allocator_unlock();
|
||||||
status = RTEMS_RESOURCE_IN_USE;
|
return RTEMS_INVALID_ID;
|
||||||
} else {
|
|
||||||
_Objects_Close( &_Region_Information, &the_region->Object );
|
|
||||||
_Region_Free( the_region );
|
|
||||||
status = RTEMS_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
status = 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();
|
_Objects_Allocator_unlock();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,29 +34,27 @@ rtems_status_code rtems_region_extend(
|
|||||||
return RTEMS_INVALID_ADDRESS;
|
return RTEMS_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Lock_allocator();
|
the_region = _Region_Get_and_lock( id );
|
||||||
|
|
||||||
the_region = _Region_Get( id );
|
if ( the_region == NULL ) {
|
||||||
|
return RTEMS_INVALID_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,25 +27,21 @@ rtems_status_code rtems_region_get_free_information(
|
|||||||
Heap_Information_block *the_info
|
Heap_Information_block *the_info
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
rtems_status_code status;
|
Region_Control *the_region;
|
||||||
Region_Control *the_region;
|
|
||||||
|
|
||||||
if ( the_info == NULL ) {
|
if ( the_info == NULL ) {
|
||||||
return RTEMS_INVALID_ADDRESS;
|
return RTEMS_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Lock_allocator();
|
the_region = _Region_Get_and_lock( id );
|
||||||
|
|
||||||
the_region = _Region_Get( id );
|
if ( the_region == NULL ) {
|
||||||
|
return RTEMS_INVALID_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Unlock_allocator();
|
memset( &the_info->Used, 0, sizeof( the_info->Used ) );
|
||||||
return status;
|
_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
|
Heap_Information_block *the_info
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
rtems_status_code status;
|
Region_Control *the_region;
|
||||||
Region_Control *the_region;
|
|
||||||
|
|
||||||
if ( the_info == NULL ) {
|
if ( the_info == NULL ) {
|
||||||
return RTEMS_INVALID_ADDRESS;
|
return RTEMS_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Lock_allocator();
|
the_region = _Region_Get_and_lock( id );
|
||||||
|
|
||||||
the_region = _Region_Get( id );
|
if ( the_region == NULL ) {
|
||||||
|
return RTEMS_INVALID_ID;
|
||||||
if ( the_region != NULL ) {
|
|
||||||
_Heap_Get_information( &the_region->Memory, the_info );
|
|
||||||
status = RTEMS_SUCCESSFUL;
|
|
||||||
} else {
|
|
||||||
status = RTEMS_INVALID_ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Unlock_allocator();
|
_Heap_Get_information( &the_region->Memory, the_info );
|
||||||
return status;
|
|
||||||
|
_Region_Unlock( the_region );
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,60 +44,58 @@ rtems_status_code rtems_region_get_segment(
|
|||||||
return RTEMS_INVALID_SIZE;
|
return RTEMS_INVALID_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Lock_allocator();
|
the_region = _Region_Get_and_lock( id );
|
||||||
|
|
||||||
the_region = _Region_Get( id );
|
if ( the_region == NULL ) {
|
||||||
|
return RTEMS_INVALID_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,20 +37,18 @@ rtems_status_code rtems_region_get_segment_size(
|
|||||||
return RTEMS_INVALID_ADDRESS;
|
return RTEMS_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Lock_allocator();
|
the_region = _Region_Get_and_lock( id );
|
||||||
|
|
||||||
the_region = _Region_Get( id );
|
if ( the_region == NULL ) {
|
||||||
|
return RTEMS_INVALID_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ void _Region_Process_queue(
|
|||||||
* switch could occur.
|
* switch could occur.
|
||||||
*/
|
*/
|
||||||
cpu_self = _Thread_Dispatch_disable();
|
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
|
* 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;
|
return RTEMS_INVALID_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Lock_allocator();
|
the_region = _Region_Get_and_lock( id );
|
||||||
|
|
||||||
the_region = _Region_Get( id );
|
if ( the_region == NULL ) {
|
||||||
|
return RTEMS_INVALID_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,27 +25,22 @@ rtems_status_code rtems_region_return_segment(
|
|||||||
void *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 ) {
|
||||||
|
return RTEMS_INVALID_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_RTEMS_Unlock_allocator();
|
if ( _Region_Free_segment( the_region, segment ) ) {
|
||||||
return status;
|
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