diff options
author | Simon Glass <sjg@chromium.org> | 2021-07-06 19:36:37 +0300 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2021-07-21 19:27:35 +0300 |
commit | c69d19c8f829d3320db5224f9f28d13cfb16049e (patch) | |
tree | c13527b8a6aecf176f48ee6c0f8f657bb4dd303a /tools/binman/etype | |
parent | 650ead1a4aac3010a029526d639682096c1d0469 (diff) | |
download | u-boot-c69d19c8f829d3320db5224f9f28d13cfb16049e.tar.xz |
binman: Support multithreading for building images
Some images may take a while to build, e.g. if they are large and use slow
compression. Support compiling sections in parallel to speed things up.
Signed-off-by: Simon Glass <sjg@chromium.org>
(fixed to use a separate test file to fix flakiness)
Diffstat (limited to 'tools/binman/etype')
-rw-r--r-- | tools/binman/etype/section.py | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index c3bac026c1..92d3f3add4 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -9,10 +9,12 @@ images to be created. """ from collections import OrderedDict +import concurrent.futures import re import sys from binman.entry import Entry +from binman import state from dtoc import fdt_util from patman import tools from patman import tout @@ -525,15 +527,43 @@ class Entry_section(Entry): def GetEntryContents(self): """Call ObtainContents() for each entry in the section """ + def _CheckDone(entry): + if not entry.ObtainContents(): + next_todo.append(entry) + return entry + todo = self._entries.values() for passnum in range(3): + threads = state.GetThreads() next_todo = [] - for entry in todo: - if not entry.ObtainContents(): - next_todo.append(entry) + + if threads == 0: + for entry in todo: + _CheckDone(entry) + else: + with concurrent.futures.ThreadPoolExecutor( + max_workers=threads) as executor: + future_to_data = { + entry: executor.submit(_CheckDone, entry) + for entry in todo} + timeout = 60 + if self.GetImage().test_section_timeout: + timeout = 0 + done, not_done = concurrent.futures.wait( + future_to_data.values(), timeout=timeout) + # Make sure we check the result, so any exceptions are + # generated. Check the results in entry order, since tests + # may expect earlier entries to fail first. + for entry in todo: + job = future_to_data[entry] + job.result() + if not_done: + self.Raise('Timed out obtaining contents') + todo = next_todo if not todo: break + if todo: self.Raise('Internal error: Could not complete processing of contents: remaining %s' % todo) |