from nmigen.hdl.ast import SignalSet
from nmigen.hdl.xfrm import ValueVisitor, StatementVisitor, LHSGroupFilter
from nmigen.sim._base import BaseProcess
+from openpower.decoder.test.crtl_path import get_crtl_path
__all__ = ["PyRTLProcess"]
code += "#include \"common.h\"\n"
code += emitter.flush()
- file = open(f"crtl/{domain_process.name}.c", "w")
+ crtl = get_crtl_path()
+
+ file = open(os.path.join(crtl, f"{domain_process.name}.c"), "w")
file.write(code)
file.close()
--- /dev/null
+# SPDX-License-Identifier: LGPL-3-or-later
+# Copyright 2022 Jacob Lifshay
+
+
+from contextlib import contextmanager
+from itertools import count
+import os
+from pathlib import Path
+import shutil
+from tempfile import NamedTemporaryFile
+from threading import local
+
+__ctrl_path = local()
+
+
+@contextmanager
+def __try_lock_file(path):
+ path = Path(path)
+ try:
+ file = path.open("xb")
+ except FileExistsError:
+ yield False
+ return
+ try:
+ yield True
+ finally:
+ file.close()
+ path.unlink()
+
+
+def get_crtl_path():
+ # type: () -> str
+ path = getattr(__ctrl_path, "path", None)
+ if path is not None:
+ assert isinstance(path, str), "invalid state"
+ return path
+ for i in range(10000):
+ path = f"crtl{i}"
+ with __try_lock_file(f"crtl{i}.lock") as locked:
+ if locked and next(Path(path).glob(".lock_*"), None) is None:
+ shutil.rmtree(path, ignore_errors=True)
+ Path(path).mkdir(parents=True, exist_ok=True)
+ tmpfile = NamedTemporaryFile(prefix=".lock_", dir=path)
+ __ctrl_path.tmpfile = tmpfile
+ __ctrl_path.path = path
+ return path
+ assert False, "can't create crtl* path"
from os.path import dirname, join
from collections import namedtuple
+from openpower.decoder.test.crtl_path import get_crtl_path
__all__ = ["PySimEngine"]
self._fragment = fragment
- # blow away and recreate crtl subdirectory. (hope like hell
- # nobody is using this in their current working directory)
- if PySimEngine._crtl_counter == 0:
- shutil.rmtree("crtl", True)
- try:
- os.mkdir("crtl")
- except FileExistsError:
- pass
+ # create crtl directory
+ crtl = get_crtl_path()
# "Processes" are the compiled modules. Each module ends up
# with its own run() function
cdef += f"void run_{process.name}(void);\n"
# write out the header file
- with open("crtl/common.h", "w") as cdef_file :
+ with open(os.path.join(crtl, "common.h"), "w") as cdef_file:
cdef_file.write(cdef)
# same with c template: read template first
src = template % (len(self._state.slots), len(self._state.slots))
# write it out
- with open("crtl/common.c", "w") as src_file:
+ with open(os.path.join(crtl, "common.c"), "w") as src_file:
src_file.write(src)
# build module named crtlNNN in crtl subdirectory
- modulename = "crtl.crtl%d" % PySimEngine._crtl_counter
- sources = ["crtl/common.c"]
- sources += [f"crtl/{process.name}.c" for process in self._processes]
+ modulename = f"{crtl}.crtl{PySimEngine._crtl_counter}"
+ sources = [os.path.join(crtl, "common.c")]
+ for process in self._processes:
+ sources.append(os.path.join(crtl, f"{process.name}.c"))
ffibuilder = FFI()
ffibuilder.cdef(cdef)
ffibuilder.set_source(modulename, cdef, sources=sources)
ffibuilder.compile(verbose=True)
-
+
# append search path of crtl directory before attempting import
- sys.path.append(os.path.join(os.getcwd()))
+ cwd = os.path.join(os.getcwd())
+ if cwd not in sys.path:
+ sys.path.append(cwd)
self._state.crtl = importlib.import_module(modulename).lib
# Use a counter to generate unique names for modules, because Python