Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreStack
0007  *
0008  * @brief This header file provides interfaces of the
0009  *   @ref RTEMSScoreStack which are only used by the implementation.
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-2006.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifndef _RTEMS_SCORE_STACKIMPL_H
0039 #define _RTEMS_SCORE_STACKIMPL_H
0040 
0041 #include <rtems/score/stack.h>
0042 #include <rtems/score/context.h>
0043 #include <rtems/score/tls.h>
0044 
0045 #ifdef __cplusplus
0046 extern "C" {
0047 #endif
0048 
0049 /**
0050  * @addtogroup RTEMSScoreStack
0051  *
0052  * @{
0053  */
0054 
0055 /**
0056  * @brief Initializes stack with the given starting address and size.
0057  *
0058  * This routine initializes the_stack record to indicate that
0059  * size bytes of memory starting at starting_address have been
0060  * reserved for a stack.
0061  *
0062  * @param[out] the_stack The stack to initialize.
0063  * @param starting_address The starting_address for the new stack.
0064  * @param size The size of the stack in bytes.
0065  */
0066 static inline void _Stack_Initialize (
0067   Stack_Control *the_stack,
0068   void          *starting_address,
0069   size_t         size
0070 )
0071 {
0072   the_stack->area = starting_address;
0073   the_stack->size = size;
0074 }
0075 
0076 /**
0077  * @brief Returns the minimum stack size.
0078  *
0079  * This function returns the minimum stack size configured
0080  * for this application.
0081  *
0082  * @return The minimum stack size.
0083  */
0084 static inline uint32_t _Stack_Minimum (void)
0085 {
0086   return rtems_minimum_stack_size;
0087 }
0088 
0089 /**
0090  * @brief Checks if the size is enough for a valid stack area on this processor.
0091  *
0092  * This function returns true if size bytes is enough memory for
0093  * a valid stack area on this processor, and false otherwise.
0094  *
0095  * @param size The stack size to check.
0096  * @param is_fp Indicates if the stack is for a floating-point thread.
0097  *
0098  * @retval true @a size is large enough.
0099  * @retval false @a size is not large enough.
0100  */
0101 static inline bool _Stack_Is_enough(
0102   size_t size,
0103   bool   is_fp
0104 )
0105 {
0106   size_t minimum;
0107 
0108   minimum = _TLS_Get_allocation_size();
0109   minimum += _Stack_Minimum();
0110 
0111 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
0112   if ( is_fp ) {
0113     minimum += CONTEXT_FP_SIZE;
0114   }
0115 #endif
0116 
0117   return ( size >= minimum );
0118 }
0119 
0120 /**
0121  * @brief Returns the appropriate stack size for the requested size.
0122  *
0123  * This function returns the appropriate stack size given the requested
0124  * size.  If the requested size is below the minimum, then the minimum
0125  * configured stack size is returned.
0126  *
0127  * @param size The stack size to check.
0128  *
0129  * @return The appropriate stack size.
0130  */
0131 static inline size_t _Stack_Ensure_minimum (
0132   size_t size
0133 )
0134 {
0135   if ( size >= _Stack_Minimum() )
0136     return size;
0137   return _Stack_Minimum();
0138 }
0139 
0140 /**
0141  * @brief Extends the stack size to account for additional data structures
0142  *   allocated in the thread storage area.
0143  *
0144  * @param stack_size is the stack size.
0145  *
0146  * @param is_fp shall be true, if the stack is for a floating-point thread,
0147  *   otherwise it shall be false.
0148  *
0149  * @return Returns the extended stack size.
0150  */
0151 static inline size_t _Stack_Extend_size(
0152   size_t stack_size,
0153   bool   is_fp
0154 )
0155 {
0156   size_t extra_size;
0157   size_t allocator_overhead;
0158 
0159   extra_size = _TLS_Get_allocation_size();
0160 
0161 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
0162   if ( is_fp ) {
0163     /* This addition cannot overflow since the TLS size cannot be that large */
0164     extra_size += CONTEXT_FP_SIZE;
0165   }
0166 #else
0167   (void) is_fp;
0168 #endif
0169 
0170   /*
0171    * In order to make sure that a user-provided stack size is the minimum which
0172    * can be allocated for the stack, we have to align it up to the next stack
0173    * boundary.
0174    */
0175   extra_size += CPU_STACK_ALIGNMENT - 1;
0176 
0177   /*
0178    * If the heap allocator does not meet the stack alignment requirement, then
0179    * we have to do the stack alignment manually in _Thread_Initialize() and
0180    * need to allocate extra space for this.
0181    */
0182   allocator_overhead = CPU_STACK_ALIGNMENT - CPU_HEAP_ALIGNMENT;
0183 
0184   if ( stack_size > SIZE_MAX - extra_size - allocator_overhead ) {
0185     /*
0186      * In case of an unsigned integer overflow, saturate at the maximum value.
0187      */
0188     return SIZE_MAX;
0189   }
0190 
0191   stack_size += extra_size;
0192   stack_size = RTEMS_ALIGN_DOWN( stack_size, CPU_STACK_ALIGNMENT );
0193 
0194   return stack_size + allocator_overhead;
0195 }
0196 
0197 /**
0198  * @brief Allocate the requested stack space.
0199  *
0200  * @param stack_size The stack space that is requested.
0201  *
0202  * @retval stack_area The allocated stack area.
0203  * @retval NULL The allocation failed.
0204  */
0205 void *_Stack_Allocate( size_t stack_size );
0206 
0207 /**
0208  * @brief Free the stack area allocated by _Stack_Allocate().
0209  *
0210  * Do nothing if the stack area is NULL.
0211  *
0212  * @param stack_area The stack area to free, or NULL.
0213  */
0214 void _Stack_Free( void *stack_area );
0215 
0216 /** @} */
0217 
0218 #ifdef __cplusplus
0219 }
0220 #endif
0221 
0222 #endif
0223 /* end of include file */