Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/thread: Allow for inline thread_yield_higher #15788

Merged
merged 9 commits into from Jan 22, 2021
22 changes: 19 additions & 3 deletions core/include/thread.h
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down
10 changes: 0 additions & 10 deletions cpu/arm7_common/arm_cpu.c
Expand Up @@ -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)
Expand Down
52 changes: 52 additions & 0 deletions cpu/arm7_common/include/thread_arch.h
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2008, 2009 Heiko Will <hwill@inf.fu-berlin.de>
* Copyright (C) 2009 Kaspar Schleiser <kaspar@schleiser.de>
*
* 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 <kaspar@schleiser.de>
* @author Heiko Will <heiko.will@fu-berlin.de>
*
* @}
*/
#ifndef THREAD_ARCH_H
#define THREAD_ARCH_H

maribu marked this conversation as resolved.
Show resolved Hide resolved
#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");
}
}
benpicco marked this conversation as resolved.
Show resolved Hide resolved

#endif /* DOXYGEN */

#ifdef __cplusplus
}
#endif

#endif /* THREAD_ARCH_H */
/** @} */
33 changes: 33 additions & 0 deletions cpu/avr8_common/include/thread_arch.h
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2021 Koen Zandberg <koen@bergzand.net>
* 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 <koen@bergzand.net>
*
* @}
*/
#ifndef THREAD_ARCH_H
#define THREAD_ARCH_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

#endif /* THREAD_ARCH_H */
/** @} */
49 changes: 49 additions & 0 deletions cpu/cortexm_common/include/thread_arch.h
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2021 Koen Zandberg <koen@bergzand.net>
* 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 <koen@bergzand.net>
*
* @}
*/
#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 */
/** @} */
10 changes: 0 additions & 10 deletions cpu/cortexm_common/thread_arch.c
Expand Up @@ -296,16 +296,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 (
Expand Down
57 changes: 57 additions & 0 deletions cpu/fe310/include/thread_arch.h
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 Koen Zandberg <koen@bergzand.net>
* 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 <koen@bergzand.net>
*
* @}
*/
#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 */
/** @} */
18 changes: 0 additions & 18 deletions cpu/fe310/thread_arch.c
Expand Up @@ -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
*/
Expand Down
51 changes: 51 additions & 0 deletions 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 <neil.jones@imgtec.com>
*
* @}
*/
#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 */
/** @} */
12 changes: 0 additions & 12 deletions cpu/mips32r2_common/thread_arch.c
Expand Up @@ -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;
Expand Down