blob: 01dd4c1b1ec0420c4090104966a9814a1a37464f [file] [log] [blame]
Benjamin Walsh456c6da2016-09-02 18:55:39 -04001/*
2 * Copyright (c) 2010-2016 Wind River Systems, Inc.
3 *
David B. Kinderac74d8b2017-01-18 17:01:01 -08004 * SPDX-License-Identifier: Apache-2.0
Benjamin Walsh456c6da2016-09-02 18:55:39 -04005 */
6
7/**
8 * @brief fixed-size stack object
9 */
10
11#include <kernel.h>
Benjamin Walshf6ca7de2016-11-08 10:36:50 -050012#include <kernel_structs.h>
Anas Nashif569f0b42016-12-17 13:18:45 -050013#include <debug/object_tracing_common.h>
Benjamin Walsh456c6da2016-09-02 18:55:39 -040014#include <toolchain.h>
Anas Nashif397d29d2017-06-17 11:30:47 -040015#include <linker/sections.h>
Benjamin Walshb4b108d2016-10-13 10:31:48 -040016#include <ksched.h>
Benjamin Walsh456c6da2016-09-02 18:55:39 -040017#include <wait_q.h>
18#include <misc/__assert.h>
Allan Stephense7d2cc22016-10-19 16:10:46 -050019#include <init.h>
20
21extern struct k_stack _k_stack_list_start[];
22extern struct k_stack _k_stack_list_end[];
23
Anas Nashif2f203c22016-12-18 06:57:45 -050024#ifdef CONFIG_OBJECT_TRACING
Allan Stephense7d2cc22016-10-19 16:10:46 -050025
Maciek Borzecki059544d2017-05-18 12:16:45 +020026struct k_stack *_trace_list_k_stack;
27
Allan Stephense7d2cc22016-10-19 16:10:46 -050028/*
29 * Complete initialization of statically defined stacks.
30 */
31static 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 Boie0b474ee2016-11-08 11:06:55 -080043SYS_INIT(init_stack_module, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS);
Allan Stephense7d2cc22016-10-19 16:10:46 -050044
Anas Nashif2f203c22016-12-18 06:57:45 -050045#endif /* CONFIG_OBJECT_TRACING */
Benjamin Walsh456c6da2016-09-02 18:55:39 -040046
Kumar Galacc334c72017-04-21 10:55:34 -050047void k_stack_init(struct k_stack *stack, u32_t *buffer, int num_entries)
Benjamin Walsh456c6da2016-09-02 18:55:39 -040048{
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 Galacc334c72017-04-21 10:55:34 -050056void k_stack_push(struct k_stack *stack, u32_t data)
Benjamin Walsh456c6da2016-09-02 18:55:39 -040057{
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 Walsh7caef452016-10-05 12:55:17 -040068 _abort_thread_timeout(first_pending_thread);
Benjamin Walsh456c6da2016-09-02 18:55:39 -040069 _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 Galacc334c72017-04-21 10:55:34 -050086int k_stack_pop(struct k_stack *stack, u32_t *data, s32_t timeout)
Benjamin Walsh456c6da2016-09-02 18:55:39 -040087{
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 Galacc334c72017-04-21 10:55:34 -0500109 *data = (u32_t)_current->base.swap_data;
Benjamin Walsh456c6da2016-09-02 18:55:39 -0400110 }
111 return result;
112}