/* SPDX-License-Identifier: BSD-2-Clause */ /** * @file * * @brief This header file defines the Region Manager API. */ /* * Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de) * Copyright (C) 1988, 2008 On-Line Applications Research Corporation (OAR) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * This file is part of the RTEMS quality process and was automatically * generated. If you find something that needs to be fixed or * worded better please post a report or patch to an RTEMS mailing list * or raise a bug report: * * https://www.rtems.org/bugs.html * * For information on updating and regenerating please refer to the How-To * section in the Software Requirements Engineering chapter of the * RTEMS Software Engineering manual. The manual is provided as a part of * a release. For development sources please refer to the online * documentation at: * * https://docs.rtems.org */ /* Generated from spec:/rtems/region/if/header */ #ifndef _RTEMS_RTEMS_REGION_H #define _RTEMS_RTEMS_REGION_H #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* Generated from spec:/rtems/region/if/group */ /** * @defgroup RTEMSAPIClassicRegion Region Manager * * @ingroup RTEMSAPIClassic * * @brief The Region Manager provides facilities to dynamically allocate memory * in variable sized units. */ /* Generated from spec:/rtems/region/if/get-segment-size */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Gets the size of the region segment. * * @param id is the region identifier. * * @param segment is the begin address of the segment. * * @param[out] size is the pointer to a uintptr_t object. When the directive * call is successful, the size of the segment in bytes will be stored in * this object. * * This directive obtains the size in bytes of the segment specified by * ``segment`` of the region specified by ``id`` in ``size``. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ADDRESS The ``segment`` parameter was NULL. * * @retval ::RTEMS_INVALID_ADDRESS The ``size`` parameter was NULL. * * @retval ::RTEMS_INVALID_ID There was no region associated with the * identifier specified by ``id``. * * @retval ::RTEMS_INVALID_ADDRESS The segment was not within the region. * * @par Notes * The actual length of the allocated segment may be larger than the requested * size because a segment size is always a multiple of the region's page size. * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * @endparblock */ rtems_status_code rtems_region_get_segment_size( rtems_id id, void *segment, uintptr_t *size ); /* Generated from spec:/rtems/region/if/create */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Creates a region. * * @param name is the object name of the region. * * @param starting_address is the starting address of the memory area managed * by the region. * * @param length is the length in bytes of the memory area managed by the * region. * * @param page_size is the alignment of the starting address and length of each * allocated segment of the region. * * @param attribute_set is the attribute set of the region. * * @param[out] id is the pointer to an ::rtems_id object. When the directive * call is successful, the identifier of the created region will be stored in * this object. * * This directive creates a region which resides on the local node. The region * has the user-defined object name specified in ``name``. The assigned object * identifier is returned in ``id``. This identifier is used to access the * region with other region related directives. * * The region manages the **contiguous memory area** which starts at * ``starting_address`` and is ``length`` bytes long. The memory area shall be * large enough to contain some internal region administration data. * * The **starting address** and **length of segments** allocated from the * region will be an integral multiple of ``page_size``. The specified page * size will be aligned to an implementation-dependent minimum alignment if * necessary. * * The **attribute set** specified in ``attribute_set`` is built through a * *bitwise or* of the attribute constants described below. Not all * combinations of attributes are allowed. Some attributes are mutually * exclusive. If mutually exclusive attributes are combined, the behaviour is * undefined. Attributes not mentioned below are not evaluated by this * directive and have no effect. Default attributes can be selected by using * the #RTEMS_DEFAULT_ATTRIBUTES constant. * * The **task wait queue discipline** is selected by the mutually exclusive * #RTEMS_FIFO and #RTEMS_PRIORITY attributes. The discipline defines the order * in which tasks wait for allocatable segments on a currently empty region. * * * The **FIFO discipline** is the default and can be emphasized through use * of the #RTEMS_FIFO attribute. * * * The **priority discipline** is selected by the #RTEMS_PRIORITY attribute. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_NAME The ``name`` parameter was invalid. * * @retval ::RTEMS_INVALID_ADDRESS The ``id`` parameter was NULL. * * @retval ::RTEMS_INVALID_ADDRESS The ``starting_address`` parameter was NULL. * * @retval ::RTEMS_TOO_MANY There was no inactive object available to create a * region. The number of regions available to the application is configured * through the #CONFIGURE_MAXIMUM_REGIONS application configuration option. * * @retval ::RTEMS_INVALID_SIZE The ``page_size`` parameter was invalid. * * @retval ::RTEMS_INVALID_SIZE The memory area specified in * ``starting_address`` and ``length`` was too small. * * @par Notes * For control and maintenance of the region, RTEMS allocates a RNCB from the * local RNCB free pool and initializes it. * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * * * The number of regions available to the application is configured through * the #CONFIGURE_MAXIMUM_REGIONS application configuration option. * * * Where the object class corresponding to the directive is configured to use * unlimited objects, the directive may allocate memory from the RTEMS * Workspace. * @endparblock */ rtems_status_code rtems_region_create( rtems_name name, void *starting_address, uintptr_t length, uintptr_t page_size, rtems_attribute attribute_set, rtems_id *id ); /* Generated from spec:/rtems/region/if/ident */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Identifies a region by the object name. * * @param name is the object name to look up. * * @param[out] id is the pointer to an ::rtems_id object. When the directive * call is successful, the object identifier of an object with the specified * name will be stored in this object. * * This directive obtains a region identifier associated with the region name * specified in ``name``. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ADDRESS The ``id`` parameter was NULL. * * @retval ::RTEMS_INVALID_NAME The ``name`` parameter was 0. * * @retval ::RTEMS_INVALID_NAME There was no object with the specified name on * the local node. * * @par Notes * @parblock * If the region name is not unique, then the region identifier will match the * first region with that name in the search order. However, this region * identifier is not guaranteed to correspond to the desired region. * * The objects are searched from lowest to the highest index. Only the local * node is searched. * * The region identifier is used with other region related directives to access * the region. * @endparblock * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within any runtime context. * * * The directive will not cause the calling task to be preempted. * @endparblock */ rtems_status_code rtems_region_ident( rtems_name name, rtems_id *id ); /* Generated from spec:/rtems/region/if/delete */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Deletes the region. * * @param id is the region identifier. * * This directive deletes the region specified by ``id``. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ID There was no region associated with the * identifier specified by ``id``. * * @retval ::RTEMS_RESOURCE_IN_USE There were segments of the region still in * use. * * @par Notes * @parblock * The region cannot be deleted if any of its segments are still allocated. * * The RNCB for the deleted region is reclaimed by RTEMS. * @endparblock * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * * * The calling task does not have to be the task that created the object. * Any local task that knows the object identifier can delete the object. * * * Where the object class corresponding to the directive is configured to use * unlimited objects, the directive may free memory to the RTEMS Workspace. * @endparblock */ rtems_status_code rtems_region_delete( rtems_id id ); /* Generated from spec:/rtems/region/if/extend */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Extends the region. * * @param id is the region identifier. * * @param starting_address is the starting address of the memory area to extend * the region. * * @param length is the length in bytes of the memory area to extend the * region. * * This directive adds the memory area which starts at ``starting_address`` for * ``length`` bytes to the region specified by ``id``. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ADDRESS The ``starting_address`` parameter was NULL. * * @retval ::RTEMS_INVALID_ID There was no region associated with the * identifier specified by ``id``. * * @retval ::RTEMS_INVALID_ADDRESS The memory area specified by * ``starting_address`` and ``length`` was insufficient to extend the heap. * * @par Notes * There are no alignment requirements for the memory area. The memory area * must be big enough to contain some maintenance blocks. It must not overlap * parts of the current heap memory areas. Disconnected memory areas added to * the heap will lead to used blocks which cover the gaps. Extending with an * inappropriate memory area will corrupt the heap resulting in undefined * behaviour. * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * @endparblock */ rtems_status_code rtems_region_extend( rtems_id id, void *starting_address, uintptr_t length ); /* Generated from spec:/rtems/region/if/get-segment */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Gets a segment from the region. * * @param id is the region identifier. * * @param size is the size in bytes of the segment to allocate. * * @param option_set is the option set. * * @param timeout is the timeout in clock ticks if the #RTEMS_WAIT option is * set. Use #RTEMS_NO_TIMEOUT to wait potentially forever. * * @param[out] segment is the pointer to a ``void`` pointer object. When the * directive call is successful, the begin address of the allocated segment * will be stored in this object. * * This directive gets a segment from the region specified by ``id``. * * The **option set** specified in ``option_set`` is built through a *bitwise * or* of the option constants described below. Not all combinations of * options are allowed. Some options are mutually exclusive. If mutually * exclusive options are combined, the behaviour is undefined. Options not * mentioned below are not evaluated by this directive and have no effect. * Default options can be selected by using the #RTEMS_DEFAULT_OPTIONS * constant. * * The calling task can **wait** or **try to get** a segment from the region * according to the mutually exclusive #RTEMS_WAIT and #RTEMS_NO_WAIT options. * * * **Waiting to get** a segment from the region is the default and can be * emphasized through the use of the #RTEMS_WAIT option. The ``timeout`` * parameter defines how long the calling task is willing to wait. Use * #RTEMS_NO_TIMEOUT to wait potentially forever, otherwise set a timeout * interval in clock ticks. * * * **Trying to get** a segment from the region is selected by the * #RTEMS_NO_WAIT option. If this option is defined, then the ``timeout`` * parameter is ignored. When a segment from the region cannot be * immediately allocated, then the ::RTEMS_UNSATISFIED status is returned. * * With either #RTEMS_WAIT or #RTEMS_NO_WAIT if there is a segment of the * requested size is available, then it is returned in ``segment`` and this * directive returns immediately with the ::RTEMS_SUCCESSFUL status code. * * If the calling task chooses to return immediately and the region has no * segment of the requested size available, then the directive returns * immediately with the ::RTEMS_UNSATISFIED status code. If the calling task * chooses to wait for a segment, then the calling task is placed on the region * wait queue and blocked. If the region was created with the #RTEMS_PRIORITY * option specified, then the calling task is inserted into the wait queue * according to its priority. But, if the region was created with the * #RTEMS_FIFO option specified, then the calling task is placed at the rear of * the wait queue. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ADDRESS The ``segment`` parameter was NULL. * * @retval ::RTEMS_INVALID_SIZE The ``size`` parameter was zero. * * @retval ::RTEMS_INVALID_ID There was no region associated with the * identifier specified by ``id``. * * @retval ::RTEMS_INVALID_SIZE The ``size`` parameter exceeded the maximum * segment size which is possible for the region. * * @retval ::RTEMS_UNSATISFIED The region had no segment of the requested size * immediately available. * * @retval ::RTEMS_TIMEOUT The timeout happened while the calling task was * waiting to get a segment from the region. * * @par Notes * The actual length of the allocated segment may be larger than the requested * size because a segment size is always a multiple of the region's page size. * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * * * When the request cannot be immediately satisfied and the #RTEMS_WAIT * option is set, the calling task blocks at some point during the directive * call. * * * The timeout functionality of the directive requires a clock tick. * @endparblock */ rtems_status_code rtems_region_get_segment( rtems_id id, uintptr_t size, rtems_option option_set, rtems_interval timeout, void **segment ); /* Generated from spec:/rtems/region/if/return-segment */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Returns the segment to the region. * * @param id is the region identifier. * * @param segment is the begin address of the segment to return. * * This directive returns the segment specified by ``segment`` to the region * specified by ``id``. The returned segment is merged with its neighbors to * form the largest possible segment. The first task on the wait queue is * examined to determine if its segment request can now be satisfied. If so, * it is given a segment and unblocked. This process is repeated until the * first task's segment request cannot be satisfied. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ID There was no region associated with the * identifier specified by ``id``. * * @retval ::RTEMS_INVALID_ADDRESS The segment was not within the region. * * @par Notes * @parblock * This directive will cause the calling task to be preempted if one or more * local tasks are waiting for a segment and the following conditions exist: * * * A waiting task has a higher priority than the calling task. * * * The size of the segment required by the waiting task is less than or equal * to the size of the segment returned. * @endparblock * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may unblock a task. This may cause the calling task to be * preempted. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * @endparblock */ rtems_status_code rtems_region_return_segment( rtems_id id, void *segment ); /* Generated from spec:/rtems/region/if/resize-segment */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Changes the size of the segment. * * @param id is the region identifier. * * @param segment is the begin address of the segment to resize. * * @param size is the requested new size of the segment. * * @param[out] old_size is the pointer to an uintptr_t object. When the * directive call is successful, the old size of the segment will be stored * in this object. * * This directive is used to increase or decrease the size of the ``segment`` * of the region specified by ``id``. When increasing the size of a segment, * it is possible that there is no memory available contiguous to the segment. * In this case, the request is unsatisfied. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ADDRESS The ``old_size`` parameter was NULL. * * @retval ::RTEMS_INVALID_ID There was no region associated with the * identifier specified by ``id``. * * @retval ::RTEMS_INVALID_ADDRESS The segment was not within the region. * * @retval ::RTEMS_UNSATISFIED The region was unable to resize the segment. * * @par Notes * If an attempt to increase the size of a segment fails, then the application * may want to allocate a new segment of the desired size, copy the contents of * the original segment to the new, larger segment and then return the original * segment. * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * @endparblock */ rtems_status_code rtems_region_resize_segment( rtems_id id, void *segment, uintptr_t size, uintptr_t *old_size ); /* Generated from spec:/rtems/region/if/get-information */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Gets the region information. * * @param id is the region identifier. * * @param[out] the_info is the pointer to a Heap_Information_block object. * When the directive call is successful, the information of the region will * be stored in this object. * * This directive is used to obtain information about the used and free memory * in the region specified by ``id``. This is a snapshot at the time of the * call. The information will be returned in the structure pointed to by * ``the_info``. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ADDRESS The ``the_info`` parameter was NULL. * * @retval ::RTEMS_INVALID_ID There was no region associated with the * identifier specified by ``id``. * * @par Notes * @parblock * This is primarily intended as a mechanism to obtain a diagnostic * information. This method forms am O(n) scan of the free and an O(n) scan of * the used blocks in the region to calculate the information provided. Given * that the execution time is driven by the number of used and free blocks, it * can take a non-deterministic time to execute. * * To get only the free information of the region use * rtems_region_get_free_information(). * @endparblock * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * @endparblock */ rtems_status_code rtems_region_get_information( rtems_id id, Heap_Information_block *the_info ); /* Generated from spec:/rtems/region/if/get-free-information */ /** * @ingroup RTEMSAPIClassicRegion * * @brief Gets the region free information. * * @param id is the region identifier. * * @param[out] the_info is the pointer to a Heap_Information_block object. * When the directive call is successful, the free information of the region * will be stored in this object. * * This directive is used to obtain information about the free memory in the * region specified by ``id``. This is a snapshot at the time of the call. The * information will be returned in the structure pointed to by ``the_info``. * * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. * * @retval ::RTEMS_INVALID_ADDRESS The ``the_info`` parameter was NULL. * * @retval ::RTEMS_INVALID_ID There was no region associated with the * identifier specified by ``id``. * * @par Notes * @parblock * This directive uses the same structure to return information as the * rtems_region_get_information() directive but does not fill in the used * information. * * This is primarily intended as a mechanism to obtain a diagnostic * information. This method forms am O(n) scan of the free in the region to * calculate the information provided. Given that the execution time is driven * by the number of used and free blocks, it can take a non-deterministic time * to execute. Typically, there are many used blocks and a much smaller number * of used blocks making a call to this directive less expensive than a call to * rtems_region_get_information(). * @endparblock * * @par Constraints * @parblock * The following constraints apply to this directive: * * * The directive may be called from within device driver initialization * context. * * * The directive may be called from within task context. * * * The directive may obtain and release the object allocator mutex. This may * cause the calling task to be preempted. * @endparblock */ rtems_status_code rtems_region_get_free_information( rtems_id id, Heap_Information_block *the_info ); #ifdef __cplusplus } #endif #endif /* _RTEMS_RTEMS_REGION_H */