source: rtems/cpukit/include/rtems/score/stackimpl.h @ 5248395

Last change on this file since 5248395 was 5248395, checked in by Sebastian Huber <sebastian.huber@…>, on 03/03/21 at 08:23:20

score: Ensure stack alignment requirement

Make sure that a user-provided stack size is the minimum size allocated
for the stack.

Make sure we meet the stack alignment requirement also for CPU ports
with CPU_STACK_ALIGNMENT > CPU_HEAP_ALIGNMENT.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSScoreStack
5 *
6 * @brief This header file provides interfaces of the
7 *   @ref RTEMSScoreStack which are only used by the implementation.
8 */
9
10/*
11 *  COPYRIGHT (c) 1989-2006.
12 *  On-Line Applications Research Corporation (OAR).
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_STACKIMPL_H
20#define _RTEMS_SCORE_STACKIMPL_H
21
22#include <rtems/score/stack.h>
23#include <rtems/score/context.h>
24#include <rtems/score/tls.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/**
31 * @addtogroup RTEMSScoreStack
32 *
33 * @{
34 */
35
36/**
37 * @brief Initializes stack with the given starting address and size.
38 *
39 * This routine initializes the_stack record to indicate that
40 * size bytes of memory starting at starting_address have been
41 * reserved for a stack.
42 *
43 * @param[out] the_stack The stack to initialize.
44 * @param starting_address The starting_address for the new stack.
45 * @param size The size of the stack in bytes.
46 */
47RTEMS_INLINE_ROUTINE void _Stack_Initialize (
48  Stack_Control *the_stack,
49  void          *starting_address,
50  size_t         size
51)
52{
53  the_stack->area = starting_address;
54  the_stack->size = size;
55}
56
57/**
58 * @brief Returns the minimum stack size.
59 *
60 * This function returns the minimum stack size configured
61 * for this application.
62 *
63 * @return The minimum stack size.
64 */
65RTEMS_INLINE_ROUTINE uint32_t _Stack_Minimum (void)
66{
67  return rtems_minimum_stack_size;
68}
69
70/**
71 * @brief Checks if the size is enough for a valid stack area on this processor.
72 *
73 * This function returns true if size bytes is enough memory for
74 * a valid stack area on this processor, and false otherwise.
75 *
76 * @param size The stack size to check.
77 * @param is_fp Indicates if the stack is for a floating-point thread.
78 *
79 * @retval true @a size is large enough.
80 * @retval false @a size is not large enough.
81 */
82RTEMS_INLINE_ROUTINE bool _Stack_Is_enough(
83  size_t size,
84  bool   is_fp
85)
86{
87  size_t minimum;
88
89  minimum = _TLS_Get_allocation_size();
90  minimum += _Stack_Minimum();
91
92#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
93  if ( is_fp ) {
94    minimum += CONTEXT_FP_SIZE;
95  }
96#endif
97
98  return ( size >= minimum );
99}
100
101/**
102 * @brief Returns the appropriate stack size for the requested size.
103 *
104 * This function returns the appropriate stack size given the requested
105 * size.  If the requested size is below the minimum, then the minimum
106 * configured stack size is returned.
107 *
108 * @param size The stack size to check.
109 *
110 * @return The appropriate stack size.
111 */
112RTEMS_INLINE_ROUTINE size_t _Stack_Ensure_minimum (
113  size_t size
114)
115{
116  if ( size >= _Stack_Minimum() )
117    return size;
118  return _Stack_Minimum();
119}
120
121/**
122 * @brief Extends the stack size to account for additional data structures
123 *   allocated in the thread storage area.
124 *
125 * @param stack_size is the stack size.
126 *
127 * @param is_fp shall be true, if the stack is for a floating-point thread,
128 *   otherwise it shall be false.
129 *
130 * @return Returns the extended stack size.
131 */
132RTEMS_INLINE_ROUTINE size_t _Stack_Extend_size(
133  size_t stack_size,
134  bool   is_fp
135)
136{
137  size_t extra_size;
138  size_t alignment_overhead;
139
140  extra_size = _TLS_Get_allocation_size();
141
142#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
143  if ( is_fp ) {
144    /* This addition cannot overflow since the TLS size cannot be that large */
145    extra_size += CONTEXT_FP_SIZE;
146  }
147#else
148  (void) is_fp;
149#endif
150
151  /*
152   * In order to make sure that a user-provided stack size is the minimum which
153   * can be allocated for the stack, we have to align it up to the next stack
154   * boundary.
155   */
156  alignment_overhead = CPU_STACK_ALIGNMENT - 1;
157
158#if CPU_STACK_ALIGNMENT > CPU_HEAP_ALIGNMENT
159  /*
160   * If the heap allocator does not meet the stack alignment requirement, then
161   * we have to do the stack alignment manually in _Thread_Initialize() and
162   * need to allocate extra space for this.
163   */
164  alignment_overhead += CPU_STACK_ALIGNMENT - CPU_HEAP_ALIGNMENT;
165#endif
166
167  if ( stack_size > SIZE_MAX - extra_size - alignment_overhead ) {
168    /*
169     * In case of an unsigned integer overflow, saturate at the maximum value.
170     */
171    return SIZE_MAX;
172  }
173
174  stack_size += extra_size;
175  stack_size = RTEMS_ALIGN_UP( stack_size, CPU_STACK_ALIGNMENT );
176
177  return stack_size;
178}
179
180/**
181 * @brief Allocate the requested stack space.
182 *
183 * @param stack_size The stack space that is requested.
184 *
185 * @retval stack_area The allocated stack area.
186 * @retval NULL The allocation failed.
187 */
188void *_Stack_Allocate( size_t stack_size );
189
190/**
191 * @brief Free the stack area allocated by _Stack_Allocate().
192 *
193 * Do nothing if the stack area is NULL.
194 *
195 * @param stack_area The stack area to free, or NULL.
196 */
197void _Stack_Free( void *stack_area );
198
199/**
200 * @brief This function does nothing.
201 *
202 * @param stack_area is not used.
203 */
204void _Stack_Free_nothing( void *stack_area );
205
206/** @} */
207
208#ifdef __cplusplus
209}
210#endif
211
212#endif
213/* end of include file */
Note: See TracBrowser for help on using the repository browser.