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; }
