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