Andrew Geissler | fc7e797 | 2023-09-11 08:24:07 -0400 | [diff] [blame^] | 1 | From fa5ed6204f9188134a87ac9dd569e1496759a7f6 Mon Sep 17 00:00:00 2001 |
Andrew Geissler | 9347dd4 | 2023-03-03 12:38:41 -0600 | [diff] [blame] | 2 | From: Ross Burton <ross.burton@arm.com> |
| 3 | Date: Tue, 8 Sep 2020 11:49:08 +0100 |
| 4 | Subject: [PATCH] tools/gen_module_code: atomically rewrite the generated files |
| 5 | |
Andrew Geissler | fc7e797 | 2023-09-11 08:24:07 -0400 | [diff] [blame^] | 6 | Upstream-Status: Submitted [https://gitlab.arm.com/arm-reference-solutions/corstone1000/external_system/rtx/-/issues/1] |
| 7 | Signed-off-by: Ross Burton <ross.burton@arm.com> |
| 8 | |
Andrew Geissler | 9347dd4 | 2023-03-03 12:38:41 -0600 | [diff] [blame] | 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> |
Andrew Geissler | fc7e797 | 2023-09-11 08:24:07 -0400 | [diff] [blame^] | 24 | |
Andrew Geissler | 9347dd4 | 2023-03-03 12:38:41 -0600 | [diff] [blame] | 25 | --- |
| 26 | tools/gen_module_code.py | 19 ++++++++++++++----- |
| 27 | 1 file changed, 14 insertions(+), 5 deletions(-) |
| 28 | |
| 29 | diff --git a/tools/gen_module_code.py b/tools/gen_module_code.py |
Andrew Geissler | fc7e797 | 2023-09-11 08:24:07 -0400 | [diff] [blame^] | 30 | index 6bf50e0..92623a7 100755 |
Andrew Geissler | 9347dd4 | 2023-03-03 12:38:41 -0600 | [diff] [blame] | 31 | --- a/tools/gen_module_code.py |
| 32 | +++ b/tools/gen_module_code.py |
| 33 | @@ -17,6 +17,7 @@ |
| 34 | import argparse |
| 35 | import os |
| 36 | import sys |
| 37 | +import tempfile |
| 38 | |
| 39 | DEFAULT_PATH = 'build/' |
| 40 | |
Andrew Geissler | fc7e797 | 2023-09-11 08:24:07 -0400 | [diff] [blame^] | 41 | @@ -55,13 +56,21 @@ TEMPLATE_C = "/* This file was auto generated using {} */\n" \ |
Andrew Geissler | 9347dd4 | 2023-03-03 12:38:41 -0600 | [diff] [blame] | 42 | |
| 43 | def generate_file(path, filename, content): |
| 44 | full_filename = os.path.join(path, filename) |
| 45 | - with open(full_filename, 'a+') as f: |
| 46 | - f.seek(0) |
| 47 | - if f.read() != content: |
| 48 | + |
| 49 | + try: |
| 50 | + with open(full_filename) as f: |
| 51 | + rewrite = f.read() != content |
| 52 | + except FileNotFoundError: |
| 53 | + rewrite = True |
| 54 | + |
| 55 | + if rewrite: |
| 56 | + with tempfile.NamedTemporaryFile(prefix="gen-module-code", |
| 57 | + dir=path, |
| 58 | + delete=False, |
| 59 | + mode="wt") as f: |
| 60 | print("[GEN] {}...".format(full_filename)) |
| 61 | - f.seek(0) |
| 62 | - f.truncate() |
| 63 | f.write(content) |
| 64 | + os.replace(f.name, full_filename) |
| 65 | |
| 66 | |
| 67 | def generate_header(path, modules): |