Mean   = 15.8
Median = 15.4   X   X       X X
                X X X X     X X
______X___X_X___X_X_X_X_X_X_X_X_X___X_____X____
 . 6 . 8 . 10. 12. 14. 16. 18. 20. 22. 24. 26. 
Part A:
floating_point_error_trap_service_routine: -- UNIX
    save state of user process
    push user's signal mask on user's stack (as if it were a parameter)
    push SIGFPE on user's stack (as if it were a parameter)
    edit user's signal mask to block delivery of SIGFPE 
    push user's PC on user's stack (as if a call had been done)
    set user's PC to the address of the signal dispatcher
    restore state of user process
    return from trap
We assume that the signal dispatcher is a bit of code in the user's
address space that is something like the following:
    signal_dispatcher( int mask, int signal)
    {
	(signal_vec[signal])();
	setsigmask(mask);
    }
This is needed so that the return from signal can automatically restore
the signal mask that was saved when the signal was delivered.  It assumes
that signal_vec is an array of pointers to signal handlers.
Half clearly understood the UNIX semantics, but only one gave a good description of the mechanism needed to implement this semantics. One in four received no credit. The most common error leading to partial credit was the assumtion that the trap handler can directly call the user's signal handler. In general, this cannot be done.
Part B:
floating_point_error_trap_service_routine: -- Mach
    save state of thread that caused trap
    block thread that caused trap
    formulate message describing the exception
    send message to the exception handler of the thread's process
    pick a ready thread to be the new current thread
    restore state of new thread
    return from trap
Three in five clearly understood Mach semantics, and one in six gave good
descriptions of a mechanism that would implement this semantics.
One in four received no credit.  The most common error was to focus on the
exception handler that receives the message, as if the hardware itself sent
the exception message.
Part C:
floating_point_error_trap_service_routine: -- VM
    save state of process that caused trap
    find process's virtual trap vector entry for floating point error trap
    save process's PC and virtual PSW as requried for virtual trap delivery
    set process's PC and virtual PSW from trap vector entry
    restore state of process that caused trap
    return from trap
One in three clearly understood VM semantics, but only two gave good
descriptions of mechanisms that would implement this semantics.  One in five
received no credit.  One common error was to assume that VM could
directly call the user's trap handler.  Another common error was to assume
that the trap handler needed to know whether the system was running on a
real or virtual machine, or whether the user was running an operating system
or a bare-machine application.
If the page table entry is marked as "page is on disk", the trap service routine goes through the normal page replacement algorithm.
If the page table entry is marked as "page not mapped to virtual address", the page fault service routine forces a virtual page-fault for the user.
Two students got no dredit here, while around half proposed PSW-based decision algorithms, modelled after the pseudocode presented in class for VM's privileged instruction trap handler (see next question).
privileged_instruction_trap_handler: -- VM
    save state of user process
    if user's virtual PSW indicates user virtual privileged mode
	i = instruction that caused trap)
        emulate(i)
    else
        find process's virtual trap vector entry for privileged instruciton trap
        save process's PC and virtual PSW as requried for virtual trap delivery
        set process's PC and virtual PSW from trap vector entry
    endif
    restore state of user process
    return from trap
Two in five did well here, almost as many got no credit at all.  Common
errors involved misreading the question, for example, by trying to write
code for emulate(i), or assuming that the trap service routine could
directly call the user's virtual trap service routine.
Over half received no credit here, despite the fact that this question was lifted directly from the study questions. The wrong answers that were given ranged over a wide variety of topics, and only one really good answer was given.
Most did well here, but two got no credit.
Just under half had good answers here, while one in four got no credit. The most common error was to associate state information with the page itself (for example, reserving the first word of every page) instead of with the page-table entry.
Part B
page_fault_trap_service_routine:
    save state of calling thread
    va = virtual address that caused trap
    pte = page_table[ va.page ]
    if pte.type = object_reference
        block calling thread
        i = instruction at address va caller's address space
        -- assume i.opcode is either LOAD or STORE (the only mem ref instrs)
        create new thread in address space of object
	make this thread the current thread
        push va.byte_in_page on stack of current thread (parameter)
        push i.operand_size on stack of current thread (parameter)
        if i.opcode = LOAD
	    thread.pc = word 0 of current address space
        else i.opcode = STORE
	    push user's register i.register on stack (parameter)
	    thread.pc = word 1 of current address space
        endif
	push -1 on stack (an invalid return address)
    else
        ... other possibilities ...
    endif
    return to current thread
The above solution is overkill!  One in eight did well here, One in four
got no credit, and many either failed to do a context switch to the thread
of the object or assumed that the trap service routine could directly call
a method of this object.
One in five did well here, while one in six got no credit. Of those who got partial credit, a surprising number misread the question and emphasized the implementation of the semantics that were given instead of emphasizing the impact of this semantic choice on the resulting user code.
-- user code
    state = "want in"
    wait( entry_sem )
    -- critical section
    state = "done"
    signal( done_sem )
-- agent
    repeat
        await token
        if state = "want in"
            signal( entry_sem )
            wait ( done_sem )
        endif
        forward token
    forever
This requires two semaphores and a two-valued variable.
Half gave essentially the above (or a variation on this theme). One in six got no credit, while as many gave answers that were sufficiently vague that correctness was difficult to evaluate. This problem was lifted almost literally from a homework problem assigned earlier in the semester.
The update phase of each transaction could be implemented using pointer assignment. System failures may interrupt the sequence of assignments that mark the commit phase of a transaction, so all changes should be logged before the commit is attempted, and on system restart, the logs must be examined and compared with any data that persists through a failure.
One in six did very well. One in three failed to address the issue of how to commit a transaction. Less common errors included failing to understand the appropriateness of the two-phase model to this system (typically proposing a client-server model) or premature lock release.