fix a race between pthread_exit and pthread_create.
inefficient, but better than crashing.
This commit is contained in:
parent
f8fe10ea6a
commit
4cdc2ed889
|
@ -1,4 +1,4 @@
|
|||
$NetBSD: TODO,v 1.5 2006/12/25 11:36:36 ad Exp $
|
||||
$NetBSD: TODO,v 1.6 2007/02/15 15:39:33 yamt Exp $
|
||||
|
||||
Bugs to fix, mostly with SA:
|
||||
|
||||
|
@ -64,11 +64,11 @@ Future work for 1:1 threads:
|
|||
|
||||
- Verify that gdb still works well (basic functionality seems to be OK).
|
||||
|
||||
- There is a race between pthread_exit() and pthread_create() for
|
||||
detached LWPs, where the stack (and pthread structure) could be reclaimed
|
||||
before the thread has a chance to call _lwp_exit(). Checking the return
|
||||
of _lwp_kill(target, 0) could be used to fix this but that seems a bit
|
||||
heavyweight. (See shared page item.)
|
||||
- A race between pthread_exit() and pthread_create() for detached LWPs,
|
||||
where the stack (and pthread structure) could be reclaimed before the
|
||||
thread has a chance to call _lwp_exit(), is currently prevented by
|
||||
checking the return of _lwp_kill(target, 0). It could be done more
|
||||
efficiently. (See shared page item.)
|
||||
|
||||
- Adaptive mutexes and spinlocks (see shared page item). These need
|
||||
to implement exponential backoff to reduce bus contention. On x86 we
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pthread.c,v 1.59 2007/02/09 23:53:24 ad Exp $ */
|
||||
/* $NetBSD: pthread.c,v 1.60 2007/02/15 15:39:38 yamt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001, 2002, 2003, 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: pthread.c,v 1.59 2007/02/09 23:53:24 ad Exp $");
|
||||
__RCSID("$NetBSD: pthread.c,v 1.60 2007/02/15 15:39:38 yamt Exp $");
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
|
@ -418,12 +418,17 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
|||
self = pthread__self();
|
||||
|
||||
pthread_spinlock(self, &pthread__deadqueue_lock);
|
||||
if (!PTQ_EMPTY(&pthread__deadqueue)) {
|
||||
newthread = PTQ_FIRST(&pthread__deadqueue);
|
||||
PTQ_REMOVE(&pthread__deadqueue, newthread, pt_allq);
|
||||
pthread_spinunlock(self, &pthread__deadqueue_lock);
|
||||
} else {
|
||||
pthread_spinunlock(self, &pthread__deadqueue_lock);
|
||||
newthread = PTQ_FIRST(&pthread__deadqueue);
|
||||
if (newthread != NULL) {
|
||||
#ifndef PTHREAD_SA
|
||||
if (_lwp_kill(newthread->pt_lid, 0) == 0 || errno != ESRCH)
|
||||
newthread = NULL;
|
||||
else
|
||||
#endif
|
||||
PTQ_REMOVE(&pthread__deadqueue, newthread, pt_allq);
|
||||
}
|
||||
pthread_spinunlock(self, &pthread__deadqueue_lock);
|
||||
if (newthread == NULL) {
|
||||
/* Set up a stack and allocate space for a pthread_st. */
|
||||
ret = pthread__stackalloc(&newthread);
|
||||
if (ret != 0) {
|
||||
|
@ -720,7 +725,6 @@ pthread_exit(void *retval)
|
|||
pthread_spinunlock(self, &pthread__allqueue_lock);
|
||||
#else
|
||||
pthread_spinunlock(self, &pthread__deadqueue_lock);
|
||||
/* XXXLWP race against stack being reclaimed. */
|
||||
_lwp_exit();
|
||||
#endif
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue