mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 10:10:06 +00:00
Add support for setting thread stack size
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.
This commit is contained in:
parent
f22c980173
commit
96dad96ae5
@ -52,3 +52,8 @@ void
|
|||||||
isc_thread_setname(isc_thread_t thread, const char *name);
|
isc_thread_setname(isc_thread_t thread, const char *name);
|
||||||
|
|
||||||
#define isc_thread_self (uintptr_t)pthread_self
|
#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 <isc/uv.h>
|
||||||
|
|
||||||
#include "os_p.h"
|
#include "os_p.h"
|
||||||
|
#include "thread_p.h"
|
||||||
|
|
||||||
static unsigned int isc__os_ncpus = 0;
|
static unsigned int isc__os_ncpus = 0;
|
||||||
static unsigned long isc__os_cacheline = ISC_OS_CACHELINE_SIZE;
|
static unsigned long isc__os_cacheline = ISC_OS_CACHELINE_SIZE;
|
||||||
@ -201,9 +202,16 @@ isc__os_initialize(void) {
|
|||||||
isc__os_cacheline = s;
|
isc__os_cacheline = s;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
void
|
||||||
isc__os_shutdown(void) {
|
isc__os_shutdown(void) {
|
||||||
/* empty, but defined for completeness */;
|
pthread_attr_destroy(&isc__thread_attr);
|
||||||
}
|
}
|
||||||
|
@ -40,12 +40,10 @@
|
|||||||
|
|
||||||
#include "thread_p.h"
|
#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;
|
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
|
* 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
|
* 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
|
void
|
||||||
isc_thread_create(isc_threadfunc_t func, void *arg, isc_thread_t *thread) {
|
isc_thread_create(isc_threadfunc_t func, void *arg, isc_thread_t *thread) {
|
||||||
int ret;
|
int ret = pthread_create(thread, &isc__thread_attr, thread_run,
|
||||||
pthread_attr_t attr;
|
thread_wrap(func, arg));
|
||||||
|
|
||||||
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));
|
|
||||||
PTHREADS_RUNTIME_CHECK(pthread_create, ret);
|
PTHREADS_RUNTIME_CHECK(pthread_create, ret);
|
||||||
|
|
||||||
pthread_attr_destroy(&attr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -188,6 +167,26 @@ isc_thread_yield(void) {
|
|||||||
#endif /* if defined(HAVE_SCHED_YIELD) */
|
#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
|
void
|
||||||
isc__thread_initialize(void) {
|
isc__thread_initialize(void) {
|
||||||
isc__thread_call_rcu_data = create_call_rcu_data(0, -1);
|
isc__thread_call_rcu_data = create_call_rcu_data(0, -1);
|
||||||
|
@ -17,6 +17,12 @@
|
|||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
|
#ifndef THREAD_MINSTACKSIZE
|
||||||
|
#define THREAD_MINSTACKSIZE (1U * 1024 * 1024)
|
||||||
|
#endif /* ifndef THREAD_MINSTACKSIZE */
|
||||||
|
|
||||||
|
extern pthread_attr_t isc__thread_attr;
|
||||||
|
|
||||||
void
|
void
|
||||||
isc__thread_initialize(void);
|
isc__thread_initialize(void);
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
|
||||||
#include "mem_p.h"
|
#include "mem_p.h"
|
||||||
|
#include "thread_p.h"
|
||||||
|
|
||||||
#include <tests/isc.h>
|
#include <tests/isc.h>
|
||||||
|
|
||||||
@ -516,6 +517,8 @@ ISC_RUN_TEST_IMPL(isc_mem_benchmark) {
|
|||||||
isc_time_t ts1, ts2;
|
isc_time_t ts1, ts2;
|
||||||
double t;
|
double t;
|
||||||
|
|
||||||
|
isc_thread_setstacksize(THREAD_MINSTACKSIZE);
|
||||||
|
|
||||||
atomic_init(&mem_size, ITEM_SIZE);
|
atomic_init(&mem_size, ITEM_SIZE);
|
||||||
|
|
||||||
ts1 = isc_time_now();
|
ts1 = isc_time_now();
|
||||||
|
@ -36,6 +36,8 @@
|
|||||||
#include <isc/time.h>
|
#include <isc/time.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
#include "thread_p.h"
|
||||||
|
|
||||||
#include <tests/isc.h>
|
#include <tests/isc.h>
|
||||||
|
|
||||||
static unsigned int loops = 100;
|
static unsigned int loops = 100;
|
||||||
@ -124,6 +126,8 @@ ISC_RUN_TEST_IMPL(isc_mutex_benchmark) {
|
|||||||
size_t cont;
|
size_t cont;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
isc_thread_setstacksize(THREAD_MINSTACKSIZE);
|
||||||
|
|
||||||
memset(threads, 0, sizeof(*threads) * workers);
|
memset(threads, 0, sizeof(*threads) * workers);
|
||||||
|
|
||||||
expected_counter = ITERS * workers * loops *
|
expected_counter = ITERS * workers * loops *
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
#include <isc/uv.h>
|
#include <isc/uv.h>
|
||||||
|
|
||||||
|
#include "thread_p.h"
|
||||||
|
|
||||||
#include <tests/isc.h>
|
#include <tests/isc.h>
|
||||||
|
|
||||||
isc_quota_t quota;
|
isc_quota_t quota;
|
||||||
@ -268,9 +270,10 @@ quota_thread(void *qtip) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ISC_RUN_TEST_IMPL(isc_quota_callback_mt) {
|
ISC_RUN_TEST_IMPL(isc_quota_callback_mt) {
|
||||||
UNUSED(state);
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
isc_thread_setstacksize(THREAD_MINSTACKSIZE);
|
||||||
|
|
||||||
isc_quota_init("a, 100);
|
isc_quota_init("a, 100);
|
||||||
static qthreadinfo_t qtis[10];
|
static qthreadinfo_t qtis[10];
|
||||||
isc_thread_t threads[10];
|
isc_thread_t threads[10];
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
#include <isc/time.h>
|
#include <isc/time.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
#include "thread_p.h"
|
||||||
|
|
||||||
#include <tests/isc.h>
|
#include <tests/isc.h>
|
||||||
|
|
||||||
static unsigned int loops = 100;
|
static unsigned int loops = 100;
|
||||||
@ -255,6 +257,8 @@ isc__rwlock_benchmark(isc_thread_t *threads, unsigned int nthreads,
|
|||||||
int dc;
|
int dc;
|
||||||
size_t cont;
|
size_t cont;
|
||||||
|
|
||||||
|
isc_thread_setstacksize(THREAD_MINSTACKSIZE);
|
||||||
|
|
||||||
expected_counter = ITERS * nthreads * loops *
|
expected_counter = ITERS * nthreads * loops *
|
||||||
((CNT_MAX - CNT_MIN) / DC + 1);
|
((CNT_MAX - CNT_MIN) / DC + 1);
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
#include <isc/time.h>
|
#include <isc/time.h>
|
||||||
#include <isc/util.h>
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
#include "thread_p.h"
|
||||||
|
|
||||||
#include <tests/isc.h>
|
#include <tests/isc.h>
|
||||||
|
|
||||||
static unsigned int loops = 100;
|
static unsigned int loops = 100;
|
||||||
@ -133,6 +135,8 @@ ISC_RUN_TEST_IMPL(isc_spinlock_benchmark) {
|
|||||||
int dc;
|
int dc;
|
||||||
size_t cont;
|
size_t cont;
|
||||||
|
|
||||||
|
isc_thread_setstacksize(THREAD_MINSTACKSIZE);
|
||||||
|
|
||||||
memset(threads, 0, sizeof(*threads) * workers);
|
memset(threads, 0, sizeof(*threads) * workers);
|
||||||
|
|
||||||
expected_counter = ITERS * workers * loops *
|
expected_counter = ITERS * workers * loops *
|
||||||
|
Loading…
x
Reference in New Issue
Block a user