do umtx_wake at userland thread exit address, so that others userland
threads can wait for a thread to exit, and safely assume that the thread has left userland and is no longer using its userland stack, this is necessary for pthread_join when a thread is waiting for another thread to exit which has user customized stack, after pthread_join returns, the userland stack can be reused for other purposes, without this change, the joiner thread has to spin at the address to ensure the thread is really exited.
This commit is contained in:
parent
a160984738
commit
23ec020060
@ -42,6 +42,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <sys/thr.h>
|
||||
#include <sys/umtx.h>
|
||||
#include <sys/limits.h>
|
||||
|
||||
#include <machine/frame.h>
|
||||
|
||||
@ -275,8 +277,10 @@ thr_exit(struct thread *td, struct thr_exit_args *uap)
|
||||
p = td->td_proc;
|
||||
|
||||
/* Signal userland that it can free the stack. */
|
||||
if ((void *)uap->state != NULL)
|
||||
if ((void *)uap->state != NULL) {
|
||||
suword((void *)uap->state, 1);
|
||||
kern_umtx_wake(td, uap->state, INT_MAX);
|
||||
}
|
||||
|
||||
PROC_LOCK(p);
|
||||
sigqueue_flush(&td->td_sigqueue);
|
||||
|
@ -687,8 +687,8 @@ do_wait(struct thread *td, struct umtx *umtx, long id, struct timespec *timeout)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
do_wake(struct thread *td, void *uaddr, int n_wake)
|
||||
int
|
||||
kern_umtx_wake(struct thread *td, void *uaddr, int n_wake)
|
||||
{
|
||||
struct umtx_key key;
|
||||
int ret;
|
||||
@ -762,7 +762,7 @@ _umtx_op(struct thread *td, struct _umtx_op_args *uap)
|
||||
error = do_wait(td, uap->umtx, uap->id, ts);
|
||||
break;
|
||||
case UMTX_OP_WAKE:
|
||||
error = do_wake(td, uap->umtx, uap->id);
|
||||
error = kern_umtx_wake(td, uap->umtx, uap->id);
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
|
@ -135,6 +135,8 @@ umtx_wake(struct umtx *umtx, int nr_wakeup)
|
||||
|
||||
struct umtx_q *umtxq_alloc(void);
|
||||
void umtxq_free(struct umtx_q *);
|
||||
struct thread;
|
||||
int kern_umtx_wake(struct thread *td, void *uaddr, int n_wake);
|
||||
|
||||
#endif /* !_KERNEL */
|
||||
#endif /* !_SYS_UMTX_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user