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) {
// 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)
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 {
}
#[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");
}
#[inline]
- /// Take a thread out of the queue waiting for the lock.
- fn mutex_dequeue_and_unblock(&mut self, id: MutexId) -> Option<ThreadId> {
+ /// 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
}
}
#[inline]
/// Take a reader out the queue waiting for the lock.
- fn rwlock_dequeue_and_unblock_reader(&mut self, id: RwLockId) -> Option<ThreadId> {
+ /// 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
}
}
#[inline]
/// Take the writer out the queue waiting for the lock.
- fn rwlock_dequeue_and_unblock_writer(&mut self, id: RwLockId) -> Option<ThreadId> {
+ /// 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
}
}