Skip to content

Commit feadc29

Browse files
committed
Remove RMW support
1 parent 152442a commit feadc29

37 files changed

+30
-800
lines changed

genmc-sys/src/lib.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ mod ffi {
8181
#[derive(Debug)]
8282
enum StoreEventType {
8383
Normal,
84-
ReadModifyWrite,
8584
CompareExchange,
8685
}
8786

@@ -93,15 +92,6 @@ mod ffi {
9392

9493
/**** \/ Result & Error types \/ ****/
9594

96-
#[must_use]
97-
#[derive(Debug)]
98-
struct ReadModifyWriteResult {
99-
old_value: GenmcScalar,
100-
new_value: GenmcScalar,
101-
isCoMaxWrite: bool,
102-
error: UniquePtr<CxxString>, // TODO GENMC: pass more error info here
103-
}
104-
10595
#[must_use]
10696
#[derive(Debug)]
10797
struct CompareExchangeResult {
@@ -176,7 +166,6 @@ mod ffi {
176166
// Result / Error types:
177167
type LoadResult;
178168
type StoreResult;
179-
type ReadModifyWriteResult;
180169
type CompareExchangeResult;
181170
type VerificationError;
182171

@@ -199,17 +188,6 @@ mod ffi {
199188
memory_ordering: MemOrdering,
200189
old_value: GenmcScalar,
201190
) -> LoadResult;
202-
fn handleReadModifyWrite(
203-
self: Pin<&mut MiriGenMCShim>,
204-
thread_id: i32,
205-
address: u64,
206-
size: u64,
207-
load_ordering: MemOrdering,
208-
store_ordering: MemOrdering,
209-
rmw_op: RMWBinOp,
210-
rhs_value: GenmcScalar,
211-
old_value: GenmcScalar,
212-
) -> ReadModifyWriteResult;
213191
fn handleCompareExchange(
214192
self: Pin<&mut MiriGenMCShim>,
215193
thread_id: i32,

genmc-sys/src_cpp/MiriInterface.cpp

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -231,41 +231,6 @@ void MiriGenMCShim::handleThreadFinish(ThreadId thread_id, uint64_t ret_val)
231231
return result;
232232
}
233233

234-
[[nodiscard]] auto MiriGenMCShim::handleReadModifyWrite(ThreadId thread_id, uint64_t address,
235-
uint64_t size, MemOrdering loadOrd,
236-
MemOrdering store_ordering, RMWBinOp rmw_op,
237-
GenmcScalar rhs_value, GenmcScalar old_val)
238-
-> ReadModifyWriteResult
239-
{
240-
auto pos = incPos(thread_id);
241-
242-
auto loc = SAddr(address);
243-
auto aSize = ASize(size);
244-
auto type = AType::Unsigned;
245-
246-
auto rhsVal = rhs_value.toSVal();
247-
auto newLab =
248-
std::make_unique<FaiReadLabel>(pos, loadOrd, loc, aSize, type, rmw_op, rhsVal);
249-
250-
auto oldValSetter = [this, old_val](SAddr loc)
251-
{ this->handleOldVal(loc, old_val); };
252-
auto result = GenMCDriver::handleLoad(std::move(newLab), oldValSetter);
253-
if (const auto *error = result.error.get())
254-
{
255-
return ReadModifyWriteResult::fromError(*error);
256-
}
257-
258-
auto oldVal = result.scalar.toSVal(); // TODO GENMC: u128 handling
259-
auto newVal = executeRMWBinOp(oldVal, rhsVal, size, rmw_op);
260-
261-
auto store_result = handleStore(thread_id, address, size, GenmcScalar(newVal), old_val,
262-
store_ordering, StoreEventType::ReadModifyWrite);
263-
264-
if (store_result.is_error())
265-
return ReadModifyWriteResult::fromError(*store_result.error.get());
266-
return ReadModifyWriteResult(oldVal, newVal, store_result.isCoMaxWrite);
267-
}
268-
269234
[[nodiscard]] auto MiriGenMCShim::handleCompareExchange(
270235
ThreadId thread_id, uint64_t address, uint64_t size, GenmcScalar expected_value,
271236
GenmcScalar new_value, GenmcScalar old_val, MemOrdering success_load_ordering,
@@ -326,9 +291,6 @@ void MiriGenMCShim::handleThreadFinish(ThreadId thread_id, uint64_t ret_val)
326291
case StoreEventType::Normal:
327292
wLab = std::make_unique<WriteLabel>(pos, ord, loc, aSize, type, val);
328293
break;
329-
case StoreEventType::ReadModifyWrite:
330-
wLab = std::make_unique<FaiWriteLabel>(pos, ord, loc, aSize, type, val);
331-
break;
332294
case StoreEventType::CompareExchange:
333295
wLab = std::make_unique<CasWriteLabel>(pos, ord, loc, aSize, type, val);
334296
break;

genmc-sys/src_cpp/MiriInterface.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ using ThreadId = int;
2727
enum class StoreEventType : uint8_t
2828
{
2929
Normal,
30-
ReadModifyWrite,
3130
CompareExchange,
3231
};
3332

@@ -56,10 +55,6 @@ struct MiriGenMCShim : private GenMCDriver
5655
///////////////////
5756
[[nodiscard]] LoadResult handleLoad(ThreadId thread_id, uint64_t address, uint64_t size,
5857
MemOrdering ord, GenmcScalar old_val);
59-
[[nodiscard]] ReadModifyWriteResult
60-
handleReadModifyWrite(ThreadId thread_id, uint64_t address, uint64_t size,
61-
MemOrdering loadOrd, MemOrdering store_ordering, RMWBinOp rmw_op,
62-
GenmcScalar rhs_value, GenmcScalar old_val);
6358
[[nodiscard]] CompareExchangeResult
6459
handleCompareExchange(ThreadId thread_id, uint64_t address, uint64_t size,
6560
GenmcScalar expected_value, GenmcScalar new_value,

src/concurrency/genmc/helper.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,6 @@ pub fn split_access(address: Size, size: Size) -> impl Iterator<Item = (u64, u64
4646
start_chunks.chain(aligned_chunks).chain(end_chunks)
4747
}
4848

49-
/// Like `scalar_to_genmc_scalar`, but returns an error if the scalar is not an integer
50-
pub fn rhs_scalar_to_genmc_scalar<'tcx>(
51-
ecx: &MiriInterpCx<'tcx>,
52-
scalar: Scalar,
53-
) -> InterpResult<'tcx, GenmcScalar> {
54-
if matches!(scalar, Scalar::Ptr(..)) {
55-
throw_unsup_format!("Right hand side of atomic operation cannot be a pointer");
56-
}
57-
scalar_to_genmc_scalar(ecx, scalar)
58-
}
59-
6049
pub fn option_scalar_to_genmc_scalar<'tcx>(
6150
ecx: &MiriInterpCx<'tcx>,
6251
maybe_scalar: Option<Scalar>,

src/concurrency/genmc/mapping.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use genmc_sys::{MemOrdering, RMWBinOp};
1+
use genmc_sys::MemOrdering;
22

33
use crate::{AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd};
44

@@ -36,26 +36,3 @@ impl AtomicRwOrd {
3636
}
3737
}
3838
}
39-
40-
pub(super) fn min_max_to_genmc_rmw_op(min: bool, is_signed: bool) -> RMWBinOp {
41-
match (min, is_signed) {
42-
(true, true) => RMWBinOp::Min, // TODO GENMC: is there a use for FMin? (Min, UMin, FMin)
43-
(false, true) => RMWBinOp::Max,
44-
(true, false) => RMWBinOp::UMin,
45-
(false, false) => RMWBinOp::UMax,
46-
}
47-
}
48-
49-
pub(super) fn to_genmc_rmw_op(bin_op: rustc_middle::mir::BinOp, negate: bool) -> RMWBinOp {
50-
match bin_op {
51-
rustc_middle::mir::BinOp::Add => RMWBinOp::Add,
52-
rustc_middle::mir::BinOp::Sub => RMWBinOp::Sub,
53-
rustc_middle::mir::BinOp::BitOr if !negate => RMWBinOp::Or,
54-
rustc_middle::mir::BinOp::BitXor if !negate => RMWBinOp::Xor,
55-
rustc_middle::mir::BinOp::BitAnd if negate => RMWBinOp::Nand,
56-
rustc_middle::mir::BinOp::BitAnd => RMWBinOp::And,
57-
_ => {
58-
panic!("unsupported atomic operation: bin_op: {bin_op:?}, negate: {negate}");
59-
}
60-
}
61-
}

src/concurrency/genmc/mod.rs

Lines changed: 29 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::sync::Arc;
33

44
use genmc_sys::{
55
ActionKind, GENMC_GLOBAL_ADDRESSES_MASK, GenmcScalar, GenmcThreadId, MemOrdering,
6-
MiriGenMCShim, RMWBinOp, StoreEventType, UniquePtr, createGenmcHandle,
6+
MiriGenMCShim, StoreEventType, UniquePtr, createGenmcHandle,
77
};
88
use rustc_abi::{Align, Size};
99
use rustc_const_eval::interpret::{AllocId, InterpCx, InterpResult, interp_ok};
@@ -12,10 +12,9 @@ use tracing::info;
1212

1313
use self::global_allocations::{EvalContextExtPriv as _, GlobalAllocationHandler};
1414
use self::helper::{
15-
genmc_scalar_to_scalar, option_scalar_to_genmc_scalar, rhs_scalar_to_genmc_scalar,
15+
genmc_scalar_to_scalar, option_scalar_to_genmc_scalar,
1616
scalar_to_genmc_scalar,
1717
};
18-
use self::mapping::{min_max_to_genmc_rmw_op, to_genmc_rmw_op};
1918
use self::thread_info_manager::ThreadInfoManager;
2019
use crate::concurrency::genmc::helper::split_access;
2120
use crate::{
@@ -205,101 +204,51 @@ impl GenmcCtx {
205204
/// Returns `(old_val, Option<new_val>)`. `new_val` might not be the latest write in coherence order, which is indicated by `None`.
206205
pub(crate) fn atomic_rmw_op<'tcx>(
207206
&self,
208-
ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
209-
address: Size,
210-
size: Size,
211-
ordering: AtomicRwOrd,
212-
(rmw_op, not): (mir::BinOp, bool),
213-
rhs_scalar: Scalar,
207+
_ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
208+
_address: Size,
209+
_size: Size,
210+
_ordering: AtomicRwOrd,
211+
(_rmw_op, _not): (mir::BinOp, bool),
212+
_rhs_scalar: Scalar,
214213
// The value that we would get, if we were to do a non-atomic load here.
215-
old_value: Scalar,
214+
_old_value: Scalar,
216215
) -> InterpResult<'tcx, (Scalar, Option<Scalar>)> {
217-
assert!(!self.allow_data_races.get()); // TODO GENMC: handle this properly
218-
let (load_ordering, store_ordering) = ordering.to_genmc_memory_orderings();
219-
let genmc_rmw_op = to_genmc_rmw_op(rmw_op, not);
220-
tracing::info!(
221-
"GenMC: atomic_rmw_op (op: {rmw_op:?}, not: {not}, genmc_rmw_op: {genmc_rmw_op:?}): rhs value: {rhs_scalar:?}, orderings ({load_ordering:?}, {store_ordering:?})"
222-
);
223-
let genmc_rhs_scalar = rhs_scalar_to_genmc_scalar(ecx, rhs_scalar)?;
224-
let genmc_old_value = scalar_to_genmc_scalar(ecx, old_value)?;
225-
self.atomic_rmw_op_impl(
226-
ecx,
227-
address,
228-
size,
229-
load_ordering,
230-
store_ordering,
231-
genmc_rmw_op,
232-
genmc_rhs_scalar,
233-
genmc_old_value,
234-
)
216+
assert!(!self.allow_data_races.get());
217+
throw_unsup_format!("FIXME(genmc): Add support for atomic min/max.")
235218
}
236219

237220
/// Inform GenMC about an atomic `min` or `max` operation.
238221
///
239222
/// Returns `(old_val, Option<new_val>)`. `new_val` might not be the latest write in coherence order, which is indicated by `None`.
240223
pub(crate) fn atomic_min_max_op<'tcx>(
241224
&self,
242-
ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
243-
address: Size,
244-
size: Size,
245-
ordering: AtomicRwOrd,
246-
min: bool,
247-
is_signed: bool,
248-
rhs_scalar: Scalar,
225+
_ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
226+
_address: Size,
227+
_size: Size,
228+
_ordering: AtomicRwOrd,
229+
_min: bool,
230+
_is_signed: bool,
231+
_rhs_scalar: Scalar,
249232
// The value that we would get, if we were to do a non-atomic load here.
250-
old_value: Scalar,
233+
_old_value: Scalar,
251234
) -> InterpResult<'tcx, (Scalar, Option<Scalar>)> {
252-
assert!(!self.allow_data_races.get()); // TODO GENMC: handle this properly
253-
let (load_ordering, store_ordering) = ordering.to_genmc_memory_orderings();
254-
let genmc_rmw_op = min_max_to_genmc_rmw_op(min, is_signed);
255-
tracing::info!(
256-
"GenMC: atomic_min_max_op (min: {min}, signed: {is_signed}, genmc_rmw_op: {genmc_rmw_op:?}): rhs value: {rhs_scalar:?}, orderings ({load_ordering:?}, {store_ordering:?})"
257-
);
258-
let genmc_rhs_scalar = rhs_scalar_to_genmc_scalar(ecx, rhs_scalar)?;
259-
let genmc_old_value = scalar_to_genmc_scalar(ecx, old_value)?;
260-
self.atomic_rmw_op_impl(
261-
ecx,
262-
address,
263-
size,
264-
load_ordering,
265-
store_ordering,
266-
genmc_rmw_op,
267-
genmc_rhs_scalar,
268-
genmc_old_value,
269-
)
235+
assert!(!self.allow_data_races.get());
236+
throw_unsup_format!("FIXME(genmc): Add support for atomic min/max.")
270237
}
271238

272239
/// Returns `(old_val, Option<new_val>)`. `new_val` might not be the latest write in coherence order, which is indicated by `None`.
273240
pub(crate) fn atomic_exchange<'tcx>(
274241
&self,
275-
ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
276-
address: Size,
277-
size: Size,
278-
rhs_scalar: Scalar,
279-
ordering: AtomicRwOrd,
242+
_ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
243+
_address: Size,
244+
_size: Size,
245+
_rhs_scalar: Scalar,
246+
_ordering: AtomicRwOrd,
280247
// The value that we would get, if we were to do a non-atomic load here.
281-
old_value: Scalar,
248+
_old_value: Scalar,
282249
) -> InterpResult<'tcx, (Scalar, Option<Scalar>)> {
283-
assert!(!self.allow_data_races.get()); // TODO GENMC: handle this properly
284-
// TODO GENMC: could maybe merge this with atomic_rmw?
285-
286-
let (load_ordering, store_ordering) = ordering.to_genmc_memory_orderings();
287-
let genmc_rmw_op = RMWBinOp::Xchg;
288-
tracing::info!(
289-
"GenMC: atomic_exchange (op: {genmc_rmw_op:?}): new value: {rhs_scalar:?}, orderings ({load_ordering:?}, {store_ordering:?})"
290-
);
291-
let genmc_rhs_scalar = scalar_to_genmc_scalar(ecx, rhs_scalar)?;
292-
let genmc_old_value = scalar_to_genmc_scalar(ecx, old_value)?;
293-
self.atomic_rmw_op_impl(
294-
ecx,
295-
address,
296-
size,
297-
load_ordering,
298-
store_ordering,
299-
genmc_rmw_op,
300-
genmc_rhs_scalar,
301-
genmc_old_value,
302-
)
250+
assert!(!self.allow_data_races.get());
251+
throw_unsup_format!("FIXME(genmc): Add support for atomic swap.")
303252
}
304253

305254
pub(crate) fn atomic_compare_exchange<'tcx>(
@@ -734,64 +683,6 @@ impl GenmcCtx {
734683
interp_ok(store_result.isCoMaxWrite)
735684
}
736685

737-
fn atomic_rmw_op_impl<'tcx>(
738-
&self,
739-
ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
740-
address: Size,
741-
size: Size,
742-
load_ordering: MemOrdering,
743-
store_ordering: MemOrdering,
744-
genmc_rmw_op: RMWBinOp,
745-
genmc_rhs_scalar: GenmcScalar,
746-
genmc_old_value: GenmcScalar,
747-
) -> InterpResult<'tcx, (Scalar, Option<Scalar>)> {
748-
assert!(
749-
size.bytes() <= 8,
750-
"TODO GENMC: no support for accesses larger than 8 bytes (got {} bytes)",
751-
size.bytes()
752-
);
753-
let machine = &ecx.machine;
754-
assert_ne!(0, size.bytes());
755-
let thread_infos = self.thread_infos.borrow();
756-
let curr_thread_id = machine.threads.active_thread();
757-
let genmc_tid = thread_infos.get_info(curr_thread_id).genmc_tid;
758-
759-
let genmc_address = address.bytes();
760-
let genmc_size = size.bytes();
761-
762-
info!(
763-
"GenMC: atomic_rmw_op, thread: {curr_thread_id:?} ({genmc_tid:?}) (op: {genmc_rmw_op:?}, rhs value: {genmc_rhs_scalar:?}), address: {address:?}, size: {size:?}, orderings: ({load_ordering:?}, {store_ordering:?})",
764-
);
765-
766-
let mut mc = self.handle.borrow_mut();
767-
let pinned_mc = mc.as_mut();
768-
let rmw_result = pinned_mc.handleReadModifyWrite(
769-
genmc_tid.0,
770-
genmc_address,
771-
genmc_size,
772-
load_ordering,
773-
store_ordering,
774-
genmc_rmw_op,
775-
genmc_rhs_scalar,
776-
genmc_old_value,
777-
);
778-
779-
if let Some(error) = rmw_result.error.as_ref() {
780-
let msg = error.to_string_lossy().to_string();
781-
info!("GenMC: RMW operation returned an error: \"{msg}\"");
782-
throw_ub_format!("{}", msg); // TODO GENMC: proper error handling: find correct error here
783-
}
784-
785-
let old_value_scalar = genmc_scalar_to_scalar(ecx, rmw_result.old_value, size)?;
786-
787-
let new_value_scalar = if rmw_result.isCoMaxWrite {
788-
Some(genmc_scalar_to_scalar(ecx, rmw_result.new_value, size)?)
789-
} else {
790-
None
791-
};
792-
interp_ok((old_value_scalar, new_value_scalar))
793-
}
794-
795686
/**** Scheduling functionality ****/
796687

797688
pub fn schedule_thread<'tcx>(

tests/genmc/pass/basics/rmw/rmw_edge_cases.i16_.stderr

Lines changed: 0 additions & 3 deletions
This file was deleted.

tests/genmc/pass/basics/rmw/rmw_edge_cases.i32_.stderr

Lines changed: 0 additions & 3 deletions
This file was deleted.

tests/genmc/pass/basics/rmw/rmw_edge_cases.i64_.stderr

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)