1be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Copyright 2016 The Chromium Authors. All rights reserved. 2be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Use of this source code is governed by a BSD-style license that can be 3be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# found in the LICENSE file. 4be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 5be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport ctypes 6be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport ctypes.util 7be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport logging 8be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport os 9be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport platform 10be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport sys 11be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport time 12be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikimport threading 13be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 14be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 15be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris CraikGET_TICK_COUNT_LAST_NOW = 0 16be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# If GET_TICK_COUNTER_LAST_NOW is less than the current time, the clock has 17be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# rolled over, and this needs to be accounted for. 18be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris CraikGET_TICK_COUNT_WRAPAROUNDS = 0 19be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# The current detected platform 20a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik_CLOCK = None 21a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik_NOW_FUNCTION = None 22be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Mapping of supported platforms and what is returned by sys.platform. 23be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik_PLATFORMS = { 24be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'mac': 'darwin', 25be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'linux': 'linux', 26be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'windows': 'win32', 27be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'cygwin': 'cygwin', 28be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'freebsd': 'freebsd', 29be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'sunos': 'sunos5', 30be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'bsd': 'bsd' 31be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik} 32be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik# Mapping of what to pass get_clocktime based on platform. 33be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik_CLOCK_MONOTONIC = { 34be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'linux': 1, 35be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'freebsd': 4, 36be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'bsd': 3, 37be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 'sunos5': 4 38be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik} 39be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 40a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik_LINUX_CLOCK = 'LINUX_CLOCK_MONOTONIC' 41a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik_MAC_CLOCK = 'MAC_MACH_ABSOLUTE_TIME' 42a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik_WIN_HIRES = 'WIN_QPC' 43a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik_WIN_LORES = 'WIN_ROLLOVER_PROTECTED_TIME_GET_TIME' 44be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 45a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikdef InitializeMacNowFunction(plat): 46a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik """Sets a monotonic clock for the Mac platform. 47be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 48be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 49be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik plat: Platform that is being run on. Unused in GetMacNowFunction. Passed 50be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik for consistency between initilaizers. 51be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 52a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik del plat # Unused 53a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global _CLOCK # pylint: disable=global-statement 54a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global _NOW_FUNCTION # pylint: disable=global-statement 55a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik _CLOCK = _MAC_CLOCK 56be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik libc = ctypes.CDLL('/usr/lib/libc.dylib', use_errno=True) 57be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik class MachTimebaseInfoData(ctypes.Structure): 58be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """System timebase info. Defined in <mach/mach_time.h>.""" 59be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik _fields_ = (('numer', ctypes.c_uint32), 60be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ('denom', ctypes.c_uint32)) 61be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 62be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik mach_absolute_time = libc.mach_absolute_time 63be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik mach_absolute_time.restype = ctypes.c_uint64 64be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 65be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik timebase = MachTimebaseInfoData() 66be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik libc.mach_timebase_info(ctypes.byref(timebase)) 67be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ticks_per_second = timebase.numer / timebase.denom * 1.0e9 68be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 69a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def MacNowFunctionImpl(): 70be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return mach_absolute_time() / ticks_per_second 71a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik _NOW_FUNCTION = MacNowFunctionImpl 72be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 73be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 74be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikdef GetClockGetTimeClockNumber(plat): 75be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik for key in _CLOCK_MONOTONIC: 76be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if plat.startswith(key): 77be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return _CLOCK_MONOTONIC[key] 78be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik raise LookupError('Platform not in clock dicitonary') 79be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 80a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikdef InitializeLinuxNowFunction(plat): 81a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik """Sets a monotonic clock for linux platforms. 82be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 83be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 84be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik plat: Platform that is being run on. 85be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 86a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global _CLOCK # pylint: disable=global-statement 87a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global _NOW_FUNCTION # pylint: disable=global-statement 88a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik _CLOCK = _LINUX_CLOCK 89be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik clock_monotonic = GetClockGetTimeClockNumber(plat) 90be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik try: 91be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik # Attempt to find clock_gettime in the C library. 92be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik clock_gettime = ctypes.CDLL(ctypes.util.find_library('c'), 93be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik use_errno=True).clock_gettime 94be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik except AttributeError: 95be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik # If not able to find int in the C library, look in rt library. 96be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik clock_gettime = ctypes.CDLL(ctypes.util.find_library('rt'), 97be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik use_errno=True).clock_gettime 98be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 99be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik class Timespec(ctypes.Structure): 100be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """Time specification, as described in clock_gettime(3).""" 101be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik _fields_ = (('tv_sec', ctypes.c_long), 102be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ('tv_nsec', ctypes.c_long)) 103be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 104a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def LinuxNowFunctionImpl(): 105be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ts = Timespec() 106be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if clock_gettime(clock_monotonic, ctypes.pointer(ts)): 107be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik errno = ctypes.get_errno() 108be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik raise OSError(errno, os.strerror(errno)) 109be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return ts.tv_sec + ts.tv_nsec / 1.0e9 110be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 111a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik _NOW_FUNCTION = LinuxNowFunctionImpl 112be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 113be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 114be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikdef IsQPCUsable(): 115a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik """Determines if system can query the performance counter. 116be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik The performance counter is a high resolution timer on windows systems. 117be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Some chipsets have unreliable performance counters, so this checks that one 118be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik of those chipsets is not present. 119be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 120be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Returns: 121be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik True if QPC is useable, false otherwise. 122be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 123be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 124be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik # Sample output: 'Intel64 Family 6 Model 23 Stepping 6, GenuineIntel' 125be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik info = platform.processor() 126be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if 'AuthenticAMD' in info and 'Family 15' in info: 127be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return False 128a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik try: # If anything goes wrong during this, assume QPC isn't available. 129be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik frequency = ctypes.c_int64() 130be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ctypes.windll.Kernel32.QueryPerformanceFrequency( 131be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ctypes.byref(frequency)) 132be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if float(frequency.value) <= 0: 133be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return False 134a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik except Exception: # pylint: disable=broad-except 135be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik logging.exception('Error when determining if QPC is usable.') 136be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return False 137be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return True 138be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 139be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 140a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikdef InitializeWinNowFunction(plat): 141a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik """Sets a monotonic clock for windows platforms. 142be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 143be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 144be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik plat: Platform that is being run on. 145be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 146a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global _CLOCK # pylint: disable=global-statement 147a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global _NOW_FUNCTION # pylint: disable=global-statement 148a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 149be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if IsQPCUsable(): 150a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik _CLOCK = _WIN_HIRES 151be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik qpc_return = ctypes.c_int64() 152be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik qpc_frequency = ctypes.c_int64() 153be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ctypes.windll.Kernel32.QueryPerformanceFrequency( 154be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik ctypes.byref(qpc_frequency)) 155be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik qpc_frequency = float(qpc_frequency.value) 156be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik qpc = ctypes.windll.Kernel32.QueryPerformanceCounter 157a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 158a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def WinNowFunctionImpl(): 159be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik qpc(ctypes.byref(qpc_return)) 160be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return qpc_return.value / qpc_frequency 161be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 162be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 163a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik _CLOCK = _WIN_LORES 164be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik kernel32 = (ctypes.cdll.kernel32 165be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if plat.startswith(_PLATFORMS['cygwin']) 166be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else ctypes.windll.kernel32) 167be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik get_tick_count_64 = getattr(kernel32, 'GetTickCount64', None) 168be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 169be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik # Windows Vista or newer 170be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if get_tick_count_64: 171be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik get_tick_count_64.restype = ctypes.c_ulonglong 172a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 173a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def WinNowFunctionImpl(): 174be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return get_tick_count_64() / 1000.0 175be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 176a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik else: # Pre Vista. 177be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik get_tick_count = kernel32.GetTickCount 178be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik get_tick_count.restype = ctypes.c_uint32 179be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik get_tick_count_lock = threading.Lock() 180a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 181a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik def WinNowFunctionImpl(): 182a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global GET_TICK_COUNT_LAST_NOW # pylint: disable=global-statement 183a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global GET_TICK_COUNT_WRAPAROUNDS # pylint: disable=global-statement 184be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik with get_tick_count_lock: 185be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik current_sample = get_tick_count() 186be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if current_sample < GET_TICK_COUNT_LAST_NOW: 187be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik GET_TICK_COUNT_WRAPAROUNDS += 1 188be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik GET_TICK_COUNT_LAST_NOW = current_sample 189be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik final_ms = GET_TICK_COUNT_WRAPAROUNDS << 32 190be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik final_ms += GET_TICK_COUNT_LAST_NOW 191be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik return final_ms / 1000.0 192a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 193a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik _NOW_FUNCTION = WinNowFunctionImpl 194be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 195be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 196be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikdef InitializeNowFunction(plat): 197a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik """Sets a monotonic clock for the current platform. 198be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 199be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik Args: 200be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik plat: Platform that is being run on. 201be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik """ 202be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik if plat.startswith(_PLATFORMS['mac']): 203a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik InitializeMacNowFunction(plat) 204be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 205be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik elif (plat.startswith(_PLATFORMS['linux']) 206be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik or plat.startswith(_PLATFORMS['freebsd']) 207be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik or plat.startswith(_PLATFORMS['bsd']) 208be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik or plat.startswith(_PLATFORMS['sunos'])): 209a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik InitializeLinuxNowFunction(plat) 210be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 211be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik elif (plat.startswith(_PLATFORMS['windows']) 212be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik or plat.startswith(_PLATFORMS['cygwin'])): 213a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik InitializeWinNowFunction(plat) 214be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 215be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik else: 216be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik raise RuntimeError('%s is not a supported platform.' % plat) 217be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 218a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global _NOW_FUNCTION 219a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik global _CLOCK 220a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik assert _NOW_FUNCTION, 'Now function not properly set during initialization.' 221a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik assert _CLOCK, 'Clock not properly set during initialization.' 222a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 223a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 224be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craikdef Now(): 225a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik return _NOW_FUNCTION() * 1e6 # convert from seconds to microseconds 226a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 227a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 228a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craikdef GetClock(): 229a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik return _CLOCK 230a23c9e9f6fc22fe5611def685e1984062b13b560Chris Craik 231be1f909aea58dd8b153538c9fa19cb0bf50bdb17Chris Craik 232a23c9e9f6fc22fe5611def685e1984062b13b560Chris CraikInitializeNowFunction(sys.platform) 233