PM delay call infrastructure improvements
- 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
This commit is contained in:
parent
f11f597777
commit
49808dcf77
8 changed files with 34 additions and 23 deletions
|
@ -639,8 +639,10 @@
|
|||
/* 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 *
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue