diff options
| author | chs <chs@NetBSD.org> | 2005-10-16 00:07:24 +0000 |
|---|---|---|
| committer | chs <chs@NetBSD.org> | 2005-10-16 00:07:24 +0000 |
| commit | 2415c56ed0bf9231e101e5688e02f50d6f296ed8 (patch) | |
| tree | 8bdbfb8e2914fb684fdae1d281c3ea2b6ee81bae /lib/libpthread | |
| parent | 07a01daf001fea24cfb7bf048033ba094559313d (diff) | |
in pthread_mutex_lock_slow(), pthread_rwlock_timedrdlock() and sem_wait(),
call pthread__start() if it hasn't already been called. this avoids
an internal assertion from the library if these routines are used
before any threads are created and they need to sleep.
fixes PR 20256, PR 24241, PR 25722, PR 26096.
Diffstat (limited to 'lib/libpthread')
| -rw-r--r-- | lib/libpthread/pthread.c | 6 | ||||
| -rw-r--r-- | lib/libpthread/pthread_int.h | 3 | ||||
| -rw-r--r-- | lib/libpthread/pthread_mutex.c | 10 | ||||
| -rw-r--r-- | lib/libpthread/pthread_rwlock.c | 18 | ||||
| -rw-r--r-- | lib/libpthread/sem.c | 10 |
5 files changed, 34 insertions, 13 deletions
diff --git a/lib/libpthread/pthread.c b/lib/libpthread/pthread.c index 6a48dfca258..071fa4f1317 100644 --- a/lib/libpthread/pthread.c +++ b/lib/libpthread/pthread.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.c,v 1.42 2005/07/01 12:35:18 yamt Exp $ */ +/* $NetBSD: pthread.c,v 1.43 2005/10/16 00:07:24 chs Exp $ */ /*- * Copyright (c) 2001,2002,2003 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread.c,v 1.42 2005/07/01 12:35:18 yamt Exp $"); +__RCSID("$NetBSD: pthread.c,v 1.43 2005/10/16 00:07:24 chs Exp $"); #include <err.h> #include <errno.h> @@ -237,7 +237,7 @@ pthread__child_callback(void) pthread__started = 0; } -static void +void pthread__start(void) { pthread_t self, idle; diff --git a/lib/libpthread/pthread_int.h b/lib/libpthread/pthread_int.h index 39c13f912de..0375ddca3d1 100644 --- a/lib/libpthread/pthread_int.h +++ b/lib/libpthread/pthread_int.h @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_int.h,v 1.31 2005/02/26 20:33:06 nathanw Exp $ */ +/* $NetBSD: pthread_int.h,v 1.32 2005/10/16 00:07:24 chs Exp $ */ /*- * Copyright (c) 2001,2002,2003 The NetBSD Foundation, Inc. @@ -274,6 +274,7 @@ pthread_t pthread__next(pthread_t self); int pthread__stackalloc(pthread_t *t); void pthread__initmain(pthread_t *t); +void pthread__start(void); void pthread__sa_start(void); void pthread__sa_recycle(pthread_t old, pthread_t new); diff --git a/lib/libpthread/pthread_mutex.c b/lib/libpthread/pthread_mutex.c index e544fd5de2b..b381ab29249 100644 --- a/lib/libpthread/pthread_mutex.c +++ b/lib/libpthread/pthread_mutex.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_mutex.c,v 1.19 2005/07/16 23:14:53 nathanw Exp $ */ +/* $NetBSD: pthread_mutex.c,v 1.20 2005/10/16 00:07:24 chs Exp $ */ /*- * Copyright (c) 2001, 2003 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_mutex.c,v 1.19 2005/07/16 23:14:53 nathanw Exp $"); +__RCSID("$NetBSD: pthread_mutex.c,v 1.20 2005/10/16 00:07:24 chs Exp $"); #include <errno.h> #include <limits.h> @@ -189,10 +189,16 @@ static int pthread_mutex_lock_slow(pthread_mutex_t *mutex) { pthread_t self; + extern int pthread__started; pthread__error(EINVAL, "Invalid mutex", mutex->ptm_magic == _PT_MUTEX_MAGIC); + if (pthread__started == 0) { + pthread__start(); + pthread__started = 1; + } + self = pthread__self(); PTHREADD_ADD(PTHREADD_MUTEX_LOCK_SLOW); diff --git a/lib/libpthread/pthread_rwlock.c b/lib/libpthread/pthread_rwlock.c index a15a3d4bf84..ac2f5bd4645 100644 --- a/lib/libpthread/pthread_rwlock.c +++ b/lib/libpthread/pthread_rwlock.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_rwlock.c,v 1.11 2005/01/09 01:57:38 nathanw Exp $ */ +/* $NetBSD: pthread_rwlock.c,v 1.12 2005/10/16 00:07:24 chs Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_rwlock.c,v 1.11 2005/01/09 01:57:38 nathanw Exp $"); +__RCSID("$NetBSD: pthread_rwlock.c,v 1.12 2005/10/16 00:07:24 chs Exp $"); #include <errno.h> @@ -248,6 +248,7 @@ pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, struct pthread_rwlock__waitarg wait; struct pt_alarm_t alarm; int retval; + #ifdef ERRORCHECK if ((rwlock == NULL) || (rwlock->ptr_magic != _PT_RWLOCK_MAGIC)) return EINVAL; @@ -258,8 +259,8 @@ pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, (abs_timeout->tv_nsec < 0) || (abs_timeout->tv_sec < 0)) return EINVAL; + self = pthread__self(); - pthread_spinlock(self, &rwlock->ptr_interlock); #ifdef ERRORCHECK if (rwlock->ptr_writer == self) { @@ -316,8 +317,10 @@ pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, { struct pthread_rwlock__waitarg wait; struct pt_alarm_t alarm; - int retval; pthread_t self; + int retval; + extern int pthread__started; + #ifdef ERRORCHECK if ((rwlock == NULL) || (rwlock->ptr_magic != _PT_RWLOCK_MAGIC)) return EINVAL; @@ -328,8 +331,13 @@ pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, (abs_timeout->tv_nsec < 0) || (abs_timeout->tv_sec < 0)) return EINVAL; + + if (pthread__started == 0) { + pthread__start(); + pthread__started = 1; + } + self = pthread__self(); - pthread_spinlock(self, &rwlock->ptr_interlock); #ifdef ERRORCHECK if (rwlock->ptr_writer == self) { diff --git a/lib/libpthread/sem.c b/lib/libpthread/sem.c index c028371fb43..f2864635e7d 100644 --- a/lib/libpthread/sem.c +++ b/lib/libpthread/sem.c @@ -1,4 +1,4 @@ -/* $NetBSD: sem.c,v 1.7 2003/11/24 23:54:13 cl Exp $ */ +/* $NetBSD: sem.c,v 1.8 2005/10/16 00:07:24 chs Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: sem.c,v 1.7 2003/11/24 23:54:13 cl Exp $"); +__RCSID("$NetBSD: sem.c,v 1.8 2005/10/16 00:07:24 chs Exp $"); #include <sys/types.h> #include <sys/ksem.h> @@ -286,6 +286,7 @@ int sem_wait(sem_t *sem) { pthread_t self; + extern int pthread__started; #ifdef ERRORCHECK if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { @@ -301,6 +302,11 @@ sem_wait(sem_t *sem) return (_ksem_wait((*sem)->usem_semid)); } + if (pthread__started == 0) { + pthread__start(); + pthread__started = 1; + } + for (;;) { pthread_spinlock(self, &(*sem)->usem_interlock); pthread_spinlock(self, &self->pt_statelock); |
