Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dmitrii-artuhov/weak-memory-models-simulator
Semester project for 'Weak Memory Models' course @ CUB 2024
https://github.com/dmitrii-artuhov/weak-memory-models-simulator
Last synced: about 1 month ago
JSON representation
Semester project for 'Weak Memory Models' course @ CUB 2024
- Host: GitHub
- URL: https://github.com/dmitrii-artuhov/weak-memory-models-simulator
- Owner: dmitrii-artuhov
- Created: 2023-11-09T14:36:22.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2023-12-12T20:23:42.000Z (about 1 year ago)
- Last Synced: 2023-12-12T21:31:13.414Z (about 1 year ago)
- Language: C++
- Homepage:
- Size: 202 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Weak memory models simulator
## Description
This project implements a couple interpreters for a simple programming language that are capable of running under different memory models.
## Programming language
It has the following instructions set:
- `r = 1` put constant into register.
- `r1 = r2 # r3` binary operation on two registers.
- `if r goto L` conditional jump on label `L`.
- `load m #x r` load value from memory by address stored in location `x` into register `r`.
- `store m #x r` store value from register `r` into memory by location `x`.
- `r1 = cas m #x r2 r3` compare-and-swap value in memory by location named `x`, expected value is stored in `r2`, desired value is stored in `r3`, shoud return the actually read value in register `r1`.
- `r1 = fai m #x r2` fetch-and-increment value in memory by location `x`, the value to increment by is stored in `r2`, should return the read value prior increment in register `r1`.
- `fence m` memory fence instruction.
- `thread_goto L` create a new thread with start instruction at label `L`.Notes on instructions:
- all values are assumed to be (fixed-width) integers.
- binary operation `#` can be one of the following: `+`, `-`, `*`, `/`.
- each instruction can be prefixed with label, e.g. `L: r = 1`.
- `m` denotes access mode: `SEQ_CST`, `REL`, `ACQ`, `REL_ACQ`, `RLX`.## Weak memory models
Program supports 4 memory models:
- **SC** (sequencially consistent, [more info](https://www.cs.utexas.edu/~bornholt/post/memory-models.html))
- **TSO** (total store ordering, [more info](https://www.cs.utexas.edu/~bornholt/post/memory-models.html#:~:text=A%20popular%20memory%20model%20that,latency%2C%20making%20execution%20significantly%20faster.))
- **PSO** (partial store ordering, [more info](https://link.springer.com/article/10.1007/s11036-022-01989-5))
- **Strong RA** (strong release acquire, [more info](https://plv.mpi-sws.org/sra/paper.pdf)): *does not yet support fences*.## Interpreters
Program supports 4 modes of executions:
- **Non-deterministic**: chooses one random execution on each run.
- **Tracing**: same as non-determinstic, but it logs the intermediate results and thread interleavings.
- **Model-checking**: enumerates all possible executions of a given program.
- **Interactive**: allows user to make a decision on what execution to explore at each choice point.## Building
**Requirements**:
- `C++17` or higher
- `CMake v3.15` or higher**Local setup**:
- `git clone https://github.com/dmitrii-artuhov/weak-memory-models-simulator.git && cd ./weak-memory-models-simulator`
- `mkdir build && cd build`
- `cmake .. && make`## Running
After building the project there will be 2 targets generated: `tests` and `simulator`.To run the `simulator` you have to pass some arguments:
- `--file`: path to file containing program code.
- `--mm`: memory model, one of `sc` (default), `tso`, `pso`, `sra`.
- `--it`: execution mode, one of `nd` (non-deterministic, default), `tr` (tracing), `mc` (model-checking), `i` (interactive).## Examples
1. **Store buffering**:
```js
thread_goto T1 // create new thread with start instruction at location `T1`
thread_goto T2 // same for `T2`
goto ENDT1: r = 1
store RLX #x r // write 1 to `x`
load RLX #y a // read from `y`
goto ENDT2: r = 1
store RLX #y r // write 1 to `y`
load RLX #x b // read from `x`
goto ENDEND: // just an empty label
```Running program with TSO memory model in model-checking mode:
```txt
> ./simulator --file ../tests/test-data/store-buffering.txt --mm tso --it mc=========== Memory state ===========
Memory: // final state of memory
x: 1
y: 1
Store buffers:
[empty]
=============================================== Thread states ==========
Thread 0 // this is a main thread (that created the rest)
[empty]Thread 1
a: 0 // value read in register `a`
r: 1Thread 2
b: 0 // value read in register `b`
r: 1====================================
=========== Memory state ===========
Memory:
y: 1
x: 1
Store buffers:
[empty]
=============================================== Thread states ==========
Thread 0
[empty]Thread 1
a: 0
r: 1Thread 2
b: 1
r: 1====================================
=========== Memory state ===========
Memory:
x: 1
y: 1
Store buffers:
[empty]
=============================================== Thread states ==========
Thread 0
[empty]Thread 1
a: 1
r: 1Thread 2
b: 0
r: 1====================================
=========== Memory state ===========
Memory:
y: 1
x: 1
Store buffers:
[empty]
=============================================== Thread states ==========
Thread 0
[empty]Thread 1
a: 1
r: 1Thread 2
b: 1
r: 1====================================
Total states generated: 4297 // number of program states explored
Final states count (unique in terms of thread subsystems states): 4
```Above we can see 4 different outcomes of the store-buffering example under TSO. Model checking mode explores all *interesting* executions of a program in order to cover all possible outcomes (by outcomes I mean all final unique thread states).
2. **Message passing**:
```js
thread_goto T1
thread_goto T2
goto ENDT1: r = 1
store RLX #x r
load RLX #y a
goto ENDT2: r = 1
store RLX #y r
load RLX #x b
goto ENDEND:
```Running program with Strong RA memory model in model-checking mode:
```txt
> ./simulator --file ../tests/test-data/message-passing.txt --mm sra --it mc=========== Memory state ===========
Memory:
Global timestamps:
x @ 1
y @ 1
Thread views:
Thread 0:
Thread 1:
x @ 1
y @ 1
Thread 2:====================================
=========== Thread states ==========
Thread 0
[empty]Thread 1
r: 1Thread 2
a: 0
b: 0====================================
=========== Memory state ===========
Memory:
Global timestamps:
x @ 1
y @ 1
Thread views:
Thread 0:
Thread 1:
x @ 1
y @ 1
Thread 2:
x @ 1====================================
=========== Thread states ==========
Thread 0
[empty]Thread 1
r: 1Thread 2
a: 0
b: 1====================================
=========== Memory state ===========
Memory:
Global timestamps:
x @ 1
y @ 1
Thread views:
Thread 0:
Thread 1:
x @ 1
y @ 1
Thread 2:
y @ 1====================================
=========== Thread states ==========
Thread 0
[empty]Thread 1
r: 1Thread 2
a: 1
b: 0====================================
=========== Memory state ===========
Memory:
Global timestamps:
x @ 1
y @ 1
Thread views:
Thread 0:
Thread 1:
x @ 1
y @ 1
Thread 2:
x @ 1
y @ 1====================================
=========== Thread states ==========
Thread 0
[empty]Thread 1
r: 1Thread 2
a: 1
b: 1====================================
Total states generated: 2716
Final states count (unique in terms of thread subsystems states): 4
```Let's modify the code by adding release memory order for all writes and acquire for all reads:
```js
thread_goto T1
thread_goto T2
goto ENDT1: r = 1
store REL #x r
store REL #y r
goto ENDT2: load ACQ #y a
load ACQ #x b
goto ENDEND:
```And run again with the same arguments:
```txt
...
Total states generated: 2642
Final states count (unique in terms of thread subsystems states): 3
```I did not put the whole output, but we see that one outcome became impossible. To be certain `{ a: 1, b: 0 }` became impossible (and it is expected result).