##// END OF EJS Templates
configitems: register the 'profiling.showmax' config
Boris Feld -
r34411:fecea78f default
parent child Browse files
Show More
@@ -1,671 +1,674
1 1 # configitems.py - centralized declaration of configuration option
2 2 #
3 3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import functools
11 11
12 12 from . import (
13 13 encoding,
14 14 error,
15 15 )
16 16
17 17 def loadconfigtable(ui, extname, configtable):
18 18 """update config item known to the ui with the extension ones"""
19 19 for section, items in configtable.items():
20 20 knownitems = ui._knownconfig.setdefault(section, {})
21 21 knownkeys = set(knownitems)
22 22 newkeys = set(items)
23 23 for key in sorted(knownkeys & newkeys):
24 24 msg = "extension '%s' overwrite config item '%s.%s'"
25 25 msg %= (extname, section, key)
26 26 ui.develwarn(msg, config='warn-config')
27 27
28 28 knownitems.update(items)
29 29
30 30 class configitem(object):
31 31 """represent a known config item
32 32
33 33 :section: the official config section where to find this item,
34 34 :name: the official name within the section,
35 35 :default: default value for this item,
36 36 :alias: optional list of tuples as alternatives.
37 37 """
38 38
39 39 def __init__(self, section, name, default=None, alias=()):
40 40 self.section = section
41 41 self.name = name
42 42 self.default = default
43 43 self.alias = list(alias)
44 44
45 45 coreitems = {}
46 46
47 47 def _register(configtable, *args, **kwargs):
48 48 item = configitem(*args, **kwargs)
49 49 section = configtable.setdefault(item.section, {})
50 50 if item.name in section:
51 51 msg = "duplicated config item registration for '%s.%s'"
52 52 raise error.ProgrammingError(msg % (item.section, item.name))
53 53 section[item.name] = item
54 54
55 55 # special value for case where the default is derived from other values
56 56 dynamicdefault = object()
57 57
58 58 # Registering actual config items
59 59
60 60 def getitemregister(configtable):
61 61 return functools.partial(_register, configtable)
62 62
63 63 coreconfigitem = getitemregister(coreitems)
64 64
65 65 coreconfigitem('auth', 'cookiefile',
66 66 default=None,
67 67 )
68 68 # bookmarks.pushing: internal hack for discovery
69 69 coreconfigitem('bookmarks', 'pushing',
70 70 default=list,
71 71 )
72 72 # bundle.mainreporoot: internal hack for bundlerepo
73 73 coreconfigitem('bundle', 'mainreporoot',
74 74 default='',
75 75 )
76 76 # bundle.reorder: experimental config
77 77 coreconfigitem('bundle', 'reorder',
78 78 default='auto',
79 79 )
80 80 coreconfigitem('censor', 'policy',
81 81 default='abort',
82 82 )
83 83 coreconfigitem('chgserver', 'idletimeout',
84 84 default=3600,
85 85 )
86 86 coreconfigitem('chgserver', 'skiphash',
87 87 default=False,
88 88 )
89 89 coreconfigitem('cmdserver', 'log',
90 90 default=None,
91 91 )
92 92 coreconfigitem('color', 'mode',
93 93 default='auto',
94 94 )
95 95 coreconfigitem('color', 'pagermode',
96 96 default=dynamicdefault,
97 97 )
98 98 coreconfigitem('commands', 'status.relative',
99 99 default=False,
100 100 )
101 101 coreconfigitem('commands', 'status.skipstates',
102 102 default=[],
103 103 )
104 104 coreconfigitem('commands', 'status.verbose',
105 105 default=False,
106 106 )
107 107 coreconfigitem('commands', 'update.requiredest',
108 108 default=False,
109 109 )
110 110 coreconfigitem('devel', 'all-warnings',
111 111 default=False,
112 112 )
113 113 coreconfigitem('devel', 'bundle2.debug',
114 114 default=False,
115 115 )
116 116 coreconfigitem('devel', 'check-locks',
117 117 default=False,
118 118 )
119 119 coreconfigitem('devel', 'check-relroot',
120 120 default=False,
121 121 )
122 122 coreconfigitem('devel', 'default-date',
123 123 default=None,
124 124 )
125 125 coreconfigitem('devel', 'deprec-warn',
126 126 default=False,
127 127 )
128 128 coreconfigitem('devel', 'disableloaddefaultcerts',
129 129 default=False,
130 130 )
131 131 coreconfigitem('devel', 'legacy.exchange',
132 132 default=list,
133 133 )
134 134 coreconfigitem('devel', 'servercafile',
135 135 default='',
136 136 )
137 137 coreconfigitem('devel', 'serverexactprotocol',
138 138 default='',
139 139 )
140 140 coreconfigitem('devel', 'serverrequirecert',
141 141 default=False,
142 142 )
143 143 coreconfigitem('devel', 'strip-obsmarkers',
144 144 default=True,
145 145 )
146 146 coreconfigitem('email', 'charsets',
147 147 default=list,
148 148 )
149 149 coreconfigitem('email', 'method',
150 150 default='smtp',
151 151 )
152 152 coreconfigitem('experimental', 'bundle-phases',
153 153 default=False,
154 154 )
155 155 coreconfigitem('experimental', 'bundle2-advertise',
156 156 default=True,
157 157 )
158 158 coreconfigitem('experimental', 'bundle2-output-capture',
159 159 default=False,
160 160 )
161 161 coreconfigitem('experimental', 'bundle2.pushback',
162 162 default=False,
163 163 )
164 164 coreconfigitem('experimental', 'bundle2lazylocking',
165 165 default=False,
166 166 )
167 167 coreconfigitem('experimental', 'bundlecomplevel',
168 168 default=None,
169 169 )
170 170 coreconfigitem('experimental', 'changegroup3',
171 171 default=False,
172 172 )
173 173 coreconfigitem('experimental', 'clientcompressionengines',
174 174 default=list,
175 175 )
176 176 coreconfigitem('experimental', 'copytrace',
177 177 default='on',
178 178 )
179 179 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
180 180 default=100,
181 181 )
182 182 coreconfigitem('experimental', 'crecordtest',
183 183 default=None,
184 184 )
185 185 coreconfigitem('experimental', 'editortmpinhg',
186 186 default=False,
187 187 )
188 188 coreconfigitem('experimental', 'stabilization',
189 189 default=list,
190 190 alias=[('experimental', 'evolution')],
191 191 )
192 192 coreconfigitem('experimental', 'stabilization.bundle-obsmarker',
193 193 default=False,
194 194 alias=[('experimental', 'evolution.bundle-obsmarker')],
195 195 )
196 196 coreconfigitem('experimental', 'stabilization.track-operation',
197 197 default=True,
198 198 alias=[('experimental', 'evolution.track-operation')]
199 199 )
200 200 coreconfigitem('experimental', 'exportableenviron',
201 201 default=list,
202 202 )
203 203 coreconfigitem('experimental', 'extendedheader.index',
204 204 default=None,
205 205 )
206 206 coreconfigitem('experimental', 'extendedheader.similarity',
207 207 default=False,
208 208 )
209 209 coreconfigitem('experimental', 'format.compression',
210 210 default='zlib',
211 211 )
212 212 coreconfigitem('experimental', 'graphshorten',
213 213 default=False,
214 214 )
215 215 coreconfigitem('experimental', 'hook-track-tags',
216 216 default=False,
217 217 )
218 218 coreconfigitem('experimental', 'httppostargs',
219 219 default=False,
220 220 )
221 221 coreconfigitem('experimental', 'manifestv2',
222 222 default=False,
223 223 )
224 224 coreconfigitem('experimental', 'mergedriver',
225 225 default=None,
226 226 )
227 227 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
228 228 default=False,
229 229 )
230 230 coreconfigitem('experimental', 'rebase.multidest',
231 231 default=False,
232 232 )
233 233 coreconfigitem('experimental', 'revertalternateinteractivemode',
234 234 default=True,
235 235 )
236 236 coreconfigitem('experimental', 'revlogv2',
237 237 default=None,
238 238 )
239 239 coreconfigitem('experimental', 'spacemovesdown',
240 240 default=False,
241 241 )
242 242 coreconfigitem('experimental', 'treemanifest',
243 243 default=False,
244 244 )
245 245 coreconfigitem('experimental', 'updatecheck',
246 246 default=None,
247 247 )
248 248 coreconfigitem('format', 'aggressivemergedeltas',
249 249 default=False,
250 250 )
251 251 coreconfigitem('format', 'chunkcachesize',
252 252 default=None,
253 253 )
254 254 coreconfigitem('format', 'dotencode',
255 255 default=True,
256 256 )
257 257 coreconfigitem('format', 'generaldelta',
258 258 default=False,
259 259 )
260 260 coreconfigitem('format', 'manifestcachesize',
261 261 default=None,
262 262 )
263 263 coreconfigitem('format', 'maxchainlen',
264 264 default=None,
265 265 )
266 266 coreconfigitem('format', 'obsstore-version',
267 267 default=None,
268 268 )
269 269 coreconfigitem('format', 'usefncache',
270 270 default=True,
271 271 )
272 272 coreconfigitem('format', 'usegeneraldelta',
273 273 default=True,
274 274 )
275 275 coreconfigitem('format', 'usestore',
276 276 default=True,
277 277 )
278 278 coreconfigitem('hostsecurity', 'ciphers',
279 279 default=None,
280 280 )
281 281 coreconfigitem('hostsecurity', 'disabletls10warning',
282 282 default=False,
283 283 )
284 284 coreconfigitem('http_proxy', 'always',
285 285 default=False,
286 286 )
287 287 coreconfigitem('http_proxy', 'host',
288 288 default=None,
289 289 )
290 290 coreconfigitem('http_proxy', 'no',
291 291 default=list,
292 292 )
293 293 coreconfigitem('http_proxy', 'passwd',
294 294 default=None,
295 295 )
296 296 coreconfigitem('http_proxy', 'user',
297 297 default=None,
298 298 )
299 299 coreconfigitem('merge', 'followcopies',
300 300 default=True,
301 301 )
302 302 coreconfigitem('pager', 'ignore',
303 303 default=list,
304 304 )
305 305 coreconfigitem('patch', 'eol',
306 306 default='strict',
307 307 )
308 308 coreconfigitem('patch', 'fuzz',
309 309 default=2,
310 310 )
311 311 coreconfigitem('paths', 'default',
312 312 default=None,
313 313 )
314 314 coreconfigitem('paths', 'default-push',
315 315 default=None,
316 316 )
317 317 coreconfigitem('phases', 'checksubrepos',
318 318 default='follow',
319 319 )
320 320 coreconfigitem('phases', 'publish',
321 321 default=True,
322 322 )
323 323 coreconfigitem('profiling', 'enabled',
324 324 default=False,
325 325 )
326 326 coreconfigitem('profiling', 'format',
327 327 default='text',
328 328 )
329 329 coreconfigitem('profiling', 'freq',
330 330 default=1000,
331 331 )
332 332 coreconfigitem('profiling', 'limit',
333 333 default=30,
334 334 )
335 335 coreconfigitem('profiling', 'nested',
336 336 default=0,
337 337 )
338 338 coreconfigitem('profiling', 'output',
339 339 default=None,
340 340 )
341 coreconfigitem('profiling', 'showmax',
342 default=0.999,
343 )
341 344 coreconfigitem('profiling', 'sort',
342 345 default='inlinetime',
343 346 )
344 347 coreconfigitem('profiling', 'statformat',
345 348 default='hotpath',
346 349 )
347 350 coreconfigitem('progress', 'assume-tty',
348 351 default=False,
349 352 )
350 353 coreconfigitem('progress', 'changedelay',
351 354 default=1,
352 355 )
353 356 coreconfigitem('progress', 'clear-complete',
354 357 default=True,
355 358 )
356 359 coreconfigitem('progress', 'debug',
357 360 default=False,
358 361 )
359 362 coreconfigitem('progress', 'delay',
360 363 default=3,
361 364 )
362 365 coreconfigitem('progress', 'disable',
363 366 default=False,
364 367 )
365 368 coreconfigitem('progress', 'estimateinterval',
366 369 default=60.0,
367 370 )
368 371 coreconfigitem('progress', 'refresh',
369 372 default=0.1,
370 373 )
371 374 coreconfigitem('progress', 'width',
372 375 default=dynamicdefault,
373 376 )
374 377 coreconfigitem('push', 'pushvars.server',
375 378 default=False,
376 379 )
377 380 coreconfigitem('server', 'bundle1',
378 381 default=True,
379 382 )
380 383 coreconfigitem('server', 'bundle1gd',
381 384 default=None,
382 385 )
383 386 coreconfigitem('server', 'compressionengines',
384 387 default=list,
385 388 )
386 389 coreconfigitem('server', 'concurrent-push-mode',
387 390 default='strict',
388 391 )
389 392 coreconfigitem('server', 'disablefullbundle',
390 393 default=False,
391 394 )
392 395 coreconfigitem('server', 'maxhttpheaderlen',
393 396 default=1024,
394 397 )
395 398 coreconfigitem('server', 'preferuncompressed',
396 399 default=False,
397 400 )
398 401 coreconfigitem('server', 'uncompressed',
399 402 default=True,
400 403 )
401 404 coreconfigitem('server', 'uncompressedallowsecret',
402 405 default=False,
403 406 )
404 407 coreconfigitem('server', 'validate',
405 408 default=False,
406 409 )
407 410 coreconfigitem('server', 'zliblevel',
408 411 default=-1,
409 412 )
410 413 coreconfigitem('smtp', 'host',
411 414 default=None,
412 415 )
413 416 coreconfigitem('smtp', 'local_hostname',
414 417 default=None,
415 418 )
416 419 coreconfigitem('smtp', 'password',
417 420 default=None,
418 421 )
419 422 coreconfigitem('smtp', 'tls',
420 423 default='none',
421 424 )
422 425 coreconfigitem('smtp', 'username',
423 426 default=None,
424 427 )
425 428 coreconfigitem('sparse', 'missingwarning',
426 429 default=True,
427 430 )
428 431 coreconfigitem('trusted', 'groups',
429 432 default=list,
430 433 )
431 434 coreconfigitem('trusted', 'users',
432 435 default=list,
433 436 )
434 437 coreconfigitem('ui', '_usedassubrepo',
435 438 default=False,
436 439 )
437 440 coreconfigitem('ui', 'allowemptycommit',
438 441 default=False,
439 442 )
440 443 coreconfigitem('ui', 'archivemeta',
441 444 default=True,
442 445 )
443 446 coreconfigitem('ui', 'askusername',
444 447 default=False,
445 448 )
446 449 coreconfigitem('ui', 'clonebundlefallback',
447 450 default=False,
448 451 )
449 452 coreconfigitem('ui', 'clonebundleprefers',
450 453 default=list,
451 454 )
452 455 coreconfigitem('ui', 'clonebundles',
453 456 default=True,
454 457 )
455 458 coreconfigitem('ui', 'color',
456 459 default='auto',
457 460 )
458 461 coreconfigitem('ui', 'commitsubrepos',
459 462 default=False,
460 463 )
461 464 coreconfigitem('ui', 'debug',
462 465 default=False,
463 466 )
464 467 coreconfigitem('ui', 'debugger',
465 468 default=None,
466 469 )
467 470 coreconfigitem('ui', 'fallbackencoding',
468 471 default=None,
469 472 )
470 473 coreconfigitem('ui', 'forcecwd',
471 474 default=None,
472 475 )
473 476 coreconfigitem('ui', 'forcemerge',
474 477 default=None,
475 478 )
476 479 coreconfigitem('ui', 'formatdebug',
477 480 default=False,
478 481 )
479 482 coreconfigitem('ui', 'formatjson',
480 483 default=False,
481 484 )
482 485 coreconfigitem('ui', 'formatted',
483 486 default=None,
484 487 )
485 488 coreconfigitem('ui', 'graphnodetemplate',
486 489 default=None,
487 490 )
488 491 coreconfigitem('ui', 'http2debuglevel',
489 492 default=None,
490 493 )
491 494 coreconfigitem('ui', 'interactive',
492 495 default=None,
493 496 )
494 497 coreconfigitem('ui', 'interface',
495 498 default=None,
496 499 )
497 500 coreconfigitem('ui', 'logblockedtimes',
498 501 default=False,
499 502 )
500 503 coreconfigitem('ui', 'logtemplate',
501 504 default=None,
502 505 )
503 506 coreconfigitem('ui', 'merge',
504 507 default=None,
505 508 )
506 509 coreconfigitem('ui', 'mergemarkers',
507 510 default='basic',
508 511 )
509 512 coreconfigitem('ui', 'mergemarkertemplate',
510 513 default=('{node|short} '
511 514 '{ifeq(tags, "tip", "", '
512 515 'ifeq(tags, "", "", "{tags} "))}'
513 516 '{if(bookmarks, "{bookmarks} ")}'
514 517 '{ifeq(branch, "default", "", "{branch} ")}'
515 518 '- {author|user}: {desc|firstline}')
516 519 )
517 520 coreconfigitem('ui', 'nontty',
518 521 default=False,
519 522 )
520 523 coreconfigitem('ui', 'origbackuppath',
521 524 default=None,
522 525 )
523 526 coreconfigitem('ui', 'paginate',
524 527 default=True,
525 528 )
526 529 coreconfigitem('ui', 'patch',
527 530 default=None,
528 531 )
529 532 coreconfigitem('ui', 'portablefilenames',
530 533 default='warn',
531 534 )
532 535 coreconfigitem('ui', 'promptecho',
533 536 default=False,
534 537 )
535 538 coreconfigitem('ui', 'quiet',
536 539 default=False,
537 540 )
538 541 coreconfigitem('ui', 'quietbookmarkmove',
539 542 default=False,
540 543 )
541 544 coreconfigitem('ui', 'remotecmd',
542 545 default='hg',
543 546 )
544 547 coreconfigitem('ui', 'report_untrusted',
545 548 default=True,
546 549 )
547 550 coreconfigitem('ui', 'rollback',
548 551 default=True,
549 552 )
550 553 coreconfigitem('ui', 'slash',
551 554 default=False,
552 555 )
553 556 coreconfigitem('ui', 'ssh',
554 557 default='ssh',
555 558 )
556 559 coreconfigitem('ui', 'statuscopies',
557 560 default=False,
558 561 )
559 562 coreconfigitem('ui', 'strict',
560 563 default=False,
561 564 )
562 565 coreconfigitem('ui', 'style',
563 566 default='',
564 567 )
565 568 coreconfigitem('ui', 'supportcontact',
566 569 default=None,
567 570 )
568 571 coreconfigitem('ui', 'textwidth',
569 572 default=78,
570 573 )
571 574 coreconfigitem('ui', 'timeout',
572 575 default='600',
573 576 )
574 577 coreconfigitem('ui', 'traceback',
575 578 default=False,
576 579 )
577 580 coreconfigitem('ui', 'tweakdefaults',
578 581 default=False,
579 582 )
580 583 coreconfigitem('ui', 'usehttp2',
581 584 default=False,
582 585 )
583 586 coreconfigitem('ui', 'username',
584 587 alias=[('ui', 'user')]
585 588 )
586 589 coreconfigitem('ui', 'verbose',
587 590 default=False,
588 591 )
589 592 coreconfigitem('verify', 'skipflags',
590 593 default=None,
591 594 )
592 595 coreconfigitem('web', 'accesslog',
593 596 default='-',
594 597 )
595 598 coreconfigitem('web', 'address',
596 599 default='',
597 600 )
598 601 coreconfigitem('web', 'allow_archive',
599 602 default=list,
600 603 )
601 604 coreconfigitem('web', 'allow_read',
602 605 default=list,
603 606 )
604 607 coreconfigitem('web', 'baseurl',
605 608 default=None,
606 609 )
607 610 coreconfigitem('web', 'cacerts',
608 611 default=None,
609 612 )
610 613 coreconfigitem('web', 'certificate',
611 614 default=None,
612 615 )
613 616 coreconfigitem('web', 'collapse',
614 617 default=False,
615 618 )
616 619 coreconfigitem('web', 'csp',
617 620 default=None,
618 621 )
619 622 coreconfigitem('web', 'deny_read',
620 623 default=list,
621 624 )
622 625 coreconfigitem('web', 'descend',
623 626 default=True,
624 627 )
625 628 coreconfigitem('web', 'description',
626 629 default="",
627 630 )
628 631 coreconfigitem('web', 'encoding',
629 632 default=lambda: encoding.encoding,
630 633 )
631 634 coreconfigitem('web', 'errorlog',
632 635 default='-',
633 636 )
634 637 coreconfigitem('web', 'ipv6',
635 638 default=False,
636 639 )
637 640 coreconfigitem('web', 'port',
638 641 default=8000,
639 642 )
640 643 coreconfigitem('web', 'prefix',
641 644 default='',
642 645 )
643 646 coreconfigitem('web', 'refreshinterval',
644 647 default=20,
645 648 )
646 649 coreconfigitem('web', 'stripes',
647 650 default=1,
648 651 )
649 652 coreconfigitem('web', 'style',
650 653 default='paper',
651 654 )
652 655 coreconfigitem('web', 'templates',
653 656 default=None,
654 657 )
655 658 coreconfigitem('worker', 'backgroundclose',
656 659 default=dynamicdefault,
657 660 )
658 661 # Windows defaults to a limit of 512 open files. A buffer of 128
659 662 # should give us enough headway.
660 663 coreconfigitem('worker', 'backgroundclosemaxqueue',
661 664 default=384,
662 665 )
663 666 coreconfigitem('worker', 'backgroundcloseminfilecount',
664 667 default=2048,
665 668 )
666 669 coreconfigitem('worker', 'backgroundclosethreadcount',
667 670 default=4,
668 671 )
669 672 coreconfigitem('worker', 'numcpus',
670 673 default=None,
671 674 )
@@ -1,238 +1,238
1 1 # profiling.py - profiling functions
2 2 #
3 3 # Copyright 2016 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import, print_function
9 9
10 10 import contextlib
11 11
12 12 from .i18n import _
13 13 from . import (
14 14 encoding,
15 15 error,
16 16 extensions,
17 17 util,
18 18 )
19 19
20 20 def _loadprofiler(ui, profiler):
21 21 """load profiler extension. return profile method, or None on failure"""
22 22 extname = profiler
23 23 extensions.loadall(ui, whitelist=[extname])
24 24 try:
25 25 mod = extensions.find(extname)
26 26 except KeyError:
27 27 return None
28 28 else:
29 29 return getattr(mod, 'profile', None)
30 30
31 31 @contextlib.contextmanager
32 32 def lsprofile(ui, fp):
33 33 format = ui.config('profiling', 'format')
34 34 field = ui.config('profiling', 'sort')
35 35 limit = ui.configint('profiling', 'limit')
36 36 climit = ui.configint('profiling', 'nested')
37 37
38 38 if format not in ['text', 'kcachegrind']:
39 39 ui.warn(_("unrecognized profiling format '%s'"
40 40 " - Ignored\n") % format)
41 41 format = 'text'
42 42
43 43 try:
44 44 from . import lsprof
45 45 except ImportError:
46 46 raise error.Abort(_(
47 47 'lsprof not available - install from '
48 48 'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
49 49 p = lsprof.Profiler()
50 50 p.enable(subcalls=True)
51 51 try:
52 52 yield
53 53 finally:
54 54 p.disable()
55 55
56 56 if format == 'kcachegrind':
57 57 from . import lsprofcalltree
58 58 calltree = lsprofcalltree.KCacheGrind(p)
59 59 calltree.output(fp)
60 60 else:
61 61 # format == 'text'
62 62 stats = lsprof.Stats(p.getstats())
63 63 stats.sort(field)
64 64 stats.pprint(limit=limit, file=fp, climit=climit)
65 65
66 66 @contextlib.contextmanager
67 67 def flameprofile(ui, fp):
68 68 try:
69 69 from flamegraph import flamegraph
70 70 except ImportError:
71 71 raise error.Abort(_(
72 72 'flamegraph not available - install from '
73 73 'https://github.com/evanhempel/python-flamegraph'))
74 74 # developer config: profiling.freq
75 75 freq = ui.configint('profiling', 'freq')
76 76 filter_ = None
77 77 collapse_recursion = True
78 78 thread = flamegraph.ProfileThread(fp, 1.0 / freq,
79 79 filter_, collapse_recursion)
80 80 start_time = util.timer()
81 81 try:
82 82 thread.start()
83 83 yield
84 84 finally:
85 85 thread.stop()
86 86 thread.join()
87 87 print('Collected %d stack frames (%d unique) in %2.2f seconds.' % (
88 88 util.timer() - start_time, thread.num_frames(),
89 89 thread.num_frames(unique=True)))
90 90
91 91 @contextlib.contextmanager
92 92 def statprofile(ui, fp):
93 93 from . import statprof
94 94
95 95 freq = ui.configint('profiling', 'freq')
96 96 if freq > 0:
97 97 # Cannot reset when profiler is already active. So silently no-op.
98 98 if statprof.state.profile_level == 0:
99 99 statprof.reset(freq)
100 100 else:
101 101 ui.warn(_("invalid sampling frequency '%s' - ignoring\n") % freq)
102 102
103 103 statprof.start(mechanism='thread')
104 104
105 105 try:
106 106 yield
107 107 finally:
108 108 data = statprof.stop()
109 109
110 110 profformat = ui.config('profiling', 'statformat')
111 111
112 112 formats = {
113 113 'byline': statprof.DisplayFormats.ByLine,
114 114 'bymethod': statprof.DisplayFormats.ByMethod,
115 115 'hotpath': statprof.DisplayFormats.Hotpath,
116 116 'json': statprof.DisplayFormats.Json,
117 117 'chrome': statprof.DisplayFormats.Chrome,
118 118 }
119 119
120 120 if profformat in formats:
121 121 displayformat = formats[profformat]
122 122 else:
123 123 ui.warn(_('unknown profiler output format: %s\n') % profformat)
124 124 displayformat = statprof.DisplayFormats.Hotpath
125 125
126 126 kwargs = {}
127 127
128 128 def fraction(s):
129 129 if isinstance(s, (float, int)):
130 130 return float(s)
131 131 if s.endswith('%'):
132 132 v = float(s[:-1]) / 100
133 133 else:
134 134 v = float(s)
135 135 if 0 <= v <= 1:
136 136 return v
137 137 raise ValueError(s)
138 138
139 139 if profformat == 'chrome':
140 140 showmin = ui.configwith(fraction, 'profiling', 'showmin', 0.005)
141 showmax = ui.configwith(fraction, 'profiling', 'showmax', 0.999)
141 showmax = ui.configwith(fraction, 'profiling', 'showmax')
142 142 kwargs.update(minthreshold=showmin, maxthreshold=showmax)
143 143 elif profformat == 'hotpath':
144 144 # inconsistent config: profiling.showmin
145 145 limit = ui.configwith(fraction, 'profiling', 'showmin', 0.05)
146 146 kwargs['limit'] = limit
147 147
148 148 statprof.display(fp, data=data, format=displayformat, **kwargs)
149 149
150 150 class profile(object):
151 151 """Start profiling.
152 152
153 153 Profiling is active when the context manager is active. When the context
154 154 manager exits, profiling results will be written to the configured output.
155 155 """
156 156 def __init__(self, ui, enabled=True):
157 157 self._ui = ui
158 158 self._output = None
159 159 self._fp = None
160 160 self._fpdoclose = True
161 161 self._profiler = None
162 162 self._enabled = enabled
163 163 self._entered = False
164 164 self._started = False
165 165
166 166 def __enter__(self):
167 167 self._entered = True
168 168 if self._enabled:
169 169 self.start()
170 170 return self
171 171
172 172 def start(self):
173 173 """Start profiling.
174 174
175 175 The profiling will stop at the context exit.
176 176
177 177 If the profiler was already started, this has no effect."""
178 178 if not self._entered:
179 179 raise error.ProgrammingError()
180 180 if self._started:
181 181 return
182 182 self._started = True
183 183 profiler = encoding.environ.get('HGPROF')
184 184 proffn = None
185 185 if profiler is None:
186 186 profiler = self._ui.config('profiling', 'type', default='stat')
187 187 if profiler not in ('ls', 'stat', 'flame'):
188 188 # try load profiler from extension with the same name
189 189 proffn = _loadprofiler(self._ui, profiler)
190 190 if proffn is None:
191 191 self._ui.warn(_("unrecognized profiler '%s' - ignored\n")
192 192 % profiler)
193 193 profiler = 'stat'
194 194
195 195 self._output = self._ui.config('profiling', 'output')
196 196
197 197 try:
198 198 if self._output == 'blackbox':
199 199 self._fp = util.stringio()
200 200 elif self._output:
201 201 path = self._ui.expandpath(self._output)
202 202 self._fp = open(path, 'wb')
203 203 else:
204 204 self._fpdoclose = False
205 205 self._fp = self._ui.ferr
206 206
207 207 if proffn is not None:
208 208 pass
209 209 elif profiler == 'ls':
210 210 proffn = lsprofile
211 211 elif profiler == 'flame':
212 212 proffn = flameprofile
213 213 else:
214 214 proffn = statprofile
215 215
216 216 self._profiler = proffn(self._ui, self._fp)
217 217 self._profiler.__enter__()
218 218 except: # re-raises
219 219 self._closefp()
220 220 raise
221 221
222 222 def __exit__(self, exception_type, exception_value, traceback):
223 223 propagate = None
224 224 if self._profiler is not None:
225 225 propagate = self._profiler.__exit__(exception_type, exception_value,
226 226 traceback)
227 227 if self._output == 'blackbox':
228 228 val = 'Profile:\n%s' % self._fp.getvalue()
229 229 # ui.log treats the input as a format string,
230 230 # so we need to escape any % signs.
231 231 val = val.replace('%', '%%')
232 232 self._ui.log('profile', val)
233 233 self._closefp()
234 234 return propagate
235 235
236 236 def _closefp(self):
237 237 if self._fpdoclose and self._fp is not None:
238 238 self._fp.close()
General Comments 0
You need to be logged in to leave comments. Login now