Skip to content

Commit 46d0673

Browse files
committed
Remove RMW support
1 parent 63199f1 commit 46d0673

37 files changed

+30
-779
lines changed

genmc-sys/src/lib.rs

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ mod ffi {
8383
#[derive(Debug)]
8484
enum StoreEventType {
8585
Normal,
86-
ReadModifyWrite,
8786
CompareExchange,
8887
}
8988

@@ -95,15 +94,6 @@ mod ffi {
9594

9695
/**** \/ Result & Error types \/ ****/
9796

98-
#[must_use]
99-
#[derive(Debug)]
100-
struct ReadModifyWriteResult {
101-
old_value: GenmcScalar,
102-
new_value: GenmcScalar,
103-
isCoMaxWrite: bool,
104-
error: UniquePtr<CxxString>, // TODO GENMC: pass more error info here
105-
}
106-
10797
#[must_use]
10898
#[derive(Debug)]
10999
struct CompareExchangeResult {
@@ -143,7 +133,6 @@ mod ffi {
143133
// Result / Error types:
144134
type LoadResult;
145135
type StoreResult;
146-
type ReadModifyWriteResult;
147136
type CompareExchangeResult;
148137

149138
type GenmcScalar;
@@ -165,17 +154,6 @@ mod ffi {
165154
memory_ordering: MemOrdering,
166155
old_value: GenmcScalar,
167156
) -> LoadResult;
168-
fn handleReadModifyWrite(
169-
self: Pin<&mut MiriGenMCShim>,
170-
thread_id: i32,
171-
address: u64,
172-
size: u64,
173-
load_ordering: MemOrdering,
174-
store_ordering: MemOrdering,
175-
rmw_op: RMWBinOp,
176-
rhs_value: GenmcScalar,
177-
old_value: GenmcScalar,
178-
) -> ReadModifyWriteResult;
179157
fn handleCompareExchange(
180158
self: Pin<&mut MiriGenMCShim>,
181159
thread_id: i32,

genmc-sys/src_cpp/MiriInterface.cpp

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -227,42 +227,6 @@ void MiriGenMCShim::handleThreadKill(ThreadId thread_id) {
227227
return result;
228228
}
229229

230-
[[nodiscard]] auto MiriGenMCShim::handleReadModifyWrite(ThreadId thread_id, uint64_t address,
231-
uint64_t size, MemOrdering loadOrd,
232-
MemOrdering store_ordering, RMWBinOp rmw_op,
233-
GenmcScalar rhs_value, GenmcScalar old_val)
234-
-> ReadModifyWriteResult
235-
{
236-
auto pos = incPos(thread_id);
237-
238-
auto loc = SAddr(address);
239-
auto aSize = ASize(size);
240-
// `type` is only used for printing.
241-
auto type = AType::Unsigned;
242-
243-
auto rhsVal = rhs_value.toSVal();
244-
auto newLab =
245-
std::make_unique<FaiReadLabel>(pos, loadOrd, loc, aSize, type, rmw_op, rhsVal);
246-
247-
auto oldValSetter = [this, old_val](SAddr loc)
248-
{ this->handleOldVal(loc, old_val); };
249-
auto result = GenMCDriver::handleLoad(std::move(newLab), oldValSetter);
250-
if (const auto *error = result.error.get())
251-
{
252-
return ReadModifyWriteResult::fromError(*error);
253-
}
254-
255-
auto oldVal = result.scalar.toSVal(); // TODO GENMC: u128 handling
256-
auto newVal = executeRMWBinOp(oldVal, rhsVal, size, rmw_op);
257-
258-
auto store_result = handleStore(thread_id, address, size, GenmcScalar(newVal), old_val,
259-
store_ordering, StoreEventType::ReadModifyWrite);
260-
261-
if (store_result.is_error())
262-
return ReadModifyWriteResult::fromError(*store_result.error.get());
263-
return ReadModifyWriteResult(oldVal, newVal, store_result.isCoMaxWrite);
264-
}
265-
266230
[[nodiscard]] auto MiriGenMCShim::handleCompareExchange(
267231
ThreadId thread_id, uint64_t address, uint64_t size, GenmcScalar expected_value,
268232
GenmcScalar new_value, GenmcScalar old_val, MemOrdering success_load_ordering,
@@ -324,9 +288,6 @@ void MiriGenMCShim::handleThreadKill(ThreadId thread_id) {
324288
case StoreEventType::Normal:
325289
wLab = std::make_unique<WriteLabel>(pos, ord, loc, aSize, type, val);
326290
break;
327-
case StoreEventType::ReadModifyWrite:
328-
wLab = std::make_unique<FaiWriteLabel>(pos, ord, loc, aSize, type, val);
329-
break;
330291
case StoreEventType::CompareExchange:
331292
wLab = std::make_unique<CasWriteLabel>(pos, ord, loc, aSize, type, val);
332293
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>(
@@ -744,64 +693,6 @@ impl GenmcCtx {
744693
interp_ok(store_result.isCoMaxWrite)
745694
}
746695

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

807698
pub fn schedule_thread<'tcx>(

tests/genmc/pass/atomics/rmw_edge_cases.i16_.stderr

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

tests/genmc/pass/atomics/rmw_edge_cases.i32_.stderr

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

tests/genmc/pass/atomics/rmw_edge_cases.i64_.stderr

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

tests/genmc/pass/atomics/rmw_edge_cases.i8_.stderr

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

0 commit comments

Comments
 (0)