MCPcopy Create free account
hub / github.com/F-Stack/f-stack / thread_single

Function thread_single

freebsd/kern/kern_thread.c:1143–1272  ·  view source on GitHub ↗

* 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

Source from the content-addressed store, hash-verified

1141 * any sleeping threads that are interruptable. (PCATCH).
1142 */
1143int
1144thread_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

Callers 6

fork_norfprocFunction · 0.85
sigexitFunction · 0.85
stop_all_procFunction · 0.85
pre_execveFunction · 0.85
post_execveFunction · 0.85
exit1Function · 0.85

Calls 8

mtx_assertFunction · 0.85
calc_remainingFunction · 0.85
remain_for_modeFunction · 0.85
weed_inhibFunction · 0.85
forward_signalFunction · 0.85
kick_proc0Function · 0.85
thread_suspend_switchFunction · 0.85
sched_relinquishFunction · 0.70

Tested by

no test coverage detected