1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* 221939df44de1705786c545cd1bf519d47250322dBen Murdoch * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. 3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2008 Google Inc. All rights reserved. 40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2007-2009 Torch Mobile, Inc. 5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without 7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions are 8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * met: 9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Redistributions of source code must retain the above copyright 11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * notice, this list of conditions and the following disclaimer. 12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Redistributions in binary form must reproduce the above 13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * copyright notice, this list of conditions and the following disclaimer 14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * in the documentation and/or other materials provided with the 15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * distribution. 16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Neither the name of Google Inc. nor the names of its 17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * contributors may be used to endorse or promote products derived from 18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * this software without specific prior written permission. 19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "config.h" 34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "CurrentTime.h" 35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 36d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS) 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch// Windows is first since we want to use hires timers, despite USE(CF) 398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// being defined. 40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// If defined, WIN32_LEAN_AND_MEAN disables timeBeginPeriod/timeEndPeriod. 41635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#undef WIN32_LEAN_AND_MEAN 42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <windows.h> 43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <math.h> 44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <stdint.h> 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <time.h> 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(QUERY_PERFORMANCE_COUNTER) 48d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE) 490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochextern "C" time_t mktime(struct tm *t); 500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 51635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <sys/timeb.h> 52635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <sys/types.h> 530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#elif PLATFORM(GTK) 578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <glib.h> 588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#elif PLATFORM(WX) 598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <wx/datetime.h> 605e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#elif PLATFORM(BREWMP) 615e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#include <AEEStdLib.h> 6221939df44de1705786c545cd1bf519d47250322dBen Murdoch#else 63635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <sys/time.h> 64635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 66cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#if PLATFORM(CHROMIUM) 67cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#error Chromium uses a different timer implementation 68cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#endif 69cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 70635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WTF { 71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 72635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectconst double msPerSecond = 1000.0; 73635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 74d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS) 75635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if USE(QUERY_PERFORMANCE_COUNTER) 770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 78635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic LARGE_INTEGER qpcFrequency; 79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic bool syncedTime; 80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic double highResUpTime() 82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 83635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // We use QPC, but only after sanity checking its result, due to bugs: 84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // http://support.microsoft.com/kb/274323 85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // http://support.microsoft.com/kb/895980 86635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("...you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)." 87635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static LARGE_INTEGER qpcLast; 89635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static DWORD tickCountLast; 90635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static bool inited; 91635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LARGE_INTEGER qpc; 93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project QueryPerformanceCounter(&qpc); 94635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DWORD tickCount = GetTickCount(); 95635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 96635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (inited) { 97635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart; 98635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project __int64 tickCountElapsed; 99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (tickCount >= tickCountLast) 100635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tickCountElapsed = (tickCount - tickCountLast); 101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else { 102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if COMPILER(MINGW) 103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project __int64 tickCountLarge = tickCount + 0x100000000ULL; 104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#else 105635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project __int64 tickCountLarge = tickCount + 0x100000000I64; 106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 107635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tickCountElapsed = tickCountLarge - tickCountLast; 108635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 110635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // force a re-sync if QueryPerformanceCounter differs from GetTickCount by more than 500ms. 111635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // (500ms value is from http://support.microsoft.com/kb/274323) 112635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project __int64 diff = tickCountElapsed - qpcElapsed; 113635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (diff > 500 || diff < -500) 114635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project syncedTime = false; 115635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else 116635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project inited = true; 117635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 118635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project qpcLast = qpc; 119635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tickCountLast = tickCount; 120635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 121635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart); 122635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic double lowResUTCTime() 125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 126d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE) 127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project SYSTEMTIME systemTime; 128635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project GetSystemTime(&systemTime); 129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project struct tm tmtime; 130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tmtime.tm_year = systemTime.wYear - 1900; 131635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tmtime.tm_mon = systemTime.wMonth - 1; 132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tmtime.tm_mday = systemTime.wDay; 133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tmtime.tm_wday = systemTime.wDayOfWeek; 134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tmtime.tm_hour = systemTime.wHour; 135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tmtime.tm_min = systemTime.wMinute; 136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project tmtime.tm_sec = systemTime.wSecond; 137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project time_t timet = mktime(&tmtime); 138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return timet * msPerSecond + systemTime.wMilliseconds; 1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 140635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project struct _timeb timebuffer; 141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project _ftime(&timebuffer); 142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return timebuffer.time * msPerSecond + timebuffer.millitm; 1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 144635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic bool qpcAvailable() 147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static bool available; 149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static bool checked; 150635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 151635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (checked) 152635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return available; 153635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 154635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project available = QueryPerformanceFrequency(&qpcFrequency); 155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project checked = true; 156635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return available; 157635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 158635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectdouble currentTime() 160635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Use a combination of ftime and QueryPerformanceCounter. 162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // ftime returns the information we want, but doesn't have sufficient resolution. 163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // QueryPerformanceCounter has high resolution, but is only usable to measure time intervals. 164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // To combine them, we call ftime and QueryPerformanceCounter initially. Later calls will use QueryPerformanceCounter 165635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // by itself, adding the delta to the saved ftime. We periodically re-sync to correct for drift. 166635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static double syncLowResUTCTime; 167635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static double syncHighResUpTime; 168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project static double lastUTCTime; 169635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 170635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project double lowResTime = lowResUTCTime(); 171635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 172635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!qpcAvailable()) 173635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return lowResTime / 1000.0; 174635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 175635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project double highResTime = highResUpTime(); 176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!syncedTime) { 178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project timeBeginPeriod(1); // increase time resolution around low-res time getter 179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project syncLowResUTCTime = lowResTime = lowResUTCTime(); 180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project timeEndPeriod(1); // restore time resolution 181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project syncHighResUpTime = highResTime; 182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project syncedTime = true; 183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project double highResElapsed = highResTime - syncHighResUpTime; 186635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project double utc = syncLowResUTCTime + highResElapsed; 187635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 188635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // force a clock re-sync if we've drifted 189635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project double lowResElapsed = lowResTime - syncLowResUTCTime; 190635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-res accuracy 191635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec) 192635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project syncedTime = false; 193635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // make sure time doesn't run backwards (only correct if difference is < 2 seconds, since DST or clock changes could occur) 195635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project const double backwardTimeLimit = 2000.0; 196635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit) 197635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return lastUTCTime / 1000.0; 198635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project lastUTCTime = utc; 199635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return utc / 1000.0; 200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 2030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic double currentSystemTime() 2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FILETIME ft; 2070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch GetCurrentFT(&ft); 2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a 2100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can 2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // prevent alignment faults on 64-bit Windows). 2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch ULARGE_INTEGER t; 2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch memcpy(&t, &ft, sizeof(t)); 2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Windows file times are in 100s of nanoseconds. 2170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // To convert to seconds, we have to divide by 10,000,000, which is more quickly 2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // done by multiplying by 0.0000001. 2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Between January 1, 1601 and January 1, 1970, there were 369 complete years, 2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // of which 89 were leap years (1700, 1800, and 1900 were not leap years). 2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // That is a total of 134774 days, which is 11644473600 seconds. 2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return t.QuadPart * 0.0000001 - 11644473600.0; 2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochdouble currentTime() 2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static bool init = false; 2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static double lastTime; 2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static DWORD lastTickCount; 2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!init) { 2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lastTime = currentSystemTime(); 2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lastTickCount = GetTickCount(); 2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch init = true; 2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return lastTime; 2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD tickCountNow = GetTickCount(); 2400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch DWORD elapsed = tickCountNow - lastTickCount; 2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch double timeNow = lastTime + (double)elapsed / 1000.; 2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (elapsed >= 0x7FFFFFFF) { 2430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lastTime = timeNow; 2440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch lastTickCount = tickCountNow; 2450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return timeNow; 2470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif // USE(QUERY_PERFORMANCE_COUNTER) 2500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#elif PLATFORM(GTK) 2528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides 2548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// better accuracy compared with Windows implementation of g_get_current_time: 2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// (http://www.google.com/codesearch/p?hl=en#HHnNRjks1t0/glib-2.5.2/glib/gmain.c&q=g_get_current_time). 2568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// Non-Windows GTK builds could use gettimeofday() directly but for the sake of consistency lets use GTK function. 2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiandouble currentTime() 2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian GTimeVal now; 2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian g_get_current_time(&now); 2618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return static_cast<double>(now.tv_sec) + static_cast<double>(now.tv_usec / 1000000.0); 2628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#elif PLATFORM(WX) 2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiandouble currentTime() 2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 2688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian wxDateTime now = wxDateTime::UNow(); 2698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0); 2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} 2718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2725e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#elif PLATFORM(BREWMP) 2735e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 2745e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// GETUTCSECONDS returns the number of seconds since 1980/01/06 00:00:00 UTC, 2755e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// and GETTIMEMS returns the number of milliseconds that have elapsed since the last 2765e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// occurrence of 00:00:00 local time. 2775e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// We can combine GETUTCSECONDS and GETTIMEMS to calculate the number of milliseconds 2785e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// since 1970/01/01 00:00:00 UTC. 2795e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockdouble currentTime() 2805e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 2815e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // diffSeconds is the number of seconds from 1970/01/01 to 1980/01/06 2825e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block const unsigned diffSeconds = 315964800; 2835e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return static_cast<double>(diffSeconds + GETUTCSECONDS() + ((GETTIMEMS() % 1000) / msPerSecond)); 2845e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 2855e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 28621939df44de1705786c545cd1bf519d47250322dBen Murdoch#else 287635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 288635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectdouble currentTime() 289635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project struct timeval now; 29121939df44de1705786c545cd1bf519d47250322dBen Murdoch gettimeofday(&now, 0); 29221939df44de1705786c545cd1bf519d47250322dBen Murdoch return now.tv_sec + now.tv_usec / 1000000.0; 293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 297635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} // namespace WTF 298