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

slprofile.py (5208B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\slprofile.py
      2 import profile
      3 import stackless
      4 import sys
      5 import blue
      6 import thread
      7 import functools
      8 stackless.globaltrace = True
      9 
     10 class Profile(profile.Profile):
     11     base = profile.Profile
     12 
     13     def __init__(self, timer = None, bias = None):
     14         self.current_tasklet = stackless.getcurrent()
     15         self.thread_id = thread.get_ident()
     16         if timer is None:
     17             timer = Timer()
     18         self.base.__init__(self, timer, bias)
     19         self.sleeping = {}
     20 
     21     def __call__(self, *args):
     22         r = self.dispatcher(*args)
     23 
     24     def _setup(self):
     25         self.cur, self.timings, self.current_tasklet = None, {}, stackless.getcurrent()
     26         self.thread_id = thread.get_ident()
     27         self.simulate_call('profiler')
     28 
     29     def start(self, name = 'start'):
     30         if getattr(self, 'running', False):
     31             return
     32         self._setup()
     33         self.simulate_call('start')
     34         self.running = True
     35         sys.setprofile(self.dispatcher)
     36 
     37     def stop(self):
     38         sys.setprofile(None)
     39         self.running = False
     40         self.TallyTimings()
     41 
     42     def runctx(self, cmd, globals, locals):
     43         self._setup()
     44         try:
     45             profile.Profile.runctx(self, cmd, globals, locals)
     46         finally:
     47             self.TallyTimings()
     48 
     49     def runcall(self, func, *args, **kw):
     50         self._setup()
     51         try:
     52             profile.Profile.runcall(self, func, *args, **kw)
     53         finally:
     54             self.TallyTimings()
     55 
     56     def trace_dispatch_return_extend_back(self, frame, t):
     57         if isinstance(self.cur[-2], Profile.fake_frame):
     58             return False
     59             self.trace_dispatch_call(frame, 0)
     60         return self.trace_dispatch_return(frame, t)
     61 
     62     def trace_dispatch_c_return_extend_back(self, frame, t):
     63         if isinstance(self.cur[-2], Profile.fake_frame):
     64             return False
     65             self.trace_dispatch_c_call(frame, 0)
     66         return self.trace_dispatch_return(frame, t)
     67 
     68     dispatch = dict(profile.Profile.dispatch)
     69     dispatch.update({'return': trace_dispatch_return_extend_back,
     70      'c_return': trace_dispatch_c_return_extend_back})
     71 
     72     def SwitchTasklet(self, t0, t1, t):
     73         pt, it, et, fn, frame, rcur = self.cur
     74         cur = (pt,
     75          it + t,
     76          et,
     77          fn,
     78          frame,
     79          rcur)
     80         self.sleeping[t0] = (cur, self.timings)
     81         self.current_tasklet = t1
     82         try:
     83             self.cur, self.timings = self.sleeping.pop(t1)
     84         except KeyError:
     85             self.cur, self.timings = None, {}
     86             self.simulate_call('profiler')
     87             self.simulate_call('new_tasklet')
     88 
     89     def ContextWrap(f):
     90 
     91         @functools.wraps(f)
     92         def ContextWrapper(self, arg, t):
     93             current = stackless.getcurrent()
     94             if current != self.current_tasklet:
     95                 self.SwitchTasklet(self.current_tasklet, current, t)
     96                 t = 0.0
     97             return f(self, arg, t)
     98 
     99         return ContextWrapper
    100 
    101     dispatch = dict([ (key, ContextWrap(val)) for key, val in dispatch.iteritems() ])
    102 
    103     def TallyTimings(self):
    104         oldtimings = self.sleeping
    105         self.sleeping = {}
    106         self.cur = self.Unwind(self.cur, self.timings)
    107         for tasklet, (cur, timings) in oldtimings.iteritems():
    108             self.Unwind(cur, timings)
    109             for k, v in timings.iteritems():
    110                 if k not in self.timings:
    111                     self.timings[k] = v
    112                 else:
    113                     cc, ns, tt, ct, callers = self.timings[k]
    114                     cc += v[0]
    115                     tt += v[2]
    116                     ct += v[3]
    117                     for k1, v1 in v[4].iteritems():
    118                         callers[k1] = callers.get(k1, 0) + v1
    119 
    120                     self.timings[k] = (cc,
    121                      ns,
    122                      tt,
    123                      ct,
    124                      callers)
    125 
    126     def Unwind(self, cur, timings):
    127         while cur[-1]:
    128             rpt, rit, ret, rfn, frame, rcur = cur
    129             frame_total = rit + ret
    130             if rfn in timings:
    131                 cc, ns, tt, ct, callers = timings[rfn]
    132             else:
    133                 cc, ns, tt, ct, callers = (0,
    134                  0,
    135                  0,
    136                  0,
    137                  {})
    138             if not ns:
    139                 ct = ct + frame_total
    140                 cc = cc + 1
    141             if rcur:
    142                 ppt, pit, pet, pfn, pframe, pcur = rcur
    143             else:
    144                 pfn = None
    145             if pfn in callers:
    146                 callers[pfn] = callers[pfn] + 1
    147             elif pfn:
    148                 callers[pfn] = 1
    149             timings[rfn] = (cc,
    150              ns - 1,
    151              tt + rit,
    152              ct,
    153              callers)
    154             ppt, pit, pet, pfn, pframe, pcur = rcur
    155             rcur = (ppt,
    156              pit + rpt,
    157              pet + frame_total,
    158              pfn,
    159              pframe,
    160              pcur)
    161             cur = rcur
    162 
    163         return cur
    164 
    165 
    166 class Timer(object):
    167 
    168     def __init__(self):
    169         self.startTime = blue.os.GetWallclockTimeNow()
    170 
    171     def __call__(self):
    172         return float(blue.os.GetWallclockTimeNow() - self.startTime) * 1e-07