Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2010-2015 Wind River Systems, Inc.
3 : : * Copyright (c) 2017 Oticon A/S
4 : : *
5 : : * SPDX-License-Identifier: Apache-2.0
6 : : */
7 : :
8 : : /**
9 : : * @file
10 : : * @brief Kernel swapper code for POSIX
11 : : *
12 : : * This module implements the arch_swap() routine for the POSIX architecture.
13 : : *
14 : : */
15 : :
16 : : #include <zephyr/kernel.h>
17 : : #include <zephyr/kernel_structs.h>
18 : : #include "posix_core.h"
19 : : #include <zephyr/irq.h>
20 : : #include "kswap.h"
21 : : #include <zephyr/pm/pm.h>
22 : :
23 : 98 : int arch_swap(unsigned int key)
24 : : {
25 : : /*
26 : : * struct k_thread * _current is the currently running thread
27 : : * struct k_thread * _kernel.ready_q.cache contains the next thread to
28 : : * run (cannot be NULL)
29 : : *
30 : : * Here a "real" arch would save all processor registers, stack pointer
31 : : * and so forth. But we do not need to do so because we use posix
32 : : * threads => those are all nicely kept by the native OS kernel
33 : : */
34 : : #if CONFIG_INSTRUMENT_THREAD_SWITCHING
35 : : z_thread_mark_switched_out();
36 : : #endif
37 : 98 : _current->callee_saved.key = key;
38 : 98 : _current->callee_saved.retval = -EAGAIN;
39 : :
40 : : /* retval may be modified with a call to
41 : : * arch_thread_return_value_set()
42 : : */
43 : :
44 : 98 : posix_thread_status_t *ready_thread_ptr =
45 : : (posix_thread_status_t *)
46 : 98 : _kernel.ready_q.cache->callee_saved.thread_status;
47 : :
48 : 98 : posix_thread_status_t *this_thread_ptr =
49 : : (posix_thread_status_t *)
50 : : _current->callee_saved.thread_status;
51 : :
52 : :
53 : 98 : z_current_thread_set(_kernel.ready_q.cache);
54 : : #if CONFIG_INSTRUMENT_THREAD_SWITCHING
55 : : z_thread_mark_switched_in();
56 : : #endif
57 : :
58 : : /*
59 : : * Here a "real" arch would load all processor registers for the thread
60 : : * to run. In this arch case, we just block this thread until allowed
61 : : * to run later, and signal to whomever is allowed to run to
62 : : * continue.
63 : : */
64 : 98 : posix_swap(ready_thread_ptr->thread_idx,
65 : : this_thread_ptr->thread_idx);
66 : :
67 : : /* When we continue, _kernel->current points back to this thread */
68 : :
69 : 52 : irq_unlock(_current->callee_saved.key);
70 : :
71 : 52 : return _current->callee_saved.retval;
72 : : }
73 : :
74 : :
75 : :
76 : : #ifdef CONFIG_ARCH_HAS_CUSTOM_SWAP_TO_MAIN
77 : : /* This is just a version of arch_swap() in which we do not save anything
78 : : * about the current thread.
79 : : *
80 : : * Note that we will never come back to this thread: posix_main_thread_start()
81 : : * does never return.
82 : : */
83 : 1 : void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr,
84 : : k_thread_entry_t _main)
85 : : {
86 : 1 : ARG_UNUSED(stack_ptr);
87 : 1 : ARG_UNUSED(_main);
88 : :
89 : 1 : posix_thread_status_t *ready_thread_ptr =
90 : : (posix_thread_status_t *)
91 : 1 : _kernel.ready_q.cache->callee_saved.thread_status;
92 : :
93 : : #ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING
94 : : z_thread_mark_switched_out();
95 : : #endif
96 : :
97 : 1 : z_current_thread_set(_kernel.ready_q.cache);
98 : :
99 : : #ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING
100 : : z_thread_mark_switched_in();
101 : : #endif
102 : :
103 : 1 : posix_main_thread_start(ready_thread_ptr->thread_idx);
104 : : } /* LCOV_EXCL_LINE */
105 : : #endif
106 : :
107 : : #ifdef CONFIG_PM
108 : : /**
109 : : * If the kernel is in idle mode, take it out
110 : : */
111 : : void posix_irq_check_idle_exit(void)
112 : : {
113 : : if (_kernel.idle) {
114 : : _kernel.idle = 0;
115 : : pm_system_resume();
116 : : }
117 : : }
118 : : #endif
|