VirtualBox

Changeset 72639 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Jun 21, 2018 1:51:44 PM (6 years ago)
Author:
vboxsync
Message:

IPRT,VMM: Try use KeShouldYieldProcessor to implement RTThreadPreemptIsPending on Windows. That'll save us a lot of pain with changing _KPRCB structures. bugref:5102

Location:
trunk/src/VBox/Runtime/r0drv/nt
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp

    r70341 r72639  
    9595/** KeInitializeTimerEx - Introduced in NT 4. */
    9696decltype(KeInitializeTimerEx)          *g_pfnrtKeInitializeTimerEx;
     97/** KeShouldYieldProcessor - Introduced in Windows 10. */
     98PFNKESHOULDYIELDPROCESSOR               g_pfnrtKeShouldYieldProcessor;
    9799/** Pointer to the MmProtectMdlSystemAddress kernel function if it's available.
    98100 * This API was introduced in XP. */
     
    306308    GET_SYSTEM_ROUTINE(KeSetTargetProcessorDpc);
    307309    GET_SYSTEM_ROUTINE(KeInitializeTimerEx);
     310    GET_SYSTEM_ROUTINE_TYPE(KeShouldYieldProcessor, PFNKESHOULDYIELDPROCESSOR);
    308311    GET_SYSTEM_ROUTINE(MmProtectMdlSystemAddress);
    309312    GET_SYSTEM_ROUTINE(MmAllocatePagesForMdl);
  • trunk/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h

    r70341 r72639  
    8585extern decltype(KeSetTargetProcessorDpc)      *g_pfnrtKeSetTargetProcessorDpc;
    8686extern decltype(KeInitializeTimerEx)          *g_pfnrtKeInitializeTimerEx;
     87extern PFNKESHOULDYIELDPROCESSOR               g_pfnrtKeShouldYieldProcessor;
    8788extern decltype(MmProtectMdlSystemAddress)    *g_pfnrtMmProtectMdlSystemAddress;
    8889extern decltype(MmAllocatePagesForMdl)        *g_pfnrtMmAllocatePagesForMdl;
  • trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp

    r70334 r72639  
    9696
    9797    /*
     98     * The KeShouldYieldProcessor API introduced in Windows 10 looks like exactly
     99     * what we want.  But of course there is a snag.  It may return with interrupts
     100     * enabled when called with them disabled.  Let's just hope it doesn't get upset
     101     * by disabled interrupts in other ways...
     102     */
     103    if (g_pfnrtKeShouldYieldProcessor)
     104    {
     105        RTCCUINTREG fSavedFlags = ASMGetFlags();
     106        bool fReturn = g_pfnrtKeShouldYieldProcessor() != FALSE;
     107        ASMSetFlags(fSavedFlags);
     108        return fReturn;
     109    }
     110
     111    /*
     112     * Fallback approach for pre W10 kernels.
     113     *
     114     * If W10 is anything to go by, we should also check and yield when:
     115     *      - pPrcb->NextThread != NULL && pPrcb->NextThread != pPrcb->CurrentThread
     116     *        when QuantumEnd is zero.
     117     *      - pPrcb->DpcRequestSummary & 1
     118     *      - pPrcb->DpcRequestSummary & 0x1e
     119     */
     120
     121    /*
    98122     * Read the globals and check if they are useful.
    99123     */
     
    154178RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
    155179{
     180    if (g_pfnrtKeShouldYieldProcessor)
     181        return true;
    156182#if 0 /** @todo RTThreadPreemptIsPending isn't good enough on w7 and possibly elsewhere. */
    157183    /* RTThreadPreemptIsPending is only reliable if we've got both offsets and size. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette