* Exit: deallocate address space and other resources, change proc state to * zombie, and unlink proc from allproc and parent's lists. Save exit status * and rusage for wait(). Check for child processes and orphan them. */
| 201 | * and rusage for wait(). Check for child processes and orphan them. |
| 202 | */ |
| 203 | void |
| 204 | exit1(struct thread *td, int rval, int signo) |
| 205 | { |
| 206 | struct proc *p, *nq, *q, *t; |
| 207 | struct thread *tdt; |
| 208 | ksiginfo_t *ksi, *ksi1; |
| 209 | int signal_parent; |
| 210 | |
| 211 | mtx_assert(&Giant, MA_NOTOWNED); |
| 212 | KASSERT(rval == 0 || signo == 0, ("exit1 rv %d sig %d", rval, signo)); |
| 213 | |
| 214 | p = td->td_proc; |
| 215 | /* |
| 216 | * XXX in case we're rebooting we just let init die in order to |
| 217 | * work around an unsolved stack overflow seen very late during |
| 218 | * shutdown on sparc64 when the gmirror worker process exists. |
| 219 | * XXX what to do now that sparc64 is gone... remove if? |
| 220 | */ |
| 221 | if (p == initproc && rebooting == 0) { |
| 222 | printf("init died (signal %d, exit %d)\n", signo, rval); |
| 223 | panic("Going nowhere without my init!"); |
| 224 | } |
| 225 | |
| 226 | /* |
| 227 | * Deref SU mp, since the thread does not return to userspace. |
| 228 | */ |
| 229 | td_softdep_cleanup(td); |
| 230 | |
| 231 | /* |
| 232 | * MUST abort all other threads before proceeding past here. |
| 233 | */ |
| 234 | PROC_LOCK(p); |
| 235 | /* |
| 236 | * First check if some other thread or external request got |
| 237 | * here before us. If so, act appropriately: exit or suspend. |
| 238 | * We must ensure that stop requests are handled before we set |
| 239 | * P_WEXIT. |
| 240 | */ |
| 241 | thread_suspend_check(0); |
| 242 | while (p->p_flag & P_HADTHREADS) { |
| 243 | /* |
| 244 | * Kill off the other threads. This requires |
| 245 | * some co-operation from other parts of the kernel |
| 246 | * so it may not be instantaneous. With this state set |
| 247 | * any thread entering the kernel from userspace will |
| 248 | * thread_exit() in trap(). Any thread attempting to |
| 249 | * sleep will return immediately with EINTR or EWOULDBLOCK |
| 250 | * which will hopefully force them to back out to userland |
| 251 | * freeing resources as they go. Any thread attempting |
| 252 | * to return to userland will thread_exit() from userret(). |
| 253 | * thread_exit() will unsuspend us when the last of the |
| 254 | * other threads exits. |
| 255 | * If there is already a thread singler after resumption, |
| 256 | * calling thread_single will fail; in that case, we just |
| 257 | * re-check all suspension request, the thread should |
| 258 | * either be suspended there or exit. |
| 259 | */ |
| 260 | if (!thread_single(p, SINGLE_EXIT)) |
no test coverage detected