123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- #ifndef ZEPHYR_KERNEL_INCLUDE_KSWAP_H_
- #define ZEPHYR_KERNEL_INCLUDE_KSWAP_H_
- #include <ksched.h>
- #include <spinlock.h>
- #include <kernel_arch_func.h>
- #ifdef CONFIG_STACK_SENTINEL
- extern void z_check_stack_sentinel(void);
- #else
- #define z_check_stack_sentinel()
- #endif
- extern struct k_spinlock sched_spinlock;
- void z_smp_release_global_lock(struct k_thread *thread);
- #ifdef CONFIG_USE_SWITCH
- static inline void wait_for_switch(struct k_thread *thread)
- {
- #ifdef CONFIG_SMP
- volatile void **shp = (void *)&thread->switch_handle;
- while (*shp == NULL) {
- k_busy_wait(1);
- }
- #endif
- }
- static ALWAYS_INLINE unsigned int do_swap(unsigned int key,
- struct k_spinlock *lock,
- int is_spinlock)
- {
- ARG_UNUSED(lock);
- struct k_thread *new_thread, *old_thread;
- #ifdef CONFIG_SPIN_VALIDATE
-
- # ifndef CONFIG_ARM64
- __ASSERT(arch_irq_unlocked(key) ||
- _current->base.thread_state & (_THREAD_DUMMY | _THREAD_DEAD),
- "Context switching while holding lock!");
- # endif
- #endif
- old_thread = _current;
- z_check_stack_sentinel();
-
- if (is_spinlock && lock != NULL && lock != &sched_spinlock) {
- k_spin_release(lock);
- }
- if (!is_spinlock || lock != &sched_spinlock) {
- (void) k_spin_lock(&sched_spinlock);
- }
- new_thread = z_swap_next_thread();
- if (new_thread != old_thread) {
- #ifdef CONFIG_TIMESLICING
- z_reset_time_slice();
- #endif
- old_thread->swap_retval = -EAGAIN;
- #ifdef CONFIG_SMP
- _current_cpu->swap_ok = 0;
- new_thread->base.cpu = arch_curr_cpu()->id;
- if (!is_spinlock) {
- z_smp_release_global_lock(new_thread);
- }
- #endif
- z_thread_mark_switched_out();
- wait_for_switch(new_thread);
- _current_cpu->current = new_thread;
- #ifdef CONFIG_SPIN_VALIDATE
- z_spin_lock_set_owner(&sched_spinlock);
- #endif
- arch_cohere_stacks(old_thread, NULL, new_thread);
- #ifdef CONFIG_SMP
-
- z_requeue_current(old_thread);
- #endif
- void *newsh = new_thread->switch_handle;
- if (IS_ENABLED(CONFIG_SMP)) {
-
- new_thread->switch_handle = NULL;
- }
- k_spin_release(&sched_spinlock);
- arch_switch(newsh, &old_thread->switch_handle);
- } else {
- k_spin_release(&sched_spinlock);
- }
- if (is_spinlock) {
- arch_irq_unlock(key);
- } else {
- irq_unlock(key);
- }
- return _current->swap_retval;
- }
- static inline int z_swap_irqlock(unsigned int key)
- {
- return do_swap(key, NULL, 0);
- }
- static inline int z_swap(struct k_spinlock *lock, k_spinlock_key_t key)
- {
- return do_swap(key.key, lock, 1);
- }
- static inline void z_swap_unlocked(void)
- {
- (void) do_swap(arch_irq_lock(), NULL, 1);
- }
- #else
- extern int arch_swap(unsigned int key);
- static inline int z_swap_irqlock(unsigned int key)
- {
- int ret;
- z_check_stack_sentinel();
- ret = arch_swap(key);
- return ret;
- }
- static ALWAYS_INLINE int z_swap(struct k_spinlock *lock, k_spinlock_key_t key)
- {
- k_spin_release(lock);
- return z_swap_irqlock(key.key);
- }
- static inline void z_swap_unlocked(void)
- {
- (void) z_swap_irqlock(arch_irq_lock());
- }
- #endif
- static inline void z_dummy_thread_init(struct k_thread *dummy_thread)
- {
- dummy_thread->base.thread_state = _THREAD_DUMMY;
- #ifdef CONFIG_SCHED_CPU_MASK
- dummy_thread->base.cpu_mask = -1;
- #endif
- dummy_thread->base.user_options = K_ESSENTIAL;
- #ifdef CONFIG_THREAD_STACK_INFO
- dummy_thread->stack_info.start = 0U;
- dummy_thread->stack_info.size = 0U;
- #endif
- #ifdef CONFIG_USERSPACE
- dummy_thread->mem_domain_info.mem_domain = &k_mem_domain_default;
- #endif
- _current_cpu->current = dummy_thread;
- }
- #endif
|