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