SLIDE 25 Exiting a Process (1/2)
18521 PUBLIC void pm_exit(rmp, exit_status) 18522 register struct mproc *rmp; /* pointer to the process to be terminated */ 18523 int exit_status; /* the process’ exit status (for parent) */ 18524 { 18525 /* A process is done. Release most of the process’ possessions. If its 18526 * parent is waiting, release the rest, else keep the process slot and 18527 * become a zombie. 18528 */ 18529 register int proc_nr; 18530 int parent_waiting, right_child; 18531 pid_t pidarg, procgrp; 18532 struct mproc *p_mp; 18533 clock_t t[5]; 18534 18535 proc_nr = (int) (rmp - mproc); /* get process slot number */ 18536 18537 /* Remember a session leader’s process group. */ 18538 procgrp = (rmp->mp_pid == mp->mp_procgrp) ? mp->mp_procgrp : 0; 18539 18540 /* If the exited process has a timer pending, kill it. */ 18541 if (rmp->mp_flags & ALARM_ON) set_alarm(proc_nr, (unsigned) 0); 18542 18543 /* Do accounting: fetch usage times and accumulate at parent. */ 18544 sys_times(proc_nr, t); 18545 p_mp = &mproc[rmp->mp_parent]; /* process’ parent */ 18546 p_mp->mp_child_utime += t[0] + rmp->mp_child_utime; /* add user time */ 18547 p_mp->mp_child_stime += t[1] + rmp->mp_child_stime; /* add system time */ 18548 18549 /* Tell the kernel and FS that the process is no longer runnable. */ 18550 tell_fs(EXIT, proc_nr, 0, 0); /* file system can free the proc slot */ 18551 sys_exit(proc_nr); 18552 18553 /* Pending reply messages for the dead process cannot be delivered. */ 18554 rmp->mp_flags &= ~REPLY; 18555 18556 /* Release the memory occupied by the child. */ 18557 if (find_share(rmp, rmp->mp_ino, rmp->mp_dev, rmp->mp_ctime) == NULL) { 18558 /* No other process shares the text segment, so free it. */ 18559 free_mem(rmp->mp_seg[T].mem_phys, rmp->mp_seg[T].mem_len); 18560 }
04 – 48 Memory Management/4.7 PM in MINIX
Exiting a Process (2/2)
18561 /* Free the data and stack segments. */ 18562 free_mem(rmp->mp_seg[D].mem_phys, 18563 rmp->mp_seg[S].mem_vir 18564 + rmp->mp_seg[S].mem_len - rmp->mp_seg[D].mem_vir); 18565 18566 /* The process slot can only be freed if the parent has done a WAIT. */ 18567 rmp->mp_exitstatus = (char) exit_status; 18568 18569 pidarg = p_mp->mp_wpid; /* who’s being waited for? */ 18570 parent_waiting = p_mp->mp_flags & WAITING; 18571 right_child = /* child meets one of the 3 tests? */ 18572 (pidarg == -1 || pidarg == rmp->mp_pid || -pidarg == rmp->mp_procgrp); 18573 18574 if (parent_waiting && right_child) { 18575 cleanup(rmp); /* tell parent and release child slot */ 18576 } else { 18577 rmp->mp_flags = IN_USE|ZOMBIE; /* parent not waiting, zombify child */ 18578 sig_proc(p_mp, SIGCHLD); /* send parent a "child died" signal */ 18579 } 18580 18581 /* If the process has children, disinherit them. INIT is the new parent. */ 18582 for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) { 18583 if (rmp->mp_flags & IN_USE && rmp->mp_parent == proc_nr) { 18584 /* ’rmp’ now points to a child to be disinherited. */ 18585 rmp->mp_parent = INIT_PROC_NR; 18586 parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING; 18587 if (parent_waiting && (rmp->mp_flags & ZOMBIE)) cleanup(rmp); 18588 } 18589 } 18590 18591 /* Send a hangup to the process’ process group if it was a session leader. */ 18592 if (procgrp != 0) check_sig(-procgrp, SIGHUP); 18593 }
04 – 49 Memory Management/4.7 PM in MINIX