PM: send replies immediately

The original delayed reply functionality was there to support swapping
in processes as they are unblocked, but swap support is long gone.
These days, this code only incurs overhead and hides bugs.

Change-Id: I4aebcd80719daa1bec45ac91975ddc9a460d74d4
This commit is contained in:
David van Moolenbroek 2013-10-27 18:37:16 +01:00 committed by Lionel Sambuc
parent f310aefcbd
commit efd3487bc5
8 changed files with 36 additions and 82 deletions

View file

@ -20,20 +20,19 @@ struct mproc mproc[NR_PROCS];
*===========================================================================*/
static char *flags_str(int flags)
{
static char str[13];
static char str[12];
str[0] = (flags & WAITING) ? 'W' : '-';
str[1] = (flags & ZOMBIE) ? 'Z' : '-';
str[2] = (flags & ALARM_ON) ? 'A' : '-';
str[3] = (flags & EXITING) ? 'E' : '-';
str[4] = (flags & TRACE_STOPPED) ? 'T' : '-';
str[5] = (flags & SIGSUSPENDED) ? 'U' : '-';
str[6] = (flags & REPLY) ? 'R' : '-';
str[7] = (flags & VFS_CALL) ? 'F' : '-';
str[8] = (flags & PROC_STOPPED) ? 's' : '-';
str[9] = (flags & PRIV_PROC) ? 'p' : '-';
str[10] = (flags & PARTIAL_EXEC) ? 'x' : '-';
str[11] = (flags & DELAY_CALL) ? 'd' : '-';
str[12] = '\0';
str[6] = (flags & VFS_CALL) ? 'F' : '-';
str[7] = (flags & PROC_STOPPED) ? 's' : '-';
str[8] = (flags & PRIV_PROC) ? 'p' : '-';
str[9] = (flags & PARTIAL_EXEC) ? 'x' : '-';
str[10] = (flags & DELAY_CALL) ? 'd' : '-';
str[11] = '\0';
return str;
}
@ -50,7 +49,7 @@ void mproc_dmp()
}
printf("Process manager (PM) process table dump\n");
printf("-process- -nr-pnr-tnr- --pid--ppid--pgrp- -uid-- -gid-- -nice- -flags------\n");
printf("-process- -nr-pnr-tnr- --pid--ppid--pgrp- -uid-- -gid-- -nice- -flags-----\n");
for (i=prev_i; i<NR_PROCS; i++) {
mp = &mproc[i];
if (mp->mp_pid == 0 && i != PM_PROC_NR) continue;

View file

@ -168,7 +168,7 @@ void exec_restart(struct mproc *rmp, int result, vir_bytes pc, vir_bytes sp,
sys_kill(rmp->mp_endpoint, SIGKILL);
return;
}
setreply(rmp-mproc, result);
reply(rmp-mproc, result);
return;
}

View file

@ -218,7 +218,7 @@ int do_srv_fork()
sig_proc(rmc, SIGSTOP, TRUE /*trace*/, FALSE /* ksig */);
/* Wakeup the newly created process */
setreply(rmc-mproc, OK);
reply(rmc-mproc, OK);
return rmc->mp_pid;
}
@ -435,7 +435,7 @@ int dump_core; /* flag indicating whether to dump core */
{
/* Wake up the tracer, completing the ptrace(T_EXIT) call */
mproc[rmp->mp_tracer].mp_reply.reply_trace = 0;
setreply(rmp->mp_tracer, OK);
reply(rmp->mp_tracer, OK);
}
/* Clean up if the parent has collected the exit status */
@ -648,7 +648,7 @@ register struct mproc *child; /* tells which process is exiting */
/* Wake up the parent by sending the reply message. */
exitstatus = (child->mp_exitstatus << 8) | (child->mp_sigstatus & 0377);
parent->mp_reply.reply_res2 = exitstatus;
setreply(child->mp_parent, child->mp_pid);
reply(child->mp_parent, child->mp_pid);
parent->mp_flags &= ~WAITING; /* parent no longer waiting */
child->mp_flags &= ~ZOMBIE; /* child no longer a zombie */
child->mp_flags |= TOLD_PARENT; /* avoid informing parent twice */
@ -672,7 +672,7 @@ struct mproc *child; /* tells which process is exiting */
exitstatus = (child->mp_exitstatus << 8) | (child->mp_sigstatus & 0377);
tracer->mp_reply.reply_res2 = exitstatus;
setreply(child->mp_tracer, child->mp_pid);
reply(child->mp_tracer, child->mp_pid);
tracer->mp_flags &= ~WAITING; /* tracer no longer waiting */
child->mp_flags &= ~TRACE_ZOMBIE; /* child no longer zombie to tracer */
child->mp_flags |= ZOMBIE; /* child is now zombie to parent */

View file

@ -6,7 +6,7 @@
*
* The entry points into this file are:
* main: starts PM running
* setreply: set the reply to be sent to process making an PM system call
* reply: send a reply to a process making a PM system call
*/
#include "pm.h"
@ -38,7 +38,6 @@
EXTERN unsigned long calls_stats[NCALLS];
#endif
static void sendreply(void);
static int get_nice_value(int queue);
static void handle_vfs_reply(void);
@ -48,7 +47,6 @@ static void handle_vfs_reply(void);
/* SEF functions and variables. */
static void sef_local_startup(void);
static int sef_cb_init_fresh(int type, sef_init_info_t *info);
static int sef_cb_signal_manager(endpoint_t target, int signo);
/*===========================================================================*
* main *
@ -93,8 +91,7 @@ int main()
expire_timers(m_in.NOTIFY_TIMESTAMP);
}
/* done, send reply and continue */
sendreply();
/* done, continue */
continue;
}
@ -140,8 +137,7 @@ int main()
}
/* Send reply. */
if (result != SUSPEND) setreply(who_p, result);
sendreply();
if (result != SUSPEND) reply(who_p, result);
}
return(OK);
}
@ -158,7 +154,7 @@ static void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_manager(sef_cb_signal_manager);
sef_setcb_signal_manager(process_ksig);
/* Let SEF perform startup. */
sef_startup();
@ -296,67 +292,27 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
}
/*===========================================================================*
* sef_cb_signal_manager *
* reply *
*===========================================================================*/
static int sef_cb_signal_manager(endpoint_t target, int signo)
{
/* Process signal on behalf of the kernel. */
int r;
r = process_ksig(target, signo);
sendreply();
return r;
}
/*===========================================================================*
* setreply *
*===========================================================================*/
void setreply(proc_nr, result)
void reply(proc_nr, result)
int proc_nr; /* process to reply to */
int result; /* result of call (usually OK or error #) */
{
/* Fill in a reply message to be sent later to a user process. System calls
* may occasionally fill in other fields, this is only for the main return
* value, and for setting the "must send reply" flag.
/* Send a reply to a user process. System calls may occasionally fill in other
* fields, this is only for the main return value and for sending the reply.
*/
register struct mproc *rmp = &mproc[proc_nr];
struct mproc *rmp;
int r;
if(proc_nr < 0 || proc_nr >= NR_PROCS)
panic("setreply arg out of range: %d", proc_nr);
panic("reply arg out of range: %d", proc_nr);
rmp = &mproc[proc_nr];
rmp->mp_reply.reply_res = result;
rmp->mp_flags |= REPLY; /* reply pending */
}
/*===========================================================================*
* sendreply *
*===========================================================================*/
static void sendreply()
{
int proc_nr;
int s;
struct mproc *rmp;
/* Send out all pending reply messages, including the answer to
* the call just made above.
*/
for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
/* In the meantime, the process may have been killed by a
* signal (e.g. if a lethal pending signal was unblocked)
* without the PM realizing it. If the slot is no longer in
* use or the process is exiting, don't try to reply.
*/
if ((rmp->mp_flags & (REPLY | IN_USE | EXITING)) ==
(REPLY | IN_USE)) {
s=sendnb(rmp->mp_endpoint, &rmp->mp_reply);
if (s != OK) {
printf("PM can't reply to %d (%s): %d\n",
rmp->mp_endpoint, rmp->mp_name, s);
}
rmp->mp_flags &= ~REPLY;
}
}
if ((r = sendnb(rmp->mp_endpoint, &rmp->mp_reply)) != OK)
printf("PM can't reply to %d (%s): %d\n", rmp->mp_endpoint,
rmp->mp_name, r);
}
/*===========================================================================*
@ -423,13 +379,13 @@ static void handle_vfs_reply()
case PM_SETGID_REPLY:
case PM_SETGROUPS_REPLY:
/* Wake up the original caller */
setreply(rmp-mproc, OK);
reply(rmp-mproc, OK);
break;
case PM_SETSID_REPLY:
/* Wake up the original caller */
setreply(rmp-mproc, rmp->mp_procgrp);
reply(rmp-mproc, rmp->mp_procgrp);
break;
@ -468,15 +424,15 @@ static void handle_vfs_reply()
/* Wake up the parent with a failed fork (unless dead) */
if (!new_parent)
setreply(rmp->mp_parent, -1);
reply(rmp->mp_parent, -1);
}
else {
/* Wake up the child */
setreply(proc_n, OK);
reply(proc_n, OK);
/* Wake up the parent, unless the parent is already dead */
if (!new_parent)
setreply(rmp->mp_parent, rmp->mp_pid);
reply(rmp->mp_parent, rmp->mp_pid);
}
break;

View file

@ -82,7 +82,6 @@ EXTERN struct mproc {
#define TOLD_PARENT 0x00040 /* parent wait() completed, ZOMBIE off */
#define TRACE_STOPPED 0x00080 /* set if process stopped for tracing */
#define SIGSUSPENDED 0x00100 /* set by SIGSUSPEND system call */
#define REPLY 0x00200 /* set if a reply message is pending */
#define VFS_CALL 0x00400 /* set if waiting for VFS (normal calls) */
#define NEW_PARENT 0x00800 /* process's parent changed during VFS call */
#define UNPAUSED 0x01000 /* VFS has replied to unpause request */

View file

@ -37,7 +37,7 @@ int do_set(void);
/* main.c */
int main(void);
void setreply(int proc_nr, int result);
void reply(int proc_nr, int result);
/* mcontext.c */
int do_getmcontext(void);

View file

@ -816,7 +816,7 @@ int signo; /* signal to send to process (1 to _NSIG-1) */
if (rmp->mp_flags & (WAITING | SIGSUSPENDED)) {
rmp->mp_flags &= ~(WAITING | SIGSUSPENDED);
setreply(slot, EINTR);
reply(slot, EINTR);
/* The process must just have been stopped by unpause(), which means
* that the UNPAUSE flag is not set.

View file

@ -262,6 +262,6 @@ int signo;
rpmp->mp_flags &= ~WAITING; /* parent is no longer waiting */
rpmp->mp_reply.reply_res2 = 0177 | (signo << 8);
setreply(rmp->mp_tracer, rmp->mp_pid);
reply(rmp->mp_tracer, rmp->mp_pid);
}
}