VirtualBox

Ignore:
Timestamp:
Feb 18, 2015 4:11:34 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
98341
Message:

IPRT,TM: Implemented the get-cpu-number optimizations for the RTTimeNanoTS code.

Location:
trunk/src/VBox/Runtime/common/time
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/time/timesup.cpp

    r54252 r54270  
    5252static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalFallback(PRTTIMENANOTSDATA pData);
    5353static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalRediscover(PRTTIMENANOTSDATA pData);
     54static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic, uint16_t iCpuSet, uint16_t iGipCpu);
    5455#endif
    5556
     
    6566static RTTIMENANOTSDATA g_TimeNanoTSData =
    6667{
    67     /* .pu64Prev      = */ &g_TimeNanoTSPrev,
    68     /* .pfnBad        = */ rtTimeNanoTSInternalBitch,
    69     /* .pfnRediscover = */ rtTimeNanoTSInternalRediscover,
    70     /* .pvDummy       = */ NULL,
    71     /* .c1nsSteps     = */ 0,
    72     /* .cExpired      = */ 0,
    73     /* .cBadPrev      = */ 0,
    74     /* .cUpdateRaces  = */ 0
     68    /* .pu64Prev       = */ &g_TimeNanoTSPrev,
     69    /* .pfnBad         = */ rtTimeNanoTSInternalBitch,
     70    /* .pfnRediscover  = */ rtTimeNanoTSInternalRediscover,
     71    /* .pfnBadCpuIndex = */ rtTimeNanoTSInternalBadCpuIndex,
     72    /* .c1nsSteps      = */ 0,
     73    /* .cExpired       = */ 0,
     74    /* .cBadPrev       = */ 0,
     75    /* .cUpdateRaces   = */ 0
    7576};
    7677
    77 /** The index into g_apfnWorkers for the function to use.
    78  * This cannot be a pointer because that'll break down in GC due to code relocation. */
    79 static uint32_t             g_iWorker = 0;
     78# ifdef IN_RC
    8079/** Array of rtTimeNanoTSInternal worker functions.
    8180 * This array is indexed by g_iWorker. */
    8281static const PFNTIMENANOTSINTERNAL g_apfnWorkers[] =
    8382{
    84 # define RTTIMENANO_WORKER_DETECT                   0
     83#  define RTTIMENANO_WORKER_DETECT                                      0
    8584    rtTimeNanoTSInternalRediscover,
    8685
    87 # define RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA     1
    88     RTTimeNanoTSLegacySyncNoDelta,
    89 # define RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA   2
    90     RTTimeNanoTSLegacySyncWithDelta,
    91 # define RTTIMENANO_WORKER_LEGACY_ASYNC             3
     86#  define RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_NO_DELTA                  1
     87    RTTimeNanoTSLegacySyncInvarNoDelta,
     88#  define RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_WITH_DELTA                2
     89    RTTimeNanoTSLegacySyncInvarWithDelta,
     90#  define RTTIMENANO_WORKER_LEGACY_ASYNC                                3
    9291    RTTimeNanoTSLegacyAsync,
    93 # define RTTIMENANO_WORKER_LEGACY_INVAR_NO_DELTA    4
    94     RTTimeNanoTSLFenceInvariantNoDelta,
    95 # define RTTIMENANO_WORKER_LEGACY_INVAR_WITH_DELTA  5
    96     RTTimeNanoTSLFenceInvariantWithDelta,
    97 
    98 # define RTTIMENANO_WORKER_LFENCE_SYNC_NO_DELTA     6
    99     RTTimeNanoTSLFenceSyncNoDelta,
    100 # define RTTIMENANO_WORKER_LFENCE_SYNC_WITH_DELTA   7
    101     RTTimeNanoTSLFenceSyncWithDelta,
    102 # define RTTIMENANO_WORKER_LFENCE_ASYNC             8
     92
     93#  define RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_NO_DELTA                  4
     94    RTTimeNanoTSLFenceSyncInvarNoDelta,
     95#  define RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_WITH_DELTA                5
     96    RTTimeNanoTSLFenceSyncInvarWithDelta,
     97#  define RTTIMENANO_WORKER_LFENCE_ASYNC                                6
    10398    RTTimeNanoTSLFenceAsync,
    104 # define RTTIMENANO_WORKER_LFENCE_INVAR_NO_DELTA    9
    105     RTTimeNanoTSLFenceInvariantNoDelta,
    106 # define RTTIMENANO_WORKER_LFENCE_INVAR_WITH_DELTA  10
    107     RTTimeNanoTSLFenceInvariantWithDelta,
    108 
    109 # define RTTIMENANO_WORKER_FALLBACK                 11
     99
     100#  define RTTIMENANO_WORKER_FALLBACK                                    7
    110101    rtTimeNanoTSInternalFallback,
    111102};
    112 
    113 
    114 /**
    115  * Helper function that's used by the assembly routines when something goes bust.
    116  *
    117  * @param   pData           Pointer to the data structure.
    118  * @param   u64NanoTS       The calculated nano ts.
    119  * @param   u64DeltaPrev    The delta relative to the previously returned timestamp.
    120  * @param   u64PrevNanoTS   The previously returned timestamp (as it was read it).
    121  */
    122 static DECLCALLBACK(void) rtTimeNanoTSInternalBitch(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS)
     103/** The index into g_apfnWorkers for the function to use.
     104 * @remarks This cannot be a pointer because that'll break down in RC due to
     105 *          code relocation. */
     106static uint32_t                 g_iWorker   = RTTIMENANO_WORKER_DETECT;
     107# else
     108/** Pointer to the worker */
     109static PFNTIMENANOTSINTERNAL    g_pfnWorker = rtTimeNanoTSInternalRediscover;
     110# endif /* IN_RC */
     111
     112
     113/**
     114 * @interface_method_impl{RTTIMENANOTSDATA, pfnBad}
     115 */
     116static DECLCALLBACK(void) rtTimeNanoTSInternalBitch(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev,
     117                                                    uint64_t u64PrevNanoTS)
    123118{
    124119    pData->cBadPrev++;
     
    130125             u64DeltaPrev, u64PrevNanoTS, u64NanoTS));
    131126}
     127
     128/**
     129 * @interface_method_impl{RTTIMENANOTSDATA, pfnBadCpuIndex}
     130 */
     131static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalBadCpuIndex(PRTTIMENANOTSDATA pData, uint16_t idApic,
     132                                                              uint16_t iCpuSet, uint16_t iGipCpu)
     133{
     134# ifndef IN_RC
     135    AssertMsgFailed(("idApic=%#x iCpuSet=%#x iGipCpu=%#x\n", idApic, iCpuSet, iGipCpu));
     136    return RTTimeSystemNanoTS();
     137# else
     138    RTAssertReleasePanic();
     139    return 0;
     140# endif
     141}
     142
    132143
    133144/**
     
    147158    return RTTimeSystemNanoTS();
    148159# else
     160    RTAssertReleasePanic();
    149161    return 0;
    150162# endif
     
    158170static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalRediscover(PRTTIMENANOTSDATA pData)
    159171{
    160     uint32_t iWorker;
    161     PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
     172    PSUPGLOBALINFOPAGE      pGip = g_pSUPGlobalInfoPage;
     173# ifdef IN_RC
     174    uint32_t                iWorker;
     175# else
     176    PFNTIMENANOTSINTERNAL   pfnWorker;
     177# endif
    162178    if (    pGip
    163179        &&  pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC
     
    167183    {
    168184        if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2)
    169             iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC
    170                     ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    171                       ? RTTIMENANO_WORKER_LFENCE_INVAR_NO_DELTA : RTTIMENANO_WORKER_LFENCE_INVAR_WITH_DELTA
    172                     : pGip->u32Mode == SUPGIPMODE_SYNC_TSC
    173                     ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    174                       ? RTTIMENANO_WORKER_LFENCE_SYNC_NO_DELTA  : RTTIMENANO_WORKER_LFENCE_SYNC_WITH_DELTA
    175                     : RTTIMENANO_WORKER_LFENCE_ASYNC;
     185        {
     186# ifdef IN_RC
     187            iWorker   = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     188                      ? RTTIMENANO_WORKER_LFENCE_ASYNC
     189                      : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     190                      ? RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_NO_DELTA
     191                      : RTTIMENANO_WORKER_LFENCE_SYNC_INVAR_WITH_DELTA;
     192# elif defined(IN_RING0)
     193            pfnWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     194                      ? RTTimeNanoTSLFenceAsync
     195                      : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     196                      ? RTTimeNanoTSLFenceSyncInvarNoDelta
     197                      : RTTimeNanoTSLFenceSyncInvarWithDelta;
     198# else
     199            if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
     200                pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     201                          ? RTTimeNanoTSLFenceAsyncUseIdtrLim
     202                          : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     203                          ? RTTimeNanoTSLFenceAsyncUseRdtscp
     204                          : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID
     205                          ? RTTimeNanoTSLFenceAsyncUseApicId
     206                          : rtTimeNanoTSInternalFallback;
     207           else
     208               pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     209                         ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     210                           ? RTTimeNanoTSLFenceSyncInvarNoDelta
     211                           : RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim
     212                         : pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     213                         ?   pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     214                           ? RTTimeNanoTSLFenceSyncInvarNoDelta
     215                           : RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp
     216                         : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID
     217                         ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     218                           ? RTTimeNanoTSLFenceSyncInvarNoDelta
     219                           : RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId
     220                         : rtTimeNanoTSInternalFallback;
     221# endif
     222        }
    176223        else
    177             iWorker = pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC
    178                     ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    179                       ? RTTIMENANO_WORKER_LEGACY_INVAR_NO_DELTA : RTTIMENANO_WORKER_LEGACY_INVAR_WITH_DELTA
    180                     : pGip->u32Mode == SUPGIPMODE_SYNC_TSC
    181                     ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
    182                       ? RTTIMENANO_WORKER_LEGACY_SYNC_NO_DELTA  : RTTIMENANO_WORKER_LEGACY_SYNC_WITH_DELTA
    183                     : RTTIMENANO_WORKER_LEGACY_ASYNC;
     224        {
     225# ifdef IN_RC
     226            iWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     227                    ? RTTIMENANO_WORKER_LEGACY_ASYNC
     228                    : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     229                    ? RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_NO_DELTA :  RTTIMENANO_WORKER_LEGACY_SYNC_INVAR_WITH_DELTA;
     230# elif defined(IN_RING0)
     231            pfnWorker = pGip->u32Mode == SUPGIPMODE_ASYNC_TSC
     232                      ? RTTimeNanoTSLegacyAsync
     233                      : pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     234                      ? RTTimeNanoTSLegacySyncInvarNoDelta
     235                      : RTTimeNanoTSLegacySyncInvarWithDelta;
     236# else
     237            if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC)
     238                pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     239                          ? RTTimeNanoTSLegacyAsyncUseRdtscp
     240                          : pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     241                          ? RTTimeNanoTSLegacyAsyncUseIdtrLim
     242                          : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID
     243                          ? RTTimeNanoTSLegacyAsyncUseApicId
     244                          : rtTimeNanoTSInternalFallback;
     245           else
     246               pfnWorker = pGip->fGetGipCpu & SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     247                         ?   pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     248                           ? RTTimeNanoTSLegacySyncInvarNoDelta
     249                           : RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp
     250                         : pGip->fGetGipCpu & SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     251                         ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO
     252                           ? RTTimeNanoTSLegacySyncInvarNoDelta
     253                           : RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim
     254                         : pGip->fGetGipCpu & SUPGIPGETCPU_APIC_ID
     255                         ? pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO
     256                           ? RTTimeNanoTSLegacySyncInvarNoDelta
     257                           : RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId
     258                         : rtTimeNanoTSInternalFallback;
     259# endif
     260        }
    184261    }
    185262    else
     263# ifdef IN_RC
    186264        iWorker = RTTIMENANO_WORKER_FALLBACK;
    187 
     265# else
     266        pfnWorker = rtTimeNanoTSInternalFallback;
     267# endif
     268
     269# ifdef IN_RC
    188270    ASMAtomicWriteU32((uint32_t volatile *)&g_iWorker, iWorker);
    189271    return g_apfnWorkers[iWorker](pData);
     272# else
     273    ASMAtomicWritePtr((void * volatile *)&g_pfnWorker, (void *)(uintptr_t)pfnWorker);
     274    return pfnWorker(pData);
     275# endif
    190276}
    191277
     
    199285{
    200286#if !defined(IN_GUEST) && !defined(RT_NO_GIP)
     287# ifdef IN_RC
    201288    return g_apfnWorkers[g_iWorker](&g_TimeNanoTSData);
     289# else
     290    return g_pfnWorker(&g_TimeNanoTSData);
     291# endif
    202292#else
    203293    return RTTimeSystemNanoTS();
  • trunk/src/VBox/Runtime/common/time/timesupA.asm

    r54202 r54270  
    2929%include "iprt/asmdefs.mac"
    3030%include "VBox/sup.mac"
     31
     32;
     33; Use the C reference implementation for now.
     34;
     35%error "This is out of date, use C code.  Not worth it for a couple of ticks in some functions and equal or worse performance in others."
     36This is out of date
     37This is out of date
     38This is out of date
    3139
    3240
  • trunk/src/VBox/Runtime/common/time/timesupref.cpp

    r54202 r54270  
    3737#include <iprt/asm-amd64-x86.h>
    3838#include <VBox/sup.h>
     39#ifdef IN_RC
     40# include <VBox/vmm/vmm.h>
     41# include <VBox/vmm/vm.h>
     42#endif
    3943#include "internal/time.h"
    4044
    4145
    42 #define GIP_MODE_SYNC_NO_DELTA          1
    43 #define GIP_MODE_SYNC_WITH_DELTA        2
    44 #define GIP_MODE_ASYNC                  3
    45 #define GIP_MODE_INVARIANT_NO_DELTA     4
    46 #define GIP_MODE_INVARIANT_WITH_DELTA   5
    47 #define IS_GIP_MODE_WITH_DELTA(a_enmMode) \
    48     ((a_enmMode) == GIP_MODE_SYNC_WITH_DELTA || (a_enmMode) == GIP_MODE_INVARIANT_WITH_DELTA)
     46#define TMPL_MODE_SYNC_INVAR_NO_DELTA       1
     47#define TMPL_MODE_SYNC_INVAR_WITH_DELTA     2
     48#define TMPL_MODE_ASYNC                     3
    4949
    5050
    5151/*
    52  * Use the CPUID instruction for some kind of serialization.
    53  */
    54 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA
    55 #undef  USE_LFENCE
    56 #define NEED_TRANSACTION_ID
    57 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncNoDelta
     52 * Use the XCHG instruction for some kind of serialization.
     53 */
     54#define TMPL_READ_FENCE()        ASMReadFence()
     55
     56#undef  TMPL_MODE
     57#define TMPL_MODE                TMPL_MODE_SYNC_INVAR_NO_DELTA
     58#undef  TMPL_GET_CPU_METHOD
     59#define TMPL_GET_CPU_METHOD      0
     60#undef  rtTimeNanoTSInternalRef
     61#define rtTimeNanoTSInternalRef  RTTimeNanoTSLegacySyncInvarNoDelta
    5862#include "timesupref.h"
    59 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncNoDelta);
    60 
    61 #undef  GIP_MODE
    62 #define GIP_MODE  GIP_MODE_SYNC_NO_DELTA
    63 #undef  rtTimeNanoTSInternalRef
    64 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncWithDelta
    65 #include "timesupref.h"
    66 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncWithDelta);
    67 
    68 #undef  GIP_MODE
    69 #define GIP_MODE GIP_MODE_ASYNC
    70 #ifdef IN_RC
    71 # undef NEED_TRANSACTION_ID
     63RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarNoDelta);
     64
     65#ifdef IN_RING3
     66
     67# undef  TMPL_MODE
     68# define TMPL_MODE               TMPL_MODE_SYNC_INVAR_WITH_DELTA
     69# undef  TMPL_GET_CPU_METHOD
     70# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_APIC_ID
     71# undef  rtTimeNanoTSInternalRef
     72# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId
     73# include "timesupref.h"
     74RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseApicId);
     75
     76# undef  TMPL_GET_CPU_METHOD
     77# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     78# undef  rtTimeNanoTSInternalRef
     79# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp
     80# include "timesupref.h"
     81RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseRdtscp);
     82
     83# undef  TMPL_GET_CPU_METHOD
     84# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     85# undef  rtTimeNanoTSInternalRef
     86# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim
     87# include "timesupref.h"
     88RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDeltaUseIdtrLim);
     89
     90# undef  TMPL_MODE
     91# define TMPL_MODE               TMPL_MODE_ASYNC
     92# undef  TMPL_GET_CPU_METHOD
     93# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_APIC_ID
     94# undef  rtTimeNanoTSInternalRef
     95# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseApicId
     96# include "timesupref.h"
     97RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseApicId);
     98
     99# undef  TMPL_GET_CPU_METHOD
     100# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     101# undef  rtTimeNanoTSInternalRef
     102# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseRdtscp
     103# include "timesupref.h"
     104RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseRdtscp);
     105
     106# undef  TMPL_GET_CPU_METHOD
     107# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     108# undef  rtTimeNanoTSInternalRef
     109# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsyncUseIdtrLim
     110# include "timesupref.h"
     111RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsyncUseIdtrLim);
     112
     113#else  /* IN_RC || IN_RING0: Disable interrupts and call getter function. */
     114
     115# undef  TMPL_MODE
     116# define TMPL_MODE               TMPL_MODE_SYNC_INVAR_WITH_DELTA
     117# undef  TMPL_GET_CPU_METHOD
     118# define TMPL_GET_CPU_METHOD     UINT32_MAX
     119# undef  rtTimeNanoTSInternalRef
     120# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacySyncInvarWithDelta
     121# include "timesupref.h"
     122RT_EXPORT_SYMBOL(RTTimeNanoTSLegacySyncInvarWithDelta);
     123
     124# undef  TMPL_MODE
     125# define TMPL_MODE TMPL_MODE_ASYNC
     126# undef  rtTimeNanoTSInternalRef
     127# define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsync
     128# include "timesupref.h"
     129RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsync);
     130
    72131#endif
    73 #undef  rtTimeNanoTSInternalRef
    74 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyAsync
    75 #include "timesupref.h"
    76 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyAsync);
    77 
    78 #undef  GIP_MODE
    79 #define GIP_MODE GIP_MODE_INVARIANT_NO_DELTA
    80 #undef  NEED_TRANSACTION_ID
    81 #define NEED_TRANSACTION_ID
    82 #undef  rtTimeNanoTSInternalRef
    83 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyInvariantNoDelta
    84 #include "timesupref.h"
    85 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantNoDelta);
    86 
    87 #undef  GIP_MODE
    88 #define GIP_MODE GIP_MODE_INVARIANT_WITH_DELTA
    89 #undef  rtTimeNanoTSInternalRef
    90 #define rtTimeNanoTSInternalRef RTTimeNanoTSLegacyInvariantWithDelta
    91 #include "timesupref.h"
    92 RT_EXPORT_SYMBOL(RTTimeNanoTSLegacyInvariantWithDelta);
    93132
    94133
     
    96135 * Use LFENCE for load serialization.
    97136 */
    98 #undef  GIP_MODE
    99 #define GIP_MODE GIP_MODE_SYNC_NO_DELTA
    100 #define USE_LFENCE
    101 #undef  NEED_TRANSACTION_ID
    102 #define NEED_TRANSACTION_ID
     137#undef  TMPL_READ_FENCE
     138#define TMPL_READ_FENCE()        ASMReadFenceSSE2()
     139
     140#undef  TMPL_MODE
     141#define TMPL_MODE                TMPL_MODE_SYNC_INVAR_NO_DELTA
     142#undef  TMPL_GET_CPU_METHOD
     143#define TMPL_GET_CPU_METHOD      0
    103144#undef  rtTimeNanoTSInternalRef
    104 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncNoDelta
     145#define rtTimeNanoTSInternalRef  RTTimeNanoTSLFenceSyncInvarNoDelta
    105146#include "timesupref.h"
    106 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncNoDelta);
    107 
    108 #undef  GIP_MODE
    109 #define GIP_MODE GIP_MODE_SYNC_WITH_DELTA
    110 #undef  rtTimeNanoTSInternalRef
    111 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncWithDelta
    112 #include "timesupref.h"
    113 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncWithDelta);
    114 
    115 #undef  GIP_MODE
    116 #define GIP_MODE GIP_MODE_ASYNC
    117 #ifdef IN_RC
    118 # undef NEED_TRANSACTION_ID
     147RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarNoDelta);
     148
     149#ifdef IN_RING3
     150
     151# undef  TMPL_MODE
     152# define TMPL_MODE               TMPL_MODE_SYNC_INVAR_WITH_DELTA
     153# undef  TMPL_GET_CPU_METHOD
     154# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_APIC_ID
     155# undef  rtTimeNanoTSInternalRef
     156# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId
     157# include "timesupref.h"
     158RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseApicId);
     159
     160# undef  TMPL_GET_CPU_METHOD
     161# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     162# undef  rtTimeNanoTSInternalRef
     163# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp
     164# include "timesupref.h"
     165RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseRdtscp);
     166
     167# undef  TMPL_GET_CPU_METHOD
     168# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     169# undef  rtTimeNanoTSInternalRef
     170# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim
     171# include "timesupref.h"
     172RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDeltaUseIdtrLim);
     173
     174# undef  TMPL_MODE
     175# define TMPL_MODE               TMPL_MODE_ASYNC
     176# undef  TMPL_GET_CPU_METHOD
     177# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_APIC_ID
     178# undef  rtTimeNanoTSInternalRef
     179# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseApicId
     180# include "timesupref.h"
     181RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseApicId);
     182
     183# undef  TMPL_GET_CPU_METHOD
     184# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     185# undef  rtTimeNanoTSInternalRef
     186# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseRdtscp
     187# include "timesupref.h"
     188RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseRdtscp);
     189
     190# undef  TMPL_GET_CPU_METHOD
     191# define TMPL_GET_CPU_METHOD     SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     192# undef  rtTimeNanoTSInternalRef
     193# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsyncUseIdtrLim
     194# include "timesupref.h"
     195RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsyncUseIdtrLim);
     196
     197#else  /* IN_RC || IN_RING0: Disable interrupts and call getter function. */
     198
     199# undef  TMPL_MODE
     200# define TMPL_MODE               TMPL_MODE_SYNC_INVAR_WITH_DELTA
     201# undef  TMPL_GET_CPU_METHOD
     202# define TMPL_GET_CPU_METHOD     UINT32_MAX
     203# undef  rtTimeNanoTSInternalRef
     204# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceSyncInvarWithDelta
     205# include "timesupref.h"
     206RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceSyncInvarWithDelta);
     207
     208# undef  TMPL_MODE
     209# define TMPL_MODE TMPL_MODE_ASYNC
     210# undef  rtTimeNanoTSInternalRef
     211# define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsync
     212# include "timesupref.h"
     213RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsync);
     214
    119215#endif
    120 #undef  rtTimeNanoTSInternalRef
    121 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceAsync
    122 #include "timesupref.h"
    123 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceAsync);
    124 
    125 #undef  GIP_MODE
    126 #define GIP_MODE GIP_MODE_INVARIANT_NO_DELTA
    127 #undef  NEED_TRANSACTION_ID
    128 #define NEED_TRANSACTION_ID
    129 #undef  rtTimeNanoTSInternalRef
    130 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceInvariantNoDelta
    131 #include "timesupref.h"
    132 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantNoDelta);
    133 
    134 #undef  GIP_MODE
    135 #define GIP_MODE GIP_MODE_INVARIANT_WITH_DELTA
    136 #undef  rtTimeNanoTSInternalRef
    137 #define rtTimeNanoTSInternalRef RTTimeNanoTSLFenceInvariantWithDelta
    138 #include "timesupref.h"
    139 RT_EXPORT_SYMBOL(RTTimeNanoTSLFenceInvariantWithDelta);
    140216
    141217
  • trunk/src/VBox/Runtime/common/time/timesupref.h

    r54202 r54270  
    4545{
    4646    uint64_t    u64Delta;
    47 #if IS_GIP_MODE_WITH_DELTA(GIP_MODE)
     47#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
    4848    int64_t     i64TscDelta;
     49# ifdef IN_RING3
     50    PSUPGIPCPU  pGipCpuAttemptedTscRecalibration = NULL;
     51# endif
    4952#endif
    5053    uint32_t    u32NanoTSFactor0;
     
    5356    uint32_t    u32UpdateIntervalTSC;
    5457    uint64_t    u64PrevNanoTS;
     58    AssertCompile(RT_IS_POWER_OF_TWO(RTCPUSET_MAX_CPUS));
    5559
    5660    /*
     
    5963    for (;;)
    6064    {
     65#ifndef IN_RING3 /* This simplifies and improves everything. */
     66        RTCCUINTREG const  uFlags = ASMIntDisableFlags();
     67#endif
     68
     69        /*
     70         * Check that the GIP is sane and that the premises for this worker function
     71         * hasn't changed (CPU onlined with bad delta or missing features).
     72         */
    6173        PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
    62 #ifdef IN_RING3
    63         if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC))
    64             return pData->pfnRediscover(pData);
    65 #endif
    66 #if GIP_MODE == GIP_MODE_ASYNC || IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    67         uint8_t const u8ApicId  = ASMGetApicId();
    68         PSUPGIPCPU pGipCpu      = &pGip->aCPUs[pGip->aiCpuFromApicId[u8ApicId]];
    69 #endif
    70 
    71 #ifdef NEED_TRANSACTION_ID
    72 # if GIP_MODE == GIP_MODE_ASYNC
    73         uint32_t u32TransactionId = pGipCpu->u32TransactionId;
     74        if (   RT_LIKELY(pGip)
     75            && RT_LIKELY(pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC)
     76#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     77            && RT_LIKELY(pGip->enmUseTscDelta >= SUPGIPUSETSCDELTA_PRACTICALLY_ZERO)
     78#else
     79            && RT_LIKELY(pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ROUGHLY_ZERO)
     80#endif
     81#if defined(IN_RING3) && TMPL_GET_CPU_METHOD != 0 && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID
     82            && RT_LIKELY(pGip->fGetGipCpu & TMPL_GET_CPU_METHOD)
     83#endif
     84           )
     85        {
     86            /*
     87             * Resolve pGipCpu if needed.  If the instruction is serializing, we
     88             * read the transaction id first if possible.
     89             */
     90#if TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     91# if   defined(IN_RING0)
     92            uint32_t const  iCpuSet  = RTMpCpuIdToSetIndex(RTMpCpuId());
     93            uint16_t const  iGipCpu  = iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)
     94                                     ? pGip->aiCpuFromCpuSetIdx[iCpuSet] : UINT16_MAX;
     95# elif defined(IN_RC)
     96            uint32_t const  iCpuSet  = VMMGetCpu(&g_VM)->iHostCpuSet;
     97            uint16_t const  iGipCpu  = iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)
     98                                     ? pGip->aiCpuFromCpuSetIdx[iCpuSet] : UINT16_MAX;
     99# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_APIC_ID
     100#  if TMPL_MODE != TMPL_MODE_ASYNC
     101            uint32_t const  u32TransactionId = pGip->aCPUs[0].u32TransactionId;
     102#  endif
     103            uint8_t  const  idApic   = ASMGetApicId();
     104            uint16_t const  iGipCpu  = pGip->aiCpuFromApicId[idApic];
     105# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     106#  if TMPL_MODE != TMPL_MODE_ASYNC
     107            uint32_t const  u32TransactionId = pGip->aCPUs[0].u32TransactionId;
     108#  endif
     109            uint32_t        uAux;
     110            ASMReadTscWithAux(&uAux);
     111            uint16_t const  iCpuSet  = uAux & (RTCPUSET_MAX_CPUS - 1);
     112            uint16_t const  iGipCpu  = pGip->aiCpuFromCpuSetIdx[iCpuSet];
     113# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     114            uint16_t const  cbLim    = ASMGetIdtrLimit();
     115            uint16_t const  iCpuSet  = (cbLim - 256 * (ARCH_BITS == 64 ? 16 : 8)) & (RTCPUSET_MAX_CPUS - 1);
     116            uint16_t const  iGipCpu  = pGip->aiCpuFromCpuSetIdx[iCpuSet];
    74117# else
    75         uint32_t u32TransactionId = pGip->aCPUs[0].u32TransactionId;
    76 # endif
    77 # ifdef USE_LFENCE
    78         ASMReadFenceSSE2();
     118#  error "What?"
     119# endif
     120            if (RT_LIKELY(iGipCpu < pGip->cCpus))
     121            {
     122                PSUPGIPCPU pGipCpu = &pGip->aCPUs[iGipCpu];
     123#else
     124            {
     125#endif
     126                /*
     127                 * Get the transaction ID if necessary and we haven't already
     128                 * read it before a serializing instruction above.  We can skip
     129                 * this for ASYNC_TSC mode in ring-0 and raw-mode context since
     130                 * we disable interrupts.
     131                 */
     132#if TMPL_MODE == TMPL_MODE_ASYNC && defined(IN_RING3)
     133                uint32_t const u32TransactionId = pGipCpu->u32TransactionId;
     134                ASMCompilerBarrier();
     135                TMPL_READ_FENCE();
     136#elif TMPL_MODE != TMPL_MODE_ASYNC \
     137   && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID \
     138   && TMPL_GET_CPU_METHOD != SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     139                uint32_t const u32TransactionId = pGip->aCPUs[0].u32TransactionId;
     140                ASMCompilerBarrier();
     141                TMPL_READ_FENCE();
     142#endif
     143
     144                /*
     145                 * Gather all the data we need.  The mess at the end is to make
     146                 * sure all loads are done before we recheck the transaction ID
     147                 * without triggering serializing twice.
     148                 */
     149                u32NanoTSFactor0        = pGip->u32UpdateIntervalNS;
     150#if TMPL_MODE == TMPL_MODE_ASYNC
     151                u32UpdateIntervalTSC    = pGipCpu->u32UpdateIntervalTSC;
     152                u64NanoTS               = pGipCpu->u64NanoTS;
     153                u64TSC                  = pGipCpu->u64TSC;
     154#else
     155                u32UpdateIntervalTSC    = pGip->aCPUs[0].u32UpdateIntervalTSC;
     156                u64NanoTS               = pGip->aCPUs[0].u64NanoTS;
     157                u64TSC                  = pGip->aCPUs[0].u64TSC;
     158# if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     159                i64TscDelta             = pGipCpu->i64TSCDelta;
     160# endif
     161#endif
     162#if TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     163                u64PrevNanoTS           = ASMAtomicUoReadU64(pData->pu64Prev);
     164                ASMCompilerBarrier();
     165                uint32_t uAux2;
     166                u64Delta                = ASMReadTscWithAux(&uAux2); /* serializing */
     167#else
     168                u64Delta                = ASMReadTSC();
     169                u64PrevNanoTS           = ASMAtomicUoReadU64(pData->pu64Prev);
     170                ASMCompilerBarrier();
     171# if TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID /* getting APIC will serialize  */ \
     172  && (defined(IN_RING3) || TMPL_MODE != TMPL_MODE_ASYNC)
     173                TMPL_READ_FENCE(); /* Expensive (~30 ticks).  Would like convincing argumentation that let us remove it. */
     174# endif
     175#endif
     176
     177                /*
     178                 * Check that we didn't change CPU.
     179                 */
     180#if defined(IN_RING3) && ( TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA )
     181# if   TMPL_GET_CPU_METHOD == SUPGIPGETCPU_APIC_ID
     182                if (RT_LIKELY(ASMGetApicId() == idApic))
     183# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS
     184                if (RT_LIKELY(uAux2 == uAux))
     185# elif TMPL_GET_CPU_METHOD == SUPGIPGETCPU_IDTR_LIMIT_MASK_MAX_SET_CPUS
     186                if (RT_LIKELY(ASMGetIdtrLimit() == cbLim))
     187# endif
     188#endif
     189                {
     190                    /*
     191                     * Check the transaction ID (see above for R0/RC + ASYNC).
     192                     */
     193#if defined(IN_RING3) || TMPL_MODE != TMPL_MODE_ASYNC
     194# if TMPL_MODE == TMPL_MODE_ASYNC
     195                    if (RT_LIKELY(pGipCpu->u32TransactionId       == u32TransactionId && !(u32TransactionId & 1) ))
    79196# else
    80         ASMReadFence();
    81 # endif
    82 #endif
    83 
    84 #if GIP_MODE == GIP_MODE_ASYNC
    85         u32UpdateIntervalTSC    = pGipCpu->u32UpdateIntervalTSC;
    86         u64NanoTS               = pGipCpu->u64NanoTS;
    87         u64TSC                  = pGipCpu->u64TSC;
    88 #else
    89         u32UpdateIntervalTSC    = pGip->aCPUs[0].u32UpdateIntervalTSC;
    90         u64NanoTS               = pGip->aCPUs[0].u64NanoTS;
    91         u64TSC                  = pGip->aCPUs[0].u64TSC;
    92 # if IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    93         i64TscDelta             = pGipCpu->i64TSCDelta;
    94 # endif
    95 #endif
    96         u32NanoTSFactor0        = pGip->u32UpdateIntervalNS;
    97         u64Delta                = ASMReadTSC();
    98         u64PrevNanoTS           = ASMAtomicReadU64(pData->pu64Prev);
    99 
    100 #ifdef NEED_TRANSACTION_ID
    101 # if GIP_MODE == GIP_MODE_ASYNC || IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    102         if (RT_UNLIKELY(u8ApicId != ASMGetApicId()))
    103             continue;
    104 # elif defined(USE_LFENCE)
    105         ASMWriteFenceSSE();
     197                    if (RT_LIKELY(pGip->aCPUs[0].u32TransactionId == u32TransactionId && !(u32TransactionId & 1) ))
     198# endif
     199#endif
     200                    {
     201
     202                        /*
     203                         * Apply the TSC delta.  If the delta is invalid and the
     204                         * execution allows it, try trigger delta recalibration.
     205                         */
     206#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA && defined(IN_RING3)
     207                        if (RT_LIKELY(   i64TscDelta != INT64_MAX
     208                                      || pGipCpu == pGipCpuAttemptedTscRecalibration))
     209#endif
     210                        {
     211#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     212# ifndef IN_RING3
     213                            if (RT_LIKELY(i64TscDelta != INT64_MAX))
     214# endif
     215                                u64Delta -= i64TscDelta;
     216#endif
     217
     218                            /*
     219                             * Bingo! We've got a consistent set of data.
     220                             */
     221#ifndef IN_RING3
     222                            ASMSetFlags(uFlags);
     223#endif
     224                            break;
     225                        }
     226#if TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA && defined(IN_RING3)
     227                        /*
     228                         * Call into the support driver to try make it recalculate the delta. We
     229                         * remember which GIP CPU structure we're probably working on so we won't
     230                         * end up in a loop if the driver for some reason cannot get the job done.
     231                         */
     232                        else /* else is unecessary, but helps checking the preprocessor spaghetti. */
     233                        {
     234                            pGipCpuAttemptedTscRecalibration = pGipCpu;
     235                            uint64_t u64TscTmp;
     236                            uint16_t idApicUpdate;
     237                            int rc = SUPR3ReadTsc(&u64TscTmp, &idApicUpdate);
     238                            if (RT_SUCCESS(rc) && idApicUpdate <= RT_ELEMENTS(pGip->aiCpuFromApicId))
     239                            {
     240                                uint32_t iUpdateGipCpu = pGip->aiCpuFromApicId[idApicUpdate];
     241                                if (iUpdateGipCpu < pGip->cCpus)
     242                                    pGipCpuAttemptedTscRecalibration = &pGip->aCPUs[iUpdateGipCpu];
     243                            }
     244                        }
     245#endif
     246                    }
     247                }
     248
     249                /*
     250                 * No joy must try again.
     251                 */
     252#ifndef IN_RING3
     253                ASMSetFlags(uFlags);
     254#endif
     255                ASMNopPause();
     256                continue;
     257            }
     258
     259#if TMPL_MODE == TMPL_MODE_ASYNC || TMPL_MODE == TMPL_MODE_SYNC_INVAR_WITH_DELTA
     260            /*
     261             * We've got a bad CPU or APIC index of some kind.
     262             */
     263            else /* else is unecessary, but helps checking the preprocessor spaghetti. */
     264            {
     265# ifndef IN_RING3
     266                ASMSetFlags(uFlags);
     267# endif
     268# if defined(IN_RING0) || defined(IN_RC) || TMPL_GET_CPU_METHOD != SUPGIPGETCPU_APIC_ID
     269                return pData->pfnBadCpuIndex(pData, UINT16_MAX-1, iCpuSet, iGipCpu);
    106270# else
    107         ASMWriteFence();
    108 # endif
    109 # if GIP_MODE == GIP_MODE_ASYNC
    110         if (RT_UNLIKELY(   pGipCpu->u32TransactionId != u32TransactionId
    111                         || (u32TransactionId & 1)))
    112             continue;
    113 # else
    114         if (RT_UNLIKELY(   pGip->aCPUs[0].u32TransactionId != u32TransactionId
    115                         || (u32TransactionId & 1)))
    116             continue;
    117 # endif
    118 #endif
    119         break;
     271                return pData->pfnBadCpuIndex(pData, idApic, UINT16_MAX-1, iGipCpu);
     272# endif
     273            }
     274#endif
     275        }
     276
     277        /*
     278         * Something changed in the GIP config or it was unmapped, figure out
     279         * the right worker function to use now.
     280         */
     281#ifndef IN_RING3
     282        ASMSetFlags(uFlags);
     283#endif
     284        return pData->pfnRediscover(pData);
    120285    }
    121286
     
    124289     */
    125290    u64Delta -= u64TSC;
    126 #if IS_GIP_MODE_WITH_DELTA(GIP_MODE)
    127     if (RT_LIKELY(i64TscDelta != INT64_MAX))
    128         u64Delta -= i64TscDelta;
    129 #endif
    130291    if (RT_UNLIKELY(u64Delta > u32UpdateIntervalTSC))
    131292    {
Note: See TracChangeset for help on using the changeset viewer.

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