diff --git a/core/include/thread.h b/core/include/thread.h index 22733b654c..5b1ba1fdc4 100644 --- a/core/include/thread.h +++ b/core/include/thread.h @@ -129,10 +129,24 @@ #include "thread_flags.h" #endif +#include "thread_arch.h" + #ifdef __cplusplus extern "C" { #endif +/** + * @brief Macro definition to inline some of the platform specific + * implementations + * + * Should be enabled when advantageous by CPU's in their thread_arch.h header + */ +#ifdef THREAD_API_INLINED +#define THREAD_MAYBE_INLINE static inline __attribute__((always_inline)) +#else +#define THREAD_MAYBE_INLINE +#endif /* THREAD_API_INLINED */ + #if defined(DEVELHELP) && !defined(CONFIG_THREAD_NAMES) /** * @brief This global macro enable storage of thread names to help developers. @@ -431,7 +445,7 @@ void thread_yield(void); * * @see thread_yield() */ -void thread_yield_higher(void); +THREAD_MAYBE_INLINE void thread_yield_higher(void); /** * @brief Puts the current thread into zombie state. @@ -594,7 +608,8 @@ static inline int thread_has_msg_queue(const volatile struct _thread *thread) * @param thread thread to work on * @returns status of thread */ -static inline thread_status_t thread_get_status(const thread_t *thread) { +static inline thread_status_t thread_get_status(const thread_t *thread) +{ return thread->status; } @@ -604,7 +619,8 @@ static inline thread_status_t thread_get_status(const thread_t *thread) { * @param thread thread to work on * @returns true if thread is active, false otherwise */ -static inline bool thread_is_active(const thread_t *thread) { +static inline bool thread_is_active(const thread_t *thread) +{ return thread->status >= STATUS_ON_RUNQUEUE; } diff --git a/cpu/arm7_common/arm_cpu.c b/cpu/arm7_common/arm_cpu.c index 855318d5b6..d358f3c0ae 100644 --- a/cpu/arm7_common/arm_cpu.c +++ b/cpu/arm7_common/arm_cpu.c @@ -36,16 +36,6 @@ __attribute__((used, section(".svc_stack"), aligned(4))) uint8_t svc_stack[ISR_S #error "ISR_STACKSIZE must be a multiple of 4" #endif -void thread_yield_higher(void) -{ - if (irq_is_in()) { - sched_context_switch_request = 1; - } - else { - __asm__("svc 0\n"); - } -} - /*---------------------------------------------------------------------------- * Processor specific routine - here for ARM7 * sizeof(void*) = sizeof(int) diff --git a/cpu/arm7_common/include/thread_arch.h b/cpu/arm7_common/include/thread_arch.h new file mode 100644 index 0000000000..c3f66c2e51 --- /dev/null +++ b/cpu/arm7_common/include/thread_arch.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008, 2009 Heiko Will + * Copyright (C) 2009 Kaspar Schleiser + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_arm7_common + * @{ + * + * @file + * @brief Implementation of the kernels thread interface + * + * @author Kaspar Schleiser + * @author Heiko Will + * + * @} + */ +#ifndef THREAD_ARCH_H +#define THREAD_ARCH_H + +#include "irq.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define THREAD_API_INLINED + +#ifndef DOXYGEN /* Doxygen is in core/include/thread.h */ + +static inline __attribute__((always_inline)) void thread_yield_higher(void) +{ + if (irq_is_in()) { + sched_context_switch_request = 1; + } + else { + __asm__("svc 0\n"); + } +} + +#endif /* DOXYGEN */ + +#ifdef __cplusplus +} +#endif + +#endif /* THREAD_ARCH_H */ +/** @} */ diff --git a/cpu/avr8_common/include/thread_arch.h b/cpu/avr8_common/include/thread_arch.h new file mode 100644 index 0000000000..ee85fb511b --- /dev/null +++ b/cpu/avr8_common/include/thread_arch.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 Koen Zandberg + * 2021 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_avr8_common + * @{ + * + * @file + * @brief Implementation of the kernels thread interface + * + * @author Koen Zandberg + * + * @} + */ +#ifndef THREAD_ARCH_H +#define THREAD_ARCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* THREAD_ARCH_H */ +/** @} */ diff --git a/cpu/cortexm_common/include/thread_arch.h b/cpu/cortexm_common/include/thread_arch.h new file mode 100644 index 0000000000..e75ec0af57 --- /dev/null +++ b/cpu/cortexm_common/include/thread_arch.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2021 Koen Zandberg + * 2021 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_cortexm_common + * @{ + * + * @file + * @brief Implementation of the kernels thread interface + * + * @author Koen Zandberg + * + * @} + */ +#ifndef THREAD_ARCH_H +#define THREAD_ARCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define THREAD_API_INLINED + +#ifndef DOXYGEN /* Doxygen is in core/include/thread.h */ + +static inline __attribute__((always_inline)) void thread_yield_higher(void) +{ + /* trigger the PENDSV interrupt to run scheduler and schedule new thread if + * applicable */ + SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; + /* flush the pipeline. Otherwise we risk that subsequent instructions are + * executed before the IRQ has actually triggered */ + __ISB(); +} + +#endif /* DOXYGEN */ + +#ifdef __cplusplus +} +#endif + +#endif /* THREAD_ARCH_H */ +/** @} */ diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index 3c4ee42a41..043ac970bc 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -291,16 +291,6 @@ void NORETURN cpu_switch_context_exit(void) UNREACHABLE(); } -void thread_yield_higher(void) -{ - /* trigger the PENDSV interrupt to run scheduler and schedule new thread if - * applicable */ - SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; - /* flush the pipeline. Otherwise we risk that subsequent instructions are - * executed before the IRQ has actually triggered */ - __ISB(); -} - #if CPU_CORE_CORTEXM_FULL_THUMB void __attribute__((naked)) __attribute__((used)) isr_pendsv(void) { __asm__ volatile ( diff --git a/cpu/fe310/include/thread_arch.h b/cpu/fe310/include/thread_arch.h new file mode 100644 index 0000000000..2af55690d2 --- /dev/null +++ b/cpu/fe310/include/thread_arch.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Koen Zandberg + * 2021 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_fe310 + * @{ + * + * @file + * @brief Implementation of the kernels thread interface + * + * @author Koen Zandberg + * + * @} + */ +#ifndef THREAD_ARCH_H +#define THREAD_ARCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define THREAD_API_INLINED + +#ifndef DOXYGEN /* Doxygen is in core/include/thread.h */ + +static inline void _ecall_dispatch(uint32_t num, void *ctx) +{ + /* function arguments are in a0 and a1 as per ABI */ + __asm__ volatile ( + "mv a0, %[num] \n" + "mv a1, %[ctx] \n" + "ECALL\n" + : /* No outputs */ + : [num] "r" (num), [ctx] "r" (ctx) + : "memory" + ); +} + +static inline __attribute__((always_inline)) void thread_yield_higher(void) +{ + _ecall_dispatch(0, NULL); +} + +#endif /* DOXYGEN */ + +#ifdef __cplusplus +} +#endif + +#endif /* THREAD_ARCH_H */ +/** @} */ diff --git a/cpu/fe310/thread_arch.c b/cpu/fe310/thread_arch.c index 54e5b3cf79..96674a15c6 100644 --- a/cpu/fe310/thread_arch.c +++ b/cpu/fe310/thread_arch.c @@ -179,24 +179,6 @@ void cpu_switch_context_exit(void) UNREACHABLE(); } -static inline void _ecall_dispatch(uint32_t num, void *ctx) -{ - /* function arguments are in a0 and a1 as per ABI */ - __asm__ volatile ( - "mv a0, %[num] \n" - "mv a1, %[ctx] \n" - "ECALL\n" - : /* No outputs */ - : [num] "r" (num), [ctx] "r" (ctx) - : "memory" - ); -} - -void thread_yield_higher(void) -{ - _ecall_dispatch(0, NULL); -} - /** * @brief Print heap statistics */ diff --git a/cpu/mips32r2_common/include/thread_arch.h b/cpu/mips32r2_common/include/thread_arch.h new file mode 100644 index 0000000000..00799085ca --- /dev/null +++ b/cpu/mips32r2_common/include/thread_arch.h @@ -0,0 +1,51 @@ +/* + * Copyright(C) 2017, 2016, Imagination Technologies Limited and/or its + * affiliated group companies. + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_mips32r2_common + * @{ + * + * @file + * @brief Implementation of the kernels thread interface + * + * @author Neil Jones + * + * @} + */ +#ifndef THREAD_ARCH_H +#define THREAD_ARCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define THREAD_API_INLINED + +#ifndef DOXYGEN /* Doxygen is in core/include/thread.h */ + +static inline __attribute__((always_inline)) void thread_yield_higher(void) +{ + /* + * throw a syscall exception to get into exception level + * we context switch at exception level. + * + * Note syscall 1 is reserved for UHI see: + * http://wiki.prplfoundation.org/w/images/4/42/UHI_Reference_Manual.pdf + */ + __asm volatile ("syscall 2"); +} + +#endif /* DOXYGEN */ + +#ifdef __cplusplus +} +#endif + +#endif /* THREAD_ARCH_H */ +/** @} */ diff --git a/cpu/mips32r2_common/thread_arch.c b/cpu/mips32r2_common/thread_arch.c index 449ce1e203..b574462fc1 100644 --- a/cpu/mips32r2_common/thread_arch.c +++ b/cpu/mips32r2_common/thread_arch.c @@ -141,18 +141,6 @@ void cpu_switch_context_exit(void) UNREACHABLE(); } -void thread_yield_higher(void) -{ - /* - * throw a syscall exception to get into exception level - * we context switch at exception level. - * - * Note syscall 1 is reserved for UHI see: - * http://wiki.prplfoundation.org/w/images/4/42/UHI_Reference_Manual.pdf - */ - __asm volatile ("syscall 2"); -} - struct linkctx* exctx_find(reg_t id, struct gpctx *gp) { struct linkctx **ctx = (struct linkctx **)&gp->link; diff --git a/cpu/msp430_common/include/thread_arch.h b/cpu/msp430_common/include/thread_arch.h new file mode 100644 index 0000000000..b123f7c513 --- /dev/null +++ b/cpu/msp430_common/include/thread_arch.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 Koen Zandberg + * 2021 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_msp430_common + * @{ + * + * @file + * @brief Implementation of the kernels thread interface + * + * @author Koen Zandberg + * + * @} + */ +#ifndef THREAD_ARCH_H +#define THREAD_ARCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* THREAD_ARCH_H */ +/** @} */ diff --git a/cpu/native/include/thread_arch.h b/cpu/native/include/thread_arch.h new file mode 100644 index 0000000000..0f27dcbfe1 --- /dev/null +++ b/cpu/native/include/thread_arch.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 Koen Zandberg + * 2021 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup cpu_native + * @{ + * + * @file + * @brief Implementation of the kernels thread interface + * + * @author Koen Zandberg + * + * @} + */ +#ifndef THREAD_ARCH_H +#define THREAD_ARCH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* THREAD_ARCH_H */ +/** @} */