Andrew Geissler | 9347dd4 | 2023-03-03 12:38:41 -0600 | [diff] [blame^] | 1 | Upstream-Status: Submitted [https://gitlab.arm.com/arm-reference-solutions/corstone1000/external_system/rtx/-/issues/1] |
| 2 | Signed-off-by: Ross Burton <ross.burton@arm.com> |
| 3 | |
| 4 | From 34e1c04534607f5605255f39fb46e26261fc9c4e Mon Sep 17 00:00:00 2001 |
| 5 | From: Ross Burton <ross.burton@arm.com> |
| 6 | Date: Tue, 8 Sep 2020 11:49:08 +0100 |
| 7 | Subject: [PATCH] tools/gen_module_code: atomically rewrite the generated files |
| 8 | |
| 9 | The gen_module rule in rules.mk is marked as .PHONY, so make will |
| 10 | execute it whenever it is mentioned. This results in gen_module_code |
| 11 | being executed 64 times for a Juno build. |
| 12 | |
| 13 | However in heavily parallel builds there's a good chance that |
| 14 | gen_module_code is writing a file whilst the compiler is reading it |
| 15 | because make also doesn't know what files are generated by |
| 16 | gen_module_code. |
| 17 | |
| 18 | The correct fix is to adjust the Makefiles so that the dependencies are |
| 19 | correct but this isn't trivial, so band-aid the problem by atomically |
| 20 | writing the generated files. |
| 21 | |
| 22 | Change-Id: I82d44f9ea6537a91002e1f80de8861d208571630 |
| 23 | Signed-off-by: Ross Burton <ross.burton@arm.com> |
| 24 | --- |
| 25 | tools/gen_module_code.py | 19 ++++++++++++++----- |
| 26 | 1 file changed, 14 insertions(+), 5 deletions(-) |
| 27 | |
| 28 | diff --git a/tools/gen_module_code.py b/tools/gen_module_code.py |
| 29 | index 7b3953845..ee099b713 100755 |
| 30 | --- a/tools/gen_module_code.py |
| 31 | +++ b/tools/gen_module_code.py |
| 32 | @@ -17,6 +17,7 @@ |
| 33 | import argparse |
| 34 | import os |
| 35 | import sys |
| 36 | +import tempfile |
| 37 | |
| 38 | DEFAULT_PATH = 'build/' |
| 39 | |
| 40 | @@ -53,13 +54,21 @@ |
| 41 | |
| 42 | def generate_file(path, filename, content): |
| 43 | full_filename = os.path.join(path, filename) |
| 44 | - with open(full_filename, 'a+') as f: |
| 45 | - f.seek(0) |
| 46 | - if f.read() != content: |
| 47 | + |
| 48 | + try: |
| 49 | + with open(full_filename) as f: |
| 50 | + rewrite = f.read() != content |
| 51 | + except FileNotFoundError: |
| 52 | + rewrite = True |
| 53 | + |
| 54 | + if rewrite: |
| 55 | + with tempfile.NamedTemporaryFile(prefix="gen-module-code", |
| 56 | + dir=path, |
| 57 | + delete=False, |
| 58 | + mode="wt") as f: |
| 59 | print("[GEN] {}...".format(full_filename)) |
| 60 | - f.seek(0) |
| 61 | - f.truncate() |
| 62 | f.write(content) |
| 63 | + os.replace(f.name, full_filename) |
| 64 | |
| 65 | |
| 66 | def generate_header(path, modules): |