libc: Call pthread_exit in user-space by up_pthread_exit

Drop to user-space in kernel/protected build with up_pthread_exit,
now all pthread_cleanup functions executed in user mode.

* A new syscall SYS_pthread_exit added
* A new tcb flag TCB_FLAG_CANCEL_DOING added
* up_pthread_exit implemented for riscv/arm arch

Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
Huang Qi
2021-05-08 18:20:02 +08:00
committed by patacongo
parent 81a01d089b
commit f4a0b7aedd
90 changed files with 533 additions and 118 deletions

View File

@@ -74,6 +74,7 @@ endif
ifeq ($(CONFIG_BUILD_KERNEL),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_signal_dispatch.c
CMN_CSRCS += arm_pthread_exit.c
endif
ifeq ($(CONFIG_ARCH_ADDRENV),y)

View File

@@ -70,6 +70,7 @@ endif
ifeq ($(CONFIG_BUILD_KERNEL),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_signal_dispatch.c
CMN_CSRCS += arm_pthread_exit.c
endif
ifeq ($(CONFIG_ARCH_ADDRENV),y)

View File

@@ -298,26 +298,28 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
break;
#endif
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
/* R0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt,
* pthread_addr_t arg) noreturn_function;
* void up_pthread_start(pthread_trampoline_t startup,
* pthread_startroutine_t entrypt, pthread_addr_t arg)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
* R1 = startup
* R2 = entrypt
* R3 = arg
*/
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode.
*/
regs[REG_PC] = (uint32_t)regs[REG_R1]; /* startup */
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
/* Change the parameter ordering to match the expectation of the
@@ -328,6 +330,35 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
regs[REG_R1] = regs[REG_R3]; /* arg */
}
break;
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
*
* void up_pthread_exit(pthread_exitroutine_t exit,
* FAR void *exit_value)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_exit
* R1 = pthread_exit trampoline routine
* R2 = exit_value
*/
case SYS_pthread_exit:
{
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode.
*/
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
/* Change the parameter ordering to match the expectation of the
* user space pthread_startup:
*/
regs[REG_R0] = regs[REG_R2]; /* exit_value */
}
break;
#endif
/* R0=SYS_signal_handler: This a user signal handler callback

View File

@@ -45,9 +45,9 @@
#ifdef CONFIG_LIB_SYSCALL
# ifdef CONFIG_BUILD_PROTECTED
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 8"
# elif CONFIG_SYS_RESERVED != 8
# error "CONFIG_SYS_RESERVED must have the value 8"
# error "CONFIG_SYS_RESERVED must be defined to have the value 9"
# elif CONFIG_SYS_RESERVED != 9
# error "CONFIG_SYS_RESERVED must have the value 9"
# endif
# else
# ifndef CONFIG_SYS_RESERVED

View File

@@ -278,30 +278,23 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
#endif
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
/* R0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt,
* pthread_addr_t arg) noreturn_function;
* void up_pthread_start(pthread_trampoline_t startup,
* pthread_startroutine_t entrypt, pthread_addr_t arg)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
* R1 = startup
* R2 = entrypt
* R3 = arg
*/
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to enter the user-space pthread start-up function in
* unprivileged mode. We need:
*
* R0 = entrypt
* R1 = arg
* PC = startup
* CSPR = user mode
*/
regs[REG_PC] = regs[REG_R0];
regs[REG_R0] = regs[REG_R1];
regs[REG_R1] = regs[REG_R2];
@@ -310,6 +303,28 @@ uint32_t *arm_syscall(uint32_t *regs)
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
}
break;
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
*
* void up_pthread_exit(pthread_exitroutine_t exit,
* FAR void *exit_value)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_exit
* R1 = pthread_exit trampoline routine
* R2 = exit_value
*/
case SYS_pthread_exit:
{
regs[REG_PC] = regs[REG_R0];
regs[REG_R0] = regs[REG_R1];
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
}
break;
#endif
#ifdef CONFIG_BUILD_KERNEL

View File

@@ -44,8 +44,8 @@
#ifdef CONFIG_BUILD_KERNEL
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 6"
# elif CONFIG_SYS_RESERVED != 6
# error "CONFIG_SYS_RESERVED must be defined to have the value 7"
# elif CONFIG_SYS_RESERVED != 7
# error "CONFIG_SYS_RESERVED must have the value 6"
# endif
#else
@@ -109,6 +109,13 @@
#define SYS_pthread_start (3)
/* SYS call 8:
*
* void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
*/
#define SYS_pthread_exit (6)
#endif /* CONFIG_BUILD_KERNEL */
/****************************************************************************

View File

@@ -312,19 +312,21 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
break;
#endif
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
/* R0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt,
* pthread_addr_t arg) noreturn_function;
* void up_pthread_start(pthread_trampoline_t startup,
* pthread_startroutine_t entrypt, pthread_addr_t arg)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
* R1 = startup
* R2 = entrypt
* R3 = arg
*/
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to return to the user-space pthread start-up function in
@@ -342,6 +344,35 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
regs[REG_R1] = regs[REG_R3]; /* arg */
}
break;
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
*
* void up_pthread_exit(pthread_exitroutine_t exit,
* FAR void *exit_value)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_exit
* R1 = pthread_exit trampoline routine
* R2 = exit_value
*/
case SYS_pthread_exit:
{
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode.
*/
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
/* Change the parameter ordering to match the expectation of the
* user space pthread_startup:
*/
regs[REG_R0] = regs[REG_R2]; /* exit_value */
}
break;
#endif
/* R0=SYS_signal_handler: This a user signal handler callback

View File

@@ -45,9 +45,9 @@
#ifdef CONFIG_LIB_SYSCALL
# ifdef CONFIG_BUILD_PROTECTED
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 8"
# elif CONFIG_SYS_RESERVED != 8
# error "CONFIG_SYS_RESERVED must have the value 8"
# error "CONFIG_SYS_RESERVED must be defined to have the value 9"
# elif CONFIG_SYS_RESERVED != 9
# error "CONFIG_SYS_RESERVED must have the value 9"
# endif
# else
# ifndef CONFIG_SYS_RESERVED
@@ -126,6 +126,13 @@
#define SYS_pthread_start (5)
/* SYS call 8:
*
* void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
*/
#define SYS_pthread_exit (8)
#endif /* !CONFIG_BUILD_FLAT */
#endif /* CONFIG_LIB_SYSCALL */

View File

@@ -273,33 +273,48 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
#endif
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
/* R0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt,
* pthread_addr_t arg) noreturn_function;
* void up_pthread_start(pthread_trampoline_t startup,
* pthread_startroutine_t entrypt, pthread_addr_t arg)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
* R1 = startup
* R2 = entrypt
* R3 = arg
*/
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to enter the user-space pthread start-up function in
* unprivileged mode. We need:
*
* R0 = startup
* R1 = arg
* PC = entrypt
* CSPR = user mode
*/
regs[REG_PC] = regs[REG_R0];
regs[REG_R0] = regs[REG_R1];
regs[REG_R1] = regs[REG_R2];
regs[REG_PC] = regs[REG_R1];
regs[REG_R0] = regs[REG_R2];
regs[REG_R1] = regs[REG_R3];
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
regs[REG_CPSR] = cpsr | PSR_MODE_USR;
}
break;
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
*
* void up_pthread_exit(pthread_exitroutine_t exit,
* FAR void *exit_value)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_exit
* R1 = pthread_exit trampoline routine
* R2 = exit_value
*/
case SYS_pthread_exit:
{
regs[REG_PC] = regs[REG_R0];
regs[REG_R0] = regs[REG_R1];
cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK;
regs[REG_CPSR] = cpsr | PSR_MODE_USR;

View File

@@ -311,19 +311,21 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
break;
#endif
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
/* R0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt,
* pthread_addr_t arg) noreturn_function;
* void up_pthread_start(pthread_trampoline_t startup,
* pthread_startroutine_t entrypt, pthread_addr_t arg)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
* R1 = startup
* R2 = entrypt
* R3 = arg
*/
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to return to the user-space pthread start-up function in
@@ -338,7 +340,36 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg)
*/
regs[REG_R0] = regs[REG_R2]; /* pthread entry */
regs[REG_R1] = regs[REG_R2]; /* arg */
regs[REG_R1] = regs[REG_R3]; /* arg */
}
break;
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
*
* void up_pthread_exit(pthread_exitroutine_t exit,
* FAR void *exit_value)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_exit
* R1 = pthread_exit trampoline routine
* R2 = exit_value
*/
case SYS_pthread_exit:
{
/* Set up to return to the user-space pthread start-up function in
* unprivileged mode.
*/
regs[REG_PC] = (uint32_t)regs[REG_R1] & ~1; /* startup */
regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR;
/* Change the parameter ordering to match the expectation of the
* user space pthread_startup:
*/
regs[REG_R0] = regs[REG_R2]; /* exit_value */
}
break;
#endif

View File

@@ -0,0 +1,62 @@
/****************************************************************************
* arch/arm/src/common/arm_pthread_exit.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <pthread.h>
#include <nuttx/arch.h>
#include "svcall.h"
#include "arm_internal.h"
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) && \
!defined(CONFIG_DISABLE_PTHREAD)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_pthread_exit
*
* Description:
* In this kernel mode build, this function will be called to execute a
* pthread in user-space. This kernel-mode stub will then be called
* transfer control to the user-mode pthread_exit.
*
* Input Parameters:
* exit - The user-space pthread_exit function
* exit_value - The pointer of the pthread exit parameter
*
* Returned Value:
* None
****************************************************************************/
void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
{
/* Let sys_call2() do all of the work */
sys_call2(SYS_pthread_exit, (uintptr_t)exit, (uintptr_t)exit_value);
}
#endif /* !CONFIG_BUILD_FLAT && __KERNEL__ && !CONFIG_DISABLE_PTHREAD */

View File

@@ -51,6 +51,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -43,6 +43,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -43,6 +43,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -90,6 +90,7 @@ endif
ifeq ($(CONFIG_BUILD_KERNEL),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_signal_dispatch.c
CMN_CSRCS += arm_pthread_exit.c
endif
ifeq ($(CONFIG_ARCH_ADDRENV),y)

View File

@@ -55,6 +55,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -51,6 +51,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -32,6 +32,7 @@ CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -42,6 +42,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -54,6 +54,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -47,6 +47,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -47,6 +47,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -45,6 +45,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -51,6 +51,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -32,6 +32,7 @@ CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -36,6 +36,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -31,6 +31,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
endif
# Source files common to all S32K1xx chip families.

View File

@@ -59,6 +59,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -76,6 +76,7 @@ endif
ifeq ($(CONFIG_BUILD_KERNEL),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_signal_dispatch.c
CMN_CSRCS += arm_pthread_exit.c
endif
ifeq ($(CONFIG_ARCH_ADDRENV),y)

View File

@@ -32,6 +32,7 @@ CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -49,6 +49,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -67,6 +67,7 @@ ifeq ($(CONFIG_ARM_MPU),y)
CMN_CSRCS += arm_mpu.c
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -58,7 +58,7 @@ CMN_CSRCS += arm_mpu.c
endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_task_start.c arm_pthread_start.c arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -32,6 +32,7 @@ CMN_CSRCS += arm_hardfault.c arm_svcall.c arm_vectors.c arm_vfork.c
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -73,6 +73,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -72,6 +72,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -63,6 +63,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -64,6 +64,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -65,6 +65,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
else

View File

@@ -59,6 +59,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_mpu.c arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -51,6 +51,7 @@ endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += arm_task_start.c arm_pthread_start.c
CMN_CSRCS += arm_pthread_exit.c
CMN_CSRCS += arm_signal_dispatch.c
CMN_UASRCS += arm_signal_handler.S
endif

View File

@@ -63,7 +63,7 @@
void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg)
{
/* Let sys_call2() do all of the work */
/* Let sys_call3() do all of the work */
sinfo("entry %p arg %p\n", entrypt, arg);

View File

@@ -55,6 +55,7 @@ CHIP_CSRCS += c906_start.c c906_timerisr.c
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c
CMN_CSRCS += riscv_pthread_exit.c
CMN_CSRCS += riscv_signal_dispatch.c riscv_pmp.c
CMN_UASRCS += riscv_signal_handler.S

View File

@@ -0,0 +1,60 @@
/****************************************************************************
* arch/risc-v/src/common/riscv_pthread_exit.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <pthread.h>
#include <nuttx/arch.h>
#include "svcall.h"
#include "riscv_internal.h"
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) && \
!defined(CONFIG_DISABLE_PTHREAD)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_pthread_exit
*
* Description:
* In this kernel mode build, this function will be called to execute a
* pthread in user-space. This kernel-mode stub will then be called
* transfer control to the user-mode pthread_exit.
*
* Input Parameters:
* exit - The user-space pthread_exit function
* exit_value - The pointer of the pthread exit parameter
*
* Returned Value:
* None
****************************************************************************/
void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
{
sys_call2(SYS_pthread_exit, (uintptr_t)exit, (uintptr_t)exit_value);
}
#endif /* !CONFIG_BUILD_FLAT && __KERNEL__ && !CONFIG_DISABLE_PTHREAD */

View File

@@ -57,7 +57,8 @@ CHIP_CSRCS += k210_cpupause.c k210_cpustart.c
endif
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c
CMN_CSRCS += riscv_task_start.c
CMN_CSRCS += riscv_pthread_start.c riscv_pthread_exit.c
CMN_CSRCS += riscv_signal_dispatch.c
CMN_UASRCS += riscv_signal_handler.S

View File

@@ -282,19 +282,21 @@ int riscv_swint(int irq, FAR void *context, FAR void *arg)
break;
#endif
/* R0=SYS_pthread_start: This a user pthread start
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
/* A0=SYS_pthread_start: This a user pthread start
*
* void up_pthread_start(pthread_startroutine_t entrypt,
* pthread_addr_t arg) noreturn_function;
* void up_pthread_start(pthread_trampoline_t startup,
* pthread_startroutine_t entrypt, pthread_addr_t arg)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_start
* R1 = entrypt
* R2 = arg
* A0 = SYS_pthread_start
* A1 = startup
* A2 = entrypt
* A3 = arg
*/
#if !defined(CONFIG_BUILD_FLAT) && !defined(CONFIG_DISABLE_PTHREAD)
case SYS_pthread_start:
{
/* Set up to return to the user-space pthread start-up function in
@@ -312,6 +314,35 @@ int riscv_swint(int irq, FAR void *context, FAR void *arg)
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
}
break;
/* R0=SYS_pthread_exit: This pthread_exit call in user-space
*
* void up_pthread_exit(pthread_exitroutine_t exit,
* FAR void *exit_value)
*
* At this point, the following values are saved in context:
*
* R0 = SYS_pthread_exit
* R1 = pthread_exit trampoline routine
* R2 = exit_value
*/
case SYS_pthread_exit:
{
/* Set up to enter the user-space pthread exit function in
* unprivileged mode.
*/
regs[REG_EPC] = (uintptr_t)regs[REG_A1] & ~1; /* exit */
/* Change the parameter ordering to match the expectation of the
* user space pthread_exit:
*/
regs[REG_A0] = regs[REG_A2]; /* exit_value */
regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */
}
break;
#endif
/* R0=SYS_signal_handler: This a user signal handler callback

View File

@@ -46,9 +46,9 @@
#ifdef CONFIG_LIB_SYSCALL
# ifdef CONFIG_BUILD_PROTECTED
# ifndef CONFIG_SYS_RESERVED
# error "CONFIG_SYS_RESERVED must be defined to have the value 8"
# elif CONFIG_SYS_RESERVED != 8
# error "CONFIG_SYS_RESERVED must have the value 8"
# error "CONFIG_SYS_RESERVED must be defined to have the value 9"
# elif CONFIG_SYS_RESERVED != 9
# error "CONFIG_SYS_RESERVED must have the value 9"
# endif
# else
# ifndef CONFIG_SYS_RESERVED
@@ -118,13 +118,20 @@
/* SYS call 5:
*
* void up_pthread_start(pthread_startroutine_t startup,
* void up_pthread_start(pthread_trampoline_t startup,
* pthread_startroutine_t entrypt, pthread_addr_t arg)
* noreturn_function
*/
#define SYS_pthread_start (5)
/* SYS call 8:
*
* void up_pthread_exit(pthread_exitroutine_t exit, FAR void *exit_value)
*/
#define SYS_pthread_exit (8)
#endif /* !CONFIG_BUILD_FLAT */
#endif /* CONFIG_LIB_SYSCALL */

View File

@@ -40,5 +40,5 @@ CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=8
CONFIG_START_MONTH=6
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@@ -40,5 +40,5 @@ CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=8
CONFIG_START_MONTH=6
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@@ -40,5 +40,5 @@ CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=8
CONFIG_START_MONTH=6
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_USER_ENTRYPOINT="nsh_main"

Some files were not shown because too many files have changed in this diff Show More