Ticket #2424: linux_and_osx.py

File linux_and_osx.py, 1.8 KB (added by Glyph, 10 years ago)

monotonic clock for linux & OS X

Line 
1#!/usr/bin/env python
2import time
3import ctypes
4
5from twisted.python.runtime import platform
6
7if platform.isMacOSX():
8    # see http://developer.apple.com/library/mac/#qa/qa1398/_index.html
9    libSystem = ctypes.CDLL('libSystem.dylib', use_errno=True)
10    CoreServices = ctypes.CDLL(
11        '/System/Library/Frameworks/CoreServices.framework/CoreServices',
12        use_errno=True)
13    mach_absolute_time = libSystem.mach_absolute_time
14    mach_absolute_time.restype = ctypes.c_uint64
15    AbsoluteToNanoseconds = CoreServices.AbsoluteToNanoseconds
16    AbsoluteToNanoseconds.restype = ctypes.c_uint64
17    AbsoluteToNanoseconds.argtypes = [ctypes.c_uint64]
18
19    def monotonicTimeOSX():
20        return AbsoluteToNanoseconds(mach_absolute_time()) * 1e-9
21    monotonicTime = monotonicTimeOSX
22
23elif platform.isLinux():
24    # see http://stackoverflow.com/questions/1205722/how-do-i-get-monotonic-time-durations-in-python
25    import os
26    CLOCK_MONOTONIC = 1 # see <linux/time.h>
27
28    class timespec(ctypes.Structure):
29        _fields_ = [('tv_sec', ctypes.c_long), ('tv_nsec', ctypes.c_long)]
30
31    librt = ctypes.CDLL('librt.so.1', use_errno=True)
32    clock_gettime = librt.clock_gettime
33    clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)]
34
35    def monotonicTimeLinux():
36        t = timespec()
37        if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) != 0:
38            errno_ = ctypes.get_errno()
39            raise OSError(errno_, os.strerror(errno_))
40        return t.tv_sec + t.tv_nsec * 1e-9
41    monotonicTime = monotonicTimeLinux
42
43
44if __name__ == "__main__":
45    startMonotonic = monotonicTime()
46    startWallclock = time.time()
47    print 'Quick, change your clock!'
48    time.sleep(7.2)
49    endMonotonic = monotonicTime()
50    endWallclock = time.time()
51    print endMonotonic - startMonotonic
52    print endWallclock - startWallclock
53