Dynamic switching of co-processor context
sebastian.huber at embedded-brains.de
Wed Oct 14 14:19:28 UTC 2009
This discussion focus on the PowerPC, but other architectures may be similar.
Suppose you have a co-processor (floating-point, digital signal processing,
vector unit) which only few tasks need (more than one) or that is seldom used
by tasks (printf() for example), then it is desirable to remove the
co-processor context switching from the normal context switch. The separation
of the context switching results in a reduced context switch time. This
reduces also the worst case time of disabled interrupts (= worst case interrupt
latency WCIL). On the PowerPC the WCIL is very likely this sequence:
1. An interrupt handler finishes its work
2. External exceptions are disabled at the end of interrupt processing
3. First half of the exception epilogue
4. A context switch is necessary
5. Context switch to a task that was suspended by an interrupt
6. Second half of the exception epilogue
7. Return from exception
8. External exceptions are enabled again
In total we have "maximum context switch time" + "exception epilogue time" = WCIL.
The co-processor context switching will be done in a task context and thus does
not affect higher priority tasks.
It will be assumed that you can enable or disable the co-processor availability
in a machine state register. At most one task may be the owner of the
co-processor context. If another task needs the co-processor the ownership has
to change. This requires saving of the context for the previous owner and
restoring of the context for the new owner. The tasks not owning the
co-processor trigger an exception if they use a co-processor facility. The
exception handler hands over the ownership. This leads to the problem that the
machine state of a not executing task has to be modified. Typically the
sequence to modify the machine state is
1. Move the machine state register into a general purpose register.
2. Modify the value in the general purpose register.
3. Write the modfied value back into the machine state register.
Here we have the problem that this sequence may be interrupted at any time. If
a context switch happens during 2. and 3. and the co-processor ownership
changes in the meantime, then the task overwrites the updated machine state
directly after it resumes execution and this may leads to a corrupted
co-processor context. On the PowerPC such a sequence is used to disable the
interrupts, so we need a workaround.
Use a special instruction to disable interrupts atomically. Not
every variant may have this.
Disable the co-processor availability in every modified machine
state register value. Example:
msr = read_from_msr()
The PowerPC needs a synchronization instruction after the move to MSR if
the FP bit is switched off.
This variant is easy. The drawback is that the co-processor may be
switched off more often than it is needed.
Check the co-processor ownership after the machine state register
update and disable the co-processor availability if required. Example:
executing = _Thread_Executing
msr = read_from_msr()
if co_processor_owner != executing
Each variant will result in a modified interrupt enable, flash, and disable
code in the Cpukit. The user has to review its code for usages of the machine
state register. The question is how to deal with this? We also need an
exception handler. Currently on the PowerPC exception handlers are not
available in the Cpukit. I converted most of the BSPs to use the shared
exception code (only mpc5xx is missing) and will commit this in the near
future. So it is feasible that we have the PowerPC exception code back in the
Cpukit some time.
I would be glad if you send me some comments to this.
Sebastian Huber, embedded brains GmbH
Address : Obere Lagerstr. 30, D-82178 Puchheim, Germany
Phone : +49 89 18 90 80 79-6
Fax : +49 89 18 90 80 79-9
E-Mail : sebastian.huber at embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the users