Close a race between a thread exiting and the freeing of it's stack.
After some discussion the best option seems to be to signal the thread's death from within the kernel. This requires that thr_exit() take an argument. Discussed with: davidxu, deischen, marcel MFC after: 3 days
This commit is contained in:
parent
18d2addc23
commit
401901ac43
@ -43,7 +43,7 @@
|
|||||||
__weak_reference(_pthread_exit, pthread_exit);
|
__weak_reference(_pthread_exit, pthread_exit);
|
||||||
|
|
||||||
/* thr_exit() */
|
/* thr_exit() */
|
||||||
extern int _thr_exit(void);
|
extern int _thr_exit(long *state);
|
||||||
|
|
||||||
static void deadlist_free_threads();
|
static void deadlist_free_threads();
|
||||||
|
|
||||||
@ -164,7 +164,6 @@ _pthread_exit(void *status)
|
|||||||
deadlist_free_threads();
|
deadlist_free_threads();
|
||||||
TAILQ_INSERT_HEAD(&_dead_list, curthread, dle);
|
TAILQ_INSERT_HEAD(&_dead_list, curthread, dle);
|
||||||
TAILQ_REMOVE(&_thread_list, curthread, tle);
|
TAILQ_REMOVE(&_thread_list, curthread, tle);
|
||||||
curthread->isdead = 1;
|
|
||||||
|
|
||||||
/* If we're the last thread, call it quits */
|
/* If we're the last thread, call it quits */
|
||||||
if (TAILQ_EMPTY(&_thread_list))
|
if (TAILQ_EMPTY(&_thread_list))
|
||||||
@ -181,7 +180,7 @@ _pthread_exit(void *status)
|
|||||||
* thread, which we can't be because we've already checked
|
* thread, which we can't be because we've already checked
|
||||||
* for that.
|
* for that.
|
||||||
*/
|
*/
|
||||||
_thr_exit();
|
_thr_exit((long *)&curthread->isdead);
|
||||||
|
|
||||||
/* This point should not be reached. */
|
/* This point should not be reached. */
|
||||||
PANIC("Dead thread has resumed");
|
PANIC("Dead thread has resumed");
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* DO NOT EDIT-- this file is automatically generated.
|
* DO NOT EDIT-- this file is automatically generated.
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
* created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.40 2004/07/14 00:03:30 peter Exp
|
* created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.41 2004/10/06 14:20:57 mtm Exp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _FREEBSD32_SYSPROTO_H_
|
#ifndef _FREEBSD32_SYSPROTO_H_
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* DO NOT EDIT-- this file is automatically generated.
|
* DO NOT EDIT-- this file is automatically generated.
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
* created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.40 2004/07/14 00:03:30 peter Exp
|
* created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.41 2004/10/06 14:20:57 mtm Exp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define FREEBSD32_SYS_syscall 0
|
#define FREEBSD32_SYS_syscall 0
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* DO NOT EDIT-- this file is automatically generated.
|
* DO NOT EDIT-- this file is automatically generated.
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
* created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.40 2004/07/14 00:03:30 peter Exp
|
* created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.41 2004/10/06 14:20:57 mtm Exp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char *freebsd32_syscallnames[] = {
|
const char *freebsd32_syscallnames[] = {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* DO NOT EDIT-- this file is automatically generated.
|
* DO NOT EDIT-- this file is automatically generated.
|
||||||
* $FreeBSD$
|
* $FreeBSD$
|
||||||
* created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.40 2004/07/14 00:03:30 peter Exp
|
* created from FreeBSD: src/sys/compat/freebsd32/syscalls.master,v 1.41 2004/10/06 14:20:57 mtm Exp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "opt_compat.h"
|
#include "opt_compat.h"
|
||||||
@ -456,7 +456,7 @@ struct sysent freebsd32_sysent[] = {
|
|||||||
{ 0, (sy_call_t *)nosys }, /* 428 = __acl_aclcheck_link */
|
{ 0, (sy_call_t *)nosys }, /* 428 = __acl_aclcheck_link */
|
||||||
{ 0, (sy_call_t *)nosys }, /* 429 = sigwait */
|
{ 0, (sy_call_t *)nosys }, /* 429 = sigwait */
|
||||||
{ SYF_MPSAFE | AS(thr_create_args), (sy_call_t *)thr_create }, /* 430 = thr_create */
|
{ SYF_MPSAFE | AS(thr_create_args), (sy_call_t *)thr_create }, /* 430 = thr_create */
|
||||||
{ SYF_MPSAFE | 0, (sy_call_t *)thr_exit }, /* 431 = thr_exit */
|
{ SYF_MPSAFE | AS(thr_exit_args), (sy_call_t *)thr_exit }, /* 431 = thr_exit */
|
||||||
{ SYF_MPSAFE | AS(thr_self_args), (sy_call_t *)thr_self }, /* 432 = thr_self */
|
{ SYF_MPSAFE | AS(thr_self_args), (sy_call_t *)thr_self }, /* 432 = thr_self */
|
||||||
{ SYF_MPSAFE | AS(thr_kill_args), (sy_call_t *)thr_kill }, /* 433 = thr_kill */
|
{ SYF_MPSAFE | AS(thr_kill_args), (sy_call_t *)thr_kill }, /* 433 = thr_kill */
|
||||||
{ SYF_MPSAFE | AS(_umtx_lock_args), (sy_call_t *)_umtx_lock }, /* 434 = _umtx_lock */
|
{ SYF_MPSAFE | AS(_umtx_lock_args), (sy_call_t *)_umtx_lock }, /* 434 = _umtx_lock */
|
||||||
|
@ -596,7 +596,7 @@
|
|||||||
; XXX implement
|
; XXX implement
|
||||||
429 UNIMPL sigwait
|
429 UNIMPL sigwait
|
||||||
430 MNOPROTO { int thr_create(ucontext_t *ctx, long *id, int flag s); }
|
430 MNOPROTO { int thr_create(ucontext_t *ctx, long *id, int flag s); }
|
||||||
431 MNOPROTO { void thr_exit(void); }
|
431 MNOPROTO { void thr_exit(long *state); }
|
||||||
432 MNOPROTO { int thr_self(long *id); }
|
432 MNOPROTO { int thr_self(long *id); }
|
||||||
433 MNOPROTO { int thr_kill(long id, int sig); }
|
433 MNOPROTO { int thr_kill(long id, int sig); }
|
||||||
434 MNOPROTO { int _umtx_lock(struct umtx *umtx); }
|
434 MNOPROTO { int _umtx_lock(struct umtx *umtx); }
|
||||||
|
@ -186,12 +186,16 @@ thr_self(struct thread *td, struct thr_self_args *uap)
|
|||||||
|
|
||||||
int
|
int
|
||||||
thr_exit(struct thread *td, struct thr_exit_args *uap)
|
thr_exit(struct thread *td, struct thr_exit_args *uap)
|
||||||
/* NULL */
|
/* long *state */
|
||||||
{
|
{
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
|
||||||
p = td->td_proc;
|
p = td->td_proc;
|
||||||
|
|
||||||
|
/* Signal userland that it can free the stack. */
|
||||||
|
if ((void *)uap->state != NULL)
|
||||||
|
suword((void *)uap->state, 1);
|
||||||
|
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
mtx_lock_spin(&sched_lock);
|
mtx_lock_spin(&sched_lock);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
int thr_create(ucontext_t *ctx, long *id, int flags);
|
int thr_create(ucontext_t *ctx, long *id, int flags);
|
||||||
int thr_self(long *id);
|
int thr_self(long *id);
|
||||||
void thr_exit(void);
|
void thr_exit(long *state);
|
||||||
int thr_kill(long id, int sig);
|
int thr_kill(long id, int sig);
|
||||||
int thr_suspend(const struct timespec *timeout);
|
int thr_suspend(const struct timespec *timeout);
|
||||||
int thr_wake(long id);
|
int thr_wake(long id);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user