* Enforce single-threading. * * Returns 1 if the caller must abort (another thread is waiting to * exit the process or similar). Process is locked! * Returns 0 when you are successfully the only thread running. * A process has successfully single threaded in the suspend mode when * There are no threads in user mode. Threads in the kernel must be * allowed to continue until they get to the u
| 1141 | * any sleeping threads that are interruptable. (PCATCH). |
| 1142 | */ |
| 1143 | int |
| 1144 | thread_single(struct proc *p, int mode) |
| 1145 | { |
| 1146 | struct thread *td; |
| 1147 | struct thread *td2; |
| 1148 | int remaining, wakeup_swapper; |
| 1149 | |
| 1150 | td = curthread; |
| 1151 | KASSERT(mode == SINGLE_EXIT || mode == SINGLE_BOUNDARY || |
| 1152 | mode == SINGLE_ALLPROC || mode == SINGLE_NO_EXIT, |
| 1153 | ("invalid mode %d", mode)); |
| 1154 | /* |
| 1155 | * If allowing non-ALLPROC singlethreading for non-curproc |
| 1156 | * callers, calc_remaining() and remain_for_mode() should be |
| 1157 | * adjusted to also account for td->td_proc != p. For now |
| 1158 | * this is not implemented because it is not used. |
| 1159 | */ |
| 1160 | KASSERT((mode == SINGLE_ALLPROC && td->td_proc != p) || |
| 1161 | (mode != SINGLE_ALLPROC && td->td_proc == p), |
| 1162 | ("mode %d proc %p curproc %p", mode, p, td->td_proc)); |
| 1163 | mtx_assert(&Giant, MA_NOTOWNED); |
| 1164 | PROC_LOCK_ASSERT(p, MA_OWNED); |
| 1165 | |
| 1166 | if ((p->p_flag & P_HADTHREADS) == 0 && mode != SINGLE_ALLPROC) |
| 1167 | return (0); |
| 1168 | |
| 1169 | /* Is someone already single threading? */ |
| 1170 | if (p->p_singlethread != NULL && p->p_singlethread != td) |
| 1171 | return (1); |
| 1172 | |
| 1173 | if (mode == SINGLE_EXIT) { |
| 1174 | p->p_flag |= P_SINGLE_EXIT; |
| 1175 | p->p_flag &= ~P_SINGLE_BOUNDARY; |
| 1176 | } else { |
| 1177 | p->p_flag &= ~P_SINGLE_EXIT; |
| 1178 | if (mode == SINGLE_BOUNDARY) |
| 1179 | p->p_flag |= P_SINGLE_BOUNDARY; |
| 1180 | else |
| 1181 | p->p_flag &= ~P_SINGLE_BOUNDARY; |
| 1182 | } |
| 1183 | if (mode == SINGLE_ALLPROC) |
| 1184 | p->p_flag |= P_TOTAL_STOP; |
| 1185 | p->p_flag |= P_STOPPED_SINGLE; |
| 1186 | PROC_SLOCK(p); |
| 1187 | p->p_singlethread = td; |
| 1188 | remaining = calc_remaining(p, mode); |
| 1189 | while (remaining != remain_for_mode(mode)) { |
| 1190 | if (P_SHOULDSTOP(p) != P_STOPPED_SINGLE) |
| 1191 | goto stopme; |
| 1192 | wakeup_swapper = 0; |
| 1193 | FOREACH_THREAD_IN_PROC(p, td2) { |
| 1194 | if (td2 == td) |
| 1195 | continue; |
| 1196 | thread_lock(td2); |
| 1197 | td2->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK; |
| 1198 | if (TD_IS_INHIBITED(td2)) { |
| 1199 | wakeup_swapper |= weed_inhib(mode, td2, p); |
| 1200 | #ifdef SMP |
no test coverage detected