@@ -80,7 +80,8 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
8080// bytes 8-11: when count > 0, id of the owner thread as a u32
8181// bytes 12-15 or 16-19 (depending on platform): mutex kind, as an i32
8282// (the kind has to be at its offset for compatibility with static initializer macros)
83- // bytes 20-23: when count > 0, id of the blockset in which the blocked threads are waiting.
83+ // bytes 20-23: when count > 0, id of the blockset in which the blocked threads
84+ // are waiting or 0 if blockset is not yet assigned.
8485
8586const PTHREAD_MUTEX_T_MIN_SIZE : u64 = 24 ;
8687
@@ -170,9 +171,9 @@ fn mutex_get_or_create_blockset<'mir, 'tcx: 'mir>(
170171// bytes 4-7: reader count, as a u32
171172// bytes 8-11: writer count, as a u32
172173// bytes 12-15: when writer or reader count > 0, id of the blockset in which the
173- // blocked writers are waiting.
174+ // blocked writers are waiting or 0 if blockset is not yet assigned .
174175// bytes 16-20: when writer count > 0, id of the blockset in which the blocked
175- // readers are waiting.
176+ // readers are waiting or 0 if blockset is not yet assigned .
176177
177178const PTHREAD_RWLOCK_T_MIN_SIZE : u64 = 20 ;
178179
@@ -342,8 +343,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
342343 Ok ( 0 )
343344 } else {
344345 // The mutex is locked. Let's check by whom.
345- let owner_thread: ThreadId =
346- mutex_get_owner ( this, mutex_op) ?. not_undef ( ) ?. to_u32 ( ) ?. into ( ) ;
346+ let owner_thread: ThreadId = mutex_get_owner ( this, mutex_op) ?. to_u32 ( ) ?. into ( ) ;
347347 if owner_thread != active_thread {
348348 // Block the active thread.
349349 let blockset = mutex_get_or_create_blockset ( this, mutex_op) ?;
@@ -425,6 +425,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
425425 mutex_set_owner ( this, mutex_op, new_owner. to_u32_scalar ( ) ) ?;
426426 } else {
427427 // No thread is waiting on this mutex.
428+ mutex_set_owner ( this, mutex_op, Scalar :: from_u32 ( 0 ) ) ?;
428429 mutex_set_locked_count ( this, mutex_op, Scalar :: from_u32 ( 0 ) ) ?;
429430 }
430431 Ok ( 0 )
@@ -550,10 +551,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
550551 Ok ( 0 )
551552 } else if writers != 0 {
552553 let reader_blockset = rwlock_get_or_create_reader_blockset ( this, rwlock_op) ?;
553- rwlock_set_writers ( this, rwlock_op, Scalar :: from_u32 ( 0 ) ) ?;
554+ // We are prioritizing writers here against the readers. As a
555+ // result, not only readers can starve writers, but also writers can
556+ // starve readers.
554557 if let Some ( _writer) = this. unblock_some_thread ( writer_blockset) ? {
555558 rwlock_set_writers ( this, rwlock_op, Scalar :: from_u32 ( 1 ) ) ?;
556559 } else {
560+ rwlock_set_writers ( this, rwlock_op, Scalar :: from_u32 ( 0 ) ) ?;
557561 let mut readers = 0 ;
558562 while let Some ( _reader) = this. unblock_some_thread ( reader_blockset) ? {
559563 readers += 1 ;
0 commit comments