From fa5ed6204f9188134a87ac9dd569e1496759a7f6 Mon Sep 17 00:00:00 2001 From: Ross Burton Date: Tue, 8 Sep 2020 11:49:08 +0100 Subject: [PATCH] tools/gen_module_code: atomically rewrite the generated files Upstream-Status: Submitted [https://gitlab.arm.com/arm-reference-solutions/corstone1000/external_system/rtx/-/issues/1] Signed-off-by: Ross Burton The gen_module rule in rules.mk is marked as .PHONY, so make will execute it whenever it is mentioned. This results in gen_module_code being executed 64 times for a Juno build. However in heavily parallel builds there's a good chance that gen_module_code is writing a file whilst the compiler is reading it because make also doesn't know what files are generated by gen_module_code. The correct fix is to adjust the Makefiles so that the dependencies are correct but this isn't trivial, so band-aid the problem by atomically writing the generated files. Change-Id: I82d44f9ea6537a91002e1f80de8861d208571630 Signed-off-by: Ross Burton --- tools/gen_module_code.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tools/gen_module_code.py b/tools/gen_module_code.py index 6bf50e0..92623a7 100755 --- a/tools/gen_module_code.py +++ b/tools/gen_module_code.py @@ -17,6 +17,7 @@ import argparse import os import sys +import tempfile DEFAULT_PATH = 'build/' @@ -55,13 +56,21 @@ TEMPLATE_C = "/* This file was auto generated using {} */\n" \ def generate_file(path, filename, content): full_filename = os.path.join(path, filename) - with open(full_filename, 'a+') as f: - f.seek(0) - if f.read() != content: + + try: + with open(full_filename) as f: + rewrite = f.read() != content + except FileNotFoundError: + rewrite = True + + if rewrite: + with tempfile.NamedTemporaryFile(prefix="gen-module-code", + dir=path, + delete=False, + mode="wt") as f: print("[GEN] {}...".format(full_filename)) - f.seek(0) - f.truncate() f.write(content) + os.replace(f.name, full_filename) def generate_header(path, modules):