From 3d51f7c26603cd65fd032bbde0535c05e9952172 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 17 May 2019 22:48:26 -0400 Subject: [PATCH] k_stack: make it 64-bit compatible The k_stack data type cannot be u32_t on a 64-bit system as it is often used to store pointers. Let's define a dedicated type for stack data values, namely stack_data_t, which can be adjusted accordingly. For now it is defined to uintptr_t which is the integer type large enough to hold a pointer, meaning it is equivalent to u32_t on 32-bit systems and u64_t on 64-bit systems. Signed-off-by: Nicolas Pitre --- doc/reference/kernel/data_passing/stacks.rst | 20 ++++++++++--------- include/kernel.h | 18 +++++++++-------- kernel/mailbox.c | 6 +++--- kernel/pipes.c | 6 +++--- kernel/stack.c | 14 ++++++------- tests/benchmarks/sys_kernel/src/stack.c | 12 +++++------ tests/kernel/obj_tracing/src/trace_obj.c | 2 +- .../stack/stack_api/src/test_stack_contexts.c | 4 ++-- .../stack/stack_api/src/test_stack_fail.c | 4 ++-- tests/kernel/stack/stack_usage/src/main.c | 16 +++++++-------- 10 files changed, 53 insertions(+), 49 deletions(-) diff --git a/doc/reference/kernel/data_passing/stacks.rst b/doc/reference/kernel/data_passing/stacks.rst index c18f3066070..0476856f58d 100644 --- a/doc/reference/kernel/data_passing/stacks.rst +++ b/doc/reference/kernel/data_passing/stacks.rst @@ -5,7 +5,7 @@ Stacks A :dfn:`stack` is a kernel object that implements a traditional last in, first out (LIFO) queue, allowing threads and ISRs -to add and remove a limited number of 32-bit data values. +to add and remove a limited number of integer data values. .. contents:: :local: @@ -19,9 +19,11 @@ by its memory address. A stack has the following key properties: -* A **queue** of 32-bit data values that have been added but not yet removed. - The queue is implemented using an array of 32-bit integers, - and must be aligned on a 4-byte boundary. +* A **queue** of integer data values that have been added but not yet removed. + The queue is implemented using an array of stack_data_t values + and must be aligned on a native word boundary. + The stack_data_t type corresponds to the native word size i.e. 32 bits or + 64 bits depending on the CPU architecture and compilation mode. * A **maximum quantity** of data values that can be queued in the array. @@ -60,13 +62,13 @@ provided and it is instead allocated from the calling thread's resource pool. The following code defines and initializes an empty stack capable of holding -up to ten 32-bit data values. +up to ten word-sized data values. .. code-block:: c #define MAX_ITEMS 10 - u32_t my_stack_array[MAX_ITEMS]; + stack_data_t my_stack_array[MAX_ITEMS]; struct k_stack my_stack; k_stack_init(&my_stack, my_stack_array, MAX_ITEMS); @@ -101,7 +103,7 @@ in a stack. /* save address of each data structure in a stack */ for (int i = 0; i < MAX_ITEMS; i++) { - k_stack_push(&my_stack, (u32_t)&my_buffers[i]); + k_stack_push(&my_stack, (stack_data_t)&my_buffers[i]); } Popping from a Stack @@ -118,13 +120,13 @@ its address back on the stack to allow the data structure to be reused. struct my_buffer_type *new_buffer; - k_stack_pop(&buffer_stack, (u32_t *)&new_buffer, K_FOREVER); + k_stack_pop(&buffer_stack, (stack_data_t *)&new_buffer, K_FOREVER); new_buffer->field1 = ... Suggested Uses ************** -Use a stack to store and retrieve 32-bit data values in a "last in, +Use a stack to store and retrieve integer data values in a "last in, first out" manner, when the maximum number of stored items is known. Configuration Options diff --git a/include/kernel.h b/include/kernel.h index 529cc58594a..ac6860ca121 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -2419,10 +2419,12 @@ struct k_lifo { */ #define K_STACK_FLAG_ALLOC ((u8_t)1) /* Buffer was allocated */ +typedef uintptr_t stack_data_t; + struct k_stack { _wait_q_t wait_q; struct k_spinlock lock; - u32_t *base, *next, *top; + stack_data_t *base, *next, *top; _OBJECT_TRACING_NEXT_PTR(k_stack) u8_t flags; @@ -2462,7 +2464,7 @@ struct k_stack { * @req K-STACK-001 */ void k_stack_init(struct k_stack *stack, - u32_t *buffer, u32_t num_entries); + stack_data_t *buffer, u32_t num_entries); /** @@ -2498,7 +2500,7 @@ void k_stack_cleanup(struct k_stack *stack); /** * @brief Push an element onto a stack. * - * This routine adds a 32-bit value @a data to @a stack. + * This routine adds a stack_data_t value @a data to @a stack. * * @note Can be called by ISRs. * @@ -2508,13 +2510,13 @@ void k_stack_cleanup(struct k_stack *stack); * @return N/A * @req K-STACK-001 */ -__syscall void k_stack_push(struct k_stack *stack, u32_t data); +__syscall void k_stack_push(struct k_stack *stack, stack_data_t data); /** * @brief Pop an element from a stack. * - * This routine removes a 32-bit value from @a stack in a "last in, first out" - * manner and stores the value in @a data. + * This routine removes a stack_data_t value from @a stack in a "last in, + * first out" manner and stores the value in @a data. * * @note Can be called by ISRs, but @a timeout must be set to K_NO_WAIT. * @@ -2528,7 +2530,7 @@ __syscall void k_stack_push(struct k_stack *stack, u32_t data); * @retval -EAGAIN Waiting period timed out. * @req K-STACK-001 */ -__syscall int k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout); +__syscall int k_stack_pop(struct k_stack *stack, stack_data_t *data, s32_t timeout); /** * @brief Statically define and initialize a stack @@ -2542,7 +2544,7 @@ __syscall int k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout); * @req K-STACK-002 */ #define K_STACK_DEFINE(name, stack_num_entries) \ - u32_t __noinit \ + stack_data_t __noinit \ _k_stack_buf_##name[stack_num_entries]; \ Z_STRUCT_SECTION_ITERABLE(k_stack, name) = \ _K_STACK_INITIALIZER(name, _k_stack_buf_##name, \ diff --git a/kernel/mailbox.c b/kernel/mailbox.c index 22190f8cf3c..4f61599ae42 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -32,13 +32,13 @@ K_STACK_DEFINE(async_msg_free, CONFIG_NUM_MBOX_ASYNC_MSGS); /* allocate an asynchronous message descriptor */ static inline void mbox_async_alloc(struct k_mbox_async **async) { - (void)k_stack_pop(&async_msg_free, (u32_t *)async, K_FOREVER); + (void)k_stack_pop(&async_msg_free, (stack_data_t *)async, K_FOREVER); } /* free an asynchronous message descriptor */ static inline void mbox_async_free(struct k_mbox_async *async) { - k_stack_push(&async_msg_free, (u32_t)async); + k_stack_push(&async_msg_free, (stack_data_t)async); } #endif /* CONFIG_NUM_MBOX_ASYNC_MSGS > 0 */ @@ -77,7 +77,7 @@ static int init_mbox_module(struct device *dev) for (i = 0; i < CONFIG_NUM_MBOX_ASYNC_MSGS; i++) { z_init_thread_base(&async_msg[i].thread, 0, _THREAD_DUMMY, 0); - k_stack_push(&async_msg_free, (u32_t)&async_msg[i]); + k_stack_push(&async_msg_free, (stack_data_t)&async_msg[i]); } #endif /* CONFIG_NUM_MBOX_ASYNC_MSGS > 0 */ diff --git a/kernel/pipes.c b/kernel/pipes.c index b61d61eef58..84f95d5273a 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -49,13 +49,13 @@ K_STACK_DEFINE(pipe_async_msgs, CONFIG_NUM_PIPE_ASYNC_MSGS); /* Allocate an asynchronous message descriptor */ static void pipe_async_alloc(struct k_pipe_async **async) { - (void)k_stack_pop(&pipe_async_msgs, (u32_t *)async, K_FOREVER); + (void)k_stack_pop(&pipe_async_msgs, (stack_data_t *)async, K_FOREVER); } /* Free an asynchronous message descriptor */ static void pipe_async_free(struct k_pipe_async *async) { - k_stack_push(&pipe_async_msgs, (u32_t)async); + k_stack_push(&pipe_async_msgs, (stack_data_t)async); } /* Finish an asynchronous operation */ @@ -108,7 +108,7 @@ static int init_pipes_module(struct device *dev) z_init_thread_timeout(&async_msg[i].thread); - k_stack_push(&pipe_async_msgs, (u32_t)&async_msg[i]); + k_stack_push(&pipe_async_msgs, (stack_data_t)&async_msg[i]); } #endif /* CONFIG_NUM_PIPE_ASYNC_MSGS > 0 */ diff --git a/kernel/stack.c b/kernel/stack.c index 9050eafeb4a..b0c7d6fae39 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -41,7 +41,7 @@ SYS_INIT(init_stack_module, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); #endif /* CONFIG_OBJECT_TRACING */ -void k_stack_init(struct k_stack *stack, u32_t *buffer, +void k_stack_init(struct k_stack *stack, stack_data_t *buffer, u32_t num_entries) { z_waitq_init(&stack->wait_q); @@ -58,7 +58,7 @@ s32_t z_impl_k_stack_alloc_init(struct k_stack *stack, u32_t num_entries) void *buffer; s32_t ret; - buffer = z_thread_malloc(num_entries * sizeof(u32_t)); + buffer = z_thread_malloc(num_entries * sizeof(stack_data_t)); if (buffer != NULL) { k_stack_init(stack, buffer, num_entries); stack->flags = K_STACK_FLAG_ALLOC; @@ -91,7 +91,7 @@ void k_stack_cleanup(struct k_stack *stack) } } -void z_impl_k_stack_push(struct k_stack *stack, u32_t data) +void z_impl_k_stack_push(struct k_stack *stack, stack_data_t data) { struct k_thread *first_pending_thread; k_spinlock_key_t key; @@ -131,7 +131,7 @@ Z_SYSCALL_HANDLER(k_stack_push, stack_p, data) } #endif -int z_impl_k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout) +int z_impl_k_stack_pop(struct k_stack *stack, stack_data_t *data, s32_t timeout) { k_spinlock_key_t key; int result; @@ -155,7 +155,7 @@ int z_impl_k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout) return -EAGAIN; } - *data = (u32_t)_current->base.swap_data; + *data = (stack_data_t)_current->base.swap_data; return 0; } @@ -163,9 +163,9 @@ int z_impl_k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout) Z_SYSCALL_HANDLER(k_stack_pop, stack, data, timeout) { Z_OOPS(Z_SYSCALL_OBJ(stack, K_OBJ_STACK)); - Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, sizeof(u32_t))); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(data, sizeof(stack_data_t))); - return z_impl_k_stack_pop((struct k_stack *)stack, (u32_t *)data, + return z_impl_k_stack_pop((struct k_stack *)stack, (stack_data_t *)data, timeout); } #endif diff --git a/tests/benchmarks/sys_kernel/src/stack.c b/tests/benchmarks/sys_kernel/src/stack.c index 57d533a3313..35071b38e90 100644 --- a/tests/benchmarks/sys_kernel/src/stack.c +++ b/tests/benchmarks/sys_kernel/src/stack.c @@ -11,8 +11,8 @@ struct k_stack stack_1; struct k_stack stack_2; -u32_t stack1[2]; -u32_t stack2[2]; +stack_data_t stack1[2]; +stack_data_t stack2[2]; /** * @@ -43,7 +43,7 @@ void stack_thread1(void *par1, void *par2, void *par3) { int num_loops = POINTER_TO_INT(par2) / 2; int i; - u32_t data; + stack_data_t data; ARG_UNUSED(par1); ARG_UNUSED(par3); @@ -79,7 +79,7 @@ void stack_thread1(void *par1, void *par2, void *par3) void stack_thread2(void *par1, void *par2, void *par3) { int i; - u32_t data; + stack_data_t data; int *pcounter = par1; int num_loops = POINTER_TO_INT(par2); @@ -111,7 +111,7 @@ void stack_thread2(void *par1, void *par2, void *par3) void stack_thread3(void *par1, void *par2, void *par3) { int i; - u32_t data; + stack_data_t data; int *pcounter = par1; int num_loops = POINTER_TO_INT(par2); @@ -220,7 +220,7 @@ int stack_test(void) K_PRIO_COOP(3), 0, K_NO_WAIT); for (i = 0; i < number_of_loops / 2U; i++) { - u32_t data; + stack_data_t data; data = 2 * i; k_stack_push(&stack_1, data); diff --git a/tests/kernel/obj_tracing/src/trace_obj.c b/tests/kernel/obj_tracing/src/trace_obj.c index eff1aa07dc7..2281e7948a9 100644 --- a/tests/kernel/obj_tracing/src/trace_obj.c +++ b/tests/kernel/obj_tracing/src/trace_obj.c @@ -53,7 +53,7 @@ static struct k_queue queue; #define NUM_BLOCKS 4 static char __aligned(8) slab[BLOCK_SIZE * NUM_BLOCKS]; -static u32_t sdata[BLOCK_SIZE * NUM_BLOCKS]; +static stack_data_t sdata[BLOCK_SIZE * NUM_BLOCKS]; static char buffer[BLOCK_SIZE * NUM_BLOCKS]; static char data[] = "test"; diff --git a/tests/kernel/stack/stack_api/src/test_stack_contexts.c b/tests/kernel/stack/stack_api/src/test_stack_contexts.c index 2727be9a91d..15c149a3fd4 100644 --- a/tests/kernel/stack/stack_api/src/test_stack_contexts.c +++ b/tests/kernel/stack/stack_api/src/test_stack_contexts.c @@ -16,7 +16,7 @@ struct k_stack stack; K_THREAD_STACK_DEFINE(threadstack, STACK_SIZE); struct k_thread thread_data; -static ZTEST_DMEM u32_t data[STACK_LEN] = { 0xABCD, 0x1234 }; +static ZTEST_DMEM stack_data_t data[STACK_LEN] = { 0xABCD, 0x1234 }; struct k_sem end_sema; static void tstack_push(struct k_stack *pstack) @@ -29,7 +29,7 @@ static void tstack_push(struct k_stack *pstack) static void tstack_pop(struct k_stack *pstack) { - u32_t rx_data; + stack_data_t rx_data; for (int i = STACK_LEN - 1; i >= 0; i--) { /**TESTPOINT: stack pop*/ diff --git a/tests/kernel/stack/stack_api/src/test_stack_fail.c b/tests/kernel/stack/stack_api/src/test_stack_fail.c index 0c688d8b67f..b387fc04030 100644 --- a/tests/kernel/stack/stack_api/src/test_stack_fail.c +++ b/tests/kernel/stack/stack_api/src/test_stack_fail.c @@ -10,12 +10,12 @@ #define TIMEOUT 100 #define STACK_LEN 2 -static ZTEST_BMEM u32_t data[STACK_LEN]; +static ZTEST_BMEM stack_data_t data[STACK_LEN]; extern struct k_stack stack; static void stack_pop_fail(struct k_stack *stack) { - u32_t rx_data; + stack_data_t rx_data; /**TESTPOINT: stack pop returns -EBUSY*/ zassert_equal(k_stack_pop(stack, &rx_data, K_NO_WAIT), -EBUSY, NULL); diff --git a/tests/kernel/stack/stack_usage/src/main.c b/tests/kernel/stack/stack_usage/src/main.c index 0b6c1be51de..e9d0ce43cbc 100644 --- a/tests/kernel/stack/stack_usage/src/main.c +++ b/tests/kernel/stack/stack_usage/src/main.c @@ -47,10 +47,10 @@ K_THREAD_STACK_DEFINE(threadstack, TSTACK_SIZE); struct k_thread thread_data; /* Data pushed to stack */ -static ZTEST_DMEM u32_t data1[STACK_LEN] = { 0xAAAA, 0xBBBB, 0xCCCC, 0xDDDD }; -static ZTEST_DMEM u32_t data2[STACK_LEN] = { 0x1111, 0x2222, 0x3333, 0x4444 }; -static ZTEST_DMEM u32_t data_isr[STACK_LEN] = { 0xABCD, 0xABCD, 0xABCD, - 0xABCD }; +static ZTEST_DMEM stack_data_t data1[STACK_LEN] = { 0xAAAA, 0xBBBB, 0xCCCC, 0xDDDD }; +static ZTEST_DMEM stack_data_t data2[STACK_LEN] = { 0x1111, 0x2222, 0x3333, 0x4444 }; +static ZTEST_DMEM stack_data_t data_isr[STACK_LEN] = { 0xABCD, 0xABCD, 0xABCD, + 0xABCD }; /* semaphore to sync threads */ static struct k_sem end_sema; @@ -82,7 +82,7 @@ static void tIsr_entry_pop(void *p) static void thread_entry_fn_single(void *p1, void *p2, void *p3) { - u32_t tmp[STACK_LEN]; + stack_data_t tmp[STACK_LEN]; u32_t i; /* Pop items from stack */ @@ -103,7 +103,7 @@ static void thread_entry_fn_single(void *p1, void *p2, void *p3) static void thread_entry_fn_dual(void *p1, void *p2, void *p3) { - u32_t tmp[STACK_LEN]; + stack_data_t tmp[STACK_LEN]; u32_t i; for (i = 0U; i < STACK_LEN; i++) { @@ -143,7 +143,7 @@ static void thread_entry_fn_isr(void *p1, void *p2, void *p3) */ static void test_single_stack_play(void) { - u32_t tmp[STACK_LEN]; + stack_data_t tmp[STACK_LEN]; u32_t i; /* Init kernel objects */ @@ -180,7 +180,7 @@ static void test_single_stack_play(void) */ static void test_dual_stack_play(void) { - u32_t tmp[STACK_LEN]; + stack_data_t tmp[STACK_LEN]; u32_t i; k_tid_t tid = k_thread_create(&thread_data, threadstack, TSTACK_SIZE,