1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
"""A high-resolution monotonic timer
This module provides a high-resolution timer via the function get_time()
Thanks to Luca Filippin for the code examples.
Credits and references:
http://stackoverflow.com/questions/1205722/how-do-i-get-monotonic-time-durations-in-python
http://stackoverflow.com/questions/1824399/get-mach-absolute-time-uptime-in-nanoseconds-in-python
https://mail.python.org/pipermail/python-dev/2009-October/093173.html
"""
__author__ = 'Florian Krause <florian@expyriment.org>, \
Oliver Lindemann <oliver@expyriment.org>'
__version__ = '0.7.0'
__revision__ = '55a4e7e'
__date__ = 'Wed Mar 26 14:33:37 2014 +0100'
try:
import ctypes
except:
ctypes = None # Does not exist on Android
import os
from sys import platform
_use_time_module = False
if platform == 'darwin':
# MAC
try:
class _TimeBase(ctypes.Structure):
_fields_ = [
('numer', ctypes.c_uint),
('denom', ctypes.c_uint)
]
_libsys_c = ctypes.CDLL('/usr/lib/system/libsystem_c.dylib')
_libsys_kernel = ctypes.CDLL('/usr/lib/system/libsystem_kernel.dylib')
_mac_abs_time = _libsys_c.mach_absolute_time
_mac_timebase_info = _libsys_kernel.mach_timebase_info
_time_base = _TimeBase()
if (_mac_timebase_info(ctypes.pointer(_time_base)) != 0):
_use_time_module = True
def get_time():
"""Get high-resolution monotonic time stamp (float) """
_mac_abs_time.restype = ctypes.c_ulonglong
return float(_mac_abs_time()) * _time_base.numer / (_time_base.denom * 1e9)
get_time()
except:
_use_time_module = True
elif platform.startswith('linux'):
# real OS
_CLOCK_MONOTONIC = 4 # actually CLOCK_MONOTONIC_RAW see <linux/time.h>
try:
class _TimeSpec(ctypes.Structure):
_fields_ = [
('tv_sec', ctypes.c_long),
('tv_nsec', ctypes.c_long)
]
_librt = ctypes.CDLL('librt.so.1', use_errno=True)
_clock_gettime = _librt.clock_gettime
_clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(_TimeSpec)]
def get_time():
"""Get high-resolution monotonic time stamp (float) """
t = _TimeSpec()
if _clock_gettime(_CLOCK_MONOTONIC, ctypes.pointer(t)) != 0:
errno_ = ctypes.get_errno()
raise OSError(errno_, os.strerror(errno_))
return t.tv_sec + t.tv_nsec * 1e-9
get_time()
except:
_use_time_module = True
elif platform == 'win32':
# win32. Code adapted from the psychopy.core.clock source code.
try:
_fcounter = ctypes.c_int64()
_qpfreq = ctypes.c_int64()
ctypes.windll.Kernel32.QueryPerformanceFrequency(ctypes.byref(_qpfreq))
_qpfreq = float(_qpfreq.value)
_winQPC = ctypes.windll.Kernel32.QueryPerformanceCounter
def get_time():
"""Get high-resolution monotonic time stamp (float) """
_winQPC(ctypes.byref(_fcounter))
return _fcounter.value/_qpfreq
get_time()
except:
_use_time_module = True
else:
# Android or something else
_use_time_module = True
if _use_time_module:
import time
warn_message = "Failed to initialize monotonic timer. Python's time module will be use."
print("Warning: " + warn_message)
if platform == 'win32':
def get_time():
"""Get high-resolution time stamp (float) """
return time.clock()
else:
def get_time():
"""Get high-resolution time stamp (float) """
return time.time()
if __name__ == "__main__":
print get_time()
|