@@ -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.profle_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
@@ -140,23 +140,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.profle_function(self.cooker.configuration.profile, self.main, "profile.log")
def _idle_check(self):
return len(self._idlefuns) == 0 and self.cooker.command.currentAsyncCommand is None
@@ -417,20 +401,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.profle_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 profle_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:
We have code duplication in the way we handle profiling of code sections. Create a common function in utils which covers this. Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> --- lib/bb/cooker.py | 16 +--------------- lib/bb/server/process.py | 33 ++------------------------------- lib/bb/utils.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 46 deletions(-)