Show More
@@ -1811,6 +1811,20 b' name = "type"' | |||||
1811 | default = "stat" |
|
1811 | default = "stat" | |
1812 |
|
1812 | |||
1813 | [[items]] |
|
1813 | [[items]] | |
|
1814 | section = "profiling" | |||
|
1815 | name = "py-spy.exe" | |||
|
1816 | default = "py-spy" | |||
|
1817 | ||||
|
1818 | [[items]] | |||
|
1819 | section = "profiling" | |||
|
1820 | name = "py-spy.freq" | |||
|
1821 | default = 100 | |||
|
1822 | ||||
|
1823 | [[items]] | |||
|
1824 | section = "profiling" | |||
|
1825 | name = "py-spy.format" | |||
|
1826 | ||||
|
1827 | [[items]] | |||
1814 | section = "progress" |
|
1828 | section = "progress" | |
1815 | name = "assume-tty" |
|
1829 | name = "assume-tty" | |
1816 | default = false |
|
1830 | default = false |
@@ -7,6 +7,9 b'' | |||||
7 |
|
7 | |||
8 |
|
8 | |||
9 | import contextlib |
|
9 | import contextlib | |
|
10 | import os | |||
|
11 | import signal | |||
|
12 | import subprocess | |||
10 |
|
13 | |||
11 | from .i18n import _ |
|
14 | from .i18n import _ | |
12 | from .pycompat import ( |
|
15 | from .pycompat import ( | |
@@ -175,6 +178,50 b' def statprofile(ui, fp):' | |||||
175 | fp.flush() |
|
178 | fp.flush() | |
176 |
|
179 | |||
177 |
|
180 | |||
|
181 | @contextlib.contextmanager | |||
|
182 | def pyspy_profile(ui, fp): | |||
|
183 | exe = ui.config(b'profiling', b'py-spy.exe') | |||
|
184 | ||||
|
185 | freq = ui.configint(b'profiling', b'py-spy.freq') | |||
|
186 | ||||
|
187 | format = ui.config(b'profiling', b'py-spy.format') | |||
|
188 | ||||
|
189 | fd = fp.fileno() | |||
|
190 | ||||
|
191 | output_path = "/dev/fd/%d" % (fd) | |||
|
192 | ||||
|
193 | my_pid = os.getpid() | |||
|
194 | ||||
|
195 | cmd = [ | |||
|
196 | exe, | |||
|
197 | "record", | |||
|
198 | "--pid", | |||
|
199 | str(my_pid), | |||
|
200 | "--native", | |||
|
201 | "--rate", | |||
|
202 | str(freq), | |||
|
203 | "--output", | |||
|
204 | output_path, | |||
|
205 | ] | |||
|
206 | ||||
|
207 | if format: | |||
|
208 | cmd.extend(["--format", format]) | |||
|
209 | ||||
|
210 | proc = subprocess.Popen( | |||
|
211 | cmd, | |||
|
212 | pass_fds={fd}, | |||
|
213 | stdout=subprocess.PIPE, | |||
|
214 | ) | |||
|
215 | ||||
|
216 | _ = proc.stdout.readline() | |||
|
217 | ||||
|
218 | try: | |||
|
219 | yield | |||
|
220 | finally: | |||
|
221 | os.kill(proc.pid, signal.SIGINT) | |||
|
222 | proc.communicate() | |||
|
223 | ||||
|
224 | ||||
178 | class profile: |
|
225 | class profile: | |
179 | """Start profiling. |
|
226 | """Start profiling. | |
180 |
|
227 | |||
@@ -214,7 +261,7 b' class profile:' | |||||
214 | proffn = None |
|
261 | proffn = None | |
215 | if profiler is None: |
|
262 | if profiler is None: | |
216 | profiler = self._ui.config(b'profiling', b'type') |
|
263 | profiler = self._ui.config(b'profiling', b'type') | |
217 | if profiler not in (b'ls', b'stat', b'flame'): |
|
264 | if profiler not in (b'ls', b'stat', b'flame', b'py-spy'): | |
218 | # try load profiler from extension with the same name |
|
265 | # try load profiler from extension with the same name | |
219 | proffn = _loadprofiler(self._ui, profiler) |
|
266 | proffn = _loadprofiler(self._ui, profiler) | |
220 | if proffn is None: |
|
267 | if proffn is None: | |
@@ -257,6 +304,8 b' class profile:' | |||||
257 | proffn = lsprofile |
|
304 | proffn = lsprofile | |
258 | elif profiler == b'flame': |
|
305 | elif profiler == b'flame': | |
259 | proffn = flameprofile |
|
306 | proffn = flameprofile | |
|
307 | elif profiler == b'py-spy': | |||
|
308 | proffn = pyspy_profile | |||
260 | else: |
|
309 | else: | |
261 | proffn = statprofile |
|
310 | proffn = statprofile | |
262 |
|
311 |
General Comments 0
You need to be logged in to leave comments.
Login now