From a80821e046c75878f4b63eac35c642b48c5825c3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 30 May 2020 22:35:58 +0200 Subject: [PATCH] also combine re-locking into the dequeue-and-unblock operation --- src/shims/sync.rs | 13 +++++-------- src/sync.rs | 32 ++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/shims/sync.rs b/src/shims/sync.rs index 01c7b4a1eb4..2669776db5b 100644 --- a/src/shims/sync.rs +++ b/src/shims/sync.rs @@ -606,9 +606,7 @@ fn pthread_rwlock_unlock(&mut self, rwlock_op: OpTy<'tcx, Tag>) -> InterpResult< if this.rwlock_is_locked(id) { // No more readers owning the lock. Give it to a writer if there // is any. - if let Some(writer) = this.rwlock_dequeue_and_unblock_writer(id) { - this.rwlock_writer_lock(id, writer); - } + this.rwlock_dequeue_and_lock_writer(id); } Ok(0) } else if Some(active_thread) == this.rwlock_writer_unlock(id) { @@ -617,13 +615,12 @@ fn pthread_rwlock_unlock(&mut self, rwlock_op: OpTy<'tcx, Tag>) -> InterpResult< // We are prioritizing writers here against the readers. As a // result, not only readers can starve writers, but also writers can // starve readers. - if let Some(writer) = this.rwlock_dequeue_and_unblock_writer(id) { - // Give the lock to another writer. - this.rwlock_writer_lock(id, writer); + if this.rwlock_dequeue_and_lock_writer(id) { + // Someone got the write lock, nice. } else { // Give the lock to all readers. - while let Some(reader) = this.rwlock_dequeue_and_unblock_reader(id) { - this.rwlock_reader_lock(id, reader); + while this.rwlock_dequeue_and_lock_reader(id) { + // Rinse and repeat. } } Ok(0) diff --git a/src/sync.rs b/src/sync.rs index 8418bd42951..723815dbf22 100644 --- a/src/sync.rs +++ b/src/sync.rs @@ -170,9 +170,7 @@ fn mutex_unlock( mutex.owner = None; // The mutex is completely unlocked. Try transfering ownership // to another thread. - if let Some(new_owner) = this.mutex_dequeue_and_unblock(id) { - this.mutex_lock(id, new_owner); - } + this.mutex_dequeue_and_lock(id); } Ok(Some(old_lock_count)) } else { @@ -182,7 +180,7 @@ fn mutex_unlock( } #[inline] - /// Put the thread into the queue waiting for the lock. + /// Put the thread into the queue waiting for the mutex. fn mutex_enqueue_and_block(&mut self, id: MutexId, thread: ThreadId) { let this = self.eval_context_mut(); assert!(this.mutex_is_locked(id), "queing on unlocked mutex"); @@ -191,14 +189,16 @@ fn mutex_enqueue_and_block(&mut self, id: MutexId, thread: ThreadId) { } #[inline] - /// Take a thread out of the queue waiting for the lock. - fn mutex_dequeue_and_unblock(&mut self, id: MutexId) -> Option { + /// Take a thread out of the queue waiting for the mutex, and lock + /// the mutex for it. Returns `true` if some thread has the mutex now. + fn mutex_dequeue_and_lock(&mut self, id: MutexId) -> bool { let this = self.eval_context_mut(); if let Some(thread) = this.machine.threads.sync.mutexes[id].queue.pop_front() { this.unblock_thread(thread); - Some(thread) + this.mutex_lock(id, thread); + true } else { - None + false } } @@ -266,13 +266,15 @@ fn rwlock_enqueue_and_block_reader( #[inline] /// Take a reader out the queue waiting for the lock. - fn rwlock_dequeue_and_unblock_reader(&mut self, id: RwLockId) -> Option { + /// Returns `true` if some thread got the rwlock. + fn rwlock_dequeue_and_lock_reader(&mut self, id: RwLockId) -> bool { let this = self.eval_context_mut(); if let Some(reader) = this.machine.threads.sync.rwlocks[id].reader_queue.pop_front() { this.unblock_thread(reader); - Some(reader) + this.rwlock_reader_lock(id, reader); + true } else { - None + false } } @@ -306,13 +308,15 @@ fn rwlock_enqueue_and_block_writer( #[inline] /// Take the writer out the queue waiting for the lock. - fn rwlock_dequeue_and_unblock_writer(&mut self, id: RwLockId) -> Option { + /// Returns `true` if some thread got the rwlock. + fn rwlock_dequeue_and_lock_writer(&mut self, id: RwLockId) -> bool { let this = self.eval_context_mut(); if let Some(writer) = this.machine.threads.sync.rwlocks[id].writer_queue.pop_front() { this.unblock_thread(writer); - Some(writer) + this.rwlock_writer_lock(id, writer); + true } else { - None + false } } -- 2.44.0