CMSC 412

EXAM 1 SOLUTION

March 15, 1999

1 [6 pts]. Solution

 interruptHandler HwIntrpt( IO ) {
   UpdateRunQPCB() ; 
   move runQ.pcb to readyQ ;
   move ioWaitQ.head.PCB to head of readyQ ;
   if ioWaitQ is not empty
     then ioDevice.controlReg := ioWaitQ.head.pcb.ioParams ;
   Scheduler() ;
 }

Alternatively,

 interruptHandler HwIntrpt( IO ) {
   UpdateRunQPCB() ;
   move runQ.pcb to readyQ ;
   move ioWaitQ.head.PCB to runQ ;
   if ioWaitQ is not empty
     then ioDevice.controlReg := ioWaitQ.head.pcb.ioParams ;
   Dispatch() ;
 }
GRADING: Roughly 1 point for each line of code.

COMMON MISTAKES:

2 [12 pts]. Solution

interruptHandler Syscall( SEND, int dest, int msg ) {
     UpdateRunQPCB() ;                                   // 1 point
     if ( recQ has a pcb, say x, with x.pid=dest         // 1 point
                         and x.src=runQ.pcb.pid )        // 1 point
        then { x.recBuff := msg ;                        // 1 point
               move x from recQ to readyQ ;              // 1 point
             }
        else { move runQ pcb to sendQ ;                  // 1 point
               Scheduler() ;
             }
interruptHandler Syscall( REC, int src ) {
     UpdateRunQPCB() ;                                   // 1 point
     if ( sendQ has a pcb, say x, with x.pid=src         // 1 point
                         and x.dest=runQ.pcb.pid )       // 1 point
        then { runQ.pcb.recBuff := x.msg ;               // 1 point
               move x from sendQ to readyQ ;             // 1 point
             }
        else { move runQ pcb to recQ ;                   // 1 point
               Scheduler() ;
             }

For a queued pcb x, the parameters of its system call (i.e., dest, msg, src) can be accessed via x.sp [because the parameters would be at or near the top of x's stack, depending on the compiler's calling convention]. Alternatively, one can add additional fields (e.g., sendBuff, src, dest) to the pcb and have the system call store the parameters there in the event of the process being blocked (i.e., taking the "else" branch).

In the above system calls, if the running process does block then it continues to be running. An alternative design for the system call is that if the running process does not block then it becomes ready (rather than stay running) and the scheduler is called in any case. The send syscall would become

interruptHandler Syscall( SEND, int dest, int msg ) {
     UpdateRunQPCB() ;                                   // 1 point
     if ( recQ has a pcb, say x, with x.pid=dest         // 1 point
                         and x.src=runQ.pcb.pid )        // 1 point
        then { x.recBuff := msg ;                        // 1 point
               move x from recQ to readyQ ;              // 1 point
               move runQ pcb to readyQ ;
             }
        else { move runQ pcb to sendQ ;                  / 1 point
             };
     Scheduler() ;

GRADING: Roughly 1 point per line of code, as indicated above.

COMMON MISTAKES:

3 [12 pts]. Solution

Part a [6 points].

Safety property holds.

Proof

End of proof

COMMON MISTAKES:

Part b [6 points].

Progress does not hold.

Counter-example execution (each entry signifies execution of the statement):

Here, P1 is hungry for ever even though P0 does not stay in CS forever and P0 and P1 execute with weak fairness.