@@ -24,15 +24,17 @@ use crate::*;
24
24
pub enum SchedulingAction {
25
25
/// Execute step on the active thread.
26
26
ExecuteStep ,
27
- /// Execute a scheduler's callback.
28
- ExecuteCallback ,
27
+ /// Execute a timeout callback.
28
+ ExecuteTimeoutCallback ,
29
29
/// Execute destructors of the active thread.
30
30
ExecuteDtors ,
31
31
/// Stop the program.
32
32
Stop ,
33
33
}
34
34
35
- type EventCallback < ' mir , ' tcx > =
35
+ /// Timeout timeout_callbacks can be created by synchronization primitives to tell the
36
+ /// scheduler that they should be called once some period of time passes.
37
+ type TimeoutCallback < ' mir , ' tcx > =
36
38
Box < dyn FnOnce ( & mut InterpCx < ' mir , ' tcx , Evaluator < ' mir , ' tcx > > ) -> InterpResult < ' tcx > + ' tcx > ;
37
39
38
40
/// A thread identifier.
@@ -161,14 +163,14 @@ impl<'mir, 'tcx> Default for Thread<'mir, 'tcx> {
161
163
/// conditional variable with a timeout creates a callback that is called after
162
164
/// the specified time and unblocks the thread. If another thread signals on the
163
165
/// conditional variable, the signal handler deletes the callback.
164
- struct CallBackInfo < ' mir , ' tcx > {
166
+ struct TimeoutCallbackInfo < ' mir , ' tcx > {
165
167
/// The callback should be called no earlier than this time.
166
168
call_time : Instant ,
167
169
/// The called function.
168
- callback : EventCallback < ' mir , ' tcx > ,
170
+ callback : TimeoutCallback < ' mir , ' tcx > ,
169
171
}
170
172
171
- impl < ' mir , ' tcx > std:: fmt:: Debug for CallBackInfo < ' mir , ' tcx > {
173
+ impl < ' mir , ' tcx > std:: fmt:: Debug for TimeoutCallbackInfo < ' mir , ' tcx > {
172
174
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
173
175
write ! ( f, "CallBack({:?})" , self . call_time)
174
176
}
@@ -183,17 +185,16 @@ pub struct ThreadManager<'mir, 'tcx> {
183
185
///
184
186
/// Note that this vector also contains terminated threads.
185
187
threads : IndexVec < ThreadId , Thread < ' mir , ' tcx > > ,
186
- /// FIXME: make private.
188
+ /// This field is pub(crate) because the synchronization primitives
189
+ /// (`crate::sync`) need a way to access it.
187
190
pub ( crate ) sync : SynchronizationState ,
188
- /// A counter used to generate unique identifiers for blocksets.
189
- blockset_counter : u32 ,
190
191
/// A mapping from a thread-local static to an allocation id of a thread
191
192
/// specific allocation.
192
193
thread_local_alloc_ids : RefCell < FxHashMap < ( DefId , ThreadId ) , AllocId > > ,
193
194
/// A flag that indicates that we should change the active thread.
194
195
yield_active_thread : bool ,
195
196
/// Callbacks that are called once the specified time passes.
196
- callbacks : FxHashMap < ThreadId , CallBackInfo < ' mir , ' tcx > > ,
197
+ timeout_callbacks : FxHashMap < ThreadId , TimeoutCallbackInfo < ' mir , ' tcx > > ,
197
198
}
198
199
199
200
impl < ' mir , ' tcx > Default for ThreadManager < ' mir , ' tcx > {
@@ -208,10 +209,9 @@ impl<'mir, 'tcx> Default for ThreadManager<'mir, 'tcx> {
208
209
active_thread : ThreadId :: new ( 0 ) ,
209
210
threads : threads,
210
211
sync : SynchronizationState :: default ( ) ,
211
- blockset_counter : 0 ,
212
212
thread_local_alloc_ids : Default :: default ( ) ,
213
213
yield_active_thread : false ,
214
- callbacks : FxHashMap :: default ( ) ,
214
+ timeout_callbacks : FxHashMap :: default ( ) ,
215
215
}
216
216
}
217
217
}
@@ -359,28 +359,28 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
359
359
}
360
360
361
361
/// Register the given `callback` to be called once the `call_time` passes.
362
- fn register_callback (
362
+ fn register_timeout_callback (
363
363
& mut self ,
364
364
thread : ThreadId ,
365
365
call_time : Instant ,
366
- callback : EventCallback < ' mir , ' tcx > ,
366
+ callback : TimeoutCallback < ' mir , ' tcx > ,
367
367
) {
368
- self . callbacks
369
- . insert ( thread, CallBackInfo { call_time : call_time, callback : callback } )
368
+ self . timeout_callbacks
369
+ . insert ( thread, TimeoutCallbackInfo { call_time : call_time, callback : callback } )
370
370
. unwrap_none ( ) ;
371
371
}
372
372
373
373
/// Unregister the callback for the `thread`.
374
- fn unregister_callback_if_exists ( & mut self , thread : ThreadId ) {
375
- self . callbacks . remove ( & thread) ;
374
+ fn unregister_timeout_callback_if_exists ( & mut self , thread : ThreadId ) {
375
+ self . timeout_callbacks . remove ( & thread) ;
376
376
}
377
377
378
378
/// Get a callback that is ready to be called.
379
- fn get_callback ( & mut self ) -> Option < ( ThreadId , EventCallback < ' mir , ' tcx > ) > {
379
+ fn get_callback ( & mut self ) -> Option < ( ThreadId , TimeoutCallback < ' mir , ' tcx > ) > {
380
380
let current_time = Instant :: now ( ) ;
381
381
// We use a for loop here to make the scheduler more deterministic.
382
382
for thread in self . threads . indices ( ) {
383
- match self . callbacks . entry ( thread) {
383
+ match self . timeout_callbacks . entry ( thread) {
384
384
Entry :: Occupied ( entry) =>
385
385
if current_time >= entry. get ( ) . call_time {
386
386
return Some ( ( thread, entry. remove ( ) . callback ) ) ;
@@ -447,17 +447,17 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
447
447
if self . threads . iter ( ) . all ( |thread| thread. state == ThreadState :: Terminated ) {
448
448
unreachable ! ( ) ;
449
449
} else if let Some ( next_call_time) =
450
- self . callbacks . values ( ) . min_by_key ( |info| info. call_time )
450
+ self . timeout_callbacks . values ( ) . min_by_key ( |info| info. call_time )
451
451
{
452
452
// All threads are currently blocked, but we have unexecuted
453
- // callbacks , which may unblock some of the threads. Hence,
453
+ // timeout_callbacks , which may unblock some of the threads. Hence,
454
454
// sleep until the first callback.
455
455
if let Some ( sleep_time) =
456
456
next_call_time. call_time . checked_duration_since ( Instant :: now ( ) )
457
457
{
458
458
std:: thread:: sleep ( sleep_time) ;
459
459
}
460
- Ok ( SchedulingAction :: ExecuteCallback )
460
+ Ok ( SchedulingAction :: ExecuteTimeoutCallback )
461
461
} else {
462
462
throw_machine_stop ! ( TerminationInfo :: Deadlock ) ;
463
463
}
@@ -647,27 +647,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
647
647
}
648
648
649
649
#[ inline]
650
- fn register_callback (
650
+ fn register_timeout_callback (
651
651
& mut self ,
652
652
thread : ThreadId ,
653
653
call_time : Instant ,
654
- callback : EventCallback < ' mir , ' tcx > ,
654
+ callback : TimeoutCallback < ' mir , ' tcx > ,
655
655
) -> InterpResult < ' tcx > {
656
656
let this = self . eval_context_mut ( ) ;
657
- this. machine . threads . register_callback ( thread, call_time, callback) ;
657
+ this. machine . threads . register_timeout_callback ( thread, call_time, callback) ;
658
658
Ok ( ( ) )
659
659
}
660
660
661
661
#[ inline]
662
- fn unregister_callback_if_exists ( & mut self , thread : ThreadId ) -> InterpResult < ' tcx > {
662
+ fn unregister_timeout_callback_if_exists ( & mut self , thread : ThreadId ) -> InterpResult < ' tcx > {
663
663
let this = self . eval_context_mut ( ) ;
664
- this. machine . threads . unregister_callback_if_exists ( thread) ;
664
+ this. machine . threads . unregister_timeout_callback_if_exists ( thread) ;
665
665
Ok ( ( ) )
666
666
}
667
667
668
- /// Execute the callback on the callback's thread.
668
+ /// Execute a timeout callback on the callback's thread.
669
669
#[ inline]
670
- fn run_scheduler_callback ( & mut self ) -> InterpResult < ' tcx > {
670
+ fn run_timeout_callback ( & mut self ) -> InterpResult < ' tcx > {
671
671
let this = self . eval_context_mut ( ) ;
672
672
let ( thread, callback) = this. machine . threads . get_callback ( ) . expect ( "no callback found" ) ;
673
673
let old_thread = this. set_active_thread ( thread) ?;
0 commit comments