/* * 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); }
/* * 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); }