This is an automated email from the ASF dual-hosted git repository. gnutt pushed a commit to branch feature/pthread-user in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit b134d176cc7f858d7c8bc91f453ffbdf5d6c77a2 Author: Gregory Nutt <gn...@nuttx.org> AuthorDate: Mon Jun 29 08:26:29 2020 -0600 pthread_cleanup functions must be called from user space 1. A user-space shim is needed to catch any return from a pthead manin function and to automatically call pthread_exit() from user space. Rename pthread_create() in sched/pthread/pthread_create.c to nx_pthread_create(). Add one new parameter: The address of the user-space pthread startup function. Instead of calling the pthread main entry (directly or indirectly), pthread_start() would call the pthread startup function, passing it the real address of the pthread main function. The call to pthread_exist would be removed from pthread_startup() and move into a new function in user space. 2. Add libs/libc/pthread/lib_pthread_start.c that would contain two trivial functions: static void pthread_startup(pthread_startroutine_t startroutine, pthread_addr_t arg) { pthread_exit(startroutine(arg)); } int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, pthread_startroutine_t startroutine, pthread_addr_t arg) { return nx_pthread_create(pthread_startup, thread, attr, startroutine, arg); } 3. Modify up_pthread_start() so that it takes three parameters: startup, entry, and arg. Modify the kernel pthread_start() logic so that it receives these there parameters and calls up_pthread_start() will all three. 4. Remove pthread_startup function pointer from struct userspace_s; it is no longer needed. Still to do: a. Rename pthread_exit() to nx_pthread_exit(). Remove logic that calls pthread_cleanup() functions. b. Make nx_pthread_exit() a system call. c. Create libc/pthread/pthread_exit() that contains only i) the logic that calls the pthread_cleanup functions, and ii) calls the nx_pthread_exit() system call. d. Extend TLS and pthread-specific data function so that the destructor is retained in TLS e. Extend pthread_exit() so that it also calls the pthread-specific data destructors from user-space. --- arch/arm/src/armv6-m/arm_svcall.c | 12 ++-- arch/arm/src/armv6-m/svcall.h | 20 +++--- arch/arm/src/armv7-a/arm_syscall.c | 12 ++-- arch/arm/src/armv7-a/svcall.h | 20 +++--- arch/arm/src/armv7-m/arm_svcall.c | 12 ++-- arch/arm/src/armv7-m/svcall.h | 20 +++--- arch/arm/src/armv7-r/arm_syscall.c | 6 +- arch/arm/src/armv7-r/svcall.h | 19 +++--- arch/arm/src/armv8-m/arm_svcall.c | 10 +-- arch/arm/src/armv8-m/svcall.h | 19 +++--- arch/arm/src/common/arm_pthread_start.c | 11 +-- arch/or1k/src/common/up_pthread_start.c | 45 +++++-------- arch/risc-v/src/common/riscv_pthread_start.c | 9 ++- arch/risc-v/src/rv64gc/riscv_swint.c | 51 +++++--------- arch/risc-v/src/rv64gc/svcall.h | 20 +++--- .../imxrt/imxrt1050-evk/kernel/imxrt_userspace.c | 3 - .../imxrt/imxrt1060-evk/kernel/imxrt_userspace.c | 3 - .../lc823450-xgevk/kernel/lc823450_userspace.c | 3 - .../lpc4088-devkit/kernel/lpc17_40_userspace.c | 3 - .../lpc4088-quickstart/kernel/lpc17_40_userspace.c | 3 - .../open1788/kernel/lpc17_40_userspace.c | 3 - .../pnev5180b/kernel/lpc17_40_userspace.c | 3 - .../lpc43xx/bambino-200e/kernel/lpc43_userspace.c | 3 - boards/arm/sam34/sam3u-ek/kernel/sam_userspace.c | 3 - .../samv7/same70-xplained/kernel/sam_userspace.c | 3 - .../arm/samv7/samv71-xult/kernel/sam_userspace.c | 3 - .../stm32/clicker2-stm32/kernel/stm32_userspace.c | 3 - .../stm32/mikroe-stm32f4/kernel/stm32_userspace.c | 3 - .../olimex-stm32-p407/kernel/stm32_userspace.c | 3 - .../arm/stm32/omnibusf4/kernel/stm32_userspace.c | 3 - .../stm32/stm3240g-eval/kernel/stm32_userspace.c | 3 - .../stm32f4discovery/kernel/stm32_userspace.c | 3 - .../stm32f746g-disco/kernel/stm32_userspace.c | 3 - .../stm32f769i-disco/kernel/stm32_userspace.c | 3 - .../stm32h7/nucleo-h743zi/kernel/stm32_userspace.c | 3 - .../stm32h747i-disco/kernel/stm32_userspace.c | 3 - .../stm32l476vg-disco/kernel/stm32l4_userspace.c | 3 - .../stm32l4r9ai-disco/kernel/stm32l4_userspace.c | 3 - boards/arm/tiva/lm3s6965-ek/kernel/lm_userspace.c | 3 - .../risc-v/k210/maix-bit/kernel/k210_userspace.c | 3 - include/nuttx/arch.h | 6 +- include/nuttx/pthread.h | 30 ++++++++- include/nuttx/sched.h | 1 + include/nuttx/userspace.h | 26 +------- include/sys/syscall_lookup.h | 2 +- libs/libc/pthread/Make.defs | 13 ++-- .../{pthread_startup.c => pthread_create.c} | 78 ++++++++++------------ sched/pthread/pthread_create.c | 39 ++++++----- syscall/syscall.csv | 2 +- 49 files changed, 246 insertions(+), 312 deletions(-) diff --git a/arch/arm/src/armv6-m/arm_svcall.c b/arch/arm/src/armv6-m/arm_svcall.c index e61f83a..7af07ad 100644 --- a/arch/arm/src/armv6-m/arm_svcall.c +++ b/arch/arm/src/armv6-m/arm_svcall.c @@ -314,22 +314,22 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg) * R2 = arg */ -#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD) +#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)USERSPACE->pthread_startup; + regs[REG_PC] = (uint32_t)regs[REG_R1]; /* startup */ regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; - /* Change the parameter ordering to match the expectation of struct - * userpace_s pthread_startup: + /* Change the parameter ordering to match the expectation of the + * useri space pthread_startup: */ - regs[REG_R0] = regs[REG_R1]; /* pthread entry */ - regs[REG_R1] = regs[REG_R2]; /* arg */ + regs[REG_R0] = regs[REG_R2]; /* pthread entry */ + regs[REG_R1] = regs[REG_R3]; /* arg */ } break; #endif diff --git a/arch/arm/src/armv6-m/svcall.h b/arch/arm/src/armv6-m/svcall.h index 5441a45..ce2b420 100644 --- a/arch/arm/src/armv6-m/svcall.h +++ b/arch/arm/src/armv6-m/svcall.h @@ -89,6 +89,7 @@ #define SYS_syscall_return (3) +#ifndef CONFIG_BUILD_FLAT #ifdef CONFIG_BUILD_PROTECTED /* SYS call 4: * @@ -98,14 +99,6 @@ #define SYS_task_start (4) -/* SYS call 5: - * - * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) - * noreturn_function - */ - -#define SYS_pthread_start (5) - /* SYS call 6: * * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, @@ -122,6 +115,17 @@ #define SYS_signal_handler_return (7) #endif /* CONFIG_BUILD_PROTECTED */ + +/* SYS call 5: + * + * void up_pthread_start(pthread_startroutine_t startup, + pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (5) + +#endif /* !CONFIG_BUILD_FLAT */ #endif /* CONFIG_LIB_SYSCALL */ /************************************************************************************ diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c index ca0cb09..acb3a49 100644 --- a/arch/arm/src/armv7-a/arm_syscall.c +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -291,19 +291,21 @@ uint32_t *arm_syscall(uint32_t *regs) * R2 = arg */ -#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_PTHREAD) +#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. We need: * - * R0 = arg - * PC = entrypt + * R0 = entrypt + * R1 = arg + * PC = startup * CSPR = user mode */ - regs[REG_PC] = regs[REG_R1]; - regs[REG_R0] = regs[REG_R2]; + regs[REG_PC] = regs[REG_R0]; + regs[REG_R0] = regs[REG_R1]; + regs[REG_R1] = regs[REG_R2]; cpsr = regs[REG_CPSR] & ~PSR_MODE_MASK; regs[REG_CPSR] = cpsr | PSR_MODE_USR; diff --git a/arch/arm/src/armv7-a/svcall.h b/arch/arm/src/armv7-a/svcall.h index 8e45835..fde1510 100644 --- a/arch/arm/src/armv7-a/svcall.h +++ b/arch/arm/src/armv7-a/svcall.h @@ -67,6 +67,7 @@ #define SYS_syscall_return (0) +#ifndef CONFIG_BUILD_FLAT #ifdef CONFIG_BUILD_KERNEL /* SYS call 1: * @@ -83,14 +84,6 @@ #define SYS_task_start (2) -/* SYS call 3: - * - * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) - * noreturn_function - */ - -#define SYS_pthread_start (3) - /* SYS call 4: * * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, @@ -106,6 +99,17 @@ #define SYS_signal_handler_return (5) +#endif /* !CONFIG_BUILD_FLAT */ + +/* SYS call 3: + * + * void up_pthread_start(pthread_startroutine_t startup, + * pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (3) + #endif /* CONFIG_BUILD_KERNEL */ /************************************************************************************ diff --git a/arch/arm/src/armv7-m/arm_svcall.c b/arch/arm/src/armv7-m/arm_svcall.c index 22fadb0..c052b7c 100644 --- a/arch/arm/src/armv7-m/arm_svcall.c +++ b/arch/arm/src/armv7-m/arm_svcall.c @@ -328,22 +328,22 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg) * R2 = arg */ -#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD) +#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)USERSPACE->pthread_startup & ~1; + 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 struct - * userpace_s pthread_startup: + /* Change the parameter ordering to match the expectation of the + * user space pthread_startup: */ - regs[REG_R0] = regs[REG_R1]; /* pthread entry */ - regs[REG_R1] = regs[REG_R2]; /* arg */ + regs[REG_R0] = regs[REG_R2]; /* pthread entry */ + regs[REG_R1] = regs[REG_R3]; /* arg */ } break; #endif diff --git a/arch/arm/src/armv7-m/svcall.h b/arch/arm/src/armv7-m/svcall.h index 948f6b2..5d6b8f9 100644 --- a/arch/arm/src/armv7-m/svcall.h +++ b/arch/arm/src/armv7-m/svcall.h @@ -81,6 +81,7 @@ #define SYS_switch_context (2) +#ifndef CONFIG_BUILD_FLAT #ifdef CONFIG_LIB_SYSCALL /* SYS call 3: * @@ -98,14 +99,6 @@ #define SYS_task_start (4) -/* SYS call 5: - * - * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) - * noreturn_function - */ - -#define SYS_pthread_start (5) - /* SYS call 6: * * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, @@ -122,6 +115,17 @@ #define SYS_signal_handler_return (7) #endif /* CONFIG_BUILD_PROTECTED */ + +/* SYS call 5: + * + * void up_pthread_start((pthread_startroutine_t startup, + * pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (5) + +#endif /* !CONFIG_BUILD_FLAT */ #endif /* CONFIG_LIB_SYSCALL */ /************************************************************************************ diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c index 380a66a..75e7866 100644 --- a/arch/arm/src/armv7-r/arm_syscall.c +++ b/arch/arm/src/armv7-r/arm_syscall.c @@ -286,19 +286,21 @@ uint32_t *arm_syscall(uint32_t *regs) * R2 = arg */ -#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD) +#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. We need: * - * R0 = arg + * R0 = startup + * R1 = arg * PC = entrypt * CSPR = user mode */ 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; diff --git a/arch/arm/src/armv7-r/svcall.h b/arch/arm/src/armv7-r/svcall.h index 51a5d26..bdb431c 100644 --- a/arch/arm/src/armv7-r/svcall.h +++ b/arch/arm/src/armv7-r/svcall.h @@ -67,6 +67,7 @@ #define SYS_syscall_return (0) +#ifndef CONFIG_BUILD_FLAT #ifdef CONFIG_BUILD_PROTECTED /* SYS call 1: * @@ -83,14 +84,6 @@ #define SYS_task_start (2) -/* SYS call 3: - * - * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) - * noreturn_function - */ - -#define SYS_pthread_start (3) - /* SYS call 4: * * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, @@ -108,6 +101,16 @@ #endif /* CONFIG_BUILD_PROTECTED */ +/* SYS call 3: + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (3) + +#endif /* !CONFIG_BUILD_FLAT */ + /************************************************************************************ * Inline Functions ************************************************************************************/ diff --git a/arch/arm/src/armv8-m/arm_svcall.c b/arch/arm/src/armv8-m/arm_svcall.c index ec03ce0..9c94053 100644 --- a/arch/arm/src/armv8-m/arm_svcall.c +++ b/arch/arm/src/armv8-m/arm_svcall.c @@ -327,21 +327,21 @@ int arm_svcall(int irq, FAR void *context, FAR void *arg) * R2 = arg */ -#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD) +#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)USERSPACE->pthread_startup & ~1; + 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 struct - * userpace_s pthread_startup: + /* Change the parameter ordering to match the expectation of the + * user space pthread_startup: */ - regs[REG_R0] = regs[REG_R1]; /* pthread entry */ + regs[REG_R0] = regs[REG_R2]; /* pthread entry */ regs[REG_R1] = regs[REG_R2]; /* arg */ } break; diff --git a/arch/arm/src/armv8-m/svcall.h b/arch/arm/src/armv8-m/svcall.h index 327412b..ec24ae4 100644 --- a/arch/arm/src/armv8-m/svcall.h +++ b/arch/arm/src/armv8-m/svcall.h @@ -89,6 +89,7 @@ #define SYS_syscall_return (3) +#ifndef CONFIG_BUILD_FLAT #ifdef CONFIG_BUILD_PROTECTED /* SYS call 4: * @@ -98,14 +99,6 @@ #define SYS_task_start (4) -/* SYS call 5: - * - * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) - * noreturn_function - */ - -#define SYS_pthread_start (5) - /* SYS call 6: * * void signal_handler(_sa_sigaction_t sighand, int signo, FAR siginfo_t *info, @@ -122,6 +115,16 @@ #define SYS_signal_handler_return (7) #endif /* CONFIG_BUILD_PROTECTED */ + +/* SYS call 5: + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (5) + +#endif /* !CONFIG_BUILD_FLAT */ #endif /* CONFIG_LIB_SYSCALL */ /************************************************************************************ diff --git a/arch/arm/src/common/arm_pthread_start.c b/arch/arm/src/common/arm_pthread_start.c index f96c4a5..1348e11 100644 --- a/arch/arm/src/common/arm_pthread_start.c +++ b/arch/arm/src/common/arm_pthread_start.c @@ -47,9 +47,10 @@ * pthread. * * Normally the a user-mode start-up stub will also execute before the - * pthread actually starts. See libc/pthread/pthread_startup.c + * pthread actually starts. See libc/pthread/pthread_create.c * * Input Parameters: + * startup - The user-space pthread startup function * entrypt - The user-space address of the pthread entry point * arg - Standard argument for the pthread entry point * @@ -60,11 +61,13 @@ * ****************************************************************************/ -void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) +void up_pthread_start(pthread_startroutine_t startup, + pthread_startroutine_t entrypt, pthread_addr_t arg) { - /* Let sys_call2() do all of the work */ + /* Let sys_call3() do all of the work */ - sys_call2(SYS_pthread_start, (uintptr_t)entrypt, (uintptr_t)arg); + sys_call3(SYS_pthread_start, (uintptr_t)startup, (uintptr_t)entrypt, + (uintptr_t)arg); PANIC(); } diff --git a/arch/or1k/src/common/up_pthread_start.c b/arch/or1k/src/common/up_pthread_start.c index 79404e8..8edbd06 100644 --- a/arch/or1k/src/common/up_pthread_start.c +++ b/arch/or1k/src/common/up_pthread_start.c @@ -1,35 +1,20 @@ /**************************************************************************** * arch/or1k/src/common/up_pthread_start.c * - * Copyright (C) 2018 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gn...@nuttx.org> + * 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 * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * 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. * ****************************************************************************/ @@ -62,9 +47,10 @@ * pthread. * * Normally the a user-mode start-up stub will also execute before the - * pthread actually starts. See libc/pthread/pthread_startup.c + * pthread actually starts. See libc/pthread/pthread_create.c * * Input Parameters: + * startup - The user-space pthread startup function * entrypt - The user-space address of the pthread entry point * arg - Standard argument for the pthread entry point * @@ -81,7 +67,8 @@ void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) sinfo("entry %p arg %p\n", entrypt, arg); - sys_call2(SYS_pthread_start, (uintptr_t)entrypt, (uintptr_t)arg); + sys_call3(SYS_pthread_start, (uintptr_t)startup, (uintptr_t)entrypt, + (uintptr_t)arg); PANIC(); } diff --git a/arch/risc-v/src/common/riscv_pthread_start.c b/arch/risc-v/src/common/riscv_pthread_start.c index f66b174..6499a47 100644 --- a/arch/risc-v/src/common/riscv_pthread_start.c +++ b/arch/risc-v/src/common/riscv_pthread_start.c @@ -47,9 +47,10 @@ * pthread. * * Normally the a user-mode start-up stub will also execute before the - * pthread actually starts. See libc/pthread/pthread_startup.c + * pthread actually starts. See libc/pthread/pthread_create.c * * Input Parameters: + * startup - The user-space pthread startup function * entrypt - The user-space address of the pthread entry point * arg - Standard argument for the pthread entry point * @@ -60,11 +61,13 @@ * ****************************************************************************/ -void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) +void up_pthread_start(pthread_startroutine_t startup, + pthread_startroutine_t entrypt, pthread_addr_t arg) { /* Let sys_call2() do all of the work */ - sys_call2(SYS_pthread_start, (uintptr_t)entrypt, (uintptr_t)arg); + sys_call3(SYS_pthread_start, (uintptr_t)startup, (uintptr_t)entrypt, + (uintptr_t)arg); PANIC(); } diff --git a/arch/risc-v/src/rv64gc/riscv_swint.c b/arch/risc-v/src/rv64gc/riscv_swint.c index d2900a2..7e6d90b 100644 --- a/arch/risc-v/src/rv64gc/riscv_swint.c +++ b/arch/risc-v/src/rv64gc/riscv_swint.c @@ -1,35 +1,20 @@ /**************************************************************************** * arch/risc-v/src/rv64gc/riscv_swint.c * - * Copyright (C) 2011-2012, 2015, 2019 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gn...@nuttx.org> + * 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 * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * 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. * ****************************************************************************/ @@ -309,21 +294,21 @@ int riscv_swint(int irq, FAR void *context, FAR void *arg) * R2 = arg */ -#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_PTHREAD) +#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_EPC] = (uintptr_t)USERSPACE->pthread_startup & ~1; + regs[REG_EPC] = (uintptr_t)regs[REG_A1] & ~1; /* startup */ - /* Change the parameter ordering to match the expectation of struct - * userpace_s pthread_startup: + /* Change the parameter ordering to match the expectation of the + * user space pthread_startup: */ - regs[REG_A0] = regs[REG_A1]; /* pthread entry */ - regs[REG_A1] = regs[REG_A2]; /* arg */ + regs[REG_A0] = regs[REG_A2]; /* pthread entry */ + regs[REG_A1] = regs[REG_A3]; /* arg */ regs[REG_INT_CTX] &= ~MSTATUS_MPPM; /* User mode */ } break; diff --git a/arch/risc-v/src/rv64gc/svcall.h b/arch/risc-v/src/rv64gc/svcall.h index 690f562..66d1440 100644 --- a/arch/risc-v/src/rv64gc/svcall.h +++ b/arch/risc-v/src/rv64gc/svcall.h @@ -82,6 +82,7 @@ #define SYS_switch_context (2) +#ifndef CONFIG_BUILD_FLAT #ifdef CONFIG_LIB_SYSCALL /* SYS call 3: * @@ -98,15 +99,6 @@ */ #define SYS_task_start (4) - -/* SYS call 5: - * - * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) - * noreturn_function - */ - -#define SYS_pthread_start (5) - /* SYS call 6: * * void signal_handler(_sa_sigaction_t sighand, int signo, @@ -123,6 +115,16 @@ #define SYS_signal_handler_return (7) #endif /* CONFIG_BUILD_PROTECTED */ + +/* SYS call 5: + * + * void up_pthread_start(pthread_startroutine_t entrypt, pthread_addr_t arg) + * noreturn_function + */ + +#define SYS_pthread_start (5) + +#endif /* !CONFIG_BUILD_FLAT */ #endif /* CONFIG_LIB_SYSCALL */ #endif /* __ARCH_RISCV_SRC_RV64GC_SVCALL_H */ diff --git a/boards/arm/imxrt/imxrt1050-evk/kernel/imxrt_userspace.c b/boards/arm/imxrt/imxrt1050-evk/kernel/imxrt_userspace.c index 2654b3b..0f0ee11 100644 --- a/boards/arm/imxrt/imxrt1050-evk/kernel/imxrt_userspace.c +++ b/boards/arm/imxrt/imxrt1050-evk/kernel/imxrt_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/imxrt/imxrt1060-evk/kernel/imxrt_userspace.c b/boards/arm/imxrt/imxrt1060-evk/kernel/imxrt_userspace.c index 3a706f3..e2557c7 100644 --- a/boards/arm/imxrt/imxrt1060-evk/kernel/imxrt_userspace.c +++ b/boards/arm/imxrt/imxrt1060-evk/kernel/imxrt_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/lc823450/lc823450-xgevk/kernel/lc823450_userspace.c b/boards/arm/lc823450/lc823450-xgevk/kernel/lc823450_userspace.c index c6ce154..7eedb98 100644 --- a/boards/arm/lc823450/lc823450-xgevk/kernel/lc823450_userspace.c +++ b/boards/arm/lc823450/lc823450-xgevk/kernel/lc823450_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/lpc17xx_40xx/lpc4088-devkit/kernel/lpc17_40_userspace.c b/boards/arm/lpc17xx_40xx/lpc4088-devkit/kernel/lpc17_40_userspace.c index 3e7a9d4..9b5106c 100644 --- a/boards/arm/lpc17xx_40xx/lpc4088-devkit/kernel/lpc17_40_userspace.c +++ b/boards/arm/lpc17xx_40xx/lpc4088-devkit/kernel/lpc17_40_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/lpc17xx_40xx/lpc4088-quickstart/kernel/lpc17_40_userspace.c b/boards/arm/lpc17xx_40xx/lpc4088-quickstart/kernel/lpc17_40_userspace.c index e7aac74..1f2b3e2 100644 --- a/boards/arm/lpc17xx_40xx/lpc4088-quickstart/kernel/lpc17_40_userspace.c +++ b/boards/arm/lpc17xx_40xx/lpc4088-quickstart/kernel/lpc17_40_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/lpc17xx_40xx/open1788/kernel/lpc17_40_userspace.c b/boards/arm/lpc17xx_40xx/open1788/kernel/lpc17_40_userspace.c index a09ab2d..09450ec 100644 --- a/boards/arm/lpc17xx_40xx/open1788/kernel/lpc17_40_userspace.c +++ b/boards/arm/lpc17xx_40xx/open1788/kernel/lpc17_40_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/lpc17xx_40xx/pnev5180b/kernel/lpc17_40_userspace.c b/boards/arm/lpc17xx_40xx/pnev5180b/kernel/lpc17_40_userspace.c index 8dd5ba6..33d220c 100644 --- a/boards/arm/lpc17xx_40xx/pnev5180b/kernel/lpc17_40_userspace.c +++ b/boards/arm/lpc17xx_40xx/pnev5180b/kernel/lpc17_40_userspace.c @@ -114,9 +114,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/lpc43xx/bambino-200e/kernel/lpc43_userspace.c b/boards/arm/lpc43xx/bambino-200e/kernel/lpc43_userspace.c index 72600e0..e59fd01 100644 --- a/boards/arm/lpc43xx/bambino-200e/kernel/lpc43_userspace.c +++ b/boards/arm/lpc43xx/bambino-200e/kernel/lpc43_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/sam34/sam3u-ek/kernel/sam_userspace.c b/boards/arm/sam34/sam3u-ek/kernel/sam_userspace.c index 55fa413..da2e8d8 100644 --- a/boards/arm/sam34/sam3u-ek/kernel/sam_userspace.c +++ b/boards/arm/sam34/sam3u-ek/kernel/sam_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/samv7/same70-xplained/kernel/sam_userspace.c b/boards/arm/samv7/same70-xplained/kernel/sam_userspace.c index e77b252..2cd4003 100644 --- a/boards/arm/samv7/same70-xplained/kernel/sam_userspace.c +++ b/boards/arm/samv7/same70-xplained/kernel/sam_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/samv7/samv71-xult/kernel/sam_userspace.c b/boards/arm/samv7/samv71-xult/kernel/sam_userspace.c index a63cc7c..01be17d 100644 --- a/boards/arm/samv7/samv71-xult/kernel/sam_userspace.c +++ b/boards/arm/samv7/samv71-xult/kernel/sam_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32/clicker2-stm32/kernel/stm32_userspace.c b/boards/arm/stm32/clicker2-stm32/kernel/stm32_userspace.c index 791543d..2a2521c 100644 --- a/boards/arm/stm32/clicker2-stm32/kernel/stm32_userspace.c +++ b/boards/arm/stm32/clicker2-stm32/kernel/stm32_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32/mikroe-stm32f4/kernel/stm32_userspace.c b/boards/arm/stm32/mikroe-stm32f4/kernel/stm32_userspace.c index fb63a4a..25af38e 100644 --- a/boards/arm/stm32/mikroe-stm32f4/kernel/stm32_userspace.c +++ b/boards/arm/stm32/mikroe-stm32f4/kernel/stm32_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32/olimex-stm32-p407/kernel/stm32_userspace.c b/boards/arm/stm32/olimex-stm32-p407/kernel/stm32_userspace.c index a6d3a3f..efe32d8 100644 --- a/boards/arm/stm32/olimex-stm32-p407/kernel/stm32_userspace.c +++ b/boards/arm/stm32/olimex-stm32-p407/kernel/stm32_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32/omnibusf4/kernel/stm32_userspace.c b/boards/arm/stm32/omnibusf4/kernel/stm32_userspace.c index a3ffc8d..08c02ae 100644 --- a/boards/arm/stm32/omnibusf4/kernel/stm32_userspace.c +++ b/boards/arm/stm32/omnibusf4/kernel/stm32_userspace.c @@ -112,9 +112,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32/stm3240g-eval/kernel/stm32_userspace.c b/boards/arm/stm32/stm3240g-eval/kernel/stm32_userspace.c index 2faeb54..4eafb03 100644 --- a/boards/arm/stm32/stm3240g-eval/kernel/stm32_userspace.c +++ b/boards/arm/stm32/stm3240g-eval/kernel/stm32_userspace.c @@ -94,9 +94,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32/stm32f4discovery/kernel/stm32_userspace.c b/boards/arm/stm32/stm32f4discovery/kernel/stm32_userspace.c index 1ec35a3..ff60953 100644 --- a/boards/arm/stm32/stm32f4discovery/kernel/stm32_userspace.c +++ b/boards/arm/stm32/stm32f4discovery/kernel/stm32_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32f7/stm32f746g-disco/kernel/stm32_userspace.c b/boards/arm/stm32f7/stm32f746g-disco/kernel/stm32_userspace.c index 6061bb2..0ee9fa1 100644 --- a/boards/arm/stm32f7/stm32f746g-disco/kernel/stm32_userspace.c +++ b/boards/arm/stm32f7/stm32f746g-disco/kernel/stm32_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32f7/stm32f769i-disco/kernel/stm32_userspace.c b/boards/arm/stm32f7/stm32f769i-disco/kernel/stm32_userspace.c index 4a66cd7..f85466e 100644 --- a/boards/arm/stm32f7/stm32f769i-disco/kernel/stm32_userspace.c +++ b/boards/arm/stm32f7/stm32f769i-disco/kernel/stm32_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32h7/nucleo-h743zi/kernel/stm32_userspace.c b/boards/arm/stm32h7/nucleo-h743zi/kernel/stm32_userspace.c index d696786..54fb39e 100644 --- a/boards/arm/stm32h7/nucleo-h743zi/kernel/stm32_userspace.c +++ b/boards/arm/stm32h7/nucleo-h743zi/kernel/stm32_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32h7/stm32h747i-disco/kernel/stm32_userspace.c b/boards/arm/stm32h7/stm32h747i-disco/kernel/stm32_userspace.c index 84079d2..4dfafe8 100644 --- a/boards/arm/stm32h7/stm32h747i-disco/kernel/stm32_userspace.c +++ b/boards/arm/stm32h7/stm32h747i-disco/kernel/stm32_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32l4/stm32l476vg-disco/kernel/stm32l4_userspace.c b/boards/arm/stm32l4/stm32l476vg-disco/kernel/stm32l4_userspace.c index f274947..548d619 100644 --- a/boards/arm/stm32l4/stm32l476vg-disco/kernel/stm32l4_userspace.c +++ b/boards/arm/stm32l4/stm32l476vg-disco/kernel/stm32l4_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/stm32l4/stm32l4r9ai-disco/kernel/stm32l4_userspace.c b/boards/arm/stm32l4/stm32l4r9ai-disco/kernel/stm32l4_userspace.c index 802c1a3..ae474c6 100644 --- a/boards/arm/stm32l4/stm32l4r9ai-disco/kernel/stm32l4_userspace.c +++ b/boards/arm/stm32l4/stm32l4r9ai-disco/kernel/stm32l4_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/arm/tiva/lm3s6965-ek/kernel/lm_userspace.c b/boards/arm/tiva/lm3s6965-ek/kernel/lm_userspace.c index 6873dc1..1e6ae7b 100644 --- a/boards/arm/tiva/lm3s6965-ek/kernel/lm_userspace.c +++ b/boards/arm/tiva/lm3s6965-ek/kernel/lm_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/boards/risc-v/k210/maix-bit/kernel/k210_userspace.c b/boards/risc-v/k210/maix-bit/kernel/k210_userspace.c index 0933520..f7ff8e5 100644 --- a/boards/risc-v/k210/maix-bit/kernel/k210_userspace.c +++ b/boards/risc-v/k210/maix-bit/kernel/k210_userspace.c @@ -95,9 +95,6 @@ const struct userspace_s userspace __attribute__ ((section (".userspace"))) = /* Task/thread startup routines */ .task_startup = nxtask_startup, -#ifndef CONFIG_DISABLE_PTHREAD - .pthread_startup = pthread_startup, -#endif /* Signal handler trampoline */ diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 328f593..2bc945f 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -554,9 +554,10 @@ void up_task_start(main_t taskentry, int argc, FAR char *argv[]) * pthread by calling this function. * * Normally the a user-mode start-up stub will also execute before the - * pthread actually starts. See libc/pthread/pthread_startup.c + * pthread actually starts. See libc/pthread/pthread_create.c * * Input Parameters: + * startup - The user-space pthread startup function * entrypt - The user-space address of the pthread entry point * arg - Standard argument for the pthread entry point * @@ -569,7 +570,8 @@ 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_startroutine_t entrypt, pthread_addr_t arg) +void up_pthread_start(pthread_startroutine_t startup, + pthread_startroutine_t entrypt, pthread_addr_t arg); noreturn_function; #endif diff --git a/include/nuttx/pthread.h b/include/nuttx/pthread.h index e92b207..59398c9 100644 --- a/include/nuttx/pthread.h +++ b/include/nuttx/pthread.h @@ -100,7 +100,7 @@ #endif /**************************************************************************** - * Public Data + * Public Types ****************************************************************************/ #ifdef __cplusplus @@ -111,6 +111,10 @@ extern "C" #define EXTERN extern #endif +/**************************************************************************** + * Public Data + ****************************************************************************/ + /* Default pthread attributes. This global can only be shared within the * kernel- or within the user- address space. */ @@ -121,6 +125,30 @@ EXTERN const pthread_attr_t g_default_pthread_attr; * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Name: nx_pthread_create + * + * Description: + * This function creates and activates a new thread with a specified + * attributes. + * + * Input Parameters: + * startup + * thread + * attr + * pthread_entry + * arg + * + * Returned Value: + * OK (0) on success; a (non-negated) errno value on failure. The errno + * variable is not set. + * + ****************************************************************************/ + +int nx_pthread_create(pthread_startroutine_t startup, FAR pthread_t *thread, + FAR const pthread_attr_t *attr, + pthread_startroutine_t entry, pthread_addr_t arg); + #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index e6cb9bd..0fab6b3 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -768,6 +768,7 @@ struct pthread_tcb_s /* Task Management Fields *****************************************************/ + pthread_startroutine_t startup; /* User-space pthread startup function */ pthread_addr_t arg; /* Startup argument */ FAR void *joininfo; /* Detach-able info to support join */ }; diff --git a/include/nuttx/userspace.h b/include/nuttx/userspace.h index 23cb033..4c9811a 100644 --- a/include/nuttx/userspace.h +++ b/include/nuttx/userspace.h @@ -100,13 +100,9 @@ struct userspace_s FAR struct mm_heap_s *us_heap; - /* Task/thread startup routines */ + /* Task startup routine */ CODE void (*task_startup)(main_t entrypt, int argc, FAR char *argv[]); -#ifndef CONFIG_DISABLE_PTHREAD - CODE void (*pthread_startup)(pthread_startroutine_t entrypt, - pthread_addr_t arg); -#endif /* Signal handler trampoline */ @@ -136,26 +132,6 @@ extern "C" * Public Function Prototypes ****************************************************************************/ -/**************************************************************************** - * Name: pthread_startup - * - * Description: - * This function is the user-space, pthread startup function. It is called - * from up_pthread_start() in user-mode. - * - * Input Parameters: - * entrypt - The user-space address of the pthread entry point - * arg - Standard argument for the pthread entry point - * - * Returned Value: - * None. This function does not return. - * - ****************************************************************************/ - -#if !defined(__KERNEL__) && !defined(CONFIG_DISABLE_PTHREAD) -void pthread_startup(pthread_startroutine_t entrypt, pthread_addr_t arg); -#endif - #undef EXTERN #ifdef __cplusplus } diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index ba5c04f..8128776 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -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(pthread_create, 4) + SYSCALL_LOOKUP(nx_pthread_create, 4) SYSCALL_LOOKUP(pthread_detach, 1) SYSCALL_LOOKUP(pthread_exit, 1) SYSCALL_LOOKUP(pthread_getschedparam, 3) diff --git a/libs/libc/pthread/Make.defs b/libs/libc/pthread/Make.defs index 3f62e4e..c625afa 100644 --- a/libs/libc/pthread/Make.defs +++ b/libs/libc/pthread/Make.defs @@ -38,19 +38,18 @@ CSRCS += pthread_barrierattr_init.c pthread_barrierattr_destroy.c CSRCS += pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c CSRCS += pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwait.c CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c -CSRCS += pthread_condinit.c pthread_conddestroy.c pthread_condtimedwait.c +CSRCS += pthread_create.c +CSRCS += pthread_get_stackaddr_np.c pthread_get_stacksize_np.c CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c CSRCS += pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c CSRCS += pthread_mutexattr_setrobust.c pthread_mutexattr_getrobust.c CSRCS += pthread_mutex_lock.c +CSRCS += pthread_once.c pthread_yield.c +CSRCS += pthread_rwlock.c pthread_rwlock_rdlock.c pthread_rwlock_wrlock.c CSRCS += pthread_setcancelstate.c pthread_setcanceltype.c CSRCS += pthread_testcancel.c -CSRCS += pthread_rwlock.c pthread_rwlock_rdlock.c pthread_rwlock_wrlock.c -CSRCS += pthread_once.c pthread_yield.c -CSRCS += pthread_get_stackaddr_np.c pthread_get_stacksize_np.c -CSRCS += pthread_condattr_setclock.c pthread_condattr_getclock.c ifeq ($(CONFIG_SMP),y) CSRCS += pthread_attr_getaffinity.c pthread_attr_setaffinity.c @@ -60,10 +59,6 @@ ifeq ($(CONFIG_PTHREAD_SPINLOCKS),y) CSRCS += pthread_spinlock.c endif -ifeq ($(CONFIG_BUILD_PROTECTED),y) -CSRCS += pthread_startup.c -endif - endif # CONFIG_DISABLE_PTHREAD # Add the pthread directory to the build diff --git a/libs/libc/pthread/pthread_startup.c b/libs/libc/pthread/pthread_create.c similarity index 59% rename from libs/libc/pthread/pthread_startup.c rename to libs/libc/pthread/pthread_create.c index 53be032..9563016 100644 --- a/libs/libc/pthread/pthread_startup.c +++ b/libs/libc/pthread/pthread_create.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libs/libc/pthread/pthread_startup.c + * libs/libc/pthread/pthread_create.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,69 +25,65 @@ #include <nuttx/config.h> #include <pthread.h> -#include <assert.h> - -#include <nuttx/userspace.h> - -#if !defined(CONFIG_BUILD_FLAT) && !defined(__KERNEL__) - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ /**************************************************************************** - * Private Type Declarations + * Private Functions ****************************************************************************/ /**************************************************************************** - * Public Data + * Name: pthread_startup + * + * Description: + * This function is the user-space, pthread startup function. Its purpose + * is to to catch the return from the pthread main function so that + * pthread_exit() can be called from user space + * + * Input Parameters: + * entry - The user-space address of the pthread entry point + * arg - Standard argument for the pthread entry point + * + * Returned Value: + * None. This function does not return. + * ****************************************************************************/ -/**************************************************************************** - * Private Data - ****************************************************************************/ +static void pthread_startup(pthread_startroutine_t entry, + pthread_addr_t arg) +{ + DEBUGASSERT(entry != NULL); -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ + /* Pass control to the thread entry point. Handle any returned value. */ -/**************************************************************************** - * Private Functions - ****************************************************************************/ + pthread_exit(entry(arg)); +} /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: pthread_startup + * Name: pthread_create * * Description: - * This function is the user-space, pthread startup function. It is called - * from up_pthread_start() in user-mode. + * This function creates and activates a new thread with a specified + * attributes. It is simply a wrapper around the nx_pthread_create system + * call. * * Input Parameters: - * entrypt - The user-space address of the pthread entry point - * arg - Standard argument for the pthread entry point + * thread + * attr + * pthread_entry + * arg * * Returned Value: - * None. This function does not return. + * OK (0) on success; a (non-negated) errno value on failure. The errno + * variable is not set. * ****************************************************************************/ -void pthread_startup(pthread_startroutine_t entrypt, pthread_addr_t arg) +int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, + pthread_startroutine_t pthread_entry, pthread_addr_t arg) { - pthread_addr_t exit_status; - - DEBUGASSERT(entrypt); - - /* Pass control to the thread entry point. */ - - exit_status = entrypt(arg); - - /* The pthread has returned */ - - pthread_exit(exit_status); + return nx_pthread_create(pthread_startup, thread, attr, pthread_entry, + arg); } - -#endif /* !CONFIG_BUILD_FLAT && !__KERNEL__ */ diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 46f036a..fbf3dc9 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -63,28 +63,29 @@ const pthread_attr_t g_default_pthread_attr = PTHREAD_ATTR_INITIALIZER; ****************************************************************************/ /**************************************************************************** - * Name: pthread_argsetup + * Name: pthread_tcb_setup * * Description: * This functions sets up parameters in the Task Control Block (TCB) in * preparation for starting a new thread. * - * pthread_argsetup() is called from nxtask_init() and nxtask_start() to + * pthread_tcb_setup() is called from nxtask_init() and nxtask_start() to * create a new task (with arguments cloned via strdup) or pthread_create() * which has one argument passed by value (distinguished by the pthread * boolean argument). * * Input Parameters: - * tcb - Address of the new task's TCB - * arg - The argument to provide to the pthread on startup. + * tcb - Address of the new task's TCB + * startup - User-space pthread startup function + * arg - The argument to provide to the pthread on startup. * * Returned Value: * None * ****************************************************************************/ -static inline void pthread_argsetup(FAR struct pthread_tcb_s *tcb, - pthread_addr_t arg) +static inline void pthread_tcb_setup(FAR struct pthread_tcb_s *tcb, + pthread_addr_t arg) { #if CONFIG_TASK_NAME_SIZE > 0 /* Copy the pthread name into the TCB */ @@ -97,7 +98,8 @@ static inline void pthread_argsetup(FAR struct pthread_tcb_s *tcb, * type wrapped by pthread_addr_t is unknown. */ - tcb->arg = arg; + tcb->startup = startup; + tcb->arg = arg; } /**************************************************************************** @@ -151,7 +153,7 @@ static void pthread_start(void) FAR struct join_s *pjoin = (FAR struct join_s *)ptcb->joininfo; pthread_addr_t exit_status; - DEBUGASSERT(group && pjoin); + DEBUGASSERT(group != NULL && pjoin != NULL); /* Successfully spawned, add the pjoin to our data set. */ @@ -179,15 +181,18 @@ static void pthread_start(void) * to switch to user-mode before calling into the pthread. */ + DEBUGASSERT(ptcb->startup != NULL && ptcb->cmn.entry.pthread != NULL); + #ifdef CONFIG_BUILD_FLAT - exit_status = (*ptcb->cmn.entry.pthread)(ptcb->arg); + exit_status = ptcb->startup(ptcb->cmn.entry.pthread, ptcb->arg); #else - up_pthread_start(ptcb->cmn.entry.pthread, ptcb->arg); + up_pthread_start(ptcb->startup, ptcb->cmn.entry.pthread, ptcb->arg); exit_status = NULL; #endif - /* The thread has returned (should never happen in the kernel mode case) */ + /* The thread has returned (should never happen) */ + DEBUGPANIC(); pthread_exit(exit_status); } @@ -196,13 +201,14 @@ static void pthread_start(void) ****************************************************************************/ /**************************************************************************** - * Name: pthread_create + * Name: nx_pthread_create * * Description: * This function creates and activates a new thread with a specified * attributes. * * Input Parameters: + * startup * thread * attr * start_routine @@ -214,8 +220,9 @@ static void pthread_start(void) * ****************************************************************************/ -int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, - pthread_startroutine_t start_routine, pthread_addr_t arg) +int nx_pthread_create(pthread_startroutine_t startup, FAR pthread_t *thread, + FAR const pthread_attr_t *attr, + pthread_startroutine_t entry, pthread_addr_t arg); { FAR struct pthread_tcb_s *ptcb; FAR struct join_s *pjoin; @@ -226,6 +233,8 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, int ret; bool group_joined = false; + DEBUGASSERT(startup != NULL); + /* If attributes were not supplied, use the default attributes */ if (!attr) @@ -426,7 +435,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, * passed by value */ - pthread_argsetup(ptcb, arg); + pthread_tcb_setup(ptcb, startup, arg); /* Join the parent's task group */ diff --git a/syscall/syscall.csv b/syscall/syscall.csv index c50b90c..93766a9 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -66,6 +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","FAR pthread_t *","pthread_startroutine_t","FAR const pthread_attr_t *","pthread_startroutine_t","pthread_addr_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 *" @@ -88,7 +89,6 @@ "pthread_cond_clockwait","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *","FAR pthread_mutex_t *","clockid_t","FAR const struct timespec *" "pthread_cond_signal","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *" "pthread_cond_wait","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_cond_t *","FAR pthread_mutex_t *" -"pthread_create","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","FAR pthread_t *","FAR const pthread_attr_t *","pthread_startroutine_t","pthread_addr_t" "pthread_detach","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","int","pthread_t" "pthread_exit","pthread.h","!defined(CONFIG_DISABLE_PTHREAD)","void","pthread_addr_t" "pthread_getaffinity_np","pthread.h","!defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_SMP)","int","pthread_t","size_t","FAR cpu_set_t*"