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>
This commit is contained in:
parent
ea44b056bc
commit
3d51f7c266
10 changed files with 53 additions and 49 deletions
|
@ -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
|
||||
|
|
|
@ -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, \
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue