Changeset 6013 in vbox for trunk/src/VBox/Runtime/common
- Timestamp:
- Dec 8, 2007 12:39:13 AM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 26632
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/time/timesysalias.cpp
r6009 r6013 1 1 /* $Id$ */ 2 2 /** @file 3 * innotek Portable Runtime - Time using SUPLib.3 * innotek Portable Runtime - Time using RTTimeSystem*. 4 4 */ 5 5 … … 29 29 * Header Files * 30 30 *******************************************************************************/ 31 #define LOG_GROUP RTLOGGROUP_TIME32 31 #include <iprt/time.h> 33 #include <iprt/asm.h>34 #include <iprt/assert.h>35 #include <iprt/err.h>36 #include <iprt/log.h>37 #ifndef IN_GUEST38 # include <VBox/sup.h>39 # include <VBox/x86.h>40 #endif41 #include "internal/time.h"42 43 44 /*******************************************************************************45 * Internal Functions *46 *******************************************************************************/47 #ifndef IN_GUEST48 static DECLCALLBACK(void) rtTimeNanoTSInternalBitch(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);49 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalFallback(PRTTIMENANOTSDATA pData);50 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalRediscover(PRTTIMENANOTSDATA pData);51 #endif52 53 54 /*******************************************************************************55 * Global Variables *56 *******************************************************************************/57 #ifndef IN_GUEST58 /** The previous timestamp value returned by RTTimeNanoTS. */59 static uint64_t g_TimeNanoTSPrev = 0;60 61 /** The RTTimeNanoTS data structure that's passed down to the worker functions. */62 static RTTIMENANOTSDATA g_TimeNanoTSData =63 {64 /* .pu64Prev = */ &g_TimeNanoTSPrev,65 /* .pfnBad = */ rtTimeNanoTSInternalBitch,66 /* .pfnRediscover = */ rtTimeNanoTSInternalRediscover,67 /* .pvDummy = */ NULL,68 /* .c1nsSteps = */ 0,69 /* .cExpired = */ 0,70 /* .cBadPrev = */ 0,71 /* .cUpdateRaces = */ 072 };73 74 /** The index into g_apfnWorkers for the function to use.75 * This cannot be a pointer because that'll break down in GC due to code relocation. */76 static uint32_t g_iWorker = 0;77 /** Array of rtTimeNanoTSInternal worker functions.78 * This array is indexed by g_iWorker. */79 static const PFNTIMENANOTSINTERNAL g_apfnWorkers[] =80 {81 #define RTTIMENANO_WORKER_DETECT 082 rtTimeNanoTSInternalRediscover,83 #define RTTIMENANO_WORKER_SYNC_CPUID 184 RTTimeNanoTSLegacySync,85 #define RTTIMENANO_WORKER_ASYNC_CPUID 286 RTTimeNanoTSLegacyAsync,87 #define RTTIMENANO_WORKER_SYNC_LFENCE 388 RTTimeNanoTSLFenceSync,89 #define RTTIMENANO_WORKER_ASYNC_LFENCE 490 RTTimeNanoTSLFenceAsync,91 #define RTTIMENANO_WORKER_FALLBACK 592 rtTimeNanoTSInternalFallback,93 };94 95 96 /**97 * Helper function that's used by the assembly routines when something goes bust.98 *99 * @param pData Pointer to the data structure.100 * @param u64NanoTS The calculated nano ts.101 * @param u64DeltaPrev The delta relative to the previously returned timestamp.102 * @param u64PrevNanoTS The previously returned timestamp (as it was read it).103 */104 static DECLCALLBACK(void) rtTimeNanoTSInternalBitch(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS)105 {106 pData->cBadPrev++;107 if ((int64_t)u64DeltaPrev < 0)108 LogRel(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64\n",109 u64DeltaPrev, u64PrevNanoTS, u64NanoTS));110 else111 Log(("TM: u64DeltaPrev=%RI64 u64PrevNanoTS=0x%016RX64 u64NanoTS=0x%016RX64 (debugging?)\n",112 u64DeltaPrev, u64PrevNanoTS, u64NanoTS));113 }114 115 /**116 * Fallback function.117 */118 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalFallback(PRTTIMENANOTSDATA pData)119 {120 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;121 if ( pGip122 && pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC123 && ( pGip->u32Mode == SUPGIPMODE_SYNC_TSC124 || pGip->u32Mode == SUPGIPMODE_ASYNC_TSC))125 return rtTimeNanoTSInternalRediscover(pData);126 NOREF(pData);127 #if defined(IN_RING3) /** @todo Add ring-0 RTTimeSystemNanoTS to all hosts. */128 return RTTimeSystemNanoTS();129 #else130 return 0;131 #endif132 }133 134 135 /**136 * Called the first time somebody asks for the time or when the GIP137 * is mapped/unmapped.138 */139 static DECLCALLBACK(uint64_t) rtTimeNanoTSInternalRediscover(PRTTIMENANOTSDATA pData)140 {141 uint32_t iWorker;142 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;143 if ( pGip144 && pGip->u32Magic == SUPGLOBALINFOPAGE_MAGIC145 && ( pGip->u32Mode == SUPGIPMODE_SYNC_TSC146 || pGip->u32Mode == SUPGIPMODE_ASYNC_TSC))147 {148 if (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_SSE2)149 iWorker = pGip->u32Mode == SUPGIPMODE_SYNC_TSC150 ? RTTIMENANO_WORKER_SYNC_LFENCE151 : RTTIMENANO_WORKER_ASYNC_LFENCE;152 else153 iWorker = pGip->u32Mode == SUPGIPMODE_SYNC_TSC154 ? RTTIMENANO_WORKER_SYNC_CPUID155 : RTTIMENANO_WORKER_ASYNC_CPUID;156 }157 else158 iWorker = RTTIMENANO_WORKER_FALLBACK;159 160 ASMAtomicXchgU32((uint32_t volatile *)&g_iWorker, iWorker);161 return g_apfnWorkers[iWorker](pData);162 }163 164 #endif /* !IN_GUEST */165 166 167 /**168 * Internal worker for getting the current nanosecond timestamp.169 */170 DECLINLINE(uint64_t) rtTimeNanoTSInternal(void)171 {172 #ifndef IN_GUEST173 return g_apfnWorkers[g_iWorker](&g_TimeNanoTSData);174 #else175 return RTTimeSystemNanoTS();176 #endif177 }178 32 179 33 … … 185 39 RTDECL(uint64_t) RTTimeNanoTS(void) 186 40 { 187 return rtTimeNanoTSInternal();41 return RTTimeSystemNanoTS(); 188 42 } 189 43 … … 196 50 RTDECL(uint64_t) RTTimeMilliTS(void) 197 51 { 198 return rtTimeNanoTSInternal() / 1000000;52 return RTTimeSystemMilliTS(); 199 53 } 200 54 201 202 #ifndef IN_GUEST203 /**204 * Debugging the time api.205 *206 * @returns the number of 1ns steps which has been applied by RTTimeNanoTS().207 */208 RTDECL(uint32_t) RTTimeDbgSteps(void)209 {210 return g_TimeNanoTSData.c1nsSteps;211 }212 213 214 /**215 * Debugging the time api.216 *217 * @returns the number of times the TSC interval expired RTTimeNanoTS().218 */219 RTDECL(uint32_t) RTTimeDbgExpired(void)220 {221 return g_TimeNanoTSData.cExpired;222 }223 224 225 /**226 * Debugging the time api.227 *228 * @returns the number of bad previous values encountered by RTTimeNanoTS().229 */230 RTDECL(uint32_t) RTTimeDbgBad(void)231 {232 return g_TimeNanoTSData.cBadPrev;233 }234 235 236 /**237 * Debugging the time api.238 *239 * @returns the number of update races in RTTimeNanoTS().240 */241 RTDECL(uint32_t) RTTimeDbgRaces(void)242 {243 return g_TimeNanoTSData.cUpdateRaces;244 }245 #endif
Note:
See TracChangeset
for help on using the changeset viewer.