From d4dd928eaa3ecab05e5d11d90b15edebc7a01b06 Mon Sep 17 00:00:00 2001 From: Rajavardhan Gundi Date: Wed, 27 Jun 2018 13:26:20 +0530 Subject: [PATCH] kernel/stack: Introduce K_THREAD_STACK_LEN macro This is a public macro which calculates the size to be allocated for stacks inside a stack array. This is necessitated because of some internal padding (e.g. for MPU scenarios). This is particularly useful when a reference to K_THREAD_STACK_ARRAY_DEFINE needs to be made from within a struct. Signed-off-by: Rajavardhan Gundi --- include/arch/arc/arch.h | 19 +++++++++++++------ include/arch/arm/arch.h | 21 +++++++++++++++++++-- include/arch/x86/arch.h | 9 ++++++--- include/kernel.h | 16 +++++++++++++++- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/include/arch/arc/arch.h b/include/arch/arc/arch.h index 57ea7ddf26a..d7cf4ae9a4d 100644 --- a/include/arch/arc/arch.h +++ b/include/arch/arc/arch.h @@ -89,12 +89,15 @@ extern "C" { sym[POW2_CEIL(STACK_SIZE_ALIGN(size)) + \ + STACK_GUARD_SIZE + CONFIG_PRIVILEGED_STACK_SIZE] +#define _ARCH_THREAD_STACK_LEN(size) \ + (POW2_CEIL(STACK_SIZE_ALIGN(size)) + \ + max(POW2_CEIL(STACK_SIZE_ALIGN(size)), \ + POW2_CEIL(STACK_GUARD_SIZE + CONFIG_PRIVILEGED_STACK_SIZE))) + #define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \ struct _k_thread_stack_element __kernel_noinit \ __aligned(POW2_CEIL(STACK_SIZE_ALIGN(size))) \ - sym[nmemb][POW2_CEIL(STACK_SIZE_ALIGN(size)) + \ - + max(POW2_CEIL(STACK_SIZE_ALIGN(size)), \ - POW2_CEIL(STACK_GUARD_SIZE + CONFIG_PRIVILEGED_STACK_SIZE))] + sym[nmemb][_ARCH_THREAD_STACK_LEN(size)] #define _ARCH_THREAD_STACK_MEMBER(sym, size) \ struct _k_thread_stack_element \ @@ -109,10 +112,12 @@ extern "C" { sym[size + \ + STACK_GUARD_SIZE + CONFIG_PRIVILEGED_STACK_SIZE] +#define _ARCH_THREAD_STACK_LEN(size) \ + ((size) + STACK_GUARD_SIZE + CONFIG_PRIVILEGED_STACK_SIZE) + #define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \ struct _k_thread_stack_element __kernel_noinit __aligned(STACK_ALIGN) \ - sym[nmemb][size + \ - + STACK_GUARD_SIZE + CONFIG_PRIVILEGED_STACK_SIZE] + sym[nmemb][_ARCH_THREAD_STACK_LEN(size)] #define _ARCH_THREAD_STACK_MEMBER(sym, size) \ struct _k_thread_stack_element __aligned(STACK_ALIGN) \ @@ -133,9 +138,11 @@ extern "C" { struct _k_thread_stack_element __kernel_noinit __aligned(STACK_ALIGN) \ sym[size + STACK_GUARD_SIZE] +#define _ARCH_THREAD_STACK_LEN(size) ((size) + STACK_GUARD_SIZE) + #define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \ struct _k_thread_stack_element __kernel_noinit __aligned(STACK_ALIGN) \ - sym[nmemb][size + STACK_GUARD_SIZE] + sym[nmemb][_ARCH_THREAD_STACK_LEN(size)] #define _ARCH_THREAD_STACK_MEMBER(sym, size) \ struct _k_thread_stack_element __aligned(STACK_ALIGN) \ diff --git a/include/arch/arm/arch.h b/include/arch/arm/arch.h index 54ab7122dea..2210cbffc59 100644 --- a/include/arch/arm/arch.h +++ b/include/arch/arm/arch.h @@ -153,6 +153,23 @@ extern "C" { sym[size+MPU_GUARD_ALIGN_AND_SIZE] #endif +/** + * @brief Calculate size of stacks to be allocated in a stack array + * + * This macro calculates the size to be allocated for the stacks + * inside a stack array. It accepts the indicated "size" as a parameter + * and if required, pads some extra bytes (e.g. for MPU scenarios). Refer + * K_THREAD_STACK_ARRAY_DEFINE definition to see how this is used. + * + * @param size Size of the stack memory region + */ +#if defined(CONFIG_USERSPACE) && \ + defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT) +#define _ARCH_THREAD_STACK_LEN(size) (POW2_CEIL(size)) +#else +#define _ARCH_THREAD_STACK_LEN(size) ((size)+MPU_GUARD_ALIGN_AND_SIZE) +#endif + /** * @brief Declare a toplevel array of thread stack memory regions * @@ -171,12 +188,12 @@ extern "C" { #define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \ struct _k_thread_stack_element __kernel_noinit \ __aligned(POW2_CEIL(size)) \ - sym[nmemb][POW2_CEIL(size)] + sym[nmemb][_ARCH_THREAD_STACK_LEN(size)] #else #define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \ struct _k_thread_stack_element __kernel_noinit \ __aligned(STACK_ALIGN) \ - sym[nmemb][size+MPU_GUARD_ALIGN_AND_SIZE] + sym[nmemb][_ARCH_THREAD_STACK_LEN(size)] #endif /** diff --git a/include/arch/x86/arch.h b/include/arch/x86/arch.h index fb8a166c257..e88c2c360c9 100644 --- a/include/arch/x86/arch.h +++ b/include/arch/x86/arch.h @@ -733,12 +733,15 @@ static inline int _arch_is_user_context(void) __aligned(_STACK_BASE_ALIGN) \ sym[ROUND_UP((size), _STACK_SIZE_ALIGN) + _STACK_GUARD_SIZE] +#define _ARCH_THREAD_STACK_LEN(size) \ + (ROUND_UP((size), \ + max(_STACK_BASE_ALIGN, _STACK_SIZE_ALIGN)) + \ + _STACK_GUARD_SIZE) + #define _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \ struct _k_thread_stack_element __kernel_noinit \ __aligned(_STACK_BASE_ALIGN) \ - sym[nmemb][ROUND_UP(size, max(_STACK_BASE_ALIGN, \ - _STACK_SIZE_ALIGN)) + \ - _STACK_GUARD_SIZE] + sym[nmemb][_ARCH_THREAD_STACK_LEN(size)] #define _ARCH_THREAD_STACK_MEMBER(sym, size) \ struct _k_thread_stack_element __aligned(_STACK_BASE_ALIGN) \ diff --git a/include/kernel.h b/include/kernel.h index 3aef5cccbeb..3027c96f2d9 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -4586,6 +4586,7 @@ extern void _timer_expiration_handler(struct _timeout *t); #define K_THREAD_STACK_DEFINE(sym, size) _ARCH_THREAD_STACK_DEFINE(sym, size) #define K_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \ _ARCH_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) +#define K_THREAD_STACK_LEN(size) _ARCH_THREAD_STACK_LEN(size) #define K_THREAD_STACK_MEMBER(sym, size) _ARCH_THREAD_STACK_MEMBER(sym, size) #define K_THREAD_STACK_SIZEOF(sym) _ARCH_THREAD_STACK_SIZEOF(sym) static inline char *K_THREAD_STACK_BUFFER(k_thread_stack_t *sym) @@ -4622,6 +4623,19 @@ static inline char *K_THREAD_STACK_BUFFER(k_thread_stack_t *sym) #define K_THREAD_STACK_DEFINE(sym, size) \ struct _k_thread_stack_element __noinit __aligned(STACK_ALIGN) sym[size] +/** + * @brief Calculate size of stacks to be allocated in a stack array + * + * This macro calculates the size to be allocated for the stacks + * inside a stack array. It accepts the indicated "size" as a parameter + * and if required, pads some extra bytes (e.g. for MPU scenarios). Refer + * K_THREAD_STACK_ARRAY_DEFINE definition to see how this is used. + * + * @param size Size of the stack memory region + * @req K-TSTACK-001 + */ +#define K_THREAD_STACK_LEN(size) (size) + /** * @brief Declare a toplevel array of thread stack memory regions * @@ -4638,7 +4652,7 @@ static inline char *K_THREAD_STACK_BUFFER(k_thread_stack_t *sym) */ #define K_THREAD_STACK_ARRAY_DEFINE(sym, nmemb, size) \ struct _k_thread_stack_element __noinit \ - __aligned(STACK_ALIGN) sym[nmemb][size] + __aligned(STACK_ALIGN) sym[nmemb][K_THREAD_STACK_LEN(size)] /** * @brief Declare an embedded stack memory region