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"

View File

@ -109,7 +109,7 @@ CONFIG_START_YEAR=2013
CONFIG_SYSTEM_I2CTOOL=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_TIME64=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=24
CONFIG_UART0_RXBUFSIZE=512
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -40,7 +40,7 @@ CONFIG_START_MONTH=10
CONFIG_START_YEAR=2013
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_TIME64=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TESTING_OSTEST=y
CONFIG_TESTING_OSTEST_NBARRIER_THREADS=3
CONFIG_TESTING_OSTEST_STACKSIZE=2048

View File

@ -173,7 +173,7 @@ CONFIG_SYSTEM_NSH_SYMTAB_COUNTNAME="g_nsymbols"
CONFIG_SYSTEM_NXPLAYER=y
CONFIG_SYSTEM_PING=y
CONFIG_SYSTEM_TIME64=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=24
CONFIG_TELNET_CHARACTER_MODE=y
CONFIG_TESTING_OSTEST=y

View File

@ -57,7 +57,7 @@ CONFIG_START_MONTH=3
CONFIG_START_YEAR=2013
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -53,7 +53,7 @@ CONFIG_START_MONTH=3
CONFIG_START_YEAR=2013
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -57,7 +57,7 @@ CONFIG_START_MONTH=3
CONFIG_START_YEAR=2013
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -67,7 +67,7 @@ CONFIG_START_MONTH=3
CONFIG_START_YEAR=2019
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_CLE=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nxterm_main"

View File

@ -21,6 +21,6 @@ CONFIG_PASS1_BUILDIR="boards/arm/lpc17xx_40xx/pnev5180b/kernel"
CONFIG_RAM_SIZE=32768
CONFIG_RAM_START=0x10000000
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -49,7 +49,7 @@ CONFIG_START_MONTH=7
CONFIG_START_YEAR=2012
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_TIMER=y
CONFIG_UART1_SERIAL_CONSOLE=y

View File

@ -48,7 +48,7 @@ CONFIG_START_DAY=10
CONFIG_START_MONTH=3
CONFIG_START_YEAR=2013
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -85,5 +85,5 @@ CONFIG_SCHED_WAITPID=y
CONFIG_SDIO_BLOCKSETUP=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_NSH_PROGNAME="init"
CONFIG_SYS_RESERVED=6
CONFIG_SYS_RESERVED=7
CONFIG_USART3_SERIAL_CONSOLE=y

View File

@ -80,6 +80,6 @@ CONFIG_START_YEAR=2015
CONFIG_SYSTEM_I2CTOOL=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_RAMTEST=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_UART3_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -52,7 +52,7 @@ CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_PWR=y
CONFIG_STM32_USART3=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=32
CONFIG_USART3_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -82,7 +82,7 @@ CONFIG_STM32_USART2=y
CONFIG_SYSLOG_CHAR=y
CONFIG_SYSLOG_DEVPATH="/dev/ttyS0"
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=11
CONFIG_TESTING_OSTEST=y
CONFIG_USBDEV=y

View File

@ -56,7 +56,7 @@ CONFIG_STM32_SDIO=y
CONFIG_STM32_USART3=y
CONFIG_STM32_USBHOST=y
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_USART3_SERIAL_CONSOLE=y
CONFIG_USBHOST_ISOC_DISABLE=y
CONFIG_USBHOST_MSC=y

View File

@ -52,7 +52,7 @@ CONFIG_STM32_PWR=y
CONFIG_STM32_USART3=y
CONFIG_STM32_USBHOST=y
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_USART3_SERIAL_CONSOLE=y
CONFIG_USBHOST_ISOC_DISABLE=y
CONFIG_USBHOST_MSC=y

View File

@ -52,7 +52,7 @@ CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_PWR=y
CONFIG_STM32_USART3=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=32
CONFIG_USART3_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -93,7 +93,7 @@ CONFIG_STMPE811_THRESHX=39
CONFIG_STMPE811_THRESHY=51
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_READLINE=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_USART3_RXBUFSIZE=128
CONFIG_USART3_SERIAL_CONSOLE=y

View File

@ -39,7 +39,7 @@ CONFIG_START_YEAR=2013
CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_USART2=y
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TESTING_OSTEST=y
CONFIG_TESTING_OSTEST_NBARRIER_THREADS=3
CONFIG_TESTING_OSTEST_STACKSIZE=2048

View File

@ -69,7 +69,7 @@ CONFIG_STM32L4_RTC=y
CONFIG_STM32L4_SAI1PLL=y
CONFIG_STM32L4_USART2=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_USART2_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"

View File

@ -73,7 +73,7 @@ CONFIG_STM32L4_SRAM2_HEAP=y
CONFIG_STM32L4_UART4=y
CONFIG_STM32L4_USART2=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_UART4_BAUD=2000000
CONFIG_UART4_RXBUFSIZE=512

View File

@ -98,7 +98,7 @@ CONFIG_SYSTEM_NETDB=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_NTPC=y
CONFIG_SYSTEM_PING=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=0
CONFIG_TIVA_ETHERNET=y
CONFIG_TIVA_GPIOA_IRQS=y

View File

@ -57,7 +57,7 @@ CONFIG_START_DAY=7
CONFIG_START_MONTH=3
CONFIG_START_YEAR=2021
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y

View File

@ -46,7 +46,7 @@ CONFIG_START_DAY=12
CONFIG_START_MONTH=5
CONFIG_START_YEAR=2020
CONFIG_SYSTEM_NSH=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y

View File

@ -51,7 +51,7 @@ CONFIG_START_YEAR=2021
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
CONFIG_SYSTEM_TASKSET=y
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y

View File

@ -42,7 +42,7 @@ CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=14
CONFIG_START_MONTH=2
CONFIG_START_YEAR=2020
CONFIG_SYS_RESERVED=8
CONFIG_SYS_RESERVED=9
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_OSTEST=y
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -558,6 +558,8 @@ void up_task_start(main_t taskentry, int argc, FAR char *argv[])
noreturn_function;
#endif
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) && \
!defined(CONFIG_DISABLE_PTHREAD)
/****************************************************************************
* Name: up_pthread_start
*
@ -583,11 +585,28 @@ void up_task_start(main_t taskentry, int argc, FAR char *argv[])
*
****************************************************************************/
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__) && \
!defined(CONFIG_DISABLE_PTHREAD)
void up_pthread_start(pthread_trampoline_t startup,
pthread_startroutine_t entrypt, pthread_addr_t arg);
noreturn_function;
/****************************************************************************
* 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);
noreturn_function;
#endif
/****************************************************************************

View File

@ -140,6 +140,7 @@ EXTERN const pthread_attr_t g_default_pthread_attr;
* for the new thread
* entry - The new thread starts execution by invoking entry
* arg - It is passed as the sole argument of entry
* exit - The user-space pthread exit function
*
* Returned Value:
* OK (0) on success; a (non-negated) errno value on failure. The errno
@ -149,7 +150,8 @@ EXTERN const pthread_attr_t g_default_pthread_attr;
int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
FAR const pthread_attr_t *attr,
pthread_startroutine_t entry, pthread_addr_t arg);
pthread_startroutine_t entry, pthread_addr_t arg,
pthread_exitroutine_t exit);
/****************************************************************************
* Name: nx_pthread_exit
@ -163,8 +165,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
* Returned Value:
* None
*
* Assumptions:
*
****************************************************************************/
void nx_pthread_exit(FAR void *exit_value) noreturn_function;

View File

@ -95,16 +95,17 @@
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
#define TCB_FLAG_CANCEL_DEFERRED (1 << 3) /* Bit 3: Deferred (vs asynch) cancellation type */
#define TCB_FLAG_CANCEL_PENDING (1 << 4) /* Bit 4: Pthread cancel is pending */
#define TCB_FLAG_POLICY_SHIFT (5) /* Bit 5-6: Scheduling policy */
#define TCB_FLAG_CANCEL_DOING (1 << 5) /* Bit 4: Pthread cancel/exit is doing */
#define TCB_FLAG_POLICY_SHIFT (6) /* Bit 5-6: Scheduling policy */
#define TCB_FLAG_POLICY_MASK (3 << TCB_FLAG_POLICY_SHIFT)
# define TCB_FLAG_SCHED_FIFO (0 << TCB_FLAG_POLICY_SHIFT) /* FIFO scheding policy */
# define TCB_FLAG_SCHED_RR (1 << TCB_FLAG_POLICY_SHIFT) /* Round robin scheding policy */
# define TCB_FLAG_SCHED_SPORADIC (2 << TCB_FLAG_POLICY_SHIFT) /* Sporadic scheding policy */
# define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */
#define TCB_FLAG_CPU_LOCKED (1 << 7) /* Bit 7: Locked to this CPU */
#define TCB_FLAG_SIGNAL_ACTION (1 << 8) /* Bit 8: In a signal handler */
#define TCB_FLAG_SYSCALL (1 << 9) /* Bit 9: In a system call */
#define TCB_FLAG_EXIT_PROCESSING (1 << 10) /* Bit 10: Exitting */
#define TCB_FLAG_CPU_LOCKED (1 << 8) /* Bit 7: Locked to this CPU */
#define TCB_FLAG_SIGNAL_ACTION (1 << 9) /* Bit 8: In a signal handler */
#define TCB_FLAG_SYSCALL (1 << 10) /* Bit 9: In a system call */
#define TCB_FLAG_EXIT_PROCESSING (1 << 11) /* Bit 10: Exitting */
/* Bits 11-15: Available */
/* Values for struct task_group tg_flags */
@ -761,6 +762,7 @@ struct pthread_tcb_s
pthread_trampoline_t trampoline; /* User-space pthread startup function */
pthread_addr_t arg; /* Startup argument */
pthread_exitroutine_t exit; /* User-space pthread exit function */
FAR void *joininfo; /* Detach-able info to support join */
};
#endif /* !CONFIG_DISABLE_PTHREAD */

View File

@ -225,6 +225,8 @@ typedef FAR void *pthread_addr_t;
typedef CODE pthread_addr_t (*pthread_startroutine_t)(pthread_addr_t);
typedef pthread_startroutine_t pthread_func_t;
typedef void (*pthread_exitroutine_t)(pthread_addr_t);
typedef void (*pthread_trampoline_t)(pthread_startroutine_t, pthread_addr_t);
struct pthread_attr_s

View File

@ -305,7 +305,7 @@ SYSCALL_LOOKUP(telldir, 1)
SYSCALL_LOOKUP(pthread_cond_broadcast, 1)
SYSCALL_LOOKUP(pthread_cond_signal, 1)
SYSCALL_LOOKUP(pthread_cond_wait, 2)
SYSCALL_LOOKUP(nx_pthread_create, 5)
SYSCALL_LOOKUP(nx_pthread_create, 6)
SYSCALL_LOOKUP(pthread_detach, 1)
SYSCALL_LOOKUP(nx_pthread_exit, 1)
SYSCALL_LOOKUP(pthread_getschedparam, 3)

View File

@ -87,5 +87,5 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
pthread_startroutine_t pthread_entry, pthread_addr_t arg)
{
return nx_pthread_create(pthread_startup, thread, attr, pthread_entry,
arg);
arg, pthread_exit);
}

View File

@ -40,7 +40,7 @@
* Terminate execution of a thread started with pthread_create.
*
* Input Parameters:
* exit_value
* exit_value - The pointer of the pthread_exit parameter
*
* Returned Value:
* None

View File

@ -24,6 +24,8 @@
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
@ -82,7 +84,15 @@ int pthread_cancel(pthread_t thread)
if (tcb == this_task())
{
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
tcb->flags |= TCB_FLAG_CANCEL_DOING;
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
PTHREAD_CANCELED);
#else
pthread_exit(PTHREAD_CANCELED);
#endif
}
/* Complete pending join operations */

View File

@ -79,6 +79,7 @@ const pthread_attr_t g_default_pthread_attr = PTHREAD_ATTR_INITIALIZER;
* tcb - Address of the new task's TCB
* trampoline - User space pthread startup function
* arg - The argument to provide to the pthread on startup.
* exit - The user-space pthread exit function
*
* Returned Value:
* None
@ -87,7 +88,8 @@ const pthread_attr_t g_default_pthread_attr = PTHREAD_ATTR_INITIALIZER;
static inline void pthread_tcb_setup(FAR struct pthread_tcb_s *ptcb,
pthread_trampoline_t trampoline,
pthread_addr_t arg)
pthread_addr_t arg,
pthread_exitroutine_t exit)
{
#if CONFIG_TASK_NAME_SIZE > 0
/* Copy the pthread name into the TCB */
@ -102,6 +104,7 @@ static inline void pthread_tcb_setup(FAR struct pthread_tcb_s *ptcb,
ptcb->trampoline = trampoline;
ptcb->arg = arg;
ptcb->exit = exit;
}
/****************************************************************************
@ -193,7 +196,12 @@ static void pthread_start(void)
/* The thread has returned (should never happen) */
DEBUGPANIC();
pthread_exit(NULL);
#ifndef CONFIG_BUILD_FLAT
ptcb->cmn.flags &= ~TCB_FLAG_CANCEL_PENDING;
ptcb->cmn.flags |= TCB_FLAG_CANCEL_DOING;
up_pthread_exit(ptcb->exit, NULL);
#endif
}
/****************************************************************************
@ -215,6 +223,7 @@ static void pthread_start(void)
* for the new thread
* entry - The new thread starts execution by invoking entry
* arg - It is passed as the sole argument of entry
* exit - The user-space pthread exit function
*
* Returned Value:
* OK (0) on success; a (non-negated) errno value on failure. The errno
@ -224,7 +233,8 @@ static void pthread_start(void)
int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
FAR const pthread_attr_t *attr,
pthread_startroutine_t entry, pthread_addr_t arg)
pthread_startroutine_t entry, pthread_addr_t arg,
pthread_exitroutine_t exit)
{
FAR struct pthread_tcb_s *ptcb;
FAR struct tls_info_s *info;
@ -237,6 +247,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
bool group_joined = false;
DEBUGASSERT(trampoline != NULL);
DEBUGASSERT(exit != NULL);
/* If attributes were not supplied, use the default attributes */
@ -450,7 +461,7 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
* passed by value
*/
pthread_tcb_setup(ptcb, trampoline, arg);
pthread_tcb_setup(ptcb, trampoline, arg, exit);
/* Join the parent's task group */

View File

@ -224,7 +224,15 @@ static void nxsig_abnormal_termination(int signo)
* REVISIT: This will not work if HAVE_GROUP_MEMBERS is not set.
*/
pthread_exit(NULL);
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
rtcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
rtcb->flags |= TCB_FLAG_CANCEL_DOING;
up_pthread_exit(((FAR struct pthread_tcb_s *)rtcb)->exit,
PTHREAD_CANCELED);
#else
pthread_exit(PTHREAD_CANCELED);
#endif
}
else
#endif

View File

@ -57,6 +57,7 @@
#include <nuttx/irq.h>
#include <nuttx/cancelpt.h>
#include <nuttx/pthread.h>
#include "sched/sched.h"
#include "semaphore/semaphore.h"
@ -139,7 +140,15 @@ bool enter_cancellation_point(void)
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
TCB_FLAG_TTYPE_PTHREAD)
{
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
tcb->flags |= TCB_FLAG_CANCEL_DOING;
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
PTHREAD_CANCELED);
#else
pthread_exit(PTHREAD_CANCELED);
#endif
}
else
#endif
@ -226,7 +235,15 @@ void leave_cancellation_point(void)
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
TCB_FLAG_TTYPE_PTHREAD)
{
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
tcb->flags |= TCB_FLAG_CANCEL_DOING;
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
PTHREAD_CANCELED);
#else
pthread_exit(PTHREAD_CANCELED);
#endif
}
else
#endif

View File

@ -112,7 +112,15 @@ int task_setcancelstate(int state, FAR int *oldstate)
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) ==
TCB_FLAG_TTYPE_PTHREAD)
{
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
tcb->flags |= TCB_FLAG_CANCEL_DOING;
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
PTHREAD_CANCELED);
#else
pthread_exit(PTHREAD_CANCELED);
#endif
}
else
#endif

View File

@ -100,7 +100,15 @@ int task_setcanceltype(int type, FAR int *oldtype)
#ifndef CONFIG_DISABLE_PTHREAD
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
{
pthread_exit(PTHREAD_CANCELED);
#if !defined(CONFIG_BUILD_FLAT) && defined(__KERNEL__)
tcb->flags &= ~TCB_FLAG_CANCEL_PENDING;
tcb->flags |= TCB_FLAG_CANCEL_DOING;
up_pthread_exit(((FAR struct pthread_tcb_s *)tcb)->exit,
PTHREAD_CANCELED);
#else
pthread_exit(PTHREAD_CANCELED);
#endif
}
else
#endif

View File

@ -66,7 +66,7 @@
"munmap","sys/mman.h","defined(CONFIG_FS_RAMMAP)","int","FAR void *","size_t"
"nx_mkfifo","nuttx/fs/fs.h","defined(CONFIG_PIPES) && CONFIG_DEV_FIFO_SIZE > 0","int","FAR const char *","mode_t","size_t"
"nx_pipe","nuttx/fs/fs.h","defined(CONFIG_PIPES) && CONFIG_DEV_PIPE_SIZE > 0","int","int [2]|FAR int *","size_t","int"
"nx_pthread_create","nuttx/pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_trampoline_t","FAR pthread_t *","FAR const pthread_attr_t *","pthread_startroutine_t","pthread_addr_t"
"nx_pthread_create","nuttx/pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_trampoline_t","FAR pthread_t *","FAR const pthread_attr_t *","pthread_startroutine_t","pthread_addr_t","pthread_exitroutine_t"
"nx_task_spawn","nuttx/spawn.h","defined(CONFIG_LIB_SYSCALL) && !defined(CONFIG_BUILD_KERNEL)","int","FAR const struct spawn_syscall_parms_s *"
"nx_vsyslog","nuttx/syslog/syslog.h","","int","int","FAR const IPTR char *","FAR va_list *"
"nxsched_get_stackinfo","nuttx/sched.h","","int","pid_t","FAR struct stackinfo_s *"

Can't render this file because it has a wrong number of fields in line 2.