From efd3487bc57acb651ca6e658a123e6809183701b Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Sun, 27 Oct 2013 18:37:16 +0100 Subject: [PATCH] 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 --- servers/is/dmp_pm.c | 17 +++++---- servers/pm/exec.c | 2 +- servers/pm/forkexit.c | 8 ++--- servers/pm/main.c | 84 +++++++++++-------------------------------- servers/pm/mproc.h | 1 - servers/pm/proto.h | 2 +- servers/pm/signal.c | 2 +- servers/pm/trace.c | 2 +- 8 files changed, 36 insertions(+), 82 deletions(-) diff --git a/servers/is/dmp_pm.c b/servers/is/dmp_pm.c index e6a46eaa5..151e4c5ac 100644 --- a/servers/is/dmp_pm.c +++ b/servers/is/dmp_pm.c @@ -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; imp_pid == 0 && i != PM_PROC_NR) continue; diff --git a/servers/pm/exec.c b/servers/pm/exec.c index f44a4940e..3fa75e889 100644 --- a/servers/pm/exec.c +++ b/servers/pm/exec.c @@ -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; } diff --git a/servers/pm/forkexit.c b/servers/pm/forkexit.c index 638f29e96..239766d6a 100644 --- a/servers/pm/forkexit.c +++ b/servers/pm/forkexit.c @@ -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 */ diff --git a/servers/pm/main.c b/servers/pm/main.c index 002f4926a..141333692 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -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; diff --git a/servers/pm/mproc.h b/servers/pm/mproc.h index ab2a2bd3f..27eb11745 100644 --- a/servers/pm/mproc.h +++ b/servers/pm/mproc.h @@ -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 */ diff --git a/servers/pm/proto.h b/servers/pm/proto.h index c1840aa1d..6762ccc65 100644 --- a/servers/pm/proto.h +++ b/servers/pm/proto.h @@ -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); diff --git a/servers/pm/signal.c b/servers/pm/signal.c index d3d7ed145..b2e727203 100644 --- a/servers/pm/signal.c +++ b/servers/pm/signal.c @@ -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. diff --git a/servers/pm/trace.c b/servers/pm/trace.c index e2077422e..efdc628bf 100644 --- a/servers/pm/trace.c +++ b/servers/pm/trace.c @@ -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); } }