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 : _current = _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 : _current = _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