Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2010-2016 Wind River Systems, Inc. |
| 3 | * |
David B. Kinder | ac74d8b | 2017-01-18 17:01:01 -0800 | [diff] [blame] | 4 | * SPDX-License-Identifier: Apache-2.0 |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | /** |
| 8 | * @brief fixed-size stack object |
| 9 | */ |
| 10 | |
| 11 | #include <kernel.h> |
Benjamin Walsh | f6ca7de | 2016-11-08 10:36:50 -0500 | [diff] [blame] | 12 | #include <kernel_structs.h> |
Anas Nashif | 569f0b4 | 2016-12-17 13:18:45 -0500 | [diff] [blame] | 13 | #include <debug/object_tracing_common.h> |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 14 | #include <toolchain.h> |
Anas Nashif | 397d29d | 2017-06-17 11:30:47 -0400 | [diff] [blame^] | 15 | #include <linker/sections.h> |
Benjamin Walsh | b4b108d | 2016-10-13 10:31:48 -0400 | [diff] [blame] | 16 | #include <ksched.h> |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 17 | #include <wait_q.h> |
| 18 | #include <misc/__assert.h> |
Allan Stephens | e7d2cc2 | 2016-10-19 16:10:46 -0500 | [diff] [blame] | 19 | #include <init.h> |
| 20 | |
| 21 | extern struct k_stack _k_stack_list_start[]; |
| 22 | extern struct k_stack _k_stack_list_end[]; |
| 23 | |
Anas Nashif | 2f203c2 | 2016-12-18 06:57:45 -0500 | [diff] [blame] | 24 | #ifdef CONFIG_OBJECT_TRACING |
Allan Stephens | e7d2cc2 | 2016-10-19 16:10:46 -0500 | [diff] [blame] | 25 | |
Maciek Borzecki | 059544d | 2017-05-18 12:16:45 +0200 | [diff] [blame] | 26 | struct k_stack *_trace_list_k_stack; |
| 27 | |
Allan Stephens | e7d2cc2 | 2016-10-19 16:10:46 -0500 | [diff] [blame] | 28 | /* |
| 29 | * Complete initialization of statically defined stacks. |
| 30 | */ |
| 31 | static int init_stack_module(struct device *dev) |
| 32 | { |
| 33 | ARG_UNUSED(dev); |
| 34 | |
| 35 | struct k_stack *stack; |
| 36 | |
| 37 | for (stack = _k_stack_list_start; stack < _k_stack_list_end; stack++) { |
| 38 | SYS_TRACING_OBJ_INIT(k_stack, stack); |
| 39 | } |
| 40 | return 0; |
| 41 | } |
| 42 | |
Andrew Boie | 0b474ee | 2016-11-08 11:06:55 -0800 | [diff] [blame] | 43 | SYS_INIT(init_stack_module, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); |
Allan Stephens | e7d2cc2 | 2016-10-19 16:10:46 -0500 | [diff] [blame] | 44 | |
Anas Nashif | 2f203c2 | 2016-12-18 06:57:45 -0500 | [diff] [blame] | 45 | #endif /* CONFIG_OBJECT_TRACING */ |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 46 | |
Kumar Gala | cc334c7 | 2017-04-21 10:55:34 -0500 | [diff] [blame] | 47 | void k_stack_init(struct k_stack *stack, u32_t *buffer, int num_entries) |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 48 | { |
| 49 | sys_dlist_init(&stack->wait_q); |
| 50 | stack->next = stack->base = buffer; |
| 51 | stack->top = stack->base + num_entries; |
| 52 | |
| 53 | SYS_TRACING_OBJ_INIT(k_stack, stack); |
| 54 | } |
| 55 | |
Kumar Gala | cc334c7 | 2017-04-21 10:55:34 -0500 | [diff] [blame] | 56 | void k_stack_push(struct k_stack *stack, u32_t data) |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 57 | { |
| 58 | struct k_thread *first_pending_thread; |
| 59 | unsigned int key; |
| 60 | |
| 61 | __ASSERT(stack->next != stack->top, "stack is full"); |
| 62 | |
| 63 | key = irq_lock(); |
| 64 | |
| 65 | first_pending_thread = _unpend_first_thread(&stack->wait_q); |
| 66 | |
| 67 | if (first_pending_thread) { |
Benjamin Walsh | 7caef45 | 2016-10-05 12:55:17 -0400 | [diff] [blame] | 68 | _abort_thread_timeout(first_pending_thread); |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 69 | _ready_thread(first_pending_thread); |
| 70 | |
| 71 | _set_thread_return_value_with_data(first_pending_thread, |
| 72 | 0, (void *)data); |
| 73 | |
| 74 | if (!_is_in_isr() && _must_switch_threads()) { |
| 75 | (void)_Swap(key); |
| 76 | return; |
| 77 | } |
| 78 | } else { |
| 79 | *(stack->next) = data; |
| 80 | stack->next++; |
| 81 | } |
| 82 | |
| 83 | irq_unlock(key); |
| 84 | } |
| 85 | |
Kumar Gala | cc334c7 | 2017-04-21 10:55:34 -0500 | [diff] [blame] | 86 | int k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout) |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 87 | { |
| 88 | unsigned int key; |
| 89 | int result; |
| 90 | |
| 91 | key = irq_lock(); |
| 92 | |
| 93 | if (likely(stack->next > stack->base)) { |
| 94 | stack->next--; |
| 95 | *data = *(stack->next); |
| 96 | irq_unlock(key); |
| 97 | return 0; |
| 98 | } |
| 99 | |
| 100 | if (timeout == K_NO_WAIT) { |
| 101 | irq_unlock(key); |
| 102 | return -EBUSY; |
| 103 | } |
| 104 | |
| 105 | _pend_current_thread(&stack->wait_q, timeout); |
| 106 | |
| 107 | result = _Swap(key); |
| 108 | if (result == 0) { |
Kumar Gala | cc334c7 | 2017-04-21 10:55:34 -0500 | [diff] [blame] | 109 | *data = (u32_t)_current->base.swap_data; |
Benjamin Walsh | 456c6da | 2016-09-02 18:55:39 -0400 | [diff] [blame] | 110 | } |
| 111 | return result; |
| 112 | } |