It appears that there is a race condition in WaitForEvent... after all events
are checked the idle event is signaled. But if a timer tick interrupt comes in
and schedules work (SignalEvent) after the loop is done but before the event is
signaled, we will delay unnecessarily for an additional timer tick interrupt
(due to an HLT or WFI) before the event is recognized. This could have a
performance impact if WaitForEvent is used in a tight loop waiting for IO.
for(;;) {
for(Index = 0; Index < NumberOfEvents; Index++) {
Status = CoreCheckEvent (UserEvents[Index]);
//
// provide index of event that caused problem
//
if (Status != EFI_NOT_READY) {
*UserIndex = Index;
return Status;
}
}
>> what if a timer tick happens here?? <<
//
// Signal the Idle event
//
CoreSignalEvent (gIdleLoopEvent);
}
}
I think the solution is that interrupts must be disabled while deciding if
there is work to do. It looks like ARM, IA32, and X64 architectures have this
exposure.
I researched if it possible to do WFI/HLT with interrupts masked off. On ARM
it is valid to issue a WFI with IRQ and FIQ masked off since it will unblock
with pending (but masked interrupts). On IA it's a bit trickier since HLT will
hang forever if interrupts are masked off. From what I've read (although I
could not find an authoritative statement in the IA documentation), the
solution is that an 'STI; HLT' together will allow the halt to be bypassed if
an interrupt is pending (see
http://lists.freebsd.org/pipermail/freebsd-current/2004-June/029369.html ).
Eugene
------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel