Changeset 5aa64518 in rtems


Ignore:
Timestamp:
May 17, 1999, 10:39:20 PM (21 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
bd83f47
Parents:
1178b8c
Message:

Split Region Manager into one routine per file.

Files:
14 added
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/rtems/src/Makefile.in

    r1178b8c r5aa64518  
    2525  taskstart tasksuspend taskwakeafter taskwakewhen
    2626
     27REGION_PIECES=\
     28  region regioncreate regiondelete regionextend regiongetsegment \
     29  regiongetsegmentsize regionident regionreturnsegemnt regionreturnsegemnt
     30
    2731C_PIECES=attr clock dpmem event intr intrbody msg \
    28    part ratemon region sem signal \
     32   part ratemon $(REGION_PIECES) sem signal \
    2933   $(TASK_PIECES) timer $(MP_PIECES)
    3034C_FILES=$(C_PIECES:%=%.c)
  • c/src/exec/rtems/src/region.c

    r1178b8c r5aa64518  
    1313 *  $Id$
    1414 */
    15 
    16 #ifdef RTEMS_REGION_FREE_SHRED_PATTERN
    17 #include <string.h>
    18 #endif
    1915
    2016#include <rtems/system.h>
     
    6763}
    6864
    69 /*PAGE
    70  *
    71  *  rtems_region_create
    72  *
    73  *  This directive creates a region of physical contiguous memory area
    74  *  from which variable sized segments can be allocated.
    75  *
    76  *  Input parameters:
    77  *    name             - user defined region name
    78  *    starting_address - physical start address of region
    79  *    length           - physical length in bytes
    80  *    page_size        - page size in bytes
    81  *    attribute_set    - region attributes
    82  *    id               - address of region id to set
    83  *
    84  *  Output parameters:
    85  *    id       - region id
    86  *    RTEMS_SUCCESSFUL - if successful
    87  *    error code - if unsuccessful
    88  */
    89 
    90 rtems_status_code rtems_region_create(
    91   rtems_name          name,
    92   void               *starting_address,
    93   unsigned32          length,
    94   unsigned32          page_size,
    95   rtems_attribute  attribute_set,
    96   Objects_Id         *id
    97 )
    98 {
    99   Region_Control *the_region;
    100 
    101   if ( !rtems_is_name_valid( name ) )
    102     return RTEMS_INVALID_NAME;
    103 
    104   if ( !_Addresses_Is_aligned( starting_address ) )
    105     return RTEMS_INVALID_ADDRESS;
    106 
    107   _Thread_Disable_dispatch();             /* to prevent deletion */
    108 
    109   the_region = _Region_Allocate();
    110 
    111   if ( !the_region ) {
    112     _Thread_Enable_dispatch();
    113     return RTEMS_TOO_MANY;
    114   }
    115 
    116   the_region->maximum_segment_size =
    117     _Heap_Initialize(&the_region->Memory, starting_address, length, page_size);
    118 
    119   if ( !the_region->maximum_segment_size ) {
    120     _Region_Free( the_region );
    121     _Thread_Enable_dispatch();
    122     return RTEMS_INVALID_SIZE;
    123   }
    124 
    125   the_region->starting_address      = starting_address;
    126   the_region->length                = length;
    127   the_region->page_size             = page_size;
    128   the_region->attribute_set         = attribute_set;
    129   the_region->number_of_used_blocks = 0;
    130 
    131   _Thread_queue_Initialize(
    132     &the_region->Wait_queue,
    133     OBJECTS_RTEMS_REGIONS,
    134     _Attributes_Is_priority( attribute_set ) ?
    135        THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
    136     STATES_WAITING_FOR_SEGMENT,
    137 #if defined(RTEMS_MULTIPROCESSING)
    138     _Region_MP_Send_extract_proxy,
    139 #else
    140     NULL,
    141 #endif
    142     RTEMS_TIMEOUT
    143   );
    144 
    145   _Objects_Open( &_Region_Information, &the_region->Object, &name );
    146 
    147   *id = the_region->Object.id;
    148   _Thread_Enable_dispatch();
    149   return RTEMS_SUCCESSFUL;
    150 }
    151 
    152 /*PAGE
    153  *
    154  *  rtems_region_ident
    155  *
    156  *  This directive returns the system ID associated with
    157  *  the region name.
    158  *
    159  *  Input parameters:
    160  *    name - user defined region name
    161  *    id   - pointer to region id
    162  *
    163  *  Output parameters:
    164  *    *id      - region id
    165  *    RTEMS_SUCCESSFUL - if successful
    166  *    error code - if unsuccessful
    167  */
    168 
    169 rtems_status_code rtems_region_ident(
    170   rtems_name    name,
    171   Objects_Id   *id
    172 )
    173 {
    174   Objects_Name_to_id_errors  status;
    175 
    176   status = _Objects_Name_to_id(
    177     &_Region_Information,
    178     &name,
    179     OBJECTS_SEARCH_LOCAL_NODE,
    180     id
    181   );
    182 
    183   return _Status_Object_name_errors_to_status[ status ];
    184 }
    185 
    186 /*PAGE
    187  *
    188  *  rtems_region_delete
    189  *
    190  *  This directive allows a thread to delete a region specified by
    191  *  the region identifier, provided that none of its segments are
    192  *  still allocated.
    193  *
    194  *  Input parameters:
    195  *    id - region id
    196  *
    197  *  Output parameters:
    198  *    RTEMS_SUCCESSFUL - if successful
    199  *    error code - if unsuccessful
    200  */
    201 
    202 rtems_status_code rtems_region_delete(
    203   Objects_Id id
    204 )
    205 {
    206   register Region_Control *the_region;
    207   Objects_Locations               location;
    208 
    209   the_region = _Region_Get( id, &location );
    210   switch ( location ) {
    211     case OBJECTS_REMOTE:        /* this error cannot be returned */
    212       return RTEMS_INTERNAL_ERROR;
    213 
    214     case OBJECTS_ERROR:
    215       return RTEMS_INVALID_ID;
    216 
    217     case OBJECTS_LOCAL:
    218       _Region_Debug_Walk( the_region, 5 );
    219       if ( the_region->number_of_used_blocks == 0 ) {
    220         _Objects_Close( &_Region_Information, &the_region->Object );
    221         _Region_Free( the_region );
    222         _Thread_Enable_dispatch();
    223         return RTEMS_SUCCESSFUL;
    224       }
    225       _Thread_Enable_dispatch();
    226       return RTEMS_RESOURCE_IN_USE;
    227   }
    228 
    229   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    230 }
    231 
    232 /*PAGE
    233  *
    234  *  rtems_region_extend
    235  *
    236  *  This directive attempts to grow a region of physical contiguous memory area
    237  *  from which variable sized segments can be allocated.
    238  *
    239  *  Input parameters:
    240  *    id         - id of region to grow
    241  *    start      - starting address of memory area for extension
    242  *    length     - physical length in bytes to grow the region
    243  *
    244  *  Output parameters:
    245  *    RTEMS_SUCCESSFUL - if successful
    246  *    error code       - if unsuccessful
    247  */
    248 
    249 rtems_status_code rtems_region_extend(
    250   Objects_Id          id,
    251   void               *starting_address,
    252   unsigned32          length
    253 )
    254 {
    255   Region_Control     *the_region;
    256   Objects_Locations   location;
    257   unsigned32          amount_extended;
    258   Heap_Extend_status  heap_status;
    259   rtems_status_code   status;
    260 
    261   status = RTEMS_SUCCESSFUL;
    262 
    263   the_region = _Region_Get( id, &location );
    264   switch ( location ) {
    265     case OBJECTS_REMOTE:        /* this error cannot be returned */
    266       return RTEMS_INTERNAL_ERROR;
    267 
    268     case OBJECTS_ERROR:
    269       return RTEMS_INVALID_ID;
    270 
    271     case OBJECTS_LOCAL:
    272 
    273       heap_status = _Heap_Extend(
    274         &the_region->Memory,
    275         starting_address,
    276         length,
    277         &amount_extended
    278       );
    279 
    280       switch ( heap_status ) {
    281         case HEAP_EXTEND_SUCCESSFUL:
    282           the_region->length                += amount_extended;
    283           the_region->maximum_segment_size  += amount_extended;
    284           break;
    285         case HEAP_EXTEND_ERROR:
    286           status = RTEMS_INVALID_ADDRESS;
    287           break;
    288         case HEAP_EXTEND_NOT_IMPLEMENTED:
    289           status = RTEMS_NOT_IMPLEMENTED;
    290           break;
    291       }
    292       _Thread_Enable_dispatch();
    293       return( status );
    294   }
    295 
    296   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    297 }
    298 
    299 /*PAGE
    300  *
    301  *  rtems_region_get_segment
    302  *
    303  *  This directive will obtain a segment from the given region.
    304  *
    305  *  Input parameters:
    306  *    id         - region id
    307  *    size       - segment size in bytes
    308  *    option_set - wait option
    309  *    timeout    - number of ticks to wait (0 means wait forever)
    310  *    segment    - pointer to segment address
    311  *
    312  *  Output parameters:
    313  *    segment    - pointer to segment address filled in
    314  *    RTEMS_SUCCESSFUL - if successful
    315  *    error code - if unsuccessful
    316  */
    317 
    318 rtems_status_code rtems_region_get_segment(
    319   Objects_Id         id,
    320   unsigned32         size,
    321   rtems_option       option_set,
    322   rtems_interval     timeout,
    323   void              **segment
    324 )
    325 {
    326   register Region_Control *the_region;
    327   Objects_Locations        location;
    328   Thread_Control          *executing;
    329   void                    *the_segment;
    330 
    331   *segment = NULL;
    332 
    333   if ( size == 0 )
    334     return RTEMS_INVALID_SIZE;
    335 
    336   executing  = _Thread_Executing;
    337   the_region = _Region_Get( id, &location );
    338   switch ( location ) {
    339     case OBJECTS_REMOTE:        /* this error cannot be returned */
    340       return RTEMS_INTERNAL_ERROR;
    341 
    342     case OBJECTS_ERROR:
    343       return RTEMS_INVALID_ID;
    344 
    345     case OBJECTS_LOCAL:
    346       if ( size > the_region->maximum_segment_size ) {
    347         _Thread_Enable_dispatch();
    348         return RTEMS_INVALID_SIZE;
    349       }
    350 
    351       _Region_Debug_Walk( the_region, 1 );
    352 
    353       the_segment = _Region_Allocate_segment( the_region, size );
    354 
    355       _Region_Debug_Walk( the_region, 2 );
    356 
    357       if ( the_segment ) {
    358         the_region->number_of_used_blocks += 1;
    359         _Thread_Enable_dispatch();
    360         *segment = the_segment;
    361         return RTEMS_SUCCESSFUL;
    362       }
    363 
    364       if ( _Options_Is_no_wait( option_set ) ) {
    365         _Thread_Enable_dispatch();
    366         return RTEMS_UNSATISFIED;
    367       }
    368 
    369       executing->Wait.queue           = &the_region->Wait_queue;
    370       executing->Wait.id              = id;
    371       executing->Wait.count           = size;
    372       executing->Wait.return_argument = (unsigned32 *) segment;
    373 
    374       _Thread_queue_Enter_critical_section( &the_region->Wait_queue );
    375 
    376       _Thread_queue_Enqueue( &the_region->Wait_queue, timeout );
    377 
    378       _Thread_Enable_dispatch();
    379       return (rtems_status_code) executing->Wait.return_code;
    380   }
    381 
    382   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    383 }
    384 /*PAGE
    385  *
    386  *  rtems_region_get_segment_size
    387  *
    388  *  This directive will return the size of the segment indicated
    389  *
    390  *  Input parameters:
    391  *    id         - region id
    392  *    segment    - segment address
    393  *    size       - pointer to segment size in bytes
    394  *
    395  *  Output parameters:
    396  *    size       - segment size in bytes filled in
    397  *    RTEMS_SUCCESSFUL - if successful
    398  *    error code - if unsuccessful
    399  */
    400 
    401 rtems_status_code rtems_region_get_segment_size(
    402   Objects_Id         id,
    403   void              *segment,
    404   unsigned32        *size
    405 )
    406 {
    407   register Region_Control *the_region;
    408   Objects_Locations        location;
    409   Thread_Control          *executing;
    410 
    411   executing  = _Thread_Executing;
    412   the_region = _Region_Get( id, &location );
    413   switch ( location ) {
    414     case OBJECTS_REMOTE:        /* this error cannot be returned */
    415       return RTEMS_INTERNAL_ERROR;
    416 
    417     case OBJECTS_ERROR:
    418       return RTEMS_INVALID_ID;
    419 
    420     case OBJECTS_LOCAL:
    421 
    422       if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) {
    423         _Thread_Enable_dispatch();
    424         return RTEMS_SUCCESSFUL;
    425       }
    426       _Thread_Enable_dispatch();
    427       return RTEMS_INVALID_ADDRESS;
    428   }
    429 
    430   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    431 }
    432 
    433 /*PAGE
    434  *
    435  *  rtems_region_return_segment
    436  *
    437  *  This directive will return a segment to its region.
    438  *
    439  *  Input parameters:
    440  *    id      - region id
    441  *    segment - pointer to segment address
    442  *
    443  *  Output parameters:
    444  *    RTEMS_SUCCESSFUL - if successful
    445  *    error code        - if unsuccessful
    446  */
    447 
    448 rtems_status_code rtems_region_return_segment(
    449   Objects_Id  id,
    450   void       *segment
    451 )
    452 {
    453   register Region_Control *the_region;
    454   Thread_Control          *the_thread;
    455   Objects_Locations        location;
    456   void                   **the_segment;
    457 #ifdef RTEMS_SHRED_ON_FREE
    458   unsigned32               size;
    459 #endif
    460   int                      status;
    461 
    462   the_region = _Region_Get( id, &location );
    463   switch ( location ) {
    464 
    465     case OBJECTS_REMOTE:        /* this error cannot be returned */
    466       return RTEMS_INTERNAL_ERROR;
    467 
    468     case OBJECTS_ERROR:
    469       return RTEMS_INVALID_ID;
    470 
    471     case OBJECTS_LOCAL:
    472 
    473       _Region_Debug_Walk( the_region, 3 );
    474 
    475 #ifdef RTEMS_REGION_FREE_SHRED_PATTERN
    476       if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) {
    477         memset(segment, (RTEMS_REGION_FREE_SHRED_BYTE & 0xFF), size);
    478       } else {
    479         _Thread_Enable_dispatch();
    480         return RTEMS_INVALID_ADDRESS;
    481       }
    482 #endif
    483 
    484       status = _Region_Free_segment( the_region, segment );
    485 
    486       _Region_Debug_Walk( the_region, 4 );
    487 
    488       if ( !status ) {
    489         _Thread_Enable_dispatch();
    490         return RTEMS_INVALID_ADDRESS;
    491       }
    492 
    493       the_region->number_of_used_blocks -= 1;
    494       for ( ; ; ) {
    495         the_thread = _Thread_queue_First( &the_region->Wait_queue );
    496 
    497         if ( the_thread == NULL )
    498            break;
    499 
    500         the_segment = (void **) _Region_Allocate_segment(
    501            the_region,
    502            the_thread->Wait.count
    503         );
    504 
    505         if ( the_segment == NULL )
    506            break;
    507 
    508         *(void **)the_thread->Wait.return_argument = the_segment;
    509         the_region->number_of_used_blocks += 1;
    510         _Thread_queue_Extract( &the_region->Wait_queue, the_thread );
    511         the_thread->Wait.return_code = RTEMS_SUCCESSFUL;
    512       }
    513 
    514       _Thread_Enable_dispatch();
    515       return RTEMS_SUCCESSFUL;
    516   }
    517 
    518   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    519 }
  • cpukit/rtems/src/region.c

    r1178b8c r5aa64518  
    1313 *  $Id$
    1414 */
    15 
    16 #ifdef RTEMS_REGION_FREE_SHRED_PATTERN
    17 #include <string.h>
    18 #endif
    1915
    2016#include <rtems/system.h>
     
    6763}
    6864
    69 /*PAGE
    70  *
    71  *  rtems_region_create
    72  *
    73  *  This directive creates a region of physical contiguous memory area
    74  *  from which variable sized segments can be allocated.
    75  *
    76  *  Input parameters:
    77  *    name             - user defined region name
    78  *    starting_address - physical start address of region
    79  *    length           - physical length in bytes
    80  *    page_size        - page size in bytes
    81  *    attribute_set    - region attributes
    82  *    id               - address of region id to set
    83  *
    84  *  Output parameters:
    85  *    id       - region id
    86  *    RTEMS_SUCCESSFUL - if successful
    87  *    error code - if unsuccessful
    88  */
    89 
    90 rtems_status_code rtems_region_create(
    91   rtems_name          name,
    92   void               *starting_address,
    93   unsigned32          length,
    94   unsigned32          page_size,
    95   rtems_attribute  attribute_set,
    96   Objects_Id         *id
    97 )
    98 {
    99   Region_Control *the_region;
    100 
    101   if ( !rtems_is_name_valid( name ) )
    102     return RTEMS_INVALID_NAME;
    103 
    104   if ( !_Addresses_Is_aligned( starting_address ) )
    105     return RTEMS_INVALID_ADDRESS;
    106 
    107   _Thread_Disable_dispatch();             /* to prevent deletion */
    108 
    109   the_region = _Region_Allocate();
    110 
    111   if ( !the_region ) {
    112     _Thread_Enable_dispatch();
    113     return RTEMS_TOO_MANY;
    114   }
    115 
    116   the_region->maximum_segment_size =
    117     _Heap_Initialize(&the_region->Memory, starting_address, length, page_size);
    118 
    119   if ( !the_region->maximum_segment_size ) {
    120     _Region_Free( the_region );
    121     _Thread_Enable_dispatch();
    122     return RTEMS_INVALID_SIZE;
    123   }
    124 
    125   the_region->starting_address      = starting_address;
    126   the_region->length                = length;
    127   the_region->page_size             = page_size;
    128   the_region->attribute_set         = attribute_set;
    129   the_region->number_of_used_blocks = 0;
    130 
    131   _Thread_queue_Initialize(
    132     &the_region->Wait_queue,
    133     OBJECTS_RTEMS_REGIONS,
    134     _Attributes_Is_priority( attribute_set ) ?
    135        THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO,
    136     STATES_WAITING_FOR_SEGMENT,
    137 #if defined(RTEMS_MULTIPROCESSING)
    138     _Region_MP_Send_extract_proxy,
    139 #else
    140     NULL,
    141 #endif
    142     RTEMS_TIMEOUT
    143   );
    144 
    145   _Objects_Open( &_Region_Information, &the_region->Object, &name );
    146 
    147   *id = the_region->Object.id;
    148   _Thread_Enable_dispatch();
    149   return RTEMS_SUCCESSFUL;
    150 }
    151 
    152 /*PAGE
    153  *
    154  *  rtems_region_ident
    155  *
    156  *  This directive returns the system ID associated with
    157  *  the region name.
    158  *
    159  *  Input parameters:
    160  *    name - user defined region name
    161  *    id   - pointer to region id
    162  *
    163  *  Output parameters:
    164  *    *id      - region id
    165  *    RTEMS_SUCCESSFUL - if successful
    166  *    error code - if unsuccessful
    167  */
    168 
    169 rtems_status_code rtems_region_ident(
    170   rtems_name    name,
    171   Objects_Id   *id
    172 )
    173 {
    174   Objects_Name_to_id_errors  status;
    175 
    176   status = _Objects_Name_to_id(
    177     &_Region_Information,
    178     &name,
    179     OBJECTS_SEARCH_LOCAL_NODE,
    180     id
    181   );
    182 
    183   return _Status_Object_name_errors_to_status[ status ];
    184 }
    185 
    186 /*PAGE
    187  *
    188  *  rtems_region_delete
    189  *
    190  *  This directive allows a thread to delete a region specified by
    191  *  the region identifier, provided that none of its segments are
    192  *  still allocated.
    193  *
    194  *  Input parameters:
    195  *    id - region id
    196  *
    197  *  Output parameters:
    198  *    RTEMS_SUCCESSFUL - if successful
    199  *    error code - if unsuccessful
    200  */
    201 
    202 rtems_status_code rtems_region_delete(
    203   Objects_Id id
    204 )
    205 {
    206   register Region_Control *the_region;
    207   Objects_Locations               location;
    208 
    209   the_region = _Region_Get( id, &location );
    210   switch ( location ) {
    211     case OBJECTS_REMOTE:        /* this error cannot be returned */
    212       return RTEMS_INTERNAL_ERROR;
    213 
    214     case OBJECTS_ERROR:
    215       return RTEMS_INVALID_ID;
    216 
    217     case OBJECTS_LOCAL:
    218       _Region_Debug_Walk( the_region, 5 );
    219       if ( the_region->number_of_used_blocks == 0 ) {
    220         _Objects_Close( &_Region_Information, &the_region->Object );
    221         _Region_Free( the_region );
    222         _Thread_Enable_dispatch();
    223         return RTEMS_SUCCESSFUL;
    224       }
    225       _Thread_Enable_dispatch();
    226       return RTEMS_RESOURCE_IN_USE;
    227   }
    228 
    229   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    230 }
    231 
    232 /*PAGE
    233  *
    234  *  rtems_region_extend
    235  *
    236  *  This directive attempts to grow a region of physical contiguous memory area
    237  *  from which variable sized segments can be allocated.
    238  *
    239  *  Input parameters:
    240  *    id         - id of region to grow
    241  *    start      - starting address of memory area for extension
    242  *    length     - physical length in bytes to grow the region
    243  *
    244  *  Output parameters:
    245  *    RTEMS_SUCCESSFUL - if successful
    246  *    error code       - if unsuccessful
    247  */
    248 
    249 rtems_status_code rtems_region_extend(
    250   Objects_Id          id,
    251   void               *starting_address,
    252   unsigned32          length
    253 )
    254 {
    255   Region_Control     *the_region;
    256   Objects_Locations   location;
    257   unsigned32          amount_extended;
    258   Heap_Extend_status  heap_status;
    259   rtems_status_code   status;
    260 
    261   status = RTEMS_SUCCESSFUL;
    262 
    263   the_region = _Region_Get( id, &location );
    264   switch ( location ) {
    265     case OBJECTS_REMOTE:        /* this error cannot be returned */
    266       return RTEMS_INTERNAL_ERROR;
    267 
    268     case OBJECTS_ERROR:
    269       return RTEMS_INVALID_ID;
    270 
    271     case OBJECTS_LOCAL:
    272 
    273       heap_status = _Heap_Extend(
    274         &the_region->Memory,
    275         starting_address,
    276         length,
    277         &amount_extended
    278       );
    279 
    280       switch ( heap_status ) {
    281         case HEAP_EXTEND_SUCCESSFUL:
    282           the_region->length                += amount_extended;
    283           the_region->maximum_segment_size  += amount_extended;
    284           break;
    285         case HEAP_EXTEND_ERROR:
    286           status = RTEMS_INVALID_ADDRESS;
    287           break;
    288         case HEAP_EXTEND_NOT_IMPLEMENTED:
    289           status = RTEMS_NOT_IMPLEMENTED;
    290           break;
    291       }
    292       _Thread_Enable_dispatch();
    293       return( status );
    294   }
    295 
    296   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    297 }
    298 
    299 /*PAGE
    300  *
    301  *  rtems_region_get_segment
    302  *
    303  *  This directive will obtain a segment from the given region.
    304  *
    305  *  Input parameters:
    306  *    id         - region id
    307  *    size       - segment size in bytes
    308  *    option_set - wait option
    309  *    timeout    - number of ticks to wait (0 means wait forever)
    310  *    segment    - pointer to segment address
    311  *
    312  *  Output parameters:
    313  *    segment    - pointer to segment address filled in
    314  *    RTEMS_SUCCESSFUL - if successful
    315  *    error code - if unsuccessful
    316  */
    317 
    318 rtems_status_code rtems_region_get_segment(
    319   Objects_Id         id,
    320   unsigned32         size,
    321   rtems_option       option_set,
    322   rtems_interval     timeout,
    323   void              **segment
    324 )
    325 {
    326   register Region_Control *the_region;
    327   Objects_Locations        location;
    328   Thread_Control          *executing;
    329   void                    *the_segment;
    330 
    331   *segment = NULL;
    332 
    333   if ( size == 0 )
    334     return RTEMS_INVALID_SIZE;
    335 
    336   executing  = _Thread_Executing;
    337   the_region = _Region_Get( id, &location );
    338   switch ( location ) {
    339     case OBJECTS_REMOTE:        /* this error cannot be returned */
    340       return RTEMS_INTERNAL_ERROR;
    341 
    342     case OBJECTS_ERROR:
    343       return RTEMS_INVALID_ID;
    344 
    345     case OBJECTS_LOCAL:
    346       if ( size > the_region->maximum_segment_size ) {
    347         _Thread_Enable_dispatch();
    348         return RTEMS_INVALID_SIZE;
    349       }
    350 
    351       _Region_Debug_Walk( the_region, 1 );
    352 
    353       the_segment = _Region_Allocate_segment( the_region, size );
    354 
    355       _Region_Debug_Walk( the_region, 2 );
    356 
    357       if ( the_segment ) {
    358         the_region->number_of_used_blocks += 1;
    359         _Thread_Enable_dispatch();
    360         *segment = the_segment;
    361         return RTEMS_SUCCESSFUL;
    362       }
    363 
    364       if ( _Options_Is_no_wait( option_set ) ) {
    365         _Thread_Enable_dispatch();
    366         return RTEMS_UNSATISFIED;
    367       }
    368 
    369       executing->Wait.queue           = &the_region->Wait_queue;
    370       executing->Wait.id              = id;
    371       executing->Wait.count           = size;
    372       executing->Wait.return_argument = (unsigned32 *) segment;
    373 
    374       _Thread_queue_Enter_critical_section( &the_region->Wait_queue );
    375 
    376       _Thread_queue_Enqueue( &the_region->Wait_queue, timeout );
    377 
    378       _Thread_Enable_dispatch();
    379       return (rtems_status_code) executing->Wait.return_code;
    380   }
    381 
    382   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    383 }
    384 /*PAGE
    385  *
    386  *  rtems_region_get_segment_size
    387  *
    388  *  This directive will return the size of the segment indicated
    389  *
    390  *  Input parameters:
    391  *    id         - region id
    392  *    segment    - segment address
    393  *    size       - pointer to segment size in bytes
    394  *
    395  *  Output parameters:
    396  *    size       - segment size in bytes filled in
    397  *    RTEMS_SUCCESSFUL - if successful
    398  *    error code - if unsuccessful
    399  */
    400 
    401 rtems_status_code rtems_region_get_segment_size(
    402   Objects_Id         id,
    403   void              *segment,
    404   unsigned32        *size
    405 )
    406 {
    407   register Region_Control *the_region;
    408   Objects_Locations        location;
    409   Thread_Control          *executing;
    410 
    411   executing  = _Thread_Executing;
    412   the_region = _Region_Get( id, &location );
    413   switch ( location ) {
    414     case OBJECTS_REMOTE:        /* this error cannot be returned */
    415       return RTEMS_INTERNAL_ERROR;
    416 
    417     case OBJECTS_ERROR:
    418       return RTEMS_INVALID_ID;
    419 
    420     case OBJECTS_LOCAL:
    421 
    422       if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) {
    423         _Thread_Enable_dispatch();
    424         return RTEMS_SUCCESSFUL;
    425       }
    426       _Thread_Enable_dispatch();
    427       return RTEMS_INVALID_ADDRESS;
    428   }
    429 
    430   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    431 }
    432 
    433 /*PAGE
    434  *
    435  *  rtems_region_return_segment
    436  *
    437  *  This directive will return a segment to its region.
    438  *
    439  *  Input parameters:
    440  *    id      - region id
    441  *    segment - pointer to segment address
    442  *
    443  *  Output parameters:
    444  *    RTEMS_SUCCESSFUL - if successful
    445  *    error code        - if unsuccessful
    446  */
    447 
    448 rtems_status_code rtems_region_return_segment(
    449   Objects_Id  id,
    450   void       *segment
    451 )
    452 {
    453   register Region_Control *the_region;
    454   Thread_Control          *the_thread;
    455   Objects_Locations        location;
    456   void                   **the_segment;
    457 #ifdef RTEMS_SHRED_ON_FREE
    458   unsigned32               size;
    459 #endif
    460   int                      status;
    461 
    462   the_region = _Region_Get( id, &location );
    463   switch ( location ) {
    464 
    465     case OBJECTS_REMOTE:        /* this error cannot be returned */
    466       return RTEMS_INTERNAL_ERROR;
    467 
    468     case OBJECTS_ERROR:
    469       return RTEMS_INVALID_ID;
    470 
    471     case OBJECTS_LOCAL:
    472 
    473       _Region_Debug_Walk( the_region, 3 );
    474 
    475 #ifdef RTEMS_REGION_FREE_SHRED_PATTERN
    476       if ( _Heap_Size_of_user_area( &the_region->Memory, segment, size ) ) {
    477         memset(segment, (RTEMS_REGION_FREE_SHRED_BYTE & 0xFF), size);
    478       } else {
    479         _Thread_Enable_dispatch();
    480         return RTEMS_INVALID_ADDRESS;
    481       }
    482 #endif
    483 
    484       status = _Region_Free_segment( the_region, segment );
    485 
    486       _Region_Debug_Walk( the_region, 4 );
    487 
    488       if ( !status ) {
    489         _Thread_Enable_dispatch();
    490         return RTEMS_INVALID_ADDRESS;
    491       }
    492 
    493       the_region->number_of_used_blocks -= 1;
    494       for ( ; ; ) {
    495         the_thread = _Thread_queue_First( &the_region->Wait_queue );
    496 
    497         if ( the_thread == NULL )
    498            break;
    499 
    500         the_segment = (void **) _Region_Allocate_segment(
    501            the_region,
    502            the_thread->Wait.count
    503         );
    504 
    505         if ( the_segment == NULL )
    506            break;
    507 
    508         *(void **)the_thread->Wait.return_argument = the_segment;
    509         the_region->number_of_used_blocks += 1;
    510         _Thread_queue_Extract( &the_region->Wait_queue, the_thread );
    511         the_thread->Wait.return_code = RTEMS_SUCCESSFUL;
    512       }
    513 
    514       _Thread_Enable_dispatch();
    515       return RTEMS_SUCCESSFUL;
    516   }
    517 
    518   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    519 }
Note: See TracChangeset for help on using the changeset viewer.