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