From d4b6226aa9cb15ddb1c75e434ddac086ce68e945 Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Thu, 23 Apr 2020 13:44:23 -0700 Subject: [PATCH] thread_stack: add Z_THREAD_STACK_SIZE_ADJUST() Define a macro which takes as input a requested stack buffer size, and returns the size of the stack object needed to contain it. An optional architecture interface is provided, though many arches will be fine with the default implementation. Signed-off-by: Andrew Boie --- include/sys/arch_interface.h | 23 +++++++++++++++++++++++ include/sys/thread_stack.h | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/include/sys/arch_interface.h b/include/sys/arch_interface.h index c9e99ec94ba..b27aeb94d37 100644 --- a/include/sys/arch_interface.h +++ b/include/sys/arch_interface.h @@ -126,6 +126,29 @@ static inline uint32_t arch_k_cycle_get_32(void); * * @see Z_THREAD_STACK_OBJ_ALIGN */ + +/** + * @def ARCH_THREAD_STACK_SIZE_ADJUST(size) + * @brief Round up a stack buffer size to alignment constraints + * + * Adjust a requested stack buffer size to the true size of its underlying + * buffer, defined as the area usable for thread stack context and thread- + * local storage. + * + * The size value passed here does not include storage reserved for platform + * data. + * + * The returned value is either the same size provided (if already properly + * aligned), or rounded up to satisfy alignment constraints. Calculations + * performed here *must* be idempotent. + * + * Optional definition. If undefined, stack buffer sizes are either: + * - Rounded up to the next power of two if user mode is enabled on an arch + * with an MPU that requires such alignment + * - Rounded up to ARCH_STACK_PTR_ALIGN + * + * @see Z_THREAD_STACK_SIZE_ADJUST + */ /** @} */ /** diff --git a/include/sys/thread_stack.h b/include/sys/thread_stack.h index a1b70de846c..ff60153d07c 100644 --- a/include/sys/thread_stack.h +++ b/include/sys/thread_stack.h @@ -113,6 +113,41 @@ static inline char *z_stack_ptr_align(char *ptr) #define Z_THREAD_STACK_OBJ_ALIGN(size) ARCH_STACK_PTR_ALIGN #endif /* ARCH_THREAD_STACK_OBJ_ALIGN */ +/** + * @def Z_THREAD_STACK_SIZE_ADJUST + * @brief Round up a requested stack size to satisfy constraints + * + * Given a requested stack buffer size, return an adjusted size value for + * the entire stack object which takes into consideration: + * + * - Reserved memory for platform data + * - Alignment of stack buffer bounds to CPU/ABI constraints + * - Alignment of stack buffer bounds to satisfy memory management hardware + * constraints such that a protection region can cover the stack buffer area + * + * If CONFIG_USERSPACE is enabled, this determines the size of stack objects + * which may be used by user mode threads, or threads running in supervisor + * mode which may later drop privileges to user mode. + * + * Arches define this with ARCH_THREAD_STACK_SIZE_ADJUST(). + * + * If ARCH_THREAD_STACK_SIZE_ADJUST is not defined, assume rounding up to + * ARCH_STACK_PTR_ALIGN is appropriate. + * + * Any memory reserved for platform data is also included in the total + * returned. + * + * @param size Requested size of the stack buffer + * @return Adjusted size of the stack object + */ +#if defined(ARCH_THREAD_STACK_SIZE_ADJUST) +#define Z_THREAD_STACK_SIZE_ADJUST(size) \ + (ARCH_THREAD_STACK_SIZE_ADJUST(size) + K_THREAD_STACK_RESERVED) +#else +#define Z_THREAD_STACK_SIZE_ADJUST(size) \ + (ROUND_UP((size), ARCH_STACK_PTR_ALIGN) + K_THREAD_STACK_RESERVED) +#endif /* ARCH_THREAD_STACK_SIZE_ADJUST */ + /** * @brief Obtain an extern reference to a stack *