System Call Template
This code is present in nearly every system call
intmask mask; /* Saved interrupt mask */
struct procent *prptr; /* Ptr to process's table entry */
pri16 prio; /* Priority to return */
mask = disable();
.
.
.
restore(mask);
return prio;
We disable the interrupts before doing any system call code and then reenable it at the end. disable()
is an Assembly Language written function. If we don’t do this, the CPU may interrupt while this code is running.
- We use the
syscall
type to distinguish between system calls and normal functions
Resume
/* resume.c - resume */
#include <xinu.h>
/*------------------------------------------------------------------------
* resume - Unsuspend a process, making it ready
*------------------------------------------------------------------------
*/
pri16 resume(
pid32 pid /* ID of process to unsuspend */
)
{
intmask mask; /* Saved interrupt mask */
struct procent *prptr; /* Ptr to process's table entry */
pri16 prio; /* Priority to return */
mask = disable();
if (isbadpid(pid)) {
restore(mask);
return (pri16)SYSERR;
}
prptr = &proctab[pid];
if (prptr->prstate != PR_SUSP) {
restore(mask);
return (pri16)SYSERR;
}
prio = prptr->prprio; /* Record priority to return */
ready(pid);
restore(mask);
return prio;
}
- We first make sure the pid is valid
- We get the pointer to the process entry in the table
- We check its state to make sure its suspended, otherwise we shouldn’t resume it
- We save the priority being resumed for returning, and then call
ready(pid)
to set the process to a ready state.ready
also adds it to the queue for later execution
Ready
/* ready.c - ready */
#include <xinu.h>
qid16 readylist; /* Index of ready list */
/*------------------------------------------------------------------------
* ready - Make a process eligible for CPU service
*------------------------------------------------------------------------
*/
status ready(
pid32 pid /* ID of process to make ready */
)
{
register struct procent *prptr;
if (isbadpid(pid)) {
return SYSERR;
}
/* Set process state to indicate ready and add to ready list */
prptr = &proctab[pid];
prptr->prstate = PR_READY;
insert(pid, readylist, prptr->prprio);
resched();
return OK;
}
- Ready is not a system call, it doesn’t have the standard system call template
- We set the process state to ready and add it to the ready list before calling
resched()
(check Process Scheduling)
Suspend
/* suspend.c - suspend */
#include <xinu.h>
/*------------------------------------------------------------------------
* suspend - Suspend a process, placing it in hibernation
*------------------------------------------------------------------------
*/
syscall suspend(
pid32 pid /* ID of process to suspend */
)
{
intmask mask; /* Saved interrupt mask */
struct procent *prptr; /* Ptr to process's table entry */
pri16 prio; /* Priority to return */
mask = disable();
if (isbadpid(pid) || (pid == NULLPROC)) {
restore(mask);
return SYSERR;
}
/* Only suspend a process that is current or ready */
prptr = &proctab[pid];
if ((prptr->prstate != PR_CURR) && (prptr->prstate != PR_READY)) {
restore(mask);
return SYSERR;
}
if (prptr->prstate == PR_READY) {
getitem(pid); /* Remove a ready process */
/* from the ready list */
prptr->prstate = PR_SUSP;
} else {
prptr->prstate = PR_SUSP; /* Mark the current process */
resched(); /* suspended and resched. */
}
prio = prptr->prprio;
restore(mask);
return prio;
}
- Remember,
getitem
will pull the process out of the ready queue entirely (look at List and Queue Manipulation) - In the second case we
resched
since we are suspending the current process - Removing a process from the ready queue will never make a different process have to be prioritized or ran, so in the first case we don’t need to call
resched