[3/8] insane.bbclass: use multiprocessing for collecting 'objdump -p' output

Message ID 20220206215316.367469-3-alex@linutronix.de
State Accepted, archived
Commit fac984b99fdb46949879516cb87153860f402c75
Headers show
Series [1/8] mesa: fold mesa-gl variant into the main recipe using mcextend class | expand

Commit Message

Alexander Kanavin Feb. 6, 2022, 9:53 p.m. UTC
This was prompted by ltp's unreasonably long package_qa times; it has
a massive amount of executables and insane runs objdump for all of
them, serially.

This reduces the time from 4 minutes to 1m20s on my machine.

Signed-off-by: Alexander Kanavin <alex@linutronix.de>
---
 meta/classes/insane.bbclass | 22 ++++++++++++++++++++--
 meta/lib/oe/qa.py           |  6 ++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

Patch

diff --git a/meta/classes/insane.bbclass b/meta/classes/insane.bbclass
index 11532ecd08..a13a947bcf 100644
--- a/meta/classes/insane.bbclass
+++ b/meta/classes/insane.bbclass
@@ -684,6 +684,10 @@  def package_qa_recipe(warnfuncs, errorfuncs, pn, d):
 
     return len(errors) == 0
 
+def prepopulate_objdump_p(elf, d):
+    output = elf.run_objdump("-p", d)
+    return (elf.name, output)
+
 # Walk over all files in a directory and call func
 def package_qa_walk(warnfuncs, errorfuncs, package, d):
     #if this will throw an exception, then fix the dict above
@@ -692,18 +696,32 @@  def package_qa_walk(warnfuncs, errorfuncs, package, d):
 
     warnings = {}
     errors = {}
+    elves = {}
     for path in pkgfiles[package]:
             elf = None
             if os.path.isfile(path):
                 elf = oe.qa.ELFFile(path)
                 try:
                     elf.open()
+                    elf.close()
                 except oe.qa.NotELFFileError:
                     elf = None
+            if elf:
+                elves[path] = elf
+
+    results = oe.utils.multiprocess_launch(prepopulate_objdump_p, elves.values(), d, extraargs=(d,))
+    for item in results:
+        elves[item[0]].set_objdump("-p", item[1])
+
+    for path in pkgfiles[package]:
+            if path in elves:
+                elves[path].open()
             for func in warnfuncs:
-                func(path, package, d, elf, warnings)
+                func(path, package, d, elves.get(path), warnings)
             for func in errorfuncs:
-                func(path, package, d, elf, errors)
+                func(path, package, d, elves.get(path), errors)
+            if path in elves:
+                elves[path].close()
 
     for w in warnings:
         oe.qa.handle_error(w, warnings[w], d)
diff --git a/meta/lib/oe/qa.py b/meta/lib/oe/qa.py
index efab7e8564..89acd3ead0 100644
--- a/meta/lib/oe/qa.py
+++ b/meta/lib/oe/qa.py
@@ -48,6 +48,9 @@  class ELFFile:
         return self
 
     def __exit__(self, exc_type, exc_value, traceback):
+        self.close()
+
+    def close(self):
         if self.data:
             self.data.close()
 
@@ -128,6 +131,9 @@  class ELFFile:
         """
         return self.getShort(ELFFile.E_MACHINE)
 
+    def set_objdump(self, cmd, output):
+        self.objdump_output[cmd] = output
+
     def run_objdump(self, cmd, d):
         import bb.process
         import sys