Introduced paired events for processes.
[pdm.git] / pdm / perf.py
1 import os, sys, resource, time, socket, threading
2
3 class attrinfo(object):
4     def __init__(self, desc = None):
5         self.desc = desc
6
7 class perfobj(object):
8     def __init__(self, *args, **kwargs):
9         super(perfobj, self).__init__()
10     
11     def pdm_protocols(self):
12         return []
13
14 class simpleattr(perfobj):
15     def __init__(self, func, info = None, *args, **kwargs):
16         super(simpleattr, self).__init__(*args, **kwargs)
17         self.func = func
18         if info is None:
19             info = attrinfo()
20         self.info = info
21
22     def readattr(self):
23         return self.func()
24
25     def attrinfo(self):
26         return self.info
27
28     def pdm_protocols(self):
29         return super(simpleattr, self).pdm_protocols() + ["attr"]
30
31 class valueattr(perfobj):
32     def __init__(self, init, info = None, *args, **kwargs):
33         super(valueattr, self).__init__(*args, **kwargs)
34         self.value = init
35         if info is None:
36             info = attrinfo()
37         self.info = info
38
39     def readattr(self):
40         return self.value
41
42     def attrinfo(self):
43         return self.info
44
45     def pdm_protocols(self):
46         return super(valueattr, self).pdm_protocols() + ["attr"]
47
48
49 class eventobj(perfobj):
50     def __init__(self, *args, **kwargs):
51         super(eventobj, self).__init__(*args, **kwargs)
52         self.subscribers = set()
53
54     def subscribe(self, cb):
55         if cb in self.subscribers:
56             raise ValueError("Already subscribed")
57         self.subscribers.add(cb)
58
59     def unsubscribe(self, cb):
60         self.subscribers.remove(cb)
61
62     def notify(self, event):
63         for cb in self.subscribers:
64             try:
65                 cb(event)
66             except: pass
67
68     def pdm_protocols(self):
69         return super(eventobj, self).pdm_protocols() + ["event"]
70
71 class staticdir(perfobj):
72     def __init__(self, *args, **kwargs):
73         super(staticdir, self).__init__(*args, **kwargs)
74         self.map = {}
75
76     def __setitem__(self, name, ob):
77         self.map[name] = ob
78
79     def __delitem__(self, name):
80         del self.map[name]
81         
82     def __getitem__(self, name):
83         return self.map[name]
84
85     def get(self, name, default = None):
86         return self.map.get(name, default)
87
88     def listdir(self):
89         return self.map.keys()
90
91     def lookup(self, name):
92         return self.map[name]
93
94     def pdm_protocols(self):
95         return super(staticdir, self).pdm_protocols() + ["dir"]
96
97 class event(object):
98     def __init__(self):
99         self.time = time.time()
100
101 idlock = threading.Lock()
102 procevid = 0
103 class startevent(event):
104     def __init__(self):
105         super(startevent, self).__init__()
106         global procevid
107         idlock.acquire()
108         try:
109             self.id = procevid
110             procevid += 1
111         finally:
112             idlock.release()
113
114 class finishevent(event):
115     def __init__(self, start, aborted):
116         super(finishevent, self).__init__()
117         self.id = start.id
118         self.aborted = aborted
119
120 sysres = staticdir()
121 itime = time.time()
122 ires = resource.getrusage(resource.RUSAGE_SELF)
123 def ct():
124     ru = resource.getrusage(resource.RUSAGE_SELF)
125     return (ru.ru_utime - ires.ru_utime) + (ru.ru_stime - ires.ru_stime)
126 sysres["realtime"] = simpleattr(func = lambda: time.time() - itime)
127 sysres["cputime"] = simpleattr(func = ct)
128 sysres["utime"] = simpleattr(func = lambda: resource.getrusage(resource.RUSAGE_SELF).ru_utime - ires.ru_utime)
129 sysres["stime"] = simpleattr(func = lambda: resource.getrusage(resource.RUSAGE_SELF).ru_stime - ires.ru_stime)
130 sysres["maxrss"] = simpleattr(func = lambda: resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
131 sysres["rusage"] = simpleattr(func = lambda: resource.getrusage(resource.RUSAGE_SELF))
132
133 sysinfo = staticdir()
134 sysinfo["pid"] = simpleattr(func = os.getpid)
135 sysinfo["uname"] = simpleattr(func = os.uname)
136 sysinfo["hostname"] = simpleattr(func = socket.gethostname)
137 sysinfo["platform"] = valueattr(init = sys.platform)