NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

timerstuff.py (4979B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\util\timerstuff.py
      2 import functools
      3 import logging
      4 import sys
      5 import traceback
      6 import weakref
      7 import blue
      8 import ccpProfile
      9 import stackless
     10 import uthread
     11 from carbon.common.lib import const
     12 log = logging.getLogger(__name__)
     13 ClockThis = sys.ClockThis
     14 ClockThisWithoutTheStars = sys.ClockThisWithoutTheStars
     15 
     16 def TimeThis(timer):
     17 
     18     def Helper(func):
     19 
     20         @functools.wraps(func)
     21         def Wrapper(*args, **kwds):
     22             t = ccpProfile.PushTimer(timer)
     23             try:
     24                 return func(*args, **kwds)
     25             finally:
     26                 ccpProfile.PopTimer(t)
     27 
     28         return Wrapper
     29 
     30     return Helper
     31 
     32 
     33 class SimpleTimingContext(object):
     34 
     35     def __enter__(self):
     36         c = stackless.getcurrent()
     37         self.t = (c.GetWallclockTime(), c.GetRunTime())
     38 
     39     def __exit__(self, exc_type, exc_value, exc_tb):
     40         a, b = self.t
     41         c = stackless.getcurrent()
     42         self.t = (c.GetWallclockTime() - a, c.GetRunTime() - b)
     43 
     44     def GetWallclockTime(self):
     45         return self.t[0]
     46 
     47     def GetRunTime(self):
     48         return self.t[1]
     49 
     50 
     51 class TimerObject:
     52 
     53     def __init__(self, useSimTime = False):
     54         self.abort = 0
     55         self.id = 0
     56         self.aborts = {}
     57         if useSimTime:
     58             self.GetTime = blue.os.GetSimTime
     59             self.Sleep = blue.pyos.synchro.SleepSim
     60         else:
     61             self.GetTime = blue.os.GetWallclockTime
     62             self.Sleep = blue.pyos.synchro.SleepWallclock
     63 
     64     def __del__(self):
     65         self.abort = 1
     66 
     67     def DelayedCall(self, func, time, *args, **kw):
     68         self.id += 1
     69         callID = self.id
     70         if time - self.GetTime() > const.DAY * 2:
     71             raise RuntimeError('Cannot sleep for more than 48 hours')
     72         uthread.new(self.DelayedCall_thread, callID, func, time, args, kw, stackless_tracing_enabled=False)
     73         return callID
     74 
     75     def DelayedCall_thread(self, callID, func, time, args, kw):
     76         delay = (time - self.GetTime()) / 10000
     77         if delay > 0:
     78             self.Sleep(delay)
     79         if callID in self.aborts:
     80             del self.aborts[callID]
     81         elif not self.abort:
     82             try:
     83                 func(*args, **kw)
     84             except:
     85                 log.exception('Error in delayed call')
     86 
     87     def KillDelayedCall(self, id):
     88         self.aborts[id] = None
     89 
     90     def KillAllDelayedCalls(self):
     91         self.abort = 1
     92 
     93 
     94 def OnTimerResync(old, new):
     95     diff = new - old
     96     for timer in AutoTimer.autoTimers.keys():
     97         timer.wakeupAt += diff / 10000
     98 
     99 
    100 class AutoTimer(object):
    101     autoTimers = weakref.WeakKeyDictionary()
    102     __resync_handler_registered = False
    103 
    104     def __init__(self, interval, method, *args, **kw):
    105         if interval <= 0:
    106             raise RuntimeError('Invalid interval for AutoTimer')
    107         if not self.__resync_handler_registered:
    108             blue.pyos.synchro.timesyncs.append(OnTimerResync)
    109             self.__resync_handler_registered = True
    110         self.run = 1
    111         self.interval = interval
    112         self.method, self.args, self.kw = method, args, kw
    113         caller_tb = traceback.extract_stack(limit=2)[0:1]
    114         caller = traceback.format_list(caller_tb)[0].replace('\n', '')
    115         methrepr = getattr(method, '__name__', '(no __name__)').replace('<', '&lt;').replace('>', '&gt;')
    116         ctx = 'AutoTimer::(%s) on %s' % (caller, methrepr)
    117         self.wakeupAt = blue.os.GetWallclockTime() / 10000 + self.interval
    118         AutoTimer.autoTimers[self] = None
    119         uthread.pool(ctx, AutoTimer.Loop, weakref.ref(self), stackless_tracing_enabled=False)
    120 
    121     def KillTimer(self):
    122         self.run = 0
    123 
    124     def Reset(self, newInterval = None):
    125         if newInterval is not None:
    126             if newInterval <= 0:
    127                 raise RuntimeError('Invalid interval for AutoTimer')
    128             self.interval = newInterval
    129         self.wakeupAt = blue.os.GetWallclockTime() / 10000 + self.interval
    130 
    131     def Loop(weakSelf):
    132         self = weakSelf()
    133         if not self or not self.run:
    134             return
    135         nap = self.interval
    136         del self
    137         while True:
    138             blue.pyos.synchro.SleepWallclock(nap)
    139             self = weakSelf()
    140             if not self or not self.run:
    141                 return
    142             now = blue.os.GetWallclockTime() / 10000
    143             if now < self.wakeupAt:
    144                 nap = self.wakeupAt - now
    145             else:
    146                 self.method(*self.args, **self.kw)
    147                 n = (now - self.wakeupAt) / self.interval
    148                 self.wakeupAt += (n + 1) * self.interval
    149                 nap = self.wakeupAt - now
    150             del self
    151 
    152     Loop = staticmethod(Loop)
    153 
    154 
    155 class Stopwatch:
    156 
    157     def __init__(self):
    158         self.started = blue.os.GetCycles()[0]
    159 
    160     def __str__(self):
    161         return '%.3f' % ((blue.os.GetCycles()[0] - self.started) / float(blue.os.GetCycles()[1]))
    162 
    163     def Reset(self):
    164         self.started = blue.os.GetCycles()[0]