summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/libntp/work_thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/libntp/work_thread.c')
-rw-r--r--contrib/ntp/libntp/work_thread.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/contrib/ntp/libntp/work_thread.c b/contrib/ntp/libntp/work_thread.c
index 49e90c1..11e3267 100644
--- a/contrib/ntp/libntp/work_thread.c
+++ b/contrib/ntp/libntp/work_thread.c
@@ -25,13 +25,38 @@
#define CHILD_EXIT_REQ ((blocking_pipe_header *)(intptr_t)-1)
#define CHILD_GONE_RESP CHILD_EXIT_REQ
+/* Queue size increments:
+ * The request queue grows a bit faster than the response queue -- the
+ * deamon can push requests and pull results faster on avarage than the
+ * worker can process requests and push results... If this really pays
+ * off is debatable.
+ */
#define WORKITEMS_ALLOC_INC 16
#define RESPONSES_ALLOC_INC 4
+/* Fiddle with min/max stack sizes. 64kB minimum seems to work, so we
+ * set the maximum to 256kB. If the minimum goes below the
+ * system-defined minimum stack size, we have to adjust accordingly.
+ */
#ifndef THREAD_MINSTACKSIZE
-#define THREAD_MINSTACKSIZE (64U * 1024)
+# define THREAD_MINSTACKSIZE (64U * 1024)
+#endif
+#ifndef __sun
+#if defined(PTHREAD_STACK_MIN) && THREAD_MINSTACKSIZE < PTHREAD_STACK_MIN
+# undef THREAD_MINSTACKSIZE
+# define THREAD_MINSTACKSIZE PTHREAD_STACK_MIN
+#endif
#endif
+#ifndef THREAD_MAXSTACKSIZE
+# define THREAD_MAXSTACKSIZE (256U * 1024)
+#endif
+#if THREAD_MAXSTACKSIZE < THREAD_MINSTACKSIZE
+# undef THREAD_MAXSTACKSIZE
+# define THREAD_MAXSTACKSIZE THREAD_MINSTACKSIZE
+#endif
+
+
#ifdef SYS_WINNT
# define thread_exit(c) _endthreadex(c)
@@ -148,15 +173,19 @@ ensure_workitems_empty_slot(
size_t new_alloc;
size_t slots_used;
+ size_t sidx;
slots_used = c->head_workitem - c->tail_workitem;
if (slots_used >= c->workitems_alloc) {
new_alloc = c->workitems_alloc + WORKITEMS_ALLOC_INC;
c->workitems = erealloc(c->workitems, new_alloc * each);
+ for (sidx = c->workitems_alloc; sidx < new_alloc; ++sidx)
+ c->workitems[sidx] = NULL;
c->tail_workitem = 0;
c->head_workitem = c->workitems_alloc;
c->workitems_alloc = new_alloc;
}
+ INSIST(NULL == c->workitems[c->head_workitem % c->workitems_alloc]);
return (0 == slots_used);
}
@@ -180,15 +209,19 @@ ensure_workresp_empty_slot(
size_t new_alloc;
size_t slots_used;
+ size_t sidx;
slots_used = c->head_response - c->tail_response;
if (slots_used >= c->responses_alloc) {
new_alloc = c->responses_alloc + RESPONSES_ALLOC_INC;
c->responses = erealloc(c->responses, new_alloc * each);
+ for (sidx = c->responses_alloc; sidx < new_alloc; ++sidx)
+ c->responses[sidx] = NULL;
c->tail_response = 0;
c->head_response = c->responses_alloc;
c->responses_alloc = new_alloc;
}
+ INSIST(NULL == c->responses[c->head_response % c->responses_alloc]);
return (0 == slots_used);
}
@@ -478,11 +511,11 @@ start_blocking_thread_internal(
# endif
pthread_attr_t thr_attr;
int rc;
- int saved_errno;
int pipe_ends[2]; /* read then write */
int is_pipe;
int flags;
- size_t stacksize;
+ size_t ostacksize;
+ size_t nstacksize;
sigset_t saved_sig_mask;
c->thread_ref = NULL;
@@ -522,21 +555,29 @@ start_blocking_thread_internal(
pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
- rc = pthread_attr_getstacksize(&thr_attr, &stacksize);
- if (-1 == rc) {
+ rc = pthread_attr_getstacksize(&thr_attr, &ostacksize);
+ if (0 != rc) {
msyslog(LOG_ERR,
- "start_blocking_thread: pthread_attr_getstacksize %m");
- } else if (stacksize < THREAD_MINSTACKSIZE) {
- rc = pthread_attr_setstacksize(&thr_attr,
- THREAD_MINSTACKSIZE);
- if (-1 == rc)
+ "start_blocking_thread: pthread_attr_getstacksize() -> %s",
+ strerror(rc));
+ } else {
+ if (ostacksize < THREAD_MINSTACKSIZE)
+ nstacksize = THREAD_MINSTACKSIZE;
+ else if (ostacksize > THREAD_MAXSTACKSIZE)
+ nstacksize = THREAD_MAXSTACKSIZE;
+ else
+ nstacksize = ostacksize;
+ if (nstacksize != ostacksize)
+ rc = pthread_attr_setstacksize(&thr_attr, nstacksize);
+ if (0 != rc)
msyslog(LOG_ERR,
- "start_blocking_thread: pthread_attr_setstacksize(0x%lx -> 0x%lx) %m",
- (u_long)stacksize,
- (u_long)THREAD_MINSTACKSIZE);
+ "start_blocking_thread: pthread_attr_setstacksize(0x%lx -> 0x%lx) -> %s",
+ (u_long)ostacksize, (u_long)nstacksize,
+ strerror(rc));
}
#else
- UNUSED_ARG(stacksize);
+ UNUSED_ARG(nstacksize);
+ UNUSED_ARG(ostacksize);
#endif
#if defined(PTHREAD_SCOPE_SYSTEM) && defined(NEED_PTHREAD_SCOPE_SYSTEM)
pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM);
@@ -545,12 +586,11 @@ start_blocking_thread_internal(
block_thread_signals(&saved_sig_mask);
rc = pthread_create(&c->thr_table[0], &thr_attr,
&blocking_thread, c);
- saved_errno = errno;
pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
pthread_attr_destroy(&thr_attr);
if (0 != rc) {
- errno = saved_errno;
- msyslog(LOG_ERR, "pthread_create() blocking child: %m");
+ msyslog(LOG_ERR, "start_blocking_thread: pthread_create() -> %s",
+ strerror(rc));
exit(1);
}
c->thread_ref = &c->thr_table[0];
OpenPOWER on IntegriCloud