Skip to content

Commit 6792457

Browse files
Vytautas Astrauskasvakaras
authored andcommitted
Implement support for synchronization primitives.
1 parent 726373f commit 6792457

File tree

18 files changed

+1276
-272
lines changed

18 files changed

+1276
-272
lines changed

src/eval.rs

Lines changed: 6 additions & 0 deletions
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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ mod operator;
3131
mod range_map;
3232
mod shims;
3333
mod stacked_borrows;
34+
mod sync;
3435
mod thread;
3536

3637
// Make all those symbols available in the same place as our own.
@@ -45,7 +46,7 @@ pub use crate::shims::fs::{DirHandler, EvalContextExt as FileEvalContextExt, Fil
4546
pub use crate::shims::intrinsics::EvalContextExt as IntrinsicsEvalContextExt;
4647
pub use crate::shims::os_str::EvalContextExt as OsStrEvalContextExt;
4748
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as PanicEvalContextExt};
48-
pub use crate::shims::sync::{EvalContextExt as SyncEvalContextExt};
49+
pub use crate::shims::sync::{EvalContextExt as SyncShimsEvalContextExt};
4950
pub use crate::shims::thread::EvalContextExt as ThreadShimsEvalContextExt;
5051
pub use crate::shims::time::EvalContextExt as TimeEvalContextExt;
5152
pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData};
@@ -70,6 +71,9 @@ pub use crate::stacked_borrows::{
7071
pub use crate::thread::{
7172
EvalContextExt as ThreadsEvalContextExt, SchedulingAction, ThreadId, ThreadManager, ThreadState,
7273
};
74+
pub use crate::sync::{
75+
EvalContextExt as SyncEvalContextExt, CondvarId, MutexId, RwLockId
76+
};
7377

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

src/machine.rs

Lines changed: 7 additions & 1 deletion
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

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,45 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
330330
let result = this.pthread_rwlock_destroy(rwlock)?;
331331
this.write_scalar(Scalar::from_i32(result), dest)?;
332332
}
333+
"pthread_condattr_init" => {
334+
let result = this.pthread_condattr_init(args[0])?;
335+
this.write_scalar(Scalar::from_i32(result), dest)?;
336+
}
337+
"pthread_condattr_setclock" => {
338+
let result = this.pthread_condattr_setclock(args[0], args[1])?;
339+
this.write_scalar(Scalar::from_i32(result), dest)?;
340+
}
341+
"pthread_condattr_getclock" => {
342+
let result = this.pthread_condattr_getclock(args[0], args[1])?;
343+
this.write_scalar(Scalar::from_i32(result), dest)?;
344+
}
345+
"pthread_condattr_destroy" => {
346+
let result = this.pthread_condattr_destroy(args[0])?;
347+
this.write_scalar(Scalar::from_i32(result), dest)?;
348+
}
349+
"pthread_cond_init" => {
350+
let result = this.pthread_cond_init(args[0], args[1])?;
351+
this.write_scalar(Scalar::from_i32(result), dest)?;
352+
}
353+
"pthread_cond_signal" => {
354+
let result = this.pthread_cond_signal(args[0])?;
355+
this.write_scalar(Scalar::from_i32(result), dest)?;
356+
}
357+
"pthread_cond_broadcast" => {
358+
let result = this.pthread_cond_broadcast(args[0])?;
359+
this.write_scalar(Scalar::from_i32(result), dest)?;
360+
}
361+
"pthread_cond_wait" => {
362+
let result = this.pthread_cond_wait(args[0], args[1])?;
363+
this.write_scalar(Scalar::from_i32(result), dest)?;
364+
}
365+
"pthread_cond_timedwait" => {
366+
this.pthread_cond_timedwait(args[0], args[1], args[2], dest)?;
367+
}
368+
"pthread_cond_destroy" => {
369+
let result = this.pthread_cond_destroy(args[0])?;
370+
this.write_scalar(Scalar::from_i32(result), dest)?;
371+
}
333372

334373
// Threading
335374
"pthread_create" => {
@@ -391,16 +430,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
391430

392431
| "pthread_attr_init"
393432
| "pthread_attr_destroy"
394-
| "pthread_condattr_init"
395-
| "pthread_condattr_destroy"
396-
| "pthread_cond_destroy"
397-
if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
398-
let &[_] = check_arg_count(args)?;
399-
this.write_null(dest)?;
400-
}
401-
| "pthread_cond_init"
402433
| "pthread_attr_setstacksize"
403-
| "pthread_condattr_setclock"
404434
if this.frame().instance.to_string().starts_with("std::sys::unix::") => {
405435
let &[_, _] = check_arg_count(args)?;
406436
this.write_null(dest)?;

0 commit comments

Comments
 (0)