# Copyright (c) 2006-2014 Sippy Software, Inc. All rights reserved. # # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from time import strftime, gmtime, localtime import sys from os.path import dirname, abspath from inspect import getfile, currentframe currentdir = dirname(abspath(getfile(currentframe()))) parentdir = dirname(currentdir) sys.path.insert(0, parentdir) from sippy.Math.recfilter import recfilter from sippy.Time.clock_dtime import clock_getdtime, CLOCK_REALTIME, CLOCK_MONOTONIC sys.path.pop(0) from threading import local class MonoGlobals(local): realt_flt = None monot_max = None def __init__(self): realt = clock_getdtime(CLOCK_REALTIME) self.monot_max = clock_getdtime(CLOCK_MONOTONIC) self.realt_flt = recfilter(0.99, realt - self.monot_max) class MonoTime(object): monot = None realt = None globals = MonoGlobals() def __init__(self, s = None, monot = None, realt = None, trust_realt = False): if s != None: parts = s.split('-', 1) self.realt = float(parts[0]) if len(parts) == 1: self.__initFromRealt() else: self.monot = float(parts[1]) return if monot == None and realt == None: if trust_realt: raise TypeError('MonoTime.__init__: realt could not be None when trust_realt is set') realt = clock_getdtime(CLOCK_REALTIME) self.monot = clock_getdtime(CLOCK_MONOTONIC) diff_flt = self.globals.realt_flt.apply(realt - self.monot) if self.globals.monot_max < self.monot: self.globals.monot_max = self.monot self.realt = self.monot + diff_flt return if monot != None: self.monot = monot if realt != None: self.realt = realt else: self.realt = monot + self.globals.realt_flt.lastval return self.realt = realt self.__initFromRealt(trust_realt) def __initFromRealt(self, trust_realt = False): self.monot = self.realt - self.globals.realt_flt.lastval if not trust_realt and self.monot > self.globals.monot_max: monot_now = clock_getdtime(CLOCK_MONOTONIC) if monot_now > self.globals.monot_max: self.globals.monot_max = monot_now self.monot = self.globals.monot_max def getdiff(self): return (self.realt - self.monot) def __str__(self): rstr = '%.6f-%.6f' % (self.realt, self.monot) return (rstr) def ftime(self, base = None): if base != None: realt = base.realt - (base.monot - self.monot) else: realt = self.realt return strftime('%Y-%m-%d %H:%M:%S+00', gmtime(round(realt))) def fptime(self, base = None): if base != None: realt = base.realt - (base.monot - self.monot) else: realt = self.realt return '%s.%.3d' % (strftime('%d %b %H:%M:%S', localtime(realt)), \ (realt % 1) * 1000) def frtime(self, base = None): if base != None: realt = base.realt - (base.monot - self.monot) else: realt = self.realt gt = gmtime(realt) day = strftime('%d', gt) if day[0] == '0': day = day[1] return strftime('%%H:%%M:%%S.000 GMT %%a %%b %s %%Y' % day, gt) def __add__(self, x): if isinstance(x, MonoTime): return (self.monot + x.monot) return (self.monot + x) def __sub__(self, x): if isinstance(x, MonoTime): return (self.monot - x.monot) return (self.monot - x) def __radd__(self, x): if isinstance(x, MonoTime): return (self.monot + x.monot) return (self.monot + x) def __rsub__(self, x): if isinstance(x, MonoTime): return (x.monot - self.monot) return (x - self.monot) def __cmp__(self, other): if other == None: return (1) if isinstance(other, int): otime = float(other) elif isinstance(other, float): otime = other else: otime = other.monot return cmp(self.monot, otime) def __lt__(self, other): return (self.monot < other.monot) def __le__(self, other): return (self.monot <= other.monot) def __eq__(self, other): if other == None: return (False) return (self.monot == other.monot) def __ne__(self, other): if other == None: return (True) return (self.monot != other.monot) def __gt__(self, other): return (self.monot > other.monot) def __ge__(self, other): return (self.monot >= other.monot) def offsetFromNow(self): now = clock_getdtime(CLOCK_MONOTONIC) return (now - self.monot) def getOffsetCopy(self, offst): return self.__class__(monot = self.monot + offst, realt = self.realt + offst) def offset(self, offst): self.monot += offst self.realt += offst def getCopy(self): return self.__class__(monot = self.monot, realt = self.realt) class selftest(object): mg1 = None mg2 = None def run_t1(self): m = MonoTime() self.mg1 = m.globals.realt_flt def run_t2(self): m = MonoTime() self.mg2 = m.globals.realt_flt def run(self): for x in range (0, 100000): m1 = MonoTime() m2 = MonoTime() if x == 0: print(m1, m2) print(m1.ftime(), m2.ftime()) #print (m1.getdiff() - m2.getdiff()) print(m1, m2) print(m1 < m2, m1 > m2, m1 == m2, m1 <= m2, m1 >= m2, m1 != m2) print(m1.ftime(), m2.ftime()) ms1 = str(m1) ms2 = str(m2) m3 = MonoTime(s = ms1) m4 = MonoTime(s = ms2) print(m3, m4) print(m3.ftime(), m4.ftime()) m5 = MonoTime(realt = m3.realt) m6 = MonoTime(monot = m4.monot) print(m5.ftime(), m6.ftime()) print(m5.globals.realt_flt == m1.globals.realt_flt) from threading import Thread t1 = Thread(target = self.run_t1) t2 = Thread(target = self.run_t2) t1.start() t2.start() t1.join() t2.join() print(self.mg1 != self.mg2) if __name__ == '__main__': selftest().run()