Skip to content

Commit dc761b9

Browse files
author
Vytautas Astrauskas
committed
Implement support for synchronization primitives.
1 parent 6c4be68 commit dc761b9

18 files changed

+1273
-265
lines changed

src/eval.rs

+6
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,12 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) ->
210210
SchedulingAction::ExecuteStep => {
211211
assert!(ecx.step()?, "a terminated thread was scheduled for execution");
212212
}
213+
SchedulingAction::ExecuteCallback => {
214+
assert!(ecx.machine.communicate,
215+
"scheduler callbacks require disabled isolation, but the code \
216+
that created the callback did not check it");
217+
ecx.run_scheduler_callback()?;
218+
}
213219
SchedulingAction::ExecuteDtors => {
214220
// This will either enable the thread again (so we go back
215221
// to `ExecuteStep`), or determine that this thread is done

src/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ mod operator;
2727
mod range_map;
2828
mod shims;
2929
mod stacked_borrows;
30+
mod sync;
3031
mod thread;
3132

3233
// Make all those symbols available in the same place as our own.
@@ -41,7 +42,7 @@ pub use crate::shims::fs::{DirHandler, EvalContextExt as FileEvalContextExt, Fil
4142
pub use crate::shims::intrinsics::EvalContextExt as IntrinsicsEvalContextExt;
4243
pub use crate::shims::os_str::EvalContextExt as OsStrEvalContextExt;
4344
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as PanicEvalContextExt};
44-
pub use crate::shims::sync::{EvalContextExt as SyncEvalContextExt};
45+
pub use crate::shims::sync::{EvalContextExt as SyncShimsEvalContextExt};
4546
pub use crate::shims::thread::EvalContextExt as ThreadShimsEvalContextExt;
4647
pub use crate::shims::time::EvalContextExt as TimeEvalContextExt;
4748
pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData};
@@ -66,6 +67,9 @@ pub use crate::stacked_borrows::{
6667
pub use crate::thread::{
6768
EvalContextExt as ThreadsEvalContextExt, SchedulingAction, ThreadId, ThreadManager, ThreadState,
6869
};
70+
pub use crate::sync::{
71+
EvalContextExt as SyncEvalContextExt, CondvarId, MutexId, RwLockId
72+
};
6973

7074
/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
7175
/// set per default, for maximal validation power.

src/machine.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::borrow::Cow;
55
use std::cell::RefCell;
66
use std::num::NonZeroU64;
77
use std::rc::Rc;
8-
use std::time::Instant;
8+
use std::time::{Instant, SystemTime};
99
use std::fmt;
1010

1111
use log::trace;
@@ -251,6 +251,11 @@ pub struct Evaluator<'mir, 'tcx> {
251251
/// The "time anchor" for this machine's monotone clock (for `Instant` simulation).
252252
pub(crate) time_anchor: Instant,
253253

254+
/// The approximate system time when "time anchor" was created. This is used
255+
/// for converting system time to monotone time so that we can simplify the
256+
/// thread scheduler to deal only with a single representation of time.
257+
pub(crate) time_anchor_timestamp: SystemTime,
258+
254259
/// The set of threads.
255260
pub(crate) threads: ThreadManager<'mir, 'tcx>,
256261

@@ -281,6 +286,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
281286
dir_handler: Default::default(),
282287
panic_payload: None,
283288
time_anchor: Instant::now(),
289+
time_anchor_timestamp: SystemTime::now(),
284290
layouts,
285291
threads: ThreadManager::default(),
286292
}

src/shims/foreign_items/posix.rs

+40-6
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,45 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
292292
let result = this.pthread_rwlock_destroy(args[0])?;
293293
this.write_scalar(Scalar::from_i32(result), dest)?;
294294
}
295+
"pthread_condattr_init" => {
296+
let result = this.pthread_condattr_init(args[0])?;
297+
this.write_scalar(Scalar::from_i32(result), dest)?;
298+
}
299+
"pthread_condattr_setclock" => {
300+
let result = this.pthread_condattr_setclock(args[0], args[1])?;
301+
this.write_scalar(Scalar::from_i32(result), dest)?;
302+
}
303+
"pthread_condattr_getclock" => {
304+
let result = this.pthread_condattr_getclock(args[0], args[1])?;
305+
this.write_scalar(Scalar::from_i32(result), dest)?;
306+
}
307+
"pthread_condattr_destroy" => {
308+
let result = this.pthread_condattr_destroy(args[0])?;
309+
this.write_scalar(Scalar::from_i32(result), dest)?;
310+
}
311+
"pthread_cond_init" => {
312+
let result = this.pthread_cond_init(args[0], args[1])?;
313+
this.write_scalar(Scalar::from_i32(result), dest)?;
314+
}
315+
"pthread_cond_signal" => {
316+
let result = this.pthread_cond_signal(args[0])?;
317+
this.write_scalar(Scalar::from_i32(result), dest)?;
318+
}
319+
"pthread_cond_broadcast" => {
320+
let result = this.pthread_cond_broadcast(args[0])?;
321+
this.write_scalar(Scalar::from_i32(result), dest)?;
322+
}
323+
"pthread_cond_wait" => {
324+
let result = this.pthread_cond_wait(args[0], args[1])?;
325+
this.write_scalar(Scalar::from_i32(result), dest)?;
326+
}
327+
"pthread_cond_timedwait" => {
328+
this.pthread_cond_timedwait(args[0], args[1], args[2], dest)?;
329+
}
330+
"pthread_cond_destroy" => {
331+
let result = this.pthread_cond_destroy(args[0])?;
332+
this.write_scalar(Scalar::from_i32(result), dest)?;
333+
}
295334

296335
// Threading
297336
"pthread_create" => {
@@ -340,12 +379,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
340379
// These shims are enabled only when the caller is in the standard library.
341380
| "pthread_attr_init"
342381
| "pthread_attr_destroy"
343-
| "pthread_attr_setstacksize"
344-
| "pthread_condattr_init"
345-
| "pthread_condattr_setclock"
346-
| "pthread_cond_init"
347-
| "pthread_condattr_destroy"
348-
| "pthread_cond_destroy" if this.frame().instance.to_string().starts_with("std::sys::unix::")
382+
| "pthread_attr_setstacksize" if this.frame().instance.to_string().starts_with("std::sys::unix::")
349383
=> {
350384
this.write_null(dest)?;
351385
}

0 commit comments

Comments
 (0)