7d8b48b114e754bcd28059a66c2f5825a4a2e652
[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().__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().__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().pdm_protocols() + ["attr"]
30
31 class valueattr(perfobj):
32     def __init__(self, init, info = None, *args, **kwargs):
33         super().__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().pdm_protocols() + ["attr"]
47
48
49 class eventobj(perfobj):
50     def __init__(self, *args, **kwargs):
51         super().__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().pdm_protocols() + ["event"]
70
71 class staticdir(perfobj):
72     def __init__(self, *args, **kwargs):
73         super().__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 list(self.map.keys())
90
91     def lookup(self, name):
92         return self.map[name]
93
94     def pdm_protocols(self):
95         return super().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
104 def getprocid():
105     global procevid
106     idlock.acquire()
107     try:
108         ret = procevid
109         procevid += 1
110         return ret
111     finally:
112         idlock.release()
113
114 class procevent(event):
115     def __init__(self, id):
116         super().__init__()
117         if isinstance(id, procevent):
118             self.id = id.id
119         else:
120             self.id = id
121
122 class startevent(procevent):
123     def __init__(self):
124         super().__init__(getprocid())
125
126 class finishevent(procevent):
127     def __init__(self, start, aborted):
128         super().__init__(start)
129         self.aborted = aborted
130
131 sysres = staticdir()
132 itime = time.time()
133 ires = resource.getrusage(resource.RUSAGE_SELF)
134 def ct():
135     ru = resource.getrusage(resource.RUSAGE_SELF)
136     return (ru.ru_utime - ires.ru_utime) + (ru.ru_stime - ires.ru_stime)
137 sysres["realtime"] = simpleattr(func = lambda: time.time() - itime)
138 sysres["cputime"] = simpleattr(func = ct)
139 sysres["utime"] = simpleattr(func = lambda: resource.getrusage(resource.RUSAGE_SELF).ru_utime - ires.ru_utime)
140 sysres["stime"] = simpleattr(func = lambda: resource.getrusage(resource.RUSAGE_SELF).ru_stime - ires.ru_stime)
141 sysres["maxrss"] = simpleattr(func = lambda: resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
142 sysres["rusage"] = simpleattr(func = lambda: resource.getrusage(resource.RUSAGE_SELF))
143
144 sysinfo = staticdir()
145 sysinfo["pid"] = simpleattr(func = os.getpid)
146 sysinfo["uname"] = simpleattr(func = os.uname)
147 sysinfo["hostname"] = simpleattr(func = socket.gethostname)
148 sysinfo["platform"] = valueattr(init = sys.platform)