The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/system/do_exit.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 
   12 FORWARD _PROTOTYPE( void clear_proc, (register struct proc *rc));
   13 
   14 /*===========================================================================*
   15  *                              do_exit                                      *
   16  *===========================================================================*/
   17 PUBLIC int do_exit(m_ptr)
   18 message *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  *===========================================================================*/
   46 PRIVATE void clear_proc(rc)
   47 register 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   int sys_id;
   53   char saved_rts_flags;
   54 
   55   /* Don't clear if already cleared. */
   56   if(isemptyp(rc)) return;
   57 
   58   /* Turn off any alarm timers at the clock. */   
   59   reset_timer(&priv(rc)->s_alarm_timer);
   60 
   61   /* Make sure that the exiting process is no longer scheduled. */
   62   if (rc->p_rts_flags == 0) lock_dequeue(rc);
   63 
   64   /* Release the process table slot. If this is a system process, also
   65    * release its privilege structure.  Further cleanup is not needed at
   66    * this point. All important fields are reinitialized when the 
   67    * slots are assigned to another, new process. 
   68    */
   69   saved_rts_flags = rc->p_rts_flags;
   70   rc->p_rts_flags = SLOT_FREE;          
   71   if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
   72 
   73   /* If the process being terminated happens to be queued trying to send a
   74    * message (e.g., the process was killed by a signal, rather than it doing 
   75    * a normal exit), then it must be removed from the message queues.
   76    */
   77   if (saved_rts_flags & SENDING) {
   78       xpp = &proc[rc->p_sendto].p_caller_q;     /* destination's queue */
   79       while (*xpp != NIL_PROC) {                /* check entire queue */
   80           if (*xpp == rc) {                     /* process is on the queue */
   81               *xpp = (*xpp)->p_q_link;          /* replace by next process */
   82 #if DEBUG_ENABLE_IPC_WARNINGS
   83               kprintf("Proc %d removed from queue at %d\n",
   84                   proc_nr(rc), rc->p_sendto);
   85 #endif
   86               break;                            /* can only be queued once */
   87           }
   88           xpp = &(*xpp)->p_q_link;              /* proceed to next queued */
   89       }
   90   }
   91 
   92   /* Likewise, if another process was sending or receive a message to or from 
   93    * the exiting process, it must be alerted that process no longer is alive.
   94    * Check all processes. 
   95    */
   96   for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
   97       if(isemptyp(rp))
   98         continue;
   99 
  100       /* Unset pending notification bits. */
  101       unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id);
  102 
  103       /* Check if process is receiving from exiting process. */
  104       if ((rp->p_rts_flags & RECEIVING) && rp->p_getfrom == proc_nr(rc)) {
  105           rp->p_reg.retreg = ESRCDIED;          /* report source died */
  106           rp->p_rts_flags &= ~RECEIVING;        /* no longer receiving */
  107 #if DEBUG_ENABLE_IPC_WARNINGS
  108           kprintf("Proc %d receive dead src %d\n", proc_nr(rp), proc_nr(rc));
  109 #endif
  110           if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
  111       } 
  112       if ((rp->p_rts_flags & SENDING) && rp->p_sendto == proc_nr(rc)) {
  113           rp->p_reg.retreg = EDSTDIED;          /* report destination died */
  114           rp->p_rts_flags &= ~SENDING;          /* no longer sending */
  115 #if DEBUG_ENABLE_IPC_WARNINGS
  116           kprintf("Proc %d send dead dst %d\n", proc_nr(rp), proc_nr(rc));
  117 #endif
  118           if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
  119       } 
  120   }
  121 
  122   /* Check the table with IRQ hooks to see if hooks should be released. */
  123   for (i=0; i < NR_IRQ_HOOKS; i++) {
  124       if (irq_hooks[i].proc_nr == proc_nr(rc)) {
  125           rm_irq_handler(&irq_hooks[i]);        /* remove interrupt handler */
  126           irq_hooks[i].proc_nr = NONE;          /* mark hook as free */
  127       }
  128   }
  129 }
  130 
  131 #endif /* USE_EXIT */
  132 

Cache object: 851bd9f0a808ae84dbd8c1a02705b3e5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.