/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main() { /* Main routine of the process manager. */ int result, s, proc_nr; struct mproc *rmp; sigset_t sigset; pm_init(); /* initialize process manager tables */ /* This is PM's main loop- get work and do it, forever and forever. */ while (TRUE) { get_work(); /* wait for an PM system call */ /* Check for system notifications first. Special cases. */ if (call_nr == SYN_ALARM) { pm_expire_timers(m_in.NOTIFY_TIMESTAMP); result = SUSPEND; /* don't reply */ } else if (call_nr == SYS_SIG) { /* signals pending */ sigset = m_in.NOTIFY_ARG; if (sigismember(&sigset, SIGKSIG)) (void) ksig_pending(); result = SUSPEND; /* don't reply */ } /* Else, if the system call number is valid, perform the call. */ else if ((unsigned) call_nr >= NCALLS) { result = ENOSYS; } else { result = (*call_vec[call_nr])(); } /* Send the results back to the user to indicate completion. */ if (result != SUSPEND) setreply(who, result); swap_in(); /* maybe a process can be swapped in? */ /* Send out all pending reply messages, including the answer to * the call just made above. The processes must not be swapped out. */ 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 just a zombie, don't try to reply. */ if ((rmp->mp_flags & (REPLY | ONSWAP | IN_USE | ZOMBIE)) == (REPLY | IN_USE)) { if ((s=send(proc_nr, &rmp->mp_reply)) != OK) { panic(__FILE__,"PM can't reply to", proc_nr); } rmp->mp_flags &= ~REPLY; } } } return(OK); }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main() { /* Main routine of the process manager. */ int result, s, proc_nr; struct mproc *rmp; sigset_t sigset; pm_init(); /* initialize process manager tables */ /* This is PM's main loop- get work and do it, forever and forever. */ while (TRUE) { get_work(); /* wait for an PM system call */ /* Check for system notifications first. Special cases. */ switch(call_nr) { case SYN_ALARM: pm_expire_timers(m_in.NOTIFY_TIMESTAMP); result = SUSPEND; /* don't reply */ break; case SYS_SIG: /* signals pending */ sigset = m_in.NOTIFY_ARG; if (sigismember(&sigset, SIGKSIG)) { (void) ksig_pending(); } result = SUSPEND; /* don't reply */ break; case PM_GET_WORK: if (who_e == FS_PROC_NR) { send_work(); result= SUSPEND; /* don't reply */ } else result= ENOSYS; break; case PM_EXIT_REPLY: case PM_REBOOT_REPLY: case PM_EXEC_REPLY: case PM_CORE_REPLY: case PM_EXIT_REPLY_TR: if (who_e == FS_PROC_NR) { handle_fs_reply(&m_in); result= SUSPEND; /* don't reply */ } else result= ENOSYS; break; case ALLOCMEM: result= do_allocmem(); break; case FORK_NB: result= do_fork_nb(); break; case EXEC_NEWMEM: result= exec_newmem(); break; case EXEC_RESTART: result= do_execrestart(); break; case PROCSTAT: result= do_procstat(); break; case GETPROCNR: result= do_getprocnr(); break; case GETPUID: result= do_getpuid(); break; case DIAG_REPL : diag_repl(); result= SUSPEND; break; default: /* Else, if the system call number is valid, perform the * call. */ if ((unsigned) call_nr >= NCALLS) { result = ENOSYS; } else { #if ENABLE_SYSCALL_STATS calls_stats[call_nr]++; #endif result = (*call_vec[call_nr])(); } break; } /* Send the results back to the user to indicate completion. */ if (result != SUSPEND) setreply(who_p, result); /* 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 just a zombie, don't try to reply. */ if ((rmp->mp_flags & (REPLY | IN_USE | ZOMBIE)) == (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; } } } return(OK); }