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 <npitre@baylibre.com>
diff --git a/doc/reference/kernel/data_passing/stacks.rst b/doc/reference/kernel/data_passing/stacks.rst
index c18f306..0476856 100644
--- a/doc/reference/kernel/data_passing/stacks.rst
+++ b/doc/reference/kernel/data_passing/stacks.rst
@@ -5,7 +5,7 @@
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 @@
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 @@
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 @@
/* 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 @@
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 529cc58..ac6860c 100644
--- a/include/kernel.h
+++ b/include/kernel.h
@@ -2419,10 +2419,12 @@
*/
#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 @@
* @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 @@
/**
* @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 @@
* @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 @@
* @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 @@
* @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 22190f8..4f61599 100644
--- a/kernel/mailbox.c
+++ b/kernel/mailbox.c
@@ -32,13 +32,13 @@
/* 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 @@
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 b61d61e..84f95d5 100644
--- a/kernel/pipes.c
+++ b/kernel/pipes.c
@@ -49,13 +49,13 @@
/* 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 @@
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 9050eaf..b0c7d6f 100644
--- a/kernel/stack.c
+++ b/kernel/stack.c
@@ -41,7 +41,7 @@
#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 @@
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 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 @@
}
#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 @@
return -EAGAIN;
}
- *data = (u32_t)_current->base.swap_data;
+ *data = (stack_data_t)_current->base.swap_data;
return 0;
}
@@ -163,9 +163,9 @@
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 57d533a..35071b3 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 @@
{
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_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_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 @@
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 eff1aa0..2281e79 100644
--- a/tests/kernel/obj_tracing/src/trace_obj.c
+++ b/tests/kernel/obj_tracing/src/trace_obj.c
@@ -53,7 +53,7 @@
#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 2727be9..15c149a 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 @@
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_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 0c688d8..b387fc0 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 0b6c1be..e9d0ce4 100644
--- a/tests/kernel/stack/stack_usage/src/main.c
+++ b/tests/kernel/stack/stack_usage/src/main.c
@@ -47,10 +47,10 @@
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 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_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 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_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,