mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 21:47:59 +00:00
fix: test: Add support for small stack size for threads
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. Merge branch 'aram/isc-thread-stack-size-small' into 'main' See merge request isc-projects/bind9!10778
This commit is contained in:
commit
f635bf4df8
@ -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);
|
||||
|
10
lib/isc/os.c
10
lib/isc/os.c
@ -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);
|
||||
}
|
||||
|
@ -40,12 +40,10 @@
|
||||
|
||||
#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);
|
||||
|
@ -17,6 +17,20 @@
|
||||
|
||||
/*! \file */
|
||||
|
||||
/*
|
||||
* The current default stack sizes are as follows:
|
||||
* - Linux glibc: 8MB
|
||||
* - Linux musl: 128kB
|
||||
* - FreeBSD: 2MB
|
||||
* - OpenBSD: 512kB
|
||||
* - NetBSD: 4MB
|
||||
*/
|
||||
#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);
|
||||
|
||||
|
34
meson.build
34
meson.build
@ -453,16 +453,6 @@ foreach fn, header : {
|
||||
'flockfile': '#include <stdio.h>',
|
||||
'getc_unlocked': '#include <stdio.h>',
|
||||
|
||||
# Thread control
|
||||
'pthread_attr_getstacksize': '#include <pthread.h>',
|
||||
'pthread_attr_setstacksize': '#include <pthread.h>',
|
||||
'pthread_barrier_init': '#include <pthread.h>',
|
||||
'pthread_set_name_np': '#include <pthread.h>',
|
||||
'pthread_setname_np': '#include <pthread.h>',
|
||||
'pthread_spin_init': '#include <pthread.h>',
|
||||
'pthread_yield': '#include <pthread.h>',
|
||||
'pthread_yield_np': '#include <pthread.h>',
|
||||
|
||||
# Processor control
|
||||
'cpuset_getaffinity': '#include <sys/cpuset.h>',
|
||||
'sched_getaffinity': '#include <sched.h>',
|
||||
@ -524,9 +514,31 @@ endif
|
||||
###
|
||||
null_dep = dependency('', required: false)
|
||||
|
||||
thread_dep = dependency('threads')
|
||||
m_dep = cc.find_library('m', required: false)
|
||||
|
||||
## Threads
|
||||
thread_dep = dependency('threads')
|
||||
|
||||
foreach fn : [
|
||||
'pthread_attr_getstacksize',
|
||||
'pthread_attr_setstacksize',
|
||||
'pthread_barrier_init',
|
||||
'pthread_set_name_np',
|
||||
'pthread_setname_np',
|
||||
'pthread_spin_init',
|
||||
'pthread_yield',
|
||||
'pthread_yield_np',
|
||||
]
|
||||
if cc.has_function(
|
||||
fn,
|
||||
prefix: '#include <pthread.h>',
|
||||
args: sys_defines,
|
||||
dependencies: thread_dep,
|
||||
)
|
||||
config.set('HAVE_@0@'.format(fn.to_upper()), 1)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
## OpenSSL
|
||||
openssl_dep = [
|
||||
dependency('libcrypto', version: '>=1.1.1'),
|
||||
|
@ -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();
|
||||
|
@ -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 *
|
||||
|
@ -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("a, 100);
|
||||
static qthreadinfo_t qtis[10];
|
||||
isc_thread_t threads[10];
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 *
|
||||
|
Loading…
x
Reference in New Issue
Block a user