[WIP] Thread Collider: Race detection / Formal Verification of Nim concurrent programs #127
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
For now, just a shell to solve my Heisenbugs deadlock/livelock woes and random failures in CI.
The goal, create a model checker that exhaustively checks all possible states (i.e. interleavings of threads and load/store/lock/condvar/futex) directly in Nim.
RFC:
(second part: Correct-by-construction thread synchronization)
Research:
The idea is to
The events in the middle on thread B and C can happen in any order.
A data structure can be verified to handle tp hold its invariant, or the result to be correct with simple asserts, if Thread Collider can generate all possible thread interleavings.
Difference with ThreadSanitizer:
ThreadSanitizer does only one execution of the program. A model checker proves that there is no race by bruteforcing all possible execution paths.
Status:
The vector clock data structure is implemented.
However, architecting the library seems quite complex from just the papers, everything seems to impact each other in a non-standard way and I need more mastery on the C++11 memory model.
For example to handle compiler reordering of relaxed atomic statements
It is possible to have r1 = 1 and r2 = 1 for this program,
contrary to first intuition.
I.e. we can see that before setting one of x or y to 1
a load at least must have happened, and so those load should be 0.
However, under a relaxed memory model, given that those load-store
are on different variables, the compiler can reorder the program to: