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*"

Reply via email to