]> Zhao Yanbai Git Server - minix.git/commitdiff
PM delay call infrastructure improvements
authorDavid van Moolenbroek <david@minix3.org>
Thu, 1 Oct 2009 10:36:09 +0000 (10:36 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 1 Oct 2009 10:36:09 +0000 (10:36 +0000)
- allow PM to tell sys_runctl() whether to use delay call feature
- only use this feature in PM for delivering signals - not for exits
- do better error checking in PM on sys_runctl() calls
- rename SIGKREADY to SIGNDELAY

include/minix/com.h
include/minix/syslib.h
include/signal.h
kernel/system.c
kernel/system/do_runctl.c
lib/syslib/sys_runctl.c
servers/pm/forkexit.c
servers/pm/signal.c

index 9b5c76572d61109ce21d95532369ccc91be2750c..50c30b77bc8da210f606c93fe7619396afacf9ec 100755 (executable)
 /* Field names for SYS_RUNCTL. */
 #define RC_ENDPT       m1_i1   /* which process to stop or resume */
 #define RC_ACTION      m1_i2   /* set or clear stop flag */
-#  define RC_STOP           0  /* stop the process, unless delaying */
+#  define RC_STOP           0  /* stop the process */
 #  define RC_RESUME         1  /* clear the stop flag */
+#define RC_FLAGS       m1_i3   /* request flags */
+#  define RC_DELAY          1  /* delay stop if process is sending */
 
 /*===========================================================================*
  *                Messages for the Reincarnation Server                     *
index b3f6d0cad1de1311840b241329d0c4df763b4bad..b879a1c96940551843a2738ce4720ed66570a7d7 100755 (executable)
@@ -41,9 +41,10 @@ _PROTOTYPE( int sys_exit, (endpoint_t proc_ep));
 _PROTOTYPE( int sys_trace, (int req, endpoint_t proc_ep, long addr, long *data_p));
 
 /* Shorthands for sys_runctl() system call. */
-#define sys_stop(proc_ep) sys_runctl(proc_ep, RC_STOP)
-#define sys_resume(proc_ep) sys_runctl(proc_ep, RC_RESUME)
-_PROTOTYPE( int sys_runctl, (endpoint_t proc_ep, int action));
+#define sys_stop(proc_ep) sys_runctl(proc_ep, RC_STOP, 0)
+#define sys_delay_stop(proc_ep) sys_runctl(proc_ep, RC_STOP, RC_DELAY)
+#define sys_resume(proc_ep) sys_runctl(proc_ep, RC_RESUME, 0)
+_PROTOTYPE( int sys_runctl, (endpoint_t proc_ep, int action, int flags));
 
 _PROTOTYPE( int sys_privctl, (endpoint_t proc_ep, int req, void *p));
 _PROTOTYPE( int sys_setgrant, (cp_grant_t *grants, int ngrants));
index 2b47fc26993c38b3725d0f12c5e5f370ca8ab238..72ae004943a1ae23c73903753df42676e5cf1bf2 100755 (executable)
@@ -66,7 +66,7 @@ typedef unsigned long sigset_t;
  */
 #define SIGKMESS         29    /* new kernel message */
 #define SIGKSIG          30    /* kernel signal pending */
-#define SIGKREADY        31    /* ready for signal delivery */
+#define SIGNDELAY        31    /* end of delay for signal delivery */
 
 #endif
 
index 3e7fff8e9e476c5d45106a064f71ca329fc914a9..888170093a8dac0cb57ebccaec5f776d2d0ef3ce 100755 (executable)
@@ -374,13 +374,13 @@ PUBLIC void sig_delay_done(rp)
 struct proc *rp;
 {
 /* A process is now known not to send any direct messages.
- * Tell PM by sending a signal to the process.
+ * Tell PM that the stop delay has ended, by sending a signal to the process.
  * Used for actual signal delivery.
  */
 
   rp->p_misc_flags &= ~MF_SIG_DELAY;
 
-  cause_sig(proc_nr(rp), SIGKREADY);
+  cause_sig(proc_nr(rp), SIGNDELAY);
 }
 
 #if _MINIX_CHIP == _CHIP_INTEL
index 5b24e259e0ddae95d87b95c72615f8aa45120fa8..466b0ce449f7bb2175ea6cbe90dbb3224f4d82e8 100644 (file)
@@ -4,6 +4,7 @@
  * The parameters for this kernel call are:
  *    m1_i1:   RC_ENDPT        process number to control
  *    m1_i2:   RC_ACTION       stop or resume the process
+ *    m1_i3:   RC_FLAGS        request flags
  */
 
 #include "../system.h"
@@ -18,10 +19,11 @@ PUBLIC int do_runctl(message *m_ptr)
 {
 /* Control a process's PROC_STOP flag. Used for process management.
  * If the process is queued sending a message or stopped for system call
- * tracing, set MF_SIG_DELAY instead of PROC_STOP, and send a SIGKREADY signal
- * later when the process is done sending. Used by PM for safe signal delivery.
+ * tracing, and the RC_DELAY request flag is given, set MF_SIG_DELAY instead
+ * of PROC_STOP, and send a SIGNDELAY signal later when the process is done
+ * sending (ending the delay). Used by PM for safe signal delivery.
  */
-  int proc_nr, action, delayed;
+  int proc_nr, action, flags, delayed;
   register struct proc *rp;
 
   /* Extract the message parameters and do sanity checking. */
@@ -30,13 +32,15 @@ PUBLIC int do_runctl(message *m_ptr)
   rp = proc_addr(proc_nr);
 
   action = m_ptr->RC_ACTION;
+  flags = m_ptr->RC_FLAGS;
 
   /* Is the target sending or syscall-traced? Then set MF_SIG_DELAY instead.
+   * Do this only when the RC_DELAY flag is set in the request flags field.
    * The process will not become runnable before PM has called SYS_ENDKSIG.
    * Note that asynchronous messages are not covered: a process using SENDA
    * should not also install signal handlers *and* expect POSIX compliance.
    */
-  if (action == RC_STOP) {
+  if (action == RC_STOP && (flags & RC_DELAY)) {
        RTS_LOCK_SET(rp, SYS_LOCK);
 
        if (RTS_ISSET(rp, SENDING) || (rp->p_misc_flags & MF_SC_DEFER))
index 7c31eef4b54ec32031459e5b889f6a80b58c2968..fb2afc7d054f182659c2a964c8de317f097194ac 100644 (file)
@@ -3,12 +3,13 @@
 /*===========================================================================*
  *                                sys_runctl                                *
  *===========================================================================*/
-PUBLIC int sys_runctl(endpoint_t proc_ep, int action)
+PUBLIC int sys_runctl(endpoint_t proc_ep, int action, int flags)
 {
   message m;
 
   m.RC_ENDPT = proc_ep;
   m.RC_ACTION = action;
+  m.RC_FLAGS = flags;
 
   return(_taskcall(SYSTASK, SYS_RUNCTL, &m));
 }
index 30b58fd316a826176ff59a4e9da03d8fcc62ad67..72266c745f3e3a5d8f793ee96859b5ba9d6c8464 100644 (file)
@@ -273,7 +273,9 @@ int dump_core;                      /* flag indicating whether to dump core */
    * This order is important so that FS can tell drivers to cancel requests
    * such as copying to/ from the exiting process, before it is gone.
    */
-  sys_stop(proc_nr_e);         /* stop the process */
+  if ((r = sys_stop(proc_nr_e)) != OK)         /* stop the process */
+       panic(__FILE__, "sys_stop failed", r);
+
   if((r=vm_willexit(proc_nr_e)) != OK) {
        panic(__FILE__, "exit_proc: vm_willexit failed", r);
   }
index 47bbedb5e3e29edfd818ffc6e52500d25a2024e4..7a234c050e11bb694de319e948f6080ddbfd9dd3 100644 (file)
@@ -298,14 +298,14 @@ sigset_t sig_map;
        check_sig(id, i);
   }
 
-  /* If SIGKREADY is set, an earlier sys_stop() failed because the process was
+  /* If SIGNDELAY is set, an earlier sys_stop() failed because the process was
    * still sending, and the kernel hereby tells us that the process is now done
    * with that. We can now try to resume what we planned to do in the first
    * place: set up a signal handler. However, the process's message may have
    * been a call to PM, in which case the process may have changed any of its
    * signal settings. The process may also have forked, exited etcetera.
    */
-  if (sigismember(&sig_map, SIGKREADY) && (rmp->mp_flags & DELAY_CALL)) {
+  if (sigismember(&sig_map, SIGNDELAY) && (rmp->mp_flags & DELAY_CALL)) {
        rmp->mp_flags &= ~DELAY_CALL;
 
        if (rmp->mp_flags & (FS_CALL | PM_SIG_PENDING))
@@ -377,7 +377,7 @@ int trace;                  /* pass signal to tracer first? */
        sigaddset(&rmp->mp_sigpending, signo);
 
        if (!(rmp->mp_flags & PM_SIG_PENDING)) {
-               /* This stop request must never result in EBUSY here! */
+               /* No delay calls: FS_CALL implies the process called us. */
                if ((r = sys_stop(rmp->mp_endpoint)) != OK)
                        panic(__FILE__, "sys_stop failed", r);
 
@@ -555,6 +555,7 @@ struct mproc *rmp;
 {
 /* FS has replied to a request from us; do signal-related work.
  */
+  int r;
 
   if (rmp->mp_flags & (FS_CALL | EXITING)) return;
 
@@ -575,7 +576,8 @@ struct mproc *rmp;
        if (!(rmp->mp_flags & FS_CALL)) {
                rmp->mp_flags &= ~(PM_SIG_PENDING | UNPAUSED);
 
-               sys_resume(rmp->mp_endpoint);
+               if ((r = sys_resume(rmp->mp_endpoint)) != OK)
+                       panic(__FILE__, "sys_resume failed", r);
        }
   }
 }
@@ -601,9 +603,7 @@ struct mproc *rmp;          /* which process */
 
   /* Check to see if process is hanging on a PAUSE, WAIT or SIGSUSPEND call. */
   if (rmp->mp_flags & (PAUSED | WAITING | SIGSUSPENDED)) {
-       /* Stop process from running.
-        * This stop request must never result in EBUSY here!
-        */
+       /* Stop process from running. No delay calls: it called us. */
        if ((r = sys_stop(rmp->mp_endpoint)) != OK)
                panic(__FILE__, "sys_stop failed", r);
 
@@ -616,10 +616,10 @@ struct mproc *rmp;                /* which process */
   /* Not paused in PM. Let FS try to unpause the process. */
   if (!(rmp->mp_flags & PM_SIG_PENDING)) {
        /* Stop process from running. */
-       r = sys_stop(rmp->mp_endpoint);
+       r = sys_delay_stop(rmp->mp_endpoint);
 
        /* If the process is still busy sending a message, the kernel will give
-        * us EBUSY now and send a SIGKREADY to the process as soon as sending
+        * us EBUSY now and send a SIGNDELAY to the process as soon as sending
         * is done.
         */
        if (r == EBUSY) {
@@ -703,7 +703,8 @@ int signo;                  /* signal to send to process (1 to _NSIG-1) */
   if ((rmp->mp_flags & (PM_SIG_PENDING | UNPAUSED)) == UNPAUSED) {
        rmp->mp_flags &= ~UNPAUSED;
 
-       sys_resume(rmp->mp_endpoint);
+       if ((r = sys_resume(rmp->mp_endpoint)) != OK)
+               panic(__FILE__, "sys_resume failed", r);
   }
 
   return(TRUE);