Skip to content

Add minimal functionality for using GenMC mode #4506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 42 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3fc854d
WIP: Add initial support for running Miri flamegraph (no flamegraph o…
Patrick-6 Apr 14, 2025
7fcd173
WIP: Start working on Miri-GenMC interop.
Patrick-6 Mar 14, 2025
af9d846
Remove duplicate tests
Patrick-6 Jul 29, 2025
9d7e964
Clean up comments.
Patrick-6 Jul 29, 2025
1631c9d
Remove leak checks from tests where possible, fix leak check for bloc…
Patrick-6 Jul 30, 2025
d9a6629
Clean up exit handling.
Patrick-6 Jul 30, 2025
c968c94
Remove unused VerificationError enum.
Patrick-6 Jul 29, 2025
24e42d0
Simplify GenMC test includes.
Patrick-6 Jul 30, 2025
61377c8
Inline test folders.
Patrick-6 Jul 30, 2025
8579860
Move tests
Patrick-6 Jul 30, 2025
44f4f75
Remove extra test variants, move tests.
Patrick-6 Jul 30, 2025
b02082b
Run fmt
Patrick-6 Jul 30, 2025
4eac4f3
Remove extra newline in program output
Patrick-6 Jul 30, 2025
0d6db1d
Remove duplicate call to handleAlloc.
Patrick-6 Jul 30, 2025
d65d9fb
Improve comments
Patrick-6 Jul 30, 2025
454bc94
Cleanup C++ code.
Patrick-6 Jul 30, 2025
7fb35c3
Use existing truncation function.
Patrick-6 Jul 30, 2025
fb7f726
Remove loom tests.
Patrick-6 Jul 27, 2025
9578b61
Remove __VERIFIER_assume
Patrick-6 Jul 26, 2025
b63acb5
Remove Mutex handling, do cleanup.
Patrick-6 Jul 26, 2025
ba5070d
Remove code for warning about missing GenMC support
Patrick-6 Jul 26, 2025
8155688
Remove graph printing
Patrick-6 Jul 26, 2025
1114119
Remove estimation mode.
Patrick-6 Jul 26, 2025
b68f8ae
Remove disabled test
Patrick-6 Jul 26, 2025
e235cf6
Simplify scheduling, do cleanup
Patrick-6 Jul 26, 2025
2a97d2c
Remove atomic fence support.
Patrick-6 Jul 26, 2025
bc9c428
Simplify next instruction type determination
Patrick-6 Jul 26, 2025
e223cd9
Cleanup
Patrick-6 Jul 26, 2025
e87d751
Remove GenMC verbosity level settings from Miri, remove MIRI_LOG debu…
Patrick-6 Jul 26, 2025
cbd64b9
Remove support for sending pointers to GenMC.
Patrick-6 Jul 26, 2025
96b1b54
More cleanup
Patrick-6 Jul 26, 2025
97444a6
Remove CXX NonNullUniquePtr.
Patrick-6 Jul 26, 2025
63199f1
Small cleanup
Patrick-6 Jul 26, 2025
46d0673
Remove RMW support
Patrick-6 Jul 26, 2025
88ea77d
Remove compare_exchange support.
Patrick-6 Jul 26, 2025
9ca1a0c
Minor cleanup
Patrick-6 Jul 26, 2025
e7a3b98
C++ code cleanup
Patrick-6 Jul 27, 2025
409164b
Remove remaining annotation code (for Mutex support)
Patrick-6 Jul 27, 2025
74f1fa1
Remove mixed atomic-non-atomic and 'read from initial value' support.
Patrick-6 Jul 28, 2025
d6d4584
Disable genmc feature by default.
Patrick-6 Jul 29, 2025
e112b22
Suppress 'unused' warning
Patrick-6 Jul 29, 2025
a42452b
Clean up TODOs and comments, improve error handling and remove accide…
Patrick-6 Jul 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions genmc-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ mod downloading {
use super::GENMC_DOWNLOAD_PATH;

/// The GenMC repository the we get our commit from.
pub(crate) const GENMC_GITHUB_URL: &str = "https://github.com/MPI-SWS/genmc.git";
pub(crate) const GENMC_GITHUB_URL: &str = "https://github.com/Patrick-6/genmc.git";
/// The GenMC commit we depend on. It must be available on the specified GenMC repository.
pub(crate) const GENMC_COMMIT: &str = "3438dd2c1202cd4a47ed7881d099abf23e4167ab";
pub(crate) const GENMC_COMMIT: &str = "56997d85fc9c07f75431570d49ce4892b22b8e6e";

pub(crate) fn download_genmc() -> PathBuf {
let Ok(genmc_download_path) = PathBuf::from_str(GENMC_DOWNLOAD_PATH);
Expand Down Expand Up @@ -224,7 +224,6 @@ fn compile_cpp_dependencies(genmc_path: &Path) {
.include(genmc_include_dir)
.include(llvm_include_dirs)
.include("./src_cpp")
.file("./src_cpp/MiriInterface.hpp")
.file("./src_cpp/MiriInterface.cpp")
.compile("genmc_interop");

Expand Down
137 changes: 132 additions & 5 deletions genmc-sys/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
pub use cxx::UniquePtr;

pub use self::ffi::*;

/// Defined in "genmc/src/Support/SAddr.hpp"
/// FIXME(genmc): `getGlobalAllocStaticMask()` is used to ensure the constant is consistent between Miri and GenMC,
/// but if https://github.com/dtolnay/cxx/issues/1051 is fixed we could share the constant directly.
pub const GENMC_GLOBAL_ADDRESSES_MASK: u64 = 1 << 63;

#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct GenmcThreadId(pub i32);
Comment on lines +10 to +12
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this has to be defined here.


pub const GENMC_MAIN_THREAD_ID: GenmcThreadId = GenmcThreadId(0);

impl GenmcScalar {
pub const UNINIT: Self = Self { value: 0, is_init: false };
/// GenMC expects a value for all stores, but we cannot always provide one (e.g., non-atomic writes).
/// FIXME(genmc): remove this if a permanent fix is ever found.
pub const DUMMY: Self = Self::from_u64(0xDEADBEEF);

pub const fn from_u64(value: u64) -> Self {
Self { value, is_init: true }
}
}

impl Default for GenmcParams {
fn default() -> Self {
Self {
print_random_schedule_seed: false,
do_symmetry_reduction: false,
// FIXME(GenMC): Add defaults for remaining parameters
}
Self { print_random_schedule_seed: false, do_symmetry_reduction: false }
}
}

Expand All @@ -20,11 +40,118 @@ mod ffi {
pub do_symmetry_reduction: bool,
// FIXME(GenMC): Add remaining parameters.
}

#[derive(Debug)]
enum ActionKind {
/// Any Mir terminator that's atomic and has load semantics.
Load,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should make it clear that "load" is "maybe load" and "non-load" is "definitely not a load".

/// Anything that's not a `Load`.
NonLoad,
}

#[derive(Debug)]
enum MemOrdering {
NotAtomic = 0,
Relaxed = 1,
// We skip 2 in case we support consume.
Acquire = 3,
Release = 4,
AcquireRelease = 5,
SequentiallyConsistent = 6,
}

#[derive(Debug, Clone, Copy)]
struct GenmcScalar {
value: u64,
is_init: bool,
}
Comment on lines +63 to +67
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have this type with the is_init flag since CXX doesn't support sending Option (or std::optional) across the language boundary. GenMC only supports up to 64 bit memory accesses, therefore the u64. Lastly, we don't support sending pointers to GenMC in this PR, so no field for provenance information (this also needs some design work on the GenMC side first).


/**** \/ Result & Error types \/ ****/

// FIXME(genmc): Rework error handling (likely requires changes on the GenMC side).

#[must_use]
#[derive(Debug)]
struct LoadResult {
is_read_opt: bool,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean? A comment would be good.

read_value: GenmcScalar,
error: UniquePtr<CxxString>,
}

#[must_use]
#[derive(Debug)]
struct StoreResult {
error: UniquePtr<CxxString>,
isCoMaxWrite: bool,
}
Comment on lines +71 to +86
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These will need to be reworked, but I'm waiting on a review of a PR with changes to how GenMC does error handling.


/**** /\ Result & Error types /\ ****/

unsafe extern "C++" {
include!("MiriInterface.hpp");

type MemOrdering;

// Types for Scheduling queries:
type ActionKind;

// Result / Error types:
type LoadResult;
type StoreResult;

type GenmcScalar;

type MiriGenMCShim;

fn createGenmcHandle(config: &GenmcParams) -> UniquePtr<MiriGenMCShim>;
fn getGlobalAllocStaticMask() -> u64;

fn handleExecutionStart(self: Pin<&mut MiriGenMCShim>);
fn handleExecutionEnd(self: Pin<&mut MiriGenMCShim>) -> UniquePtr<CxxString>;

fn handleLoad(
self: Pin<&mut MiriGenMCShim>,
thread_id: i32,
address: u64,
size: u64,
memory_ordering: MemOrdering,
old_value: GenmcScalar,
) -> LoadResult;
fn handleStore(
self: Pin<&mut MiriGenMCShim>,
thread_id: i32,
address: u64,
size: u64,
value: GenmcScalar,
old_value: GenmcScalar,
memory_ordering: MemOrdering,
) -> StoreResult;

fn handleMalloc(
self: Pin<&mut MiriGenMCShim>,
thread_id: i32,
size: u64,
alignment: u64,
) -> u64;
fn handleFree(self: Pin<&mut MiriGenMCShim>, thread_id: i32, address: u64, size: u64);

fn handleThreadCreate(self: Pin<&mut MiriGenMCShim>, thread_id: i32, parent_id: i32);
fn handleThreadJoin(self: Pin<&mut MiriGenMCShim>, thread_id: i32, child_id: i32);
fn handleThreadFinish(self: Pin<&mut MiriGenMCShim>, thread_id: i32, ret_val: u64);
fn handleThreadKill(self: Pin<&mut MiriGenMCShim>, thread_id: i32);

/**** Scheduling ****/
fn scheduleNext(
self: Pin<&mut MiriGenMCShim>,
curr_thread_id: i32,
curr_thread_next_instr_kind: ActionKind,
) -> i64;

fn getBlockedExecutionCount(self: &MiriGenMCShim) -> u64;
fn getExploredExecutionCount(self: &MiriGenMCShim) -> u64;

/// Check whether there are more executions to explore.
/// If there are more executions, this method prepares for the next execution and returns `true`.
fn isExplorationDone(self: Pin<&mut MiriGenMCShim>) -> bool;
}
}
Loading
Loading