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