source: branches/minix3-book/kernel/system/do_exit.c@ 25

Last change on this file since 25 was 4, checked in by Mattia Monga, 14 years ago

Importazione sorgenti libro

File size: 3.6 KB
Line 
1/* The kernel call implemented in this file:
2 * m_type: SYS_EXIT
3 *
4 * The parameters for this kernel call are:
5 * m1_i1: PR_PROC_NR (slot number of exiting process)
6 */
7
8#include "../system.h"
9
10#if USE_EXIT
11
12FORWARD _PROTOTYPE( void clear_proc, (register struct proc *rc));
13
14/*===========================================================================*
15 * do_exit *
16 *===========================================================================*/
17PUBLIC int do_exit(m_ptr)
18message *m_ptr; /* pointer to request message */
19{
20/* Handle sys_exit. A user process has exited or a system process requests
21 * to exit. Only the PM can request other process slots to be cleared.
22 * The routine to clean up a process table slot cancels outstanding timers,
23 * possibly removes the process from the message queues, and resets certain
24 * process table fields to the default values.
25 */
26 int exit_proc_nr;
27
28 /* Determine what process exited. User processes are handled here. */
29 if (PM_PROC_NR == m_ptr->m_source) {
30 exit_proc_nr = m_ptr->PR_PROC_NR; /* get exiting process */
31 if (exit_proc_nr != SELF) { /* PM tries to exit self */
32 if (! isokprocn(exit_proc_nr)) return(EINVAL);
33 clear_proc(proc_addr(exit_proc_nr)); /* exit a user process */
34 return(OK); /* report back to PM */
35 }
36 }
37
38 /* The PM or some other system process requested to be exited. */
39 clear_proc(proc_addr(m_ptr->m_source));
40 return(EDONTREPLY);
41}
42
43/*===========================================================================*
44 * clear_proc *
45 *===========================================================================*/
46PRIVATE void clear_proc(rc)
47register struct proc *rc; /* slot of process to clean up */
48{
49 register struct proc *rp; /* iterate over process table */
50 register struct proc **xpp; /* iterate over caller queue */
51 int i;
52
53 /* Turn off any alarm timers at the clock. */
54 reset_timer(&priv(rc)->s_alarm_timer);
55
56 /* Make sure that the exiting process is no longer scheduled. */
57 if (rc->p_rts_flags == 0) lock_dequeue(rc);
58
59 /* If the process being terminated happens to be queued trying to send a
60 * message (e.g., the process was killed by a signal, rather than it doing
61 * a normal exit), then it must be removed from the message queues.
62 */
63 if (rc->p_rts_flags & SENDING) {
64 /* Check all proc slots to see if the exiting process is queued. */
65 for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
66 if (rp->p_caller_q == NIL_PROC) continue;
67 /* Make sure that the exiting process is not on the queue. */
68 xpp = &rp->p_caller_q;
69 while (*xpp != NIL_PROC) { /* check entire queue */
70 if (*xpp == rc) { /* process is on the queue */
71 *xpp = (*xpp)->p_q_link; /* replace by next process */
72 break;
73 }
74 xpp = &(*xpp)->p_q_link; /* proceed to next queued */
75 }
76 }
77 }
78
79 /* Check the table with IRQ hooks to see if hooks should be released. */
80 for (i=0; i < NR_IRQ_HOOKS; i++) {
81 if (irq_hooks[i].proc_nr == proc_nr(rc)) {
82 rm_irq_handler(&irq_hooks[i]); /* remove interrupt handler */
83 irq_hooks[i].proc_nr = NONE; /* mark hook as free */
84 }
85 }
86
87 /* Now it is safe to release the process table slot. If this is a system
88 * process, also release its privilege structure. Further cleanup is not
89 * needed at this point. All important fields are reinitialized when the
90 * slots are assigned to another, new process.
91 */
92 rc->p_rts_flags = SLOT_FREE;
93 if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
94}
95
96#endif /* USE_EXIT */
97
Note: See TracBrowser for help on using the repository browser.