From 5aa64518b5bb046469386afbe530957dbb28a603 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 17 May 1999 22:39:20 +0000 Subject: Split Region Manager into one routine per file. --- cpukit/rtems/src/region.c | 455 -------------------------------- cpukit/rtems/src/regioncreate.c | 106 ++++++++ cpukit/rtems/src/regiondelete.c | 69 +++++ cpukit/rtems/src/regionextend.c | 90 +++++++ cpukit/rtems/src/regiongetsegment.c | 109 ++++++++ cpukit/rtems/src/regiongetsegmentsize.c | 72 +++++ cpukit/rtems/src/regionident.c | 57 ++++ cpukit/rtems/src/regionreturnsegment.c | 115 ++++++++ 8 files changed, 618 insertions(+), 455 deletions(-) create mode 100644 cpukit/rtems/src/regioncreate.c create mode 100644 cpukit/rtems/src/regiondelete.c create mode 100644 cpukit/rtems/src/regionextend.c create mode 100644 cpukit/rtems/src/regiongetsegment.c create mode 100644 cpukit/rtems/src/regiongetsegmentsize.c create mode 100644 cpukit/rtems/src/regionident.c create mode 100644 cpukit/rtems/src/regionreturnsegment.c (limited to 'cpukit') diff --git a/cpukit/rtems/src/region.c b/cpukit/rtems/src/region.c index d7b27132a0..fc9a7c34ed 100644 --- a/cpukit/rtems/src/region.c +++ b/cpukit/rtems/src/region.c @@ -13,10 +13,6 @@ * $Id$ */ -#ifdef RTEMS_REGION_FREE_SHRED_PATTERN -#include -#endif - #include #include #include @@ -66,454 +62,3 @@ void _Region_Manager_initialization( } -/*PAGE - * - * rtems_region_create - * - * This directive creates a region of physical contiguous memory area - * from which variable sized segments can be allocated. - * - * Input parameters: - * name - user defined region name - * starting_address - physical start address of region - * length - physical length in bytes - * page_size - page size in bytes - * attribute_set - region attributes - * id - address of region id to set - * - * Output parameters: - * id - region id - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_region_create( - rtems_name name, - void *starting_address, - unsigned32 length, - unsigned32 page_size, - rtems_attribute attribute_set, - Objects_Id *id -) -{ - Region_Control *the_region; - - if ( !rtems_is_name_valid( name ) ) - return RTEMS_INVALID_NAME; - - if ( !_Addresses_Is_aligned( starting_address ) ) - return RTEMS_INVALID_ADDRESS; - - _Thread_Disable_dispatch(); /* to prevent deletion */ - - the_region = _Region_Allocate(); - - if ( !the_region ) { - _Thread_Enable_dispatch(); - return RTEMS_TOO_MANY; - } - - the_region->maximum_segment_size = - _Heap_Initialize(&the_region->Memory, starting_address, length, page_size); - - if ( !the_region->maximum_segment_size ) { - _Region_Free( the_region ); - _Thread_Enable_dispatch(); - return RTEMS_INVALID_SIZE; - } - - the_region->starting_address = starting_address; - the_region->length = length; - the_region->page_size = page_size; - the_region->attribute_set = attribute_set; - the_region->number_of_used_blocks = 0; - - _Thread_queue_Initialize( - &the_region->Wait_queue, - OBJECTS_RTEMS_REGIONS, - _Attributes_Is_priority( attribute_set ) ? - THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, - STATES_WAITING_FOR_SEGMENT, -#if defined(RTEMS_MULTIPROCESSING) - _Region_MP_Send_extract_proxy, -#else - NULL, -#endif - RTEMS_TIMEOUT - ); - - _Objects_Open( &_Region_Information, &the_region->Object, &name ); - - *id = the_region->Object.id; - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; -} - -/*PAGE - * - * rtems_region_ident - * - * This directive returns the system ID associated with - * the region name. - * - * Input parameters: - * name - user defined region name - * id - pointer to region id - * - * Output parameters: - * *id - region id - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_region_ident( - rtems_name name, - Objects_Id *id -) -{ - Objects_Name_to_id_errors status; - - status = _Objects_Name_to_id( - &_Region_Information, - &name, - OBJECTS_SEARCH_LOCAL_NODE, - id - ); - - return _Status_Object_name_errors_to_status[ status ]; -} - -/*PAGE - * - * rtems_region_delete - * - * This directive allows a thread to delete a region specified by - * the region identifier, provided that none of its segments are - * still allocated. - * - * Input parameters: - * id - region id - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_region_delete( - Objects_Id id -) -{ - register Region_Control *the_region; - Objects_Locations location; - - the_region = _Region_Get( id, &location ); - switch ( location ) { - case OBJECTS_REMOTE: /* this error cannot be returned */ - return RTEMS_INTERNAL_ERROR; - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - _Region_Debug_Walk( the_region, 5 ); - if ( the_region->number_of_used_blocks == 0 ) { - _Objects_Close( &_Region_Information, &the_region->Object ); - _Region_Free( the_region ); - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_RESOURCE_IN_USE; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_region_extend - * - * This directive attempts to grow a region of physical contiguous memory area - * from which variable sized segments can be allocated. - * - * Input parameters: - * id - id of region to grow - * start - starting address of memory area for extension - * length - physical length in bytes to grow the region - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_region_extend( - Objects_Id id, - void *starting_address, - unsigned32 length -) -{ - Region_Control *the_region; - Objects_Locations location; - unsigned32 amount_extended; - Heap_Extend_status heap_status; - rtems_status_code status; - - status = RTEMS_SUCCESSFUL; - - the_region = _Region_Get( id, &location ); - switch ( location ) { - case OBJECTS_REMOTE: /* this error cannot be returned */ - return RTEMS_INTERNAL_ERROR; - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - - heap_status = _Heap_Extend( - &the_region->Memory, - starting_address, - length, - &amount_extended - ); - - switch ( heap_status ) { - case HEAP_EXTEND_SUCCESSFUL: - the_region->length += amount_extended; - the_region->maximum_segment_size += amount_extended; - break; - case HEAP_EXTEND_ERROR: - status = RTEMS_INVALID_ADDRESS; - break; - case HEAP_EXTEND_NOT_IMPLEMENTED: - status = RTEMS_NOT_IMPLEMENTED; - break; - } - _Thread_Enable_dispatch(); - return( status ); - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_region_get_segment - * - * This directive will obtain a segment from the given region. - * - * Input parameters: - * id - region id - * size - segment size in bytes - * option_set - wait option - * timeout - number of ticks to wait (0 means wait forever) - * segment - pointer to segment address - * - * Output parameters: - * segment - pointer to segment address filled in - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_region_get_segment( - Objects_Id id, - unsigned32 size, - rtems_option option_set, - rtems_interval timeout, - void **segment -) -{ - register Region_Control *the_region; - Objects_Locations location; - Thread_Control *executing; - void *the_segment; - - *segment = NULL; - - if ( size == 0 ) - return RTEMS_INVALID_SIZE; - - executing = _Thread_Executing; - the_region = _Region_Get( id, &location ); - switch ( location ) { - case OBJECTS_REMOTE: /* this error cannot be returned */ - return RTEMS_INTERNAL_ERROR; - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - if ( size > the_region->maximum_segment_size ) { - _Thread_Enable_dispatch(); - return RTEMS_INVALID_SIZE; - } - - _Region_Debug_Walk( the_region, 1 ); - - the_segment = _Region_Allocate_segment( the_region, size ); - - _Region_Debug_Walk( the_region, 2 ); - - if ( the_segment ) { - the_region->number_of_used_blocks += 1; - _Thread_Enable_dispatch(); - *segment = the_segment; - return RTEMS_SUCCESSFUL; - } - - if ( _Options_Is_no_wait( option_set ) ) { - _Thread_Enable_dispatch(); - return RTEMS_UNSATISFIED; - } - - executing->Wait.queue = &the_region->Wait_queue; - executing->Wait.id = id; - executing->Wait.count = size; - executing->Wait.return_argument = (unsigned32 *) segment; - - _Thread_queue_Enter_critical_section( &the_region->Wait_queue ); - - _Thread_queue_Enqueue( &the_region->Wait_queue, timeout ); - - _Thread_Enable_dispatch(); - return (rtems_status_code) executing->Wait.return_code; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} -/*PAGE - * - * rtems_region_get_segment_size - * - * This directive will return the size of the segment indicated - * - * Input parameters: - * id - region id - * segment - segment address - * size - pointer to segment size in bytes - * - * Output parameters: - * size - segment size in bytes filled in - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_region_get_segment_size( - Objects_Id id, - void *segment, - unsigned32 *size -) -{ - register Region_Control *the_region; - Objects_Locations location; - Thread_Control *executing; - - executing = _Thread_Executing; - the_region = _Region_Get( id, &location ); - switch ( location ) { - case OBJECTS_REMOTE: /* this error cannot be returned */ - return RTEMS_INTERNAL_ERROR; - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - - if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) { - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - _Thread_Enable_dispatch(); - return RTEMS_INVALID_ADDRESS; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} - -/*PAGE - * - * rtems_region_return_segment - * - * This directive will return a segment to its region. - * - * Input parameters: - * id - region id - * segment - pointer to segment address - * - * Output parameters: - * RTEMS_SUCCESSFUL - if successful - * error code - if unsuccessful - */ - -rtems_status_code rtems_region_return_segment( - Objects_Id id, - void *segment -) -{ - register Region_Control *the_region; - Thread_Control *the_thread; - Objects_Locations location; - void **the_segment; -#ifdef RTEMS_SHRED_ON_FREE - unsigned32 size; -#endif - int status; - - the_region = _Region_Get( id, &location ); - switch ( location ) { - - case OBJECTS_REMOTE: /* this error cannot be returned */ - return RTEMS_INTERNAL_ERROR; - - case OBJECTS_ERROR: - return RTEMS_INVALID_ID; - - case OBJECTS_LOCAL: - - _Region_Debug_Walk( the_region, 3 ); - -#ifdef RTEMS_REGION_FREE_SHRED_PATTERN - if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) { - memset(segment, (RTEMS_REGION_FREE_SHRED_BYTE & 0xFF), size); - } else { - _Thread_Enable_dispatch(); - return RTEMS_INVALID_ADDRESS; - } -#endif - - status = _Region_Free_segment( the_region, segment ); - - _Region_Debug_Walk( the_region, 4 ); - - if ( !status ) { - _Thread_Enable_dispatch(); - return RTEMS_INVALID_ADDRESS; - } - - the_region->number_of_used_blocks -= 1; - for ( ; ; ) { - the_thread = _Thread_queue_First( &the_region->Wait_queue ); - - if ( the_thread == NULL ) - break; - - the_segment = (void **) _Region_Allocate_segment( - the_region, - the_thread->Wait.count - ); - - if ( the_segment == NULL ) - break; - - *(void **)the_thread->Wait.return_argument = the_segment; - the_region->number_of_used_blocks += 1; - _Thread_queue_Extract( &the_region->Wait_queue, the_thread ); - the_thread->Wait.return_code = RTEMS_SUCCESSFUL; - } - - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - - return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ -} diff --git a/cpukit/rtems/src/regioncreate.c b/cpukit/rtems/src/regioncreate.c new file mode 100644 index 0000000000..49be2c5802 --- /dev/null +++ b/cpukit/rtems/src/regioncreate.c @@ -0,0 +1,106 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_region_create + * + * This directive creates a region of physical contiguous memory area + * from which variable sized segments can be allocated. + * + * Input parameters: + * name - user defined region name + * starting_address - physical start address of region + * length - physical length in bytes + * page_size - page size in bytes + * attribute_set - region attributes + * id - address of region id to set + * + * Output parameters: + * id - region id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_create( + rtems_name name, + void *starting_address, + unsigned32 length, + unsigned32 page_size, + rtems_attribute attribute_set, + Objects_Id *id +) +{ + Region_Control *the_region; + + if ( !rtems_is_name_valid( name ) ) + return RTEMS_INVALID_NAME; + + if ( !_Addresses_Is_aligned( starting_address ) ) + return RTEMS_INVALID_ADDRESS; + + _Thread_Disable_dispatch(); /* to prevent deletion */ + + the_region = _Region_Allocate(); + + if ( !the_region ) { + _Thread_Enable_dispatch(); + return RTEMS_TOO_MANY; + } + + the_region->maximum_segment_size = + _Heap_Initialize(&the_region->Memory, starting_address, length, page_size); + + if ( !the_region->maximum_segment_size ) { + _Region_Free( the_region ); + _Thread_Enable_dispatch(); + return RTEMS_INVALID_SIZE; + } + + the_region->starting_address = starting_address; + the_region->length = length; + the_region->page_size = page_size; + the_region->attribute_set = attribute_set; + the_region->number_of_used_blocks = 0; + + _Thread_queue_Initialize( + &the_region->Wait_queue, + OBJECTS_RTEMS_REGIONS, + _Attributes_Is_priority( attribute_set ) ? + THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, + STATES_WAITING_FOR_SEGMENT, +#if defined(RTEMS_MULTIPROCESSING) + _Region_MP_Send_extract_proxy, +#else + NULL, +#endif + RTEMS_TIMEOUT + ); + + _Objects_Open( &_Region_Information, &the_region->Object, &name ); + + *id = the_region->Object.id; + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/rtems/src/regiondelete.c b/cpukit/rtems/src/regiondelete.c new file mode 100644 index 0000000000..59e38464b0 --- /dev/null +++ b/cpukit/rtems/src/regiondelete.c @@ -0,0 +1,69 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_region_delete + * + * This directive allows a thread to delete a region specified by + * the region identifier, provided that none of its segments are + * still allocated. + * + * Input parameters: + * id - region id + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_delete( + Objects_Id id +) +{ + register Region_Control *the_region; + Objects_Locations location; + + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_REMOTE: /* this error cannot be returned */ + return RTEMS_INTERNAL_ERROR; + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + _Region_Debug_Walk( the_region, 5 ); + if ( the_region->number_of_used_blocks == 0 ) { + _Objects_Close( &_Region_Information, &the_region->Object ); + _Region_Free( the_region ); + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_RESOURCE_IN_USE; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/regionextend.c b/cpukit/rtems/src/regionextend.c new file mode 100644 index 0000000000..ab2eb5f713 --- /dev/null +++ b/cpukit/rtems/src/regionextend.c @@ -0,0 +1,90 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_region_extend + * + * This directive attempts to grow a region of physical contiguous memory area + * from which variable sized segments can be allocated. + * + * Input parameters: + * id - id of region to grow + * start - starting address of memory area for extension + * length - physical length in bytes to grow the region + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_extend( + Objects_Id id, + void *starting_address, + unsigned32 length +) +{ + Region_Control *the_region; + Objects_Locations location; + unsigned32 amount_extended; + Heap_Extend_status heap_status; + rtems_status_code status; + + status = RTEMS_SUCCESSFUL; + + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_REMOTE: /* this error cannot be returned */ + return RTEMS_INTERNAL_ERROR; + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + + heap_status = _Heap_Extend( + &the_region->Memory, + starting_address, + length, + &amount_extended + ); + + switch ( heap_status ) { + case HEAP_EXTEND_SUCCESSFUL: + the_region->length += amount_extended; + the_region->maximum_segment_size += amount_extended; + break; + case HEAP_EXTEND_ERROR: + status = RTEMS_INVALID_ADDRESS; + break; + case HEAP_EXTEND_NOT_IMPLEMENTED: + status = RTEMS_NOT_IMPLEMENTED; + break; + } + _Thread_Enable_dispatch(); + return( status ); + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c new file mode 100644 index 0000000000..68d05fbc12 --- /dev/null +++ b/cpukit/rtems/src/regiongetsegment.c @@ -0,0 +1,109 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_region_get_segment + * + * This directive will obtain a segment from the given region. + * + * Input parameters: + * id - region id + * size - segment size in bytes + * option_set - wait option + * timeout - number of ticks to wait (0 means wait forever) + * segment - pointer to segment address + * + * Output parameters: + * segment - pointer to segment address filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_get_segment( + Objects_Id id, + unsigned32 size, + rtems_option option_set, + rtems_interval timeout, + void **segment +) +{ + register Region_Control *the_region; + Objects_Locations location; + Thread_Control *executing; + void *the_segment; + + *segment = NULL; + + if ( size == 0 ) + return RTEMS_INVALID_SIZE; + + executing = _Thread_Executing; + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_REMOTE: /* this error cannot be returned */ + return RTEMS_INTERNAL_ERROR; + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + if ( size > the_region->maximum_segment_size ) { + _Thread_Enable_dispatch(); + return RTEMS_INVALID_SIZE; + } + + _Region_Debug_Walk( the_region, 1 ); + + the_segment = _Region_Allocate_segment( the_region, size ); + + _Region_Debug_Walk( the_region, 2 ); + + if ( the_segment ) { + the_region->number_of_used_blocks += 1; + _Thread_Enable_dispatch(); + *segment = the_segment; + return RTEMS_SUCCESSFUL; + } + + if ( _Options_Is_no_wait( option_set ) ) { + _Thread_Enable_dispatch(); + return RTEMS_UNSATISFIED; + } + + executing->Wait.queue = &the_region->Wait_queue; + executing->Wait.id = id; + executing->Wait.count = size; + executing->Wait.return_argument = (unsigned32 *) segment; + + _Thread_queue_Enter_critical_section( &the_region->Wait_queue ); + + _Thread_queue_Enqueue( &the_region->Wait_queue, timeout ); + + _Thread_Enable_dispatch(); + return (rtems_status_code) executing->Wait.return_code; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/regiongetsegmentsize.c b/cpukit/rtems/src/regiongetsegmentsize.c new file mode 100644 index 0000000000..726f47cf2d --- /dev/null +++ b/cpukit/rtems/src/regiongetsegmentsize.c @@ -0,0 +1,72 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_region_get_segment_size + * + * This directive will return the size of the segment indicated + * + * Input parameters: + * id - region id + * segment - segment address + * size - pointer to segment size in bytes + * + * Output parameters: + * size - segment size in bytes filled in + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_get_segment_size( + Objects_Id id, + void *segment, + unsigned32 *size +) +{ + register Region_Control *the_region; + Objects_Locations location; + Thread_Control *executing; + + executing = _Thread_Executing; + the_region = _Region_Get( id, &location ); + switch ( location ) { + case OBJECTS_REMOTE: /* this error cannot be returned */ + return RTEMS_INTERNAL_ERROR; + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + + if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) { + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ADDRESS; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} diff --git a/cpukit/rtems/src/regionident.c b/cpukit/rtems/src/regionident.c new file mode 100644 index 0000000000..3ad1687ccf --- /dev/null +++ b/cpukit/rtems/src/regionident.c @@ -0,0 +1,57 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_region_ident + * + * This directive returns the system ID associated with + * the region name. + * + * Input parameters: + * name - user defined region name + * id - pointer to region id + * + * Output parameters: + * *id - region id + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_ident( + rtems_name name, + Objects_Id *id +) +{ + Objects_Name_to_id_errors status; + + status = _Objects_Name_to_id( + &_Region_Information, + &name, + OBJECTS_SEARCH_LOCAL_NODE, + id + ); + + return _Status_Object_name_errors_to_status[ status ]; +} diff --git a/cpukit/rtems/src/regionreturnsegment.c b/cpukit/rtems/src/regionreturnsegment.c new file mode 100644 index 0000000000..7910d26e8d --- /dev/null +++ b/cpukit/rtems/src/regionreturnsegment.c @@ -0,0 +1,115 @@ +/* + * Region Manager + * + * + * COPYRIGHT (c) 1989-1998. + * On-Line Applications Research Corporation (OAR). + * Copyright assigned to U.S. Government, 1994. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.OARcorp.com/rtems/license.html. + * + * $Id$ + */ + +#ifdef RTEMS_REGION_FREE_SHRED_PATTERN +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +/*PAGE + * + * rtems_region_return_segment + * + * This directive will return a segment to its region. + * + * Input parameters: + * id - region id + * segment - pointer to segment address + * + * Output parameters: + * RTEMS_SUCCESSFUL - if successful + * error code - if unsuccessful + */ + +rtems_status_code rtems_region_return_segment( + Objects_Id id, + void *segment +) +{ + register Region_Control *the_region; + Thread_Control *the_thread; + Objects_Locations location; + void **the_segment; +#ifdef RTEMS_REGION_FREE_SHRED_PATTERN + unsigned32 size; +#endif + int status; + + the_region = _Region_Get( id, &location ); + switch ( location ) { + + case OBJECTS_REMOTE: /* this error cannot be returned */ + return RTEMS_INTERNAL_ERROR; + + case OBJECTS_ERROR: + return RTEMS_INVALID_ID; + + case OBJECTS_LOCAL: + + _Region_Debug_Walk( the_region, 3 ); + +#ifdef RTEMS_REGION_FREE_SHRED_PATTERN + if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) { + memset(segment, (RTEMS_REGION_FREE_SHRED_BYTE & 0xFF), size); + } else { + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ADDRESS; + } +#endif + + status = _Region_Free_segment( the_region, segment ); + + _Region_Debug_Walk( the_region, 4 ); + + if ( !status ) { + _Thread_Enable_dispatch(); + return RTEMS_INVALID_ADDRESS; + } + + the_region->number_of_used_blocks -= 1; + for ( ; ; ) { + the_thread = _Thread_queue_First( &the_region->Wait_queue ); + + if ( the_thread == NULL ) + break; + + the_segment = (void **) _Region_Allocate_segment( + the_region, + the_thread->Wait.count + ); + + if ( the_segment == NULL ) + break; + + *(void **)the_thread->Wait.return_argument = the_segment; + the_region->number_of_used_blocks += 1; + _Thread_queue_Extract( &the_region->Wait_queue, the_thread ); + the_thread->Wait.return_code = RTEMS_SUCCESSFUL; + } + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + } + + return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ +} -- cgit v1.2.3