SINGLE_PTRACE has almost the same semantic as SINGLE_SUSPEND. The difference is that there's no need to wait for other threads to be parked.
Diff below changes single_thread_set() to be explicit when waiting is required. This allows us to get rid of SINGLE_PTRACE now and soon to use SINGLE_SUSPEND around proc_stop(), even when the thread is not being traced. ok? Index: kern/kern_exec.c =================================================================== RCS file: /cvs/src/sys/kern/kern_exec.c,v retrieving revision 1.219 diff -u -p -r1.219 kern_exec.c --- kern/kern_exec.c 15 Oct 2020 16:31:11 -0000 1.219 +++ kern/kern_exec.c 4 Mar 2021 09:17:09 -0000 @@ -432,7 +432,7 @@ sys_execve(struct proc *p, void *v, regi * we're committed: any further errors will kill the process, so * kill the other threads now. */ - single_thread_set(p, SINGLE_EXIT, 0); + single_thread_set(p, SINGLE_EXIT, 1); /* * Prepare vmspace for remapping. Note that uvmspace_exec can replace Index: kern/kern_exit.c =================================================================== RCS file: /cvs/src/sys/kern/kern_exit.c,v retrieving revision 1.196 diff -u -p -r1.196 kern_exit.c --- kern/kern_exit.c 15 Feb 2021 09:35:59 -0000 1.196 +++ kern/kern_exit.c 4 Mar 2021 09:17:10 -0000 @@ -136,7 +136,7 @@ exit1(struct proc *p, int xexit, int xsi } else { /* nope, multi-threaded */ if (flags == EXIT_NORMAL) - single_thread_set(p, SINGLE_EXIT, 0); + single_thread_set(p, SINGLE_EXIT, 1); else if (flags == EXIT_THREAD) single_thread_check(p, 0); } Index: kern/kern_sig.c =================================================================== RCS file: /cvs/src/sys/kern/kern_sig.c,v retrieving revision 1.274 diff -u -p -r1.274 kern_sig.c --- kern/kern_sig.c 4 Mar 2021 09:02:37 -0000 1.274 +++ kern/kern_sig.c 4 Mar 2021 09:17:10 -0000 @@ -1490,7 +1490,7 @@ sigexit(struct proc *p, int signum) /* if there are other threads, pause them */ if (P_HASSIBLING(p)) - single_thread_set(p, SINGLE_SUSPEND, 0); + single_thread_set(p, SINGLE_SUSPEND, 1); if (coredump(p) == 0) signum |= WCOREFLAG; @@ -2000,14 +2000,12 @@ single_thread_check(struct proc *p, int * where the other threads should stop: * - SINGLE_SUSPEND: stop wherever they are, will later either be told to exit * (by setting to SINGLE_EXIT) or be released (via single_thread_clear()) - * - SINGLE_PTRACE: stop wherever they are, will wait for them to stop - * later (via single_thread_wait()) and released as with SINGLE_SUSPEND * - SINGLE_UNWIND: just unwind to kernel boundary, will be told to exit * or released as with SINGLE_SUSPEND * - SINGLE_EXIT: unwind to kernel boundary and exit */ int -single_thread_set(struct proc *p, enum single_thread_mode mode, int deep) +single_thread_set(struct proc *p, enum single_thread_mode mode, int wait) { struct process *pr = p->p_p; struct proc *q; @@ -2016,7 +2014,7 @@ single_thread_set(struct proc *p, enum s KASSERT(curproc == p); SCHED_LOCK(s); - error = single_thread_check_locked(p, deep, s); + error = single_thread_check_locked(p, (mode == SINGLE_UNWIND), s); if (error) { SCHED_UNLOCK(s); return error; @@ -2024,7 +2022,6 @@ single_thread_set(struct proc *p, enum s switch (mode) { case SINGLE_SUSPEND: - case SINGLE_PTRACE: break; case SINGLE_UNWIND: atomic_setbits_int(&pr->ps_flags, PS_SINGLEUNWIND); @@ -2063,8 +2060,7 @@ single_thread_set(struct proc *p, enum s /* if it's not interruptible, then just have to wait */ if (q->p_flag & P_SINTR) { /* merely need to suspend? just stop it */ - if (mode == SINGLE_SUSPEND || - mode == SINGLE_PTRACE) { + if (mode == SINGLE_SUSPEND) { q->p_stat = SSTOP; break; } @@ -2089,7 +2085,7 @@ single_thread_set(struct proc *p, enum s } SCHED_UNLOCK(s); - if (mode != SINGLE_PTRACE) + if (wait) single_thread_wait(pr, 1); return 0;