@@ -3,6 +3,7 @@ use std::time::Duration;
3
3
use rustc_target:: abi:: Size ;
4
4
5
5
use crate :: concurrency:: init_once:: InitOnceStatus ;
6
+ use crate :: concurrency:: sync:: { CondvarLock , RwLockMode } ;
6
7
use crate :: concurrency:: thread:: MachineCallback ;
7
8
use crate :: * ;
8
9
@@ -18,23 +19,24 @@ pub trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tc
18
19
& mut self ,
19
20
thread : ThreadId ,
20
21
lock : RwLockId ,
21
- shared : bool ,
22
+ mode : RwLockMode ,
22
23
) -> InterpResult < ' tcx > {
23
24
let this = self . eval_context_mut ( ) ;
24
25
this. unblock_thread ( thread) ;
25
26
26
- if shared {
27
- if this. rwlock_is_locked ( lock) {
28
- this. rwlock_enqueue_and_block_reader ( lock, thread) ;
29
- } else {
30
- this. rwlock_reader_lock ( lock, thread) ;
31
- }
32
- } else {
33
- if this. rwlock_is_write_locked ( lock) {
34
- this. rwlock_enqueue_and_block_writer ( lock, thread) ;
35
- } else {
36
- this. rwlock_writer_lock ( lock, thread) ;
37
- }
27
+ match mode {
28
+ RwLockMode :: Read =>
29
+ if this. rwlock_is_locked ( lock) {
30
+ this. rwlock_enqueue_and_block_reader ( lock, thread) ;
31
+ } else {
32
+ this. rwlock_reader_lock ( lock, thread) ;
33
+ } ,
34
+ RwLockMode :: Write =>
35
+ if this. rwlock_is_write_locked ( lock) {
36
+ this. rwlock_enqueue_and_block_writer ( lock, thread) ;
37
+ } else {
38
+ this. rwlock_writer_lock ( lock, thread) ;
39
+ } ,
38
40
}
39
41
40
42
Ok ( ( ) )
@@ -383,14 +385,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
383
385
} ;
384
386
385
387
let shared_mode = 0x1 ; // CONDITION_VARIABLE_LOCKMODE_SHARED is not in std
386
- let shared = flags == shared_mode;
388
+ let mode = if flags == 0 {
389
+ RwLockMode :: Write
390
+ } else if flags == shared_mode {
391
+ RwLockMode :: Read
392
+ } else {
393
+ throw_unsup_format ! ( "unsupported `Flags` {flags} in `SleepConditionVariableSRW`" ) ;
394
+ } ;
387
395
388
396
let active_thread = this. get_active_thread ( ) ;
389
397
390
- let was_locked = if shared {
391
- this. rwlock_reader_unlock ( lock_id, active_thread)
392
- } else {
393
- this. rwlock_writer_unlock ( lock_id, active_thread)
398
+ let was_locked = match mode {
399
+ RwLockMode :: Read => this. rwlock_reader_unlock ( lock_id, active_thread) ,
400
+ RwLockMode :: Write => this. rwlock_writer_unlock ( lock_id, active_thread) ,
394
401
} ;
395
402
396
403
if !was_locked {
@@ -400,27 +407,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
400
407
}
401
408
402
409
this. block_thread ( active_thread) ;
403
- this. condvar_wait ( condvar_id, active_thread, lock_id. to_u32 ( ) , shared ) ;
410
+ this. condvar_wait ( condvar_id, active_thread, CondvarLock :: RwLock { id : lock_id, mode } ) ;
404
411
405
412
if let Some ( timeout_time) = timeout_time {
406
413
struct Callback < ' tcx > {
407
414
thread : ThreadId ,
408
415
condvar_id : CondvarId ,
409
416
lock_id : RwLockId ,
410
- shared : bool ,
417
+ mode : RwLockMode ,
411
418
dest : PlaceTy < ' tcx , Provenance > ,
412
419
}
413
420
414
421
impl < ' tcx > VisitTags for Callback < ' tcx > {
415
422
fn visit_tags ( & self , visit : & mut dyn FnMut ( SbTag ) ) {
416
- let Callback { thread : _, condvar_id : _, lock_id : _, shared : _, dest } = self ;
423
+ let Callback { thread : _, condvar_id : _, lock_id : _, mode : _, dest } = self ;
417
424
dest. visit_tags ( visit) ;
418
425
}
419
426
}
420
427
421
428
impl < ' mir , ' tcx : ' mir > MachineCallback < ' mir , ' tcx > for Callback < ' tcx > {
422
429
fn call ( & self , this : & mut MiriInterpCx < ' mir , ' tcx > ) -> InterpResult < ' tcx > {
423
- this. reacquire_cond_lock ( self . thread , self . lock_id , self . shared ) ?;
430
+ this. reacquire_cond_lock ( self . thread , self . lock_id , self . mode ) ?;
424
431
425
432
this. condvar_remove_waiter ( self . condvar_id , self . thread ) ;
426
433
@@ -438,7 +445,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
438
445
thread : active_thread,
439
446
condvar_id,
440
447
lock_id,
441
- shared ,
448
+ mode ,
442
449
dest : dest. clone ( ) ,
443
450
} ) ,
444
451
) ;
@@ -451,9 +458,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
451
458
let this = self . eval_context_mut ( ) ;
452
459
let condvar_id = this. condvar_get_or_create_id ( condvar_op, CONDVAR_ID_OFFSET ) ?;
453
460
454
- if let Some ( ( thread, lock, shared) ) = this. condvar_signal ( condvar_id) {
455
- this. reacquire_cond_lock ( thread, RwLockId :: from_u32 ( lock) , shared) ?;
456
- this. unregister_timeout_callback_if_exists ( thread) ;
461
+ if let Some ( ( thread, lock) ) = this. condvar_signal ( condvar_id) {
462
+ if let CondvarLock :: RwLock { id, mode } = lock {
463
+ this. reacquire_cond_lock ( thread, id, mode) ?;
464
+ this. unregister_timeout_callback_if_exists ( thread) ;
465
+ } else {
466
+ panic ! ( "mutexes should not exist on windows" ) ;
467
+ }
457
468
}
458
469
459
470
Ok ( ( ) )
@@ -466,9 +477,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
466
477
let this = self . eval_context_mut ( ) ;
467
478
let condvar_id = this. condvar_get_or_create_id ( condvar_op, CONDVAR_ID_OFFSET ) ?;
468
479
469
- while let Some ( ( thread, lock, shared) ) = this. condvar_signal ( condvar_id) {
470
- this. reacquire_cond_lock ( thread, RwLockId :: from_u32 ( lock) , shared) ?;
471
- this. unregister_timeout_callback_if_exists ( thread) ;
480
+ while let Some ( ( thread, lock) ) = this. condvar_signal ( condvar_id) {
481
+ if let CondvarLock :: RwLock { id, mode } = lock {
482
+ this. reacquire_cond_lock ( thread, id, mode) ?;
483
+ this. unregister_timeout_callback_if_exists ( thread) ;
484
+ } else {
485
+ panic ! ( "mutexes should not exist on windows" ) ;
486
+ }
472
487
}
473
488
474
489
Ok ( ( ) )
0 commit comments