Exemplo n.º 1
0
/*
 * Kill all lwps associated with the current process except the
 * current lwp.   Return an error if we race another thread trying to
 * do the same thing and lose the race.
 *
 * If forexec is non-zero the current thread and process flags are
 * cleaned up so they can be reused.
 *
 * Caller must hold curproc->p_token
 */
int
killalllwps(int forexec)
{
	struct lwp *lp = curthread->td_lwp;
	struct proc *p = lp->lwp_proc;

	/*
	 * Interlock against P_WEXIT.  Only one of the process's thread
	 * is allowed to do the master exit.
	 */
	if (p->p_flags & P_WEXIT)
		return (EALREADY);
	p->p_flags |= P_WEXIT;

	/*
	 * Interlock with LWP_MP_WEXIT and kill any remaining LWPs
	 */
	atomic_set_int(&lp->lwp_mpflags, LWP_MP_WEXIT);
	if (p->p_nthreads > 1)
		killlwps(lp);

	/*
	 * If doing this for an exec, clean up the remaining thread
	 * (us) for continuing operation after all the other threads
	 * have been killed.
	 */
	if (forexec) {
		atomic_clear_int(&lp->lwp_mpflags, LWP_MP_WEXIT);
		p->p_flags &= ~P_WEXIT;
	}
	return(0);
}
Exemplo n.º 2
0
/*
 * Kill all lwps associated with the current process except the
 * current lwp.   Return an error if we race another thread trying to
 * do the same thing and lose the race.
 *
 * If forexec is non-zero the current thread and process flags are
 * cleaned up so they can be reused.
 *
 * Caller must hold curproc->p_token
 */
int
killalllwps(int forexec)
{
	struct lwp *lp = curthread->td_lwp;
	struct proc *p = lp->lwp_proc;
	int fakestop;

	/*
	 * Interlock against P_WEXIT.  Only one of the process's thread
	 * is allowed to do the master exit.
	 */
	if (p->p_flags & P_WEXIT)
		return (EALREADY);
	p->p_flags |= P_WEXIT;

	/*
	 * Set temporary stopped state in case we are racing a coredump.
	 * Otherwise the coredump may hang forever.
	 */
	if (lp->lwp_mpflags & LWP_MP_WSTOP) {
		fakestop = 0;
	} else {
		atomic_set_int(&lp->lwp_mpflags, LWP_MP_WSTOP);
		++p->p_nstopped;
		fakestop = 1;
		wakeup(&p->p_nstopped);
	}

	/*
	 * Interlock with LWP_MP_WEXIT and kill any remaining LWPs
	 */
	atomic_set_int(&lp->lwp_mpflags, LWP_MP_WEXIT);
	if (p->p_nthreads > 1)
		killlwps(lp);

	/*
	 * Undo temporary stopped state
	 */
	if (fakestop) {
		atomic_clear_int(&lp->lwp_mpflags, LWP_MP_WSTOP);
		--p->p_nstopped;
	}

	/*
	 * If doing this for an exec, clean up the remaining thread
	 * (us) for continuing operation after all the other threads
	 * have been killed.
	 */
	if (forexec) {
		atomic_clear_int(&lp->lwp_mpflags, LWP_MP_WEXIT);
		p->p_flags &= ~P_WEXIT;
	}
	return(0);
}