Browse Source

bitbake: main: Add an option to specify what to profile

Starting with python 3.12, profiling now stays enabled over threads yet
you can't extract the profile data in the threads themselves, which makes it
difficult to use for our use case.

Our main loop starts the idle loop which starts the parsing threads and this
means we can't profile in the main loop and the parsing threads or the idle
loop at the same time due to this.

Add options to the commandline so you can specify which piece of bitbake
you want to enable profiling for. This allows some profiling with python 3.12
onwards rather than crashing.

(Bitbake rev: 09f29a4968841ee5070f70277ba8c253bb14f017)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Richard Purdie 3 months ago
parent
commit
f209f127e6

+ 1 - 1
bitbake/bin/bitbake-server

@@ -30,7 +30,7 @@ logfile = sys.argv[4]
 lockname = sys.argv[5]
 sockname = sys.argv[6]
 timeout = float(sys.argv[7])
-profile = bool(int(sys.argv[8]))
+profile = sys.argv[8]
 xmlrpcinterface = (sys.argv[9], int(sys.argv[10]))
 if xmlrpcinterface[0] == "None":
     xmlrpcinterface = (None, xmlrpcinterface[1])

+ 1 - 1
bitbake/lib/bb/cooker.py

@@ -2027,7 +2027,7 @@ class Parser(multiprocessing.Process):
             self.exit = True
 
     def run(self):
-        bb.utils.profile_function(self.profile, self.realrun, "profile-parse-%s.log" % multiprocessing.current_process().name, process=False)
+        bb.utils.profile_function("parsing" in 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

+ 4 - 2
bitbake/lib/bb/main.py

@@ -208,8 +208,10 @@ def create_bitbake_parser():
                              "failed and anything depending on it cannot be built, as much as "
                              "possible will be built before stopping.")
 
-    exec_group.add_argument("-P", "--profile", action="store_true",
-                        help="Profile the command and save reports.")
+    exec_group.add_argument("-P", "--profile", action="append",
+                        default=[],
+                        help="Profile the command and save reports. Specify 'main', 'idle' or 'parsing' "
+                             "to indicate which bitbake code to profile.")
 
     exec_group.add_argument("-S", "--dump-signatures", action="append",
                         default=[], metavar="SIGNATURE_HANDLER",

+ 3 - 3
bitbake/lib/bb/server/process.py

@@ -137,7 +137,7 @@ class ProcessServer():
             serverlog("Error writing to lock file: %s" % str(e))
             pass
 
-        return bb.utils.profile_function(self.cooker.configuration.profile, self.main, "profile-mainloop.log")
+        return bb.utils.profile_function("main" in 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
@@ -398,7 +398,7 @@ class ProcessServer():
                 serverlog("".join(msg))
 
     def idle_thread(self):
-        bb.utils.profile_function(self.cooker.configuration.profile, self.idle_thread_internal, "profile-idleloop.log")
+        bb.utils.profile_function("idle" in self.cooker.configuration.profile, self.idle_thread_internal, "profile-idleloop.log")
 
     def idle_thread_internal(self):
         def remove_idle_func(function):
@@ -600,7 +600,7 @@ class BitBakeServer(object):
         os.set_inheritable(self.bitbake_lock.fileno(), True)
         os.set_inheritable(self.readypipein, True)
         serverscript = os.path.realpath(os.path.dirname(__file__) + "/../../../bin/bitbake-server")
-        os.execl(sys.executable, sys.executable, serverscript, "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.logfile, self.bitbake_lock.name, self.sockname,  str(self.server_timeout or 0), str(int(self.profile)), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1]))
+        os.execl(sys.executable, sys.executable, serverscript, "decafbad", str(self.bitbake_lock.fileno()), str(self.readypipein), self.logfile, self.bitbake_lock.name, self.sockname,  str(self.server_timeout or 0), str(list(self.profile)), str(self.xmlrpcinterface[0]), str(self.xmlrpcinterface[1]))
 
 def execServer(lockfd, readypipeinfd, lockname, sockname, server_timeout, xmlrpcinterface, profile):