How about this:

    * a per-process fp-in-use flag
    * a per-cpu fp-save-block ID (incrementing serial number)

    When a context switch from process A to process B occurs:

        if (process-A-using-FP) {
            increment ID
            save FP state for process A and ID
            fp-save-block-id = ID
        if (process-B-using-FP) {
            if (fp-save-block-id != B->saved_fp_state->ID) {
                restore FP state for B

    So lets take a few test cases:

    * Interrupt occurs

        - fp context saved
        - interrupt is scheduled on same cpu (lets say)
        - interrupt completes, original process switched back to
        - ID matches, no restore operation required.

    * Multiple interrupts occur or several context switches occur
      from the point of view of some cpu.

        - fp context saved
        - multiple interrupts & context switches occur, but none
          require the use of the FPU
        - switch back to original process
        - ID matches, no restore operation required.

    * Interrupt occurs, original process woken up on different cpu

        - fp context saved
        - all sorts of things happen
        - original process woken up on different cpu
        - ID does not match (ID is per-cpu), restore FP context

    * Kernel bcopy operation in case where no process switch occurs
      (i.e. current process was using the FP and while we went into
      kernel mode, we have not yet saved the FP state anywhere).

        if (process-A-using-FP) {
            push FP state for process A on stack
            push process-A-using-FP flag
        set process-A-using-FP flag
        use FP registers to do bcopy

        restore process-A-using-FP flag from stack
        restore FP state from stack

    This solution isn't perfect, we still wind up saving the FP state
    in the case of an interrupt, but at least we don't have to restore
    it if it is determined to still be valid.  Additionally it is possible
    that we might be able to switch between several processes under normal
    operating conditions and not have to restore the FP state of the original
    one when we get back to it if none of the intervening processes (or the
    kernel) use the FP.

    I can't think up of anything more optimal that isn't overly complex.  


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to