mirror of
https://git.yoctoproject.org/poky
synced 2026-04-20 00:32:13 +02:00
bitbake: cooker/process/utils: Create profiling common function to remove code duplication
We have code duplication in the way we handle profiling of code sections. Create a common function in utils which covers this. The main loop and idle loop profile files were also reversed. Fix this and the naming, removing a couple of unused variables containing the profile log names in the process too. (Bitbake rev: b4f6bae97ac9607420fc49fd4c9e957d89c9a5f3) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
@@ -2027,21 +2027,7 @@ class Parser(multiprocessing.Process):
|
||||
self.exit = True
|
||||
|
||||
def run(self):
|
||||
|
||||
if not self.profile:
|
||||
self.realrun()
|
||||
return
|
||||
|
||||
try:
|
||||
import cProfile as profile
|
||||
except:
|
||||
import profile
|
||||
prof = profile.Profile()
|
||||
try:
|
||||
profile.Profile.runcall(prof, self.realrun)
|
||||
finally:
|
||||
logfile = "profile-parse-%s.log" % multiprocessing.current_process().name
|
||||
prof.dump_stats(logfile)
|
||||
bb.utils.profile_function(self.profile, self.realrun, "profile-parse-%s.log" % multiprocessing.current_process().name, process=False)
|
||||
|
||||
def realrun(self):
|
||||
# Signal handling here is hard. We must not terminate any process or thread holding the write
|
||||
|
||||
@@ -80,9 +80,6 @@ class idleFinish():
|
||||
self.msg = msg
|
||||
|
||||
class ProcessServer():
|
||||
profile_filename = "profile.log"
|
||||
profile_processed_filename = "profile.log.processed"
|
||||
|
||||
def __init__(self, lock, lockname, sock, sockname, server_timeout, xmlrpcinterface):
|
||||
self.command_channel = False
|
||||
self.command_channel_reply = False
|
||||
@@ -140,23 +137,7 @@ class ProcessServer():
|
||||
serverlog("Error writing to lock file: %s" % str(e))
|
||||
pass
|
||||
|
||||
if self.cooker.configuration.profile:
|
||||
try:
|
||||
import cProfile as profile
|
||||
except:
|
||||
import profile
|
||||
prof = profile.Profile()
|
||||
|
||||
ret = profile.Profile.runcall(prof, self.main)
|
||||
|
||||
prof.dump_stats("profile.log")
|
||||
bb.utils.process_profilelog("profile.log")
|
||||
serverlog("Raw profiling information saved to profile.log and processed statistics to profile.log.processed")
|
||||
|
||||
else:
|
||||
ret = self.main()
|
||||
|
||||
return ret
|
||||
return bb.utils.profile_function(self.cooker.configuration.profile, self.main, "profile-mainloop.log")
|
||||
|
||||
def _idle_check(self):
|
||||
return len(self._idlefuns) == 0 and self.cooker.command.currentAsyncCommand is None
|
||||
@@ -417,20 +398,7 @@ class ProcessServer():
|
||||
serverlog("".join(msg))
|
||||
|
||||
def idle_thread(self):
|
||||
if self.cooker.configuration.profile:
|
||||
try:
|
||||
import cProfile as profile
|
||||
except:
|
||||
import profile
|
||||
prof = profile.Profile()
|
||||
|
||||
ret = profile.Profile.runcall(prof, self.idle_thread_internal)
|
||||
|
||||
prof.dump_stats("profile-mainloop.log")
|
||||
bb.utils.process_profilelog("profile-mainloop.log")
|
||||
serverlog("Raw profiling information saved to profile-mainloop.log and processed statistics to profile-mainloop.log.processed")
|
||||
else:
|
||||
self.idle_thread_internal()
|
||||
bb.utils.profile_function(self.cooker.configuration.profile, self.idle_thread_internal, "profile-idleloop.log")
|
||||
|
||||
def idle_thread_internal(self):
|
||||
def remove_idle_func(function):
|
||||
|
||||
@@ -1418,6 +1418,34 @@ def cpu_count():
|
||||
def nonblockingfd(fd):
|
||||
fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||
|
||||
def profile_function(profile, function, output_fn, process=True):
|
||||
"""Common function to profile a code block and optionally process the
|
||||
output using or processing function.
|
||||
|
||||
Arguments:
|
||||
|
||||
- ``profile``: a boolean saying whether to enable profiling or not
|
||||
- ``function``: the function call to profile/run
|
||||
- ``outputfn``: where to write the profiling data
|
||||
- ``process``: whether to process the profiling data and write a report
|
||||
|
||||
Returns the wrapped function return value
|
||||
"""
|
||||
if profile:
|
||||
try:
|
||||
import cProfile as profile
|
||||
except:
|
||||
import profile
|
||||
prof = profile.Profile()
|
||||
ret = profile.Profile.runcall(prof, function)
|
||||
prof.dump_stats(output_fn)
|
||||
if process:
|
||||
process_profilelog(output_fn)
|
||||
serverlog("Raw profiling information saved to %s and processed statistics to %s.processed" % (output_fn, output_fn))
|
||||
return ret
|
||||
else:
|
||||
return function()
|
||||
|
||||
def process_profilelog(fn, pout = None):
|
||||
# Either call with a list of filenames and set pout or a filename and optionally pout.
|
||||
if not pout:
|
||||
|
||||
Reference in New Issue
Block a user