Skip to content

Commit 88ea77d

Browse files
committed
Remove compare_exchange support.
1 parent 46d0673 commit 88ea77d

File tree

11 files changed

+19
-298
lines changed

11 files changed

+19
-298
lines changed

genmc-sys/src/lib.rs

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,6 @@ mod ffi {
7979
UMin = 10,
8080
}
8181

82-
// TODO GENMC: do these have to be shared with the Rust side?
83-
#[derive(Debug)]
84-
enum StoreEventType {
85-
Normal,
86-
CompareExchange,
87-
}
88-
8982
#[derive(Debug, Clone, Copy)]
9083
struct GenmcScalar {
9184
value: u64,
@@ -94,15 +87,6 @@ mod ffi {
9487

9588
/**** \/ Result & Error types \/ ****/
9689

97-
#[must_use]
98-
#[derive(Debug)]
99-
struct CompareExchangeResult {
100-
old_value: GenmcScalar, // TODO GENMC: handle bigger values
101-
is_success: bool,
102-
isCoMaxWrite: bool,
103-
error: UniquePtr<CxxString>, // TODO GENMC: pass more error info here
104-
}
105-
10690
#[must_use]
10791
#[derive(Debug)]
10892
struct LoadResult {
@@ -125,15 +109,13 @@ mod ffi {
125109

126110
type MemOrdering;
127111
type RMWBinOp;
128-
type StoreEventType;
129112

130113
// Types for Scheduling queries:
131114
type ActionKind;
132115

133116
// Result / Error types:
134117
type LoadResult;
135118
type StoreResult;
136-
type CompareExchangeResult;
137119

138120
type GenmcScalar;
139121

@@ -154,19 +136,6 @@ mod ffi {
154136
memory_ordering: MemOrdering,
155137
old_value: GenmcScalar,
156138
) -> LoadResult;
157-
fn handleCompareExchange(
158-
self: Pin<&mut MiriGenMCShim>,
159-
thread_id: i32,
160-
address: u64,
161-
size: u64,
162-
expected_value: GenmcScalar,
163-
new_value: GenmcScalar,
164-
old_value: GenmcScalar,
165-
success_load_ordering: MemOrdering,
166-
success_store_ordering: MemOrdering,
167-
fail_load_ordering: MemOrdering,
168-
can_fail_spuriously: bool,
169-
) -> CompareExchangeResult;
170139
fn handleStore(
171140
self: Pin<&mut MiriGenMCShim>,
172141
thread_id: i32,
@@ -175,7 +144,6 @@ mod ffi {
175144
value: GenmcScalar,
176145
old_value: GenmcScalar,
177146
memory_ordering: MemOrdering,
178-
store_event_type: StoreEventType,
179147
) -> StoreResult;
180148

181149
fn handleMalloc(

genmc-sys/src_cpp/MiriInterface.cpp

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ void MiriGenMCShim::handleThreadKill(ThreadId thread_id) {
213213
MemOrdering ord, GenmcScalar old_val) -> LoadResult
214214
{
215215
auto pos = incPos(thread_id);
216-
216+
217217
auto loc = SAddr(address);
218218
auto aSize = ASize(size);
219219
// `type` is only used for printing.
@@ -227,50 +227,9 @@ void MiriGenMCShim::handleThreadKill(ThreadId thread_id) {
227227
return result;
228228
}
229229

230-
[[nodiscard]] auto MiriGenMCShim::handleCompareExchange(
231-
ThreadId thread_id, uint64_t address, uint64_t size, GenmcScalar expected_value,
232-
GenmcScalar new_value, GenmcScalar old_val, MemOrdering success_load_ordering,
233-
MemOrdering success_store_ordering, MemOrdering fail_load_ordering,
234-
bool can_fail_spuriously) -> CompareExchangeResult
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 expectedVal = expected_value.toSVal();
244-
auto newVal = new_value.toSVal();
245-
246-
// FIXME(GenMC): properly handle failure memory ordering.
247-
248-
auto newLab = std::make_unique<CasReadLabel>(pos, success_load_ordering, loc, aSize, type,
249-
expectedVal, newVal);
250-
251-
auto oldValSetter = [this, old_val](SAddr loc)
252-
{ this->handleOldVal(loc, old_val); };
253-
auto result = GenMCDriver::handleLoad(std::move(newLab), oldValSetter);
254-
if (const auto *error = result.error.get())
255-
{
256-
return CompareExchangeResult::fromError(*error);
257-
}
258-
259-
auto oldVal = result.scalar.toSVal();
260-
if (oldVal != expectedVal)
261-
return CompareExchangeResult::failure(oldVal);
262-
263-
auto store_result = handleStore(thread_id, address, size, GenmcScalar(newVal), old_val,
264-
success_store_ordering, StoreEventType::CompareExchange);
265-
266-
if (store_result.is_error())
267-
return CompareExchangeResult::fromError(*store_result.error);
268-
return CompareExchangeResult::success(oldVal, store_result.isCoMaxWrite);
269-
}
270-
271230
[[nodiscard]] auto MiriGenMCShim::handleStore(ThreadId thread_id, uint64_t address, uint64_t size,
272231
GenmcScalar value, GenmcScalar old_val,
273-
MemOrdering ord, StoreEventType store_event_type)
232+
MemOrdering ord)
274233
-> StoreResult
275234
{
276235
auto pos = incPos(thread_id);
@@ -282,18 +241,7 @@ void MiriGenMCShim::handleThreadKill(ThreadId thread_id) {
282241

283242
auto val = value.toSVal();
284243

285-
std::unique_ptr<WriteLabel> wLab;
286-
switch (store_event_type)
287-
{
288-
case StoreEventType::Normal:
289-
wLab = std::make_unique<WriteLabel>(pos, ord, loc, aSize, type, val);
290-
break;
291-
case StoreEventType::CompareExchange:
292-
wLab = std::make_unique<CasWriteLabel>(pos, ord, loc, aSize, type, val);
293-
break;
294-
default:
295-
ERROR("Unsupported Store Event Type");
296-
}
244+
std::unique_ptr<WriteLabel> wLab = std::make_unique<WriteLabel>(pos, ord, loc, aSize, type, val);
297245

298246
auto oldValSetter = [this, old_val](SAddr loc)
299247
{

genmc-sys/src_cpp/MiriInterface.hpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,9 @@ struct MiriGenMCShim : private GenMCDriver
5555
///////////////////
5656
[[nodiscard]] LoadResult handleLoad(ThreadId thread_id, uint64_t address, uint64_t size,
5757
MemOrdering ord, GenmcScalar old_val);
58-
[[nodiscard]] CompareExchangeResult
59-
handleCompareExchange(ThreadId thread_id, uint64_t address, uint64_t size,
60-
GenmcScalar expected_value, GenmcScalar new_value,
61-
GenmcScalar old_val, MemOrdering success_load_ordering,
62-
MemOrdering success_store_ordering, MemOrdering fail_load_ordering,
63-
bool can_fail_spuriously);
6458
[[nodiscard]] StoreResult handleStore(ThreadId thread_id, uint64_t address, uint64_t size,
6559
GenmcScalar value, GenmcScalar old_val,
66-
MemOrdering ord, StoreEventType store_event_type);
60+
MemOrdering ord);
6761

6862
/**** Memory (de)allocation ****/
6963

src/concurrency/genmc/mapping.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use genmc_sys::MemOrdering;
22

3-
use crate::{AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd};
3+
use crate::{AtomicReadOrd, AtomicWriteOrd};
44

55
impl AtomicReadOrd {
66
pub(super) fn convert(self) -> MemOrdering {
@@ -21,18 +21,3 @@ impl AtomicWriteOrd {
2121
}
2222
}
2323
}
24-
25-
impl AtomicRwOrd {
26-
/// Split up the atomic success ordering of a read-modify-write operation into GenMC's representation.
27-
/// Note that both returned orderings are currently identical, because this is what GenMC expects.
28-
pub(super) fn to_genmc_memory_orderings(self) -> (MemOrdering, MemOrdering) {
29-
match self {
30-
AtomicRwOrd::Relaxed => (MemOrdering::Relaxed, MemOrdering::Relaxed),
31-
AtomicRwOrd::Acquire => (MemOrdering::Acquire, MemOrdering::Acquire),
32-
AtomicRwOrd::Release => (MemOrdering::Release, MemOrdering::Release),
33-
AtomicRwOrd::AcqRel => (MemOrdering::AcquireRelease, MemOrdering::AcquireRelease),
34-
AtomicRwOrd::SeqCst =>
35-
(MemOrdering::SequentiallyConsistent, MemOrdering::SequentiallyConsistent),
36-
}
37-
}
38-
}

src/concurrency/genmc/mod.rs

Lines changed: 14 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,15 @@ use std::sync::Arc;
33

44
use genmc_sys::{
55
ActionKind, GENMC_GLOBAL_ADDRESSES_MASK, GenmcScalar, GenmcThreadId, MemOrdering,
6-
MiriGenMCShim, StoreEventType, UniquePtr, createGenmcHandle,
6+
MiriGenMCShim, UniquePtr, createGenmcHandle,
77
};
88
use rustc_abi::{Align, Size};
99
use rustc_const_eval::interpret::{AllocId, InterpCx, InterpResult, interp_ok};
1010
use rustc_middle::{mir, throw_machine_stop, throw_ub_format, throw_unsup_format};
1111
use tracing::info;
1212

1313
use self::global_allocations::{EvalContextExtPriv as _, GlobalAllocationHandler};
14-
use self::helper::{
15-
genmc_scalar_to_scalar, option_scalar_to_genmc_scalar,
16-
scalar_to_genmc_scalar,
17-
};
14+
use self::helper::{genmc_scalar_to_scalar, option_scalar_to_genmc_scalar, scalar_to_genmc_scalar};
1815
use self::thread_info_manager::ThreadInfoManager;
1916
use crate::concurrency::genmc::helper::split_access;
2017
use crate::{
@@ -214,7 +211,7 @@ impl GenmcCtx {
214211
_old_value: Scalar,
215212
) -> InterpResult<'tcx, (Scalar, Option<Scalar>)> {
216213
assert!(!self.allow_data_races.get());
217-
throw_unsup_format!("FIXME(genmc): Add support for atomic min/max.")
214+
throw_unsup_format!("FIXME(genmc): Add support for atomic RMW.")
218215
}
219216

220217
/// Inform GenMC about an atomic `min` or `max` operation.
@@ -253,69 +250,19 @@ impl GenmcCtx {
253250

254251
pub(crate) fn atomic_compare_exchange<'tcx>(
255252
&self,
256-
ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
257-
address: Size,
258-
size: Size,
259-
expected_old_value: Scalar,
260-
new_value: Scalar,
261-
success: AtomicRwOrd,
262-
fail: AtomicReadOrd,
263-
can_fail_spuriously: bool,
253+
_ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
254+
_address: Size,
255+
_size: Size,
256+
_expected_old_value: Scalar,
257+
_new_value: Scalar,
258+
_success: AtomicRwOrd,
259+
_fail: AtomicReadOrd,
260+
_can_fail_spuriously: bool,
264261
// The value that we would get, if we were to do a non-atomic load here.
265-
old_value: Scalar,
262+
_old_value: Scalar,
266263
) -> InterpResult<'tcx, (Scalar, bool, bool)> {
267-
assert!(!self.allow_data_races.get()); // TODO GENMC: handle this properly
268-
269-
let machine = &ecx.machine;
270-
let (success_load_ordering, success_store_ordering) = success.to_genmc_memory_orderings();
271-
let fail_load_ordering = fail.convert();
272-
273-
info!(
274-
"GenMC: atomic_compare_exchange, address: {address:?}, size: {size:?} (expect: {expected_old_value:?}, new: {new_value:?}, old_value: {old_value:?}, {success:?}, {fail:?}), can fail spuriously: {can_fail_spuriously}"
275-
);
276-
info!(
277-
"GenMC: atomic_compare_exchange orderings: success: ({success_load_ordering:?}, {success_store_ordering:?}), failure load ordering: {fail_load_ordering:?}"
278-
);
279-
280-
let thread_infos = self.thread_infos.borrow();
281-
let curr_thread = machine.threads.active_thread();
282-
let genmc_tid = thread_infos.get_info(curr_thread).genmc_tid;
283-
284-
let genmc_address = address.bytes();
285-
let genmc_size = size.bytes();
286-
287-
let genmc_expected_value = scalar_to_genmc_scalar(ecx, expected_old_value)?;
288-
let genmc_new_value = scalar_to_genmc_scalar(ecx, new_value)?;
289-
let genmc_old_value = scalar_to_genmc_scalar(ecx, old_value)?;
290-
291-
let mut mc = self.handle.borrow_mut();
292-
let pinned_mc = mc.as_mut().unwrap();
293-
let cas_result = pinned_mc.handleCompareExchange(
294-
genmc_tid.0,
295-
genmc_address,
296-
genmc_size,
297-
genmc_expected_value,
298-
genmc_new_value,
299-
genmc_old_value,
300-
success_load_ordering,
301-
success_store_ordering,
302-
fail_load_ordering,
303-
can_fail_spuriously,
304-
);
305-
306-
if let Some(error) = cas_result.error.as_ref() {
307-
let msg = error.to_string_lossy().to_string();
308-
info!("GenMC: RMW operation returned an error: \"{msg}\"");
309-
throw_ub_format!("{}", msg); // TODO GENMC: proper error handling: find correct error here
310-
}
311-
312-
let return_scalar = genmc_scalar_to_scalar(ecx, cas_result.old_value, size)?;
313-
info!(
314-
"GenMC: atomic_compare_exchange: result: {cas_result:?}, returning scalar: {return_scalar:?}"
315-
);
316-
// The write can only be a co-maximal write if the CAS succeeded.
317-
assert!(cas_result.is_success || !cas_result.isCoMaxWrite);
318-
interp_ok((return_scalar, cas_result.isCoMaxWrite, cas_result.is_success))
264+
assert!(!self.allow_data_races.get());
265+
throw_unsup_format!("FIXME(genmc): Add support for atomic compare_exchange.")
319266
}
320267

321268
/// Inform GenMC about a non-atomic memory load
@@ -681,7 +628,6 @@ impl GenmcCtx {
681628
genmc_value,
682629
genmc_old_value,
683630
memory_ordering,
684-
StoreEventType::Normal,
685631
);
686632

687633
if let Some(error) = store_result.error.as_ref() {

tests/genmc/pass/atomics/cas_simple.rs

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

tests/genmc/pass/atomics/cas_simple.stderr

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

0 commit comments

Comments
 (0)