https://github.com/wyfo/synchronizer
Another concurrency permutation testing tool for Rust.
https://github.com/wyfo/synchronizer
Last synced: 8 months ago
JSON representation
Another concurrency permutation testing tool for Rust.
- Host: GitHub
- URL: https://github.com/wyfo/synchronizer
- Owner: wyfo
- License: mit
- Created: 2023-07-21T07:54:28.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2023-08-07T17:11:14.000Z (about 2 years ago)
- Last Synced: 2025-01-11T16:13:28.625Z (9 months ago)
- Language: Rust
- Size: 27.3 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# synchronizer
Another concurrency permutation testing tool for Rust.## Example
The following program can fail if the thread run before the assertion. *synchronizer* will trigger the failure
```rust
use std::sync::Arc;use synchronizer::{
sync::atomic::{AtomicBool, Ordering},
thread,
};synchronizer::run(|| {
let b = Arc::new(AtomicBool::default());
let b2 = b.clone();
let thread = thread::spawn(move || {
b2.store(true, Ordering::Relaxed);
});
assert!(!b.load(Ordering::Relaxed));
thread.join().unwrap();
}); // panics
```## How it works
*synchronizer* wraps modules `std::thread` and `std::thread` and add thread synchronization for each operation (atomic, thread spawning, mutex, etc.); only one thread run between each operation.
The execution steps/running threads are tracked, and permuted at the end of the execution for the next one.
In case of failure, *synchronize* will print the execution summary, with threads' state and synchronized operations in execution order, to help understanding the failure.
## Difference with *loom*
I don't know how [*loom*](https://github.com/tokio-rs/loom) works in detail, but *synchronizer* don't do causality computations, it just runs the program one thread at a time.
Also, in unsynchronized-context (when `synchronizer::run` is not called), *synchronizer* wrapper functions/types just works as the wrapped functions/types. In fact, most of the wrapped types are `#[repr(transparent)]`.
So you can just add *synchronizer* to `[dev-dependencies]` and use it in normal tests; there is no need of `--cfg synchronizer`.By the way, library with low-level synchronization primitive could add *synchronizer* as a feature to enable using them in synchronized tests.
I haven't measured performance yet, so I cannot compare with *loom* in terms of execution rapidity.
## TODO
- The execution summary is quite crude, it's just a `#[derive(Debug)]` for now
- Spurious wakeups are not handled yet (but it's not really difficult and should be done soon)
- Add asynchronous support? just a `block_on` method?
- Add cell borrowing tracking? Actually, it could be done in an independent library, and IMO it should be independent.