]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add support for setting thread stack size
authorOndřej Surý <ondrej@isc.org>
Mon, 4 Aug 2025 15:03:42 +0000 (17:03 +0200)
committerOndřej Surý <ondrej@isc.org>
Tue, 5 Aug 2025 08:46:09 +0000 (10:46 +0200)
When running the isc_quota unit test with less than usual amount of
RAM (e.g. in a CI for architectures with 32 bits of address space),
the pthread_create() function fails with the "Resource temporarily
unavailable (11):" error code.

Add functions to get and set the thread stack size (if requested),
and use these to set the thread stack size to smaller value in the
isc_quota unit test.

lib/isc/include/isc/thread.h
lib/isc/os.c
lib/isc/thread.c
lib/isc/thread_p.h
tests/isc/mem_test.c
tests/isc/mutex_test.c
tests/isc/quota_test.c
tests/isc/rwlock_test.c
tests/isc/spinlock_test.c

index 17c0fff9b18fa9b205af910a9c8eee44fd49f674..1a9b0917f035fc3596367bd2cd861f9607537474 100644 (file)
@@ -52,3 +52,8 @@ void
 isc_thread_setname(isc_thread_t thread, const char *name);
 
 #define isc_thread_self (uintptr_t)pthread_self
+
+size_t
+isc_thread_getstacksize(void);
+void
+isc_thread_setstacksize(size_t stacksize);
index b50248d59196f62f28c8381b2bcba24fb80c511f..8c3ced67c4bbc398f6cb289669b1791051bb7e82 100644 (file)
@@ -20,6 +20,7 @@
 #include <isc/uv.h>
 
 #include "os_p.h"
+#include "thread_p.h"
 
 static unsigned int isc__os_ncpus = 0;
 static unsigned long isc__os_cacheline = ISC_OS_CACHELINE_SIZE;
@@ -201,9 +202,16 @@ isc__os_initialize(void) {
                isc__os_cacheline = s;
        }
 #endif
+
+       pthread_attr_init(&isc__thread_attr);
+
+       size_t stacksize = isc_thread_getstacksize();
+       if (stacksize != 0 && stacksize < THREAD_MINSTACKSIZE) {
+               isc_thread_setstacksize(THREAD_MINSTACKSIZE);
+       }
 }
 
 void
 isc__os_shutdown(void) {
-       /* empty, but defined for completeness */;
+       pthread_attr_destroy(&isc__thread_attr);
 }
index 5841a467fea6116f0e2da2a870bcfe954a85c7ba..ea9e1fb028a0589ed11241b41e4b6ac0a24e8557 100644 (file)
 
 #include "thread_p.h"
 
-#ifndef THREAD_MINSTACKSIZE
-#define THREAD_MINSTACKSIZE (1024U * 1024)
-#endif /* ifndef THREAD_MINSTACKSIZE */
-
 static struct call_rcu_data *isc__thread_call_rcu_data = NULL;
 
+pthread_attr_t isc__thread_attr;
+
 /*
  * We can't use isc_mem API here, because it's called too early and the
  * memory debugging flags can be changed later causing mismatch between flags
@@ -126,28 +124,9 @@ isc_thread_main(isc_threadfunc_t func, void *arg) {
 
 void
 isc_thread_create(isc_threadfunc_t func, void *arg, isc_thread_t *thread) {
-       int ret;
-       pthread_attr_t attr;
-
-       pthread_attr_init(&attr);
-
-#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
-       defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
-       size_t stacksize;
-       ret = pthread_attr_getstacksize(&attr, &stacksize);
-       PTHREADS_RUNTIME_CHECK(pthread_attr_getstacksize, ret);
-
-       if (stacksize < THREAD_MINSTACKSIZE) {
-               ret = pthread_attr_setstacksize(&attr, THREAD_MINSTACKSIZE);
-               PTHREADS_RUNTIME_CHECK(pthread_attr_setstacksize, ret);
-       }
-#endif /* if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
-       * defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) */
-
-       ret = pthread_create(thread, &attr, thread_run, thread_wrap(func, arg));
+       int ret = pthread_create(thread, &isc__thread_attr, thread_run,
+                                thread_wrap(func, arg));
        PTHREADS_RUNTIME_CHECK(pthread_create, ret);
-
-       pthread_attr_destroy(&attr);
 }
 
 void
@@ -188,6 +167,26 @@ isc_thread_yield(void) {
 #endif /* if defined(HAVE_SCHED_YIELD) */
 }
 
+size_t
+isc_thread_getstacksize(void) {
+       size_t stacksize = 0;
+
+#if HAVE_PTHREAD_ATTR_GETSTACKSIZE
+       int ret = pthread_attr_getstacksize(&isc__thread_attr, &stacksize);
+       PTHREADS_RUNTIME_CHECK(pthread_attr_getstacksize, ret);
+#endif /* HAVE_PTHREAD_ATTR_GETSTACKSIZE */
+
+       return stacksize;
+}
+
+void
+isc_thread_setstacksize(size_t stacksize ISC_ATTR_UNUSED) {
+#if HAVE_PTHREAD_ATTR_SETSTACKSIZE
+       int ret = pthread_attr_setstacksize(&isc__thread_attr, stacksize);
+       PTHREADS_RUNTIME_CHECK(pthread_attr_setstacksize, ret);
+#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
+}
+
 void
 isc__thread_initialize(void) {
        isc__thread_call_rcu_data = create_call_rcu_data(0, -1);
index 6ed32cd984cf34d468c32edb6aafcbf59f019709..0fd02a9684ac0724fd2afa82774e75ddf57c13fc 100644 (file)
 
 /*! \file */
 
+#ifndef THREAD_MINSTACKSIZE
+#define THREAD_MINSTACKSIZE (1U * 1024 * 1024)
+#endif /* ifndef THREAD_MINSTACKSIZE */
+
+extern pthread_attr_t isc__thread_attr;
+
 void
 isc__thread_initialize(void);
 
index a19a8ee9649d2f3e5734538eae56abc02190565a..7cb7e06a8d3b71621214666799c9a6978805f84b 100644 (file)
@@ -37,6 +37,7 @@
 #include <isc/util.h>
 
 #include "mem_p.h"
+#include "thread_p.h"
 
 #include <tests/isc.h>
 
@@ -516,6 +517,8 @@ ISC_RUN_TEST_IMPL(isc_mem_benchmark) {
        isc_time_t ts1, ts2;
        double t;
 
+       isc_thread_setstacksize(THREAD_MINSTACKSIZE);
+
        atomic_init(&mem_size, ITEM_SIZE);
 
        ts1 = isc_time_now();
index eb09ce04433a524c93687c445cfa6847f847ea24..44c4b0ef29583386bd469de26d7b8855374e0a6d 100644 (file)
@@ -36,6 +36,8 @@
 #include <isc/time.h>
 #include <isc/util.h>
 
+#include "thread_p.h"
+
 #include <tests/isc.h>
 
 static unsigned int loops = 100;
@@ -124,6 +126,8 @@ ISC_RUN_TEST_IMPL(isc_mutex_benchmark) {
        size_t cont;
        int r;
 
+       isc_thread_setstacksize(THREAD_MINSTACKSIZE);
+
        memset(threads, 0, sizeof(*threads) * workers);
 
        expected_counter = ITERS * workers * loops *
index 6b9677978df32850ad14b8bc1a0919446fd849bf..dbc28015e4fcfe5f5dfa97c2a6225e6424e1a7c9 100644 (file)
@@ -32,6 +32,8 @@
 #include <isc/util.h>
 #include <isc/uv.h>
 
+#include "thread_p.h"
+
 #include <tests/isc.h>
 
 isc_quota_t quota;
@@ -268,9 +270,10 @@ quota_thread(void *qtip) {
 }
 
 ISC_RUN_TEST_IMPL(isc_quota_callback_mt) {
-       UNUSED(state);
        int i;
 
+       isc_thread_setstacksize(THREAD_MINSTACKSIZE);
+
        isc_quota_init(&quota, 100);
        static qthreadinfo_t qtis[10];
        isc_thread_t threads[10];
index efc9827c2fa2b3549c150a4add24390e6067a799..a26334c92aa6b0a58ce48333799e6759a9801a01 100644 (file)
@@ -37,6 +37,8 @@
 #include <isc/time.h>
 #include <isc/util.h>
 
+#include "thread_p.h"
+
 #include <tests/isc.h>
 
 static unsigned int loops = 100;
@@ -255,6 +257,8 @@ isc__rwlock_benchmark(isc_thread_t *threads, unsigned int nthreads,
        int dc;
        size_t cont;
 
+       isc_thread_setstacksize(THREAD_MINSTACKSIZE);
+
        expected_counter = ITERS * nthreads * loops *
                           ((CNT_MAX - CNT_MIN) / DC + 1);
 
index 6c739a713d9cd398461465a11219dab94cb326d4..bd9fc37d0d1cdbabb374341e27e15d0406209ce5 100644 (file)
@@ -42,6 +42,8 @@
 #include <isc/time.h>
 #include <isc/util.h>
 
+#include "thread_p.h"
+
 #include <tests/isc.h>
 
 static unsigned int loops = 100;
@@ -133,6 +135,8 @@ ISC_RUN_TEST_IMPL(isc_spinlock_benchmark) {
        int dc;
        size_t cont;
 
+       isc_thread_setstacksize(THREAD_MINSTACKSIZE);
+
        memset(threads, 0, sizeof(*threads) * workers);
 
        expected_counter = ITERS * workers * loops *