- Jun 11, 2024
-
-
Matthew Fernandez authored
CI tweaks
-
Matthew Fernandez authored
-
Matthew Fernandez authored
The 13.2 image seems no longer accessible, despite the OS not yet being EOLed.
-
Matthew Fernandez authored
more close-on-exec tweaks
-
- Jun 09, 2024
-
-
Matthew Fernandez authored
-
Matthew Fernandez authored
-
Matthew Fernandez authored
-
Matthew Fernandez authored
GCC 14
-
- Jun 05, 2024
-
-
Matthew Fernandez authored
fix a couple of 'murphi2uclid' bugs
-
- Jun 03, 2024
-
-
Matthew Fernandez authored
-
Matthew Fernandez authored
-
Matthew Fernandez authored
use close-on-exec to more simply clean up pipe file descriptors
-
Matthew Fernandez authored
A recent bug fix in the Zig compiler¹ made me realise this code was unnecessarily carrying open file descriptors (the source ones to the `dup2` operations) into the child process. We can address this and simplify the whole situation by taking advantage of the `dup2` happening _before_ exec, and thus close-on-exec does what we need. ¹ https://github.com/ziglang/zig/commit/389181f6be8810b5cd432e236a962229257a5b59
-
Matthew Fernandez authored
-
Matthew Fernandez authored
-
- Jun 01, 2024
-
-
Matthew Fernandez authored
This is based on `murphi2uclid`. But unlike Uclid5 translation, this is much more rough. The semantics and structure of SMV are sufficiently different that an automatic translation would be more like a compiler than the AST-walking strategy employed by the `murphi2*` tools. It does not seem worth undertaking something this ambitious until we get some experience in whether this translation is useful. The translation gives up in numerous scenarios. But it should be more usable once we implement the ability to ingest partial Murphi models.
-
- May 19, 2024
-
-
Matthew Fernandez authored
Ubuntu 20.04 is now the oldest version of Ubuntu still within support.
-
- May 09, 2024
-
-
Matthew Fernandez authored
a9de733a, 5dac7295, 10acb279, and cc345ea2 introduced handling of some unicode characters that map to ASCII characters involved in starting a comment. These would incorrectly be considered as eligible aliases within comment tokens. E.g. `÷×` would be treated as validly starting a multi-line comment. This problem seems somewhat latent in that most sequences that would be confused in this way are not valid Murphi substrings anyway. The only one I can come up with is: x := y −-- a comment -- ▲▲ -- │└─ actual start of the comment -- └─ unicode subtraction character z; -- ◄── conclusion of the subtraction This would be misinterpreted as the comment starting one character earlier. It is unclear whether this is an actual problem because the translation both before and after this change is identical; it is only the internal state of `murphi2murphi` that differs. Translation of something like this produces invalid Murphi source, but it is unclear what the user would want to happen here.
-
Matthew Fernandez authored
-
Matthew Fernandez authored
-
- May 07, 2024
-
-
Matthew Fernandez authored
-
Matthew Fernandez authored
remove 'final' from AST, Indexer
-
- May 06, 2024
-
-
Matthew Fernandez authored
Doxygen apparently understands this as an alternative to `\p` and it allows writing with less ambiguity.
-
Matthew Fernandez authored
External users sometimes want to extend the AST with their own nodes or a node that is “this existing node with a slight tweak.” Having methods marked `final` forces them into forking Rumur just to remove these annotations. Recent analysis has also suggested there is no significant performance benefit from `final`.¹ ¹ https://16bpp.net/blog/post/the-performance-impact-of-cpp-final-keyword/
-
- May 05, 2024
-
-
Matthew Fernandez authored
avoid linking libatomic if possible on ARM64
-
Matthew Fernandez authored
-
Matthew Fernandez authored
Double-word atomics are used to implement lock-free reference-counted pointers.¹ Compiler built-ins (the GCC __sync and __atomic built-ins) are used to access this functionality. It is up to the compiler how to lower these built-ins, and it chooses between emitting inline instructions or calling into the libatomic runtime support library.² The implementations in libatomic are typically not lock-free – they work by using per-variable-instance mutexes – which negates the performance benefits of the lock-free algorithm we are trying to implement. In tight code like our scenario, the function call overhead into libatomic is also a noticeable factor. It was observed that on ARM64 GCC lowers these __atomic built-ins into libatomic calls. ARM64 has Load-Linked/Store-Conditional (LL/SC) instructions that can be used to implement these inline, but GCC has traditionally avoided using these to back the atomics.³ While compiler developers were debating the utility of these instructions, ARM introduced “Large System Extensions,” adding a new CASP family of instructions that more efficiently implements compare-and-swap. So our aim is to use the CASP instructions where possible. We have the following matrix: ┌──────┬───────────────────────┬───────────────────────┐ │ │ Clang │ GCC │ ├──────┼───────────────────────┼───────────────────────┤ │ load │ __atomic │ __sync │ │ │ <armv8.1-a: LL/SC │ <armv8.1-a: libatomic │ │ │ ≥armv8.1-a: CASP │ ≥armv8.1-a: CASP │ ├──────┼───────────────────────┼───────────────────────┤ │ store│ __atomic │ __sync │ │ │ <armv8.1-a: LL/SC │ <armv8.1-a: libatomic │ │ │ ≥armv8.1-a: CASP │ ≥armv8.1-a: CASP │ ├──────┼───────────────────────┼───────────────────────┤ │ CAS │ __atomic │ __sync │ │ │ <armv8.1-a: libatomic │ <armv8.1-a: libatomic │ │ │ ≥armv8.1-a: CASP │ ≥armv8.1-a: CASP │ └──────┴───────────────────────┴───────────────────────┘ This seems to result in a near-optimal situation on ≥armv8.1-a. For <armv8.1-a, the only way to avoid linking against libatomic seems to be resorting to inline assembly which is not worthwhile. Reported-by: e69d5a347277e5e7cb23518d93266bdac89a4bad ¹ Specifically “Hazard Pointers” as described in Maged Michael’s “Hazard Pointers: Safe Memory Reclamation for Lock-Free Objects” in TPDS 15(8) 2004. ² GCC 10.1 introduced a third option that does a runtime check, similar to GNU indirect functions (IFUNCs), https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/making-the-most-of-the-arm-architecture-in-gcc-10. However, this is not relevant to us. ³ See https://gcc.gnu.org/pipermail/gcc-help/2017-June.txt for a lengthy debate on this and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878 for the underlying rationale for avoiding both LL/SC and cmpxchg for backing these atomics. As one participant in the first linked discussion accurately summarises, “I think what’s happened makes perfect sense at each step of the way but has led to an outcome which is crazy.”
-
Matthew Fernandez authored
This is preparation for leveraging this to avoid linking against libatomic on aarch64.
-
Matthew Fernandez authored
As discussed in the prior commit, this can avoid the need for linking against libatomic.
-
Matthew Fernandez authored
The value of `-march=…` can be a factor in deciding whether linking against libatomic is required. In particular, on aarch64 libatomic is required for < armv8.1-a.
-
Matthew Fernandez authored
Upcoming changes make this branch apply on aarch64 too. Unfortunately as-is it triggers a GCC bug. This rephrasing manages to side step the issue. GCC: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114310
-
- Apr 30, 2024
-
-
Matthew Fernandez authored
Python modernisation
-
Matthew Fernandez authored
-
Matthew Fernandez authored
This is more intuitive to C programmers and more in line with contemporary formatter choices like Black.
-
Matthew Fernandez authored
-
Matthew Fernandez authored
The last fragments of Travis CI testing were removed in bfefe96b.
-
Matthew Fernandez authored
It is unclear why we were not using this already. b3288d12 backported this script to Python 3.4, but `shutil.which` is already available there.
-
Matthew Fernandez authored
-
- Apr 27, 2024
-
-
Matthew Fernandez authored
fix: avoid mixing '__sync_*' and '__atomic_*' built-ins on ref-counted pointers
-
- Apr 26, 2024
-
-
Matthew Fernandez authored
When operating on reference counted pointers that take up a double-word, `refcounted_ptr_peek` was using a single-word read as an optimisation because it only needs the first word of the data. Meanwhile the other operations on reference counted pointers were using double-word compare-and-swap. On x86-64 with `-mcx16`, this results in near-optimal code: `CMPXCHG16B` for the double-word operations and `MOV` for the single-word read.¹ Similar for x86. Unfortunately on other platforms, this design can result in non-atomic operations. To understand why, note that the compiler has a number of options for lowering both the `__sync_*` built-ins and the `__atomic_*` built-ins. Two of these options are (1) an inline instruction sequence and (2) a call to a libatomic function. A constraint is that its choices must interoperate correctly. For example, lowering a 16-bit `__atomic_load` to a `MOV` and a 16-bit `__atomic_store` to a libatomic call (which is typically implemented with a per-instance mutex) would be incorrect. The following interleaving could occur, assuming X begins with the value 0x0: 1. Thread A calls `__atomic_store` on X 2. Thread A’s libatomic call takes a lock on X 3. Thread A writes 0xad into the first byte of X 4. Thread B loads both bytes of X in a single instruction 5. Thread A writes 0xde into the second byte of X 6. Thread A releases the lock on X It would have been valid for thread B to read either 0x0 (seeing the value before A’s store) or 0xdead (seeing the value after A’s store), but it instead saw a torn read of 0x00ad. Because the load and store do not agree on the protocol for synchronisation, atomicity can be violated. Crucially the compiler is only required to maintain this compatibility between the _same_ built-ins on the _same_ data type. The `__sync_*` built-ins and the `__atomic_*` built-ins are not required to use compatible protocols (and indeed they do not on x86-64 with `-mcx16`). And operations on a double-word type are not required to use a compatible protocol with operations on a single-word type (and indeed they do not on x86-64 _without_ `-mcx16`). The code in `refcounted_ptr_peek` was violating _both_ of these assumptions. On x86-64 without `-mcx16` it resulted in racy code, as it also did on ARM64. We could try to detect the narrow scenario wherein it is safe to mix built-ins because we know exactly which single instructions they will be lowered to (the ideal case on x86-64 described in the first paragraph), but this change conservatively switches to a double-word read which we know meets the compiler’s assumptions. ¹ `MOV` is atomic on naturally aligned 8-/16-/32-/64-bit data on x86-64.
-