This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 439f658351c94b8e5eb97f0da8e57ed0213c0ace
Author: Marco Casaroli <[email protected]>
AuthorDate: Sun Oct 18 20:06:23 2026 +0200

    libc, sched, binfmt: Use RLIMIT_STACK for the default stack size.
    
    A process could not choose the default stack size of the threads and
    programs that it starts: it was always CONFIG_PTHREAD_STACK_DEFAULT for
    a thread and CONFIG_ELF_STACKSIZE for a program.
    
    When the RLIMIT_STACK soft limit is set, it is the default stack size of
    a new thread (pthread_attr_init() and pthread_create() without
    attributes) and the stack size of a new ELF program that does not set
    nx_stacksize, as on Linux.  lib_get_stacksize() gives this size; it keeps
    the value between PTHREAD_STACK_MIN and the largest stack that a task can
    have (TLS_MAXSTACK with CONFIG_TLS_ALIGNED).  Without a limit, the
    defaults do not change.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 binfmt/elf.c                                       |  5 +-
 include/nuttx/lib/lib.h                            |  4 ++
 libs/libc/misc/CMakeLists.txt                      |  1 +
 libs/libc/misc/Make.defs                           |  2 +-
 .../lib_getstacksize.c}                            | 64 ++++++++--------------
 libs/libc/pthread/pthread_attr_init.c              |  5 ++
 sched/pthread/pthread_create.c                     |  4 ++
 7 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/binfmt/elf.c b/binfmt/elf.c
index c6ec0eeb907..ca24544a08b 100644
--- a/binfmt/elf.c
+++ b/binfmt/elf.c
@@ -36,6 +36,7 @@
 #include <nuttx/arch.h>
 #include <nuttx/binfmt/binfmt.h>
 #include <nuttx/kmalloc.h>
+#include <nuttx/lib/lib.h>
 
 #include "binfmt.h"
 
@@ -190,7 +191,9 @@ static int elf_loadbinary(FAR struct binary_s *binp,
     }
   else
     {
-      binp->stacksize = CONFIG_ELF_STACKSIZE;
+      /* The RLIMIT_STACK soft limit of the caller, if it set one */
+
+      binp->stacksize = lib_get_stacksize(CONFIG_ELF_STACKSIZE);
     }
 
   ret = libelf_findsymbol(&loadinfo, "nx_priority", &sym);
diff --git a/include/nuttx/lib/lib.h b/include/nuttx/lib/lib.h
index c6d7e7ada8d..b2cd716bb83 100644
--- a/include/nuttx/lib/lib.h
+++ b/include/nuttx/lib/lib.h
@@ -120,6 +120,10 @@ FAR struct file_struct *lib_get_stream(int fd);
 
 unsigned long nrand(unsigned long limit);
 
+/* Functions defined in lib_getstacksize.c **********************************/
+
+size_t lib_get_stacksize(size_t size);
+
 /* Functions defined in lib_tempbuffer.c ************************************/
 
 #ifdef CONFIG_LIBC_TEMPBUFFER
diff --git a/libs/libc/misc/CMakeLists.txt b/libs/libc/misc/CMakeLists.txt
index c226fd40e8c..afa2b1f6630 100644
--- a/libs/libc/misc/CMakeLists.txt
+++ b/libs/libc/misc/CMakeLists.txt
@@ -48,6 +48,7 @@ list(
   lib_utimensat.c
   lib_mallopt.c
   lib_getnprocs.c
+  lib_getstacksize.c
   lib_mntent.c)
 
 if(CONFIG_HAVE_CXXINITIALIZE)
diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs
index 1a1e1f606a6..ecca32f3d1e 100644
--- a/libs/libc/misc/Make.defs
+++ b/libs/libc/misc/Make.defs
@@ -27,7 +27,7 @@ CSRCS += lib_utsname.c lib_getrandom.c lib_xorshift128.c 
lib_tea_encrypt.c
 CSRCS += lib_tea_decrypt.c lib_impure.c lib_memfd.c
 CSRCS += lib_mutex.c lib_fchmodat.c lib_fstatat.c lib_getfullpath.c
 CSRCS += lib_openat.c lib_mkdirat.c lib_utimensat.c lib_mallopt.c
-CSRCS += lib_idr.c lib_getnprocs.c lib_mntent.c
+CSRCS += lib_idr.c lib_getnprocs.c lib_getstacksize.c lib_mntent.c
 
 ifeq ($(CONFIG_HAVE_CXXINITIALIZE),y)
 CSRCS += lib_cxx_initialize.c
diff --git a/libs/libc/pthread/pthread_attr_init.c 
b/libs/libc/misc/lib_getstacksize.c
similarity index 55%
copy from libs/libc/pthread/pthread_attr_init.c
copy to libs/libc/misc/lib_getstacksize.c
index 8622ca1ee7f..772f6e86fa8 100644
--- a/libs/libc/pthread/pthread_attr_init.c
+++ b/libs/libc/misc/lib_getstacksize.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * libs/libc/pthread/pthread_attr_init.c
+ * libs/libc/misc/lib_getstacksize.c
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -26,68 +26,52 @@
 
 #include <nuttx/config.h>
 
+#include <sys/resource.h>
 #include <pthread.h>
-#include <string.h>
-#include <nuttx/debug.h>
-#include <errno.h>
 
-#include <nuttx/pthread.h>
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/* Default pthread attributes (see include/nuttx/pthread.h).  When configured
- * to build separate kernel- and user-address spaces, this global is
- * duplicated in each address spaced.  This copy can only be shared within
- * the user address space.
- */
-
-#if !defined(CONFIG_BUILD_FLAT) && !defined(__KERNEL__)
-const pthread_attr_t g_default_pthread_attr = PTHREAD_ATTR_INITIALIZER;
-#endif
+#include <nuttx/lib/lib.h>
+#include <nuttx/tls.h>
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name:  pthread_attr_init
+ * Name: lib_get_stacksize
  *
  * Description:
- *   Initializes a thread attributes object (attr) with
- *   default values for all of the individual attributes
- *   used by a given implementation.
+ *   Return the default stack size of a new thread or program: the
+ *   RLIMIT_STACK soft limit, kept between PTHREAD_STACK_MIN and the largest
+ *   stack that a task can have, or the given size if there is no limit.
  *
  * Input Parameters:
- *   attr
+ *   size - The stack size to use if there is no limit.
  *
  * Returned Value:
- *   0 on success, otherwise an error number
- *
- * Assumptions:
+ *   The stack size in bytes.
  *
  ****************************************************************************/
 
-int pthread_attr_init(FAR pthread_attr_t *attr)
+size_t lib_get_stacksize(size_t size)
 {
-  int ret = OK;
+  struct rlimit rlim;
 
-  linfo("attr=%p\n", attr);
-  if (!attr)
+  if (getrlimit(RLIMIT_STACK, &rlim) < 0 || rlim.rlim_cur == RLIM_INFINITY)
     {
-      ret = ENOMEM;
+      return size;
     }
-  else
+
+  if (rlim.rlim_cur < PTHREAD_STACK_MIN)
     {
-      /* Set the child thread priority to be the default
-       * priority. Set the child stack size to some arbitrary
-       * default value.
-       */
+      rlim.rlim_cur = PTHREAD_STACK_MIN;
+    }
 
-      memcpy(attr, &g_default_pthread_attr, sizeof(pthread_attr_t));
+#ifdef CONFIG_TLS_ALIGNED
+  if (rlim.rlim_cur > TLS_MAXSTACK)
+    {
+      rlim.rlim_cur = TLS_MAXSTACK;
     }
+#endif
 
-  linfo("Returning %d\n", ret);
-  return ret;
+  return rlim.rlim_cur;
 }
diff --git a/libs/libc/pthread/pthread_attr_init.c 
b/libs/libc/pthread/pthread_attr_init.c
index 8622ca1ee7f..1b2aa0d7616 100644
--- a/libs/libc/pthread/pthread_attr_init.c
+++ b/libs/libc/pthread/pthread_attr_init.c
@@ -31,6 +31,7 @@
 #include <nuttx/debug.h>
 #include <errno.h>
 
+#include <nuttx/lib/lib.h>
 #include <nuttx/pthread.h>
 
 /****************************************************************************
@@ -86,6 +87,10 @@ int pthread_attr_init(FAR pthread_attr_t *attr)
        */
 
       memcpy(attr, &g_default_pthread_attr, sizeof(pthread_attr_t));
+
+      /* The RLIMIT_STACK soft limit gives the default stack size */
+
+      attr->stacksize = lib_get_stacksize(attr->stacksize);
     }
 
   linfo("Returning %d\n", ret);
diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c
index 684495b101c..8b245239dd8 100644
--- a/sched/pthread/pthread_create.c
+++ b/sched/pthread/pthread_create.c
@@ -40,6 +40,7 @@
 #include <nuttx/arch.h>
 #include <nuttx/semaphore.h>
 #include <nuttx/kmalloc.h>
+#include <nuttx/lib/lib.h>
 #include <nuttx/pthread.h>
 
 #include "task/task.h"
@@ -207,6 +208,9 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR 
pthread_t *thread,
           default_attr.priority = parent->sched_priority;
         }
 
+      /* The RLIMIT_STACK soft limit gives the default stack size */
+
+      default_attr.stacksize = lib_get_stacksize(default_attr.stacksize);
       attr = &default_attr;
     }
 

Reply via email to