Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libpthread Arrange to pause for a while if pthread_cond_...
details: https://anonhg.NetBSD.org/src/rev/d7b06738e72e
branches: trunk
changeset: 542531:d7b06738e72e
user: nathanw <nathanw%NetBSD.org@localhost>
date: Sat Feb 01 00:57:31 2003 +0000
description:
Arrange to pause for a while if pthread_cond_wait() or
pthread_cond_timedwait() is called before any threads have been
created and the SA infrastructure is up and running.
Addresses PR lib/20139.
XXX probably need to do this for all of the pthread_*_timedlock()
functions, too.
diffstat:
lib/libpthread/pthread_cond.c | 58 +++++++++++++++++++++++++++++++++++++++++-
1 files changed, 56 insertions(+), 2 deletions(-)
diffs (105 lines):
diff -r 26ba1fceb459 -r d7b06738e72e lib/libpthread/pthread_cond.c
--- a/lib/libpthread/pthread_cond.c Sat Feb 01 00:42:03 2003 +0000
+++ b/lib/libpthread/pthread_cond.c Sat Feb 01 00:57:31 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_cond.c,v 1.5 2003/01/31 04:59:40 nathanw Exp $ */
+/* $NetBSD: pthread_cond.c,v 1.6 2003/02/01 00:57:31 nathanw Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -39,6 +39,8 @@
#include <assert.h>
#include <errno.h>
#include <sys/cdefs.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include "pthread.h"
#include "pthread_int.h"
@@ -51,7 +53,13 @@
#define SDPRINTF(x)
#endif
+int _sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+extern int pthread__started;
+
static void pthread_cond_wait__callback(void *);
+static int pthread_cond_wait_nothread(pthread_t, pthread_mutex_t *,
+ const struct timespec *);
__strong_alias(__libc_cond_init,pthread_cond_init)
__strong_alias(__libc_cond_signal,pthread_cond_signal)
@@ -107,6 +115,11 @@
#endif
self = pthread__self();
PTHREADD_ADD(PTHREADD_COND_WAIT);
+
+ /* Just hang out for a while if threads aren't running yet. */
+ if (__predict_false(pthread__started == 0))
+ return pthread_cond_wait_nothread(self, mutex, NULL);
+
pthread_spinlock(self, &cond->ptc_lock);
#ifdef ERRORCHECK
if (cond->ptc_mutex == NULL)
@@ -174,6 +187,12 @@
return EINVAL;
#endif
self = pthread__self();
+ PTHREADD_ADD(PTHREADD_COND_TIMEDWAIT);
+
+ /* Just hang out for a while if threads aren't running yet. */
+ if (__predict_false(pthread__started == 0))
+ return pthread_cond_wait_nothread(self, mutex, abstime);
+
pthread_spinlock(self, &cond->ptc_lock);
#ifdef ERRORCHECK
if (cond->ptc_mutex == NULL)
@@ -190,7 +209,7 @@
}
}
#endif
- PTHREADD_ADD(PTHREADD_COND_TIMEDWAIT);
+
wait.ptw_thread = self;
wait.ptw_cond = cond;
retval = 0;
@@ -348,3 +367,38 @@
return 0;
}
+
+/* Utility routine to hang out for a while if threads haven't started yet. */
+static int
+pthread_cond_wait_nothread(pthread_t self, pthread_mutex_t *mutex,
+ const struct timespec *abstime)
+{
+ struct timeval now, tv, *tvp;
+ int retval;
+
+ if (abstime == NULL)
+ tvp = NULL;
+ else {
+ tvp = &tv;
+ gettimeofday(&now, NULL);
+ TIMESPEC_TO_TIMEVAL(tvp, abstime);
+ timersub(tvp, &now, tvp);
+ }
+
+ /*
+ * The libpthread select() wrapper has cancellation tests, but
+ * we need to have the mutex locked when testing for
+ * cancellation and unlocked while we sleep. So, skip the
+ * wrapper.
+ */
+ pthread__testcancel(self);
+ pthread_mutex_unlock(mutex);
+ retval = _sys_select(0, NULL, NULL, NULL, tvp);
+ pthread_mutex_lock(mutex);
+ pthread__testcancel(self);
+
+ if (retval == 0)
+ return ETIMEDOUT;
+ else
+ return EINTR;
+}
Home |
Main Index |
Thread Index |
Old Index