summaryrefslogtreecommitdiffstats
path: root/bitbake/lib
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2025-07-16 15:56:38 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2025-07-17 10:45:57 +0100
commite16dd314450cb2b85e4984c17fa60403b662ef8c (patch)
tree0e3276eae79d9f130183188df5fa64698e66b466 /bitbake/lib
parent6933d4b57ef9b2b6bbc8c97069a4f54e46eb3e4d (diff)
downloadpoky-e16dd314450cb2b85e4984c17fa60403b662ef8c.tar.gz
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>
Diffstat (limited to 'bitbake/lib')
-rw-r--r--bitbake/lib/bb/cooker.py16
-rw-r--r--bitbake/lib/bb/server/process.py36
-rw-r--r--bitbake/lib/bb/utils.py28
3 files changed, 31 insertions, 49 deletions
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index dc131939ed..c60fcd2719 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -2027,21 +2027,7 @@ class Parser(multiprocessing.Process):
2027 self.exit = True 2027 self.exit = True
2028 2028
2029 def run(self): 2029 def run(self):
2030 2030 bb.utils.profile_function(self.profile, self.realrun, "profile-parse-%s.log" % multiprocessing.current_process().name, process=False)
2031 if not self.profile:
2032 self.realrun()
2033 return
2034
2035 try:
2036 import cProfile as profile
2037 except:
2038 import profile
2039 prof = profile.Profile()
2040 try:
2041 profile.Profile.runcall(prof, self.realrun)
2042 finally:
2043 logfile = "profile-parse-%s.log" % multiprocessing.current_process().name
2044 prof.dump_stats(logfile)
2045 2031
2046 def realrun(self): 2032 def realrun(self):
2047 # Signal handling here is hard. We must not terminate any process or thread holding the write 2033 # Signal handling here is hard. We must not terminate any process or thread holding the write
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py
index 4b35be62cd..2c5057bff1 100644
--- a/bitbake/lib/bb/server/process.py
+++ b/bitbake/lib/bb/server/process.py
@@ -80,9 +80,6 @@ class idleFinish():
80 self.msg = msg 80 self.msg = msg
81 81
82class ProcessServer(): 82class ProcessServer():
83 profile_filename = "profile.log"
84 profile_processed_filename = "profile.log.processed"
85
86 def __init__(self, lock, lockname, sock, sockname, server_timeout, xmlrpcinterface): 83 def __init__(self, lock, lockname, sock, sockname, server_timeout, xmlrpcinterface):
87 self.command_channel = False 84 self.command_channel = False
88 self.command_channel_reply = False 85 self.command_channel_reply = False
@@ -140,23 +137,7 @@ class ProcessServer():
140 serverlog("Error writing to lock file: %s" % str(e)) 137 serverlog("Error writing to lock file: %s" % str(e))
141 pass 138 pass
142 139
143 if self.cooker.configuration.profile: 140 return bb.utils.profile_function(self.cooker.configuration.profile, self.main, "profile-mainloop.log")
144 try:
145 import cProfile as profile
146 except:
147 import profile
148 prof = profile.Profile()
149
150 ret = profile.Profile.runcall(prof, self.main)
151
152 prof.dump_stats("profile.log")
153 bb.utils.process_profilelog("profile.log")
154 serverlog("Raw profiling information saved to profile.log and processed statistics to profile.log.processed")
155
156 else:
157 ret = self.main()
158
159 return ret
160 141
161 def _idle_check(self): 142 def _idle_check(self):
162 return len(self._idlefuns) == 0 and self.cooker.command.currentAsyncCommand is None 143 return len(self._idlefuns) == 0 and self.cooker.command.currentAsyncCommand is None
@@ -417,20 +398,7 @@ class ProcessServer():
417 serverlog("".join(msg)) 398 serverlog("".join(msg))
418 399
419 def idle_thread(self): 400 def idle_thread(self):
420 if self.cooker.configuration.profile: 401 bb.utils.profile_function(self.cooker.configuration.profile, self.idle_thread_internal, "profile-idleloop.log")
421 try:
422 import cProfile as profile
423 except:
424 import profile
425 prof = profile.Profile()
426
427 ret = profile.Profile.runcall(prof, self.idle_thread_internal)
428
429 prof.dump_stats("profile-mainloop.log")
430 bb.utils.process_profilelog("profile-mainloop.log")
431 serverlog("Raw profiling information saved to profile-mainloop.log and processed statistics to profile-mainloop.log.processed")
432 else:
433 self.idle_thread_internal()
434 402
435 def idle_thread_internal(self): 403 def idle_thread_internal(self):
436 def remove_idle_func(function): 404 def remove_idle_func(function):
diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py
index 1cc74ed546..f688f7dd68 100644
--- a/bitbake/lib/bb/utils.py
+++ b/bitbake/lib/bb/utils.py
@@ -1418,6 +1418,34 @@ def cpu_count():
1418def nonblockingfd(fd): 1418def nonblockingfd(fd):
1419 fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK) 1419 fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
1420 1420
1421def profile_function(profile, function, output_fn, process=True):
1422 """Common function to profile a code block and optionally process the
1423 output using or processing function.
1424
1425 Arguments:
1426
1427 - ``profile``: a boolean saying whether to enable profiling or not
1428 - ``function``: the function call to profile/run
1429 - ``outputfn``: where to write the profiling data
1430 - ``process``: whether to process the profiling data and write a report
1431
1432 Returns the wrapped function return value
1433 """
1434 if profile:
1435 try:
1436 import cProfile as profile
1437 except:
1438 import profile
1439 prof = profile.Profile()
1440 ret = profile.Profile.runcall(prof, function)
1441 prof.dump_stats(output_fn)
1442 if process:
1443 process_profilelog(output_fn)
1444 serverlog("Raw profiling information saved to %s and processed statistics to %s.processed" % (output_fn, output_fn))
1445 return ret
1446 else:
1447 return function()
1448
1421def process_profilelog(fn, pout = None): 1449def process_profilelog(fn, pout = None):
1422 # Either call with a list of filenames and set pout or a filename and optionally pout. 1450 # Either call with a list of filenames and set pout or a filename and optionally pout.
1423 if not pout: 1451 if not pout: