From c8dd9f7780c426e592a3ccb231e6bfab51f15eb9 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Wed, 30 Oct 2013 03:58:36 +0100 Subject: [PATCH] kernel: Add thread_unblock() and use it where possible --- headers/private/kernel/thread.h | 1 + src/system/kernel/debug/system_profiler.cpp | 3 +-- src/system/kernel/fs/Vnode.cpp | 3 +-- src/system/kernel/fs/fifo.cpp | 3 +-- src/system/kernel/locks/lock.cpp | 18 +++++------------- src/system/kernel/posix/xsi_message_queue.cpp | 12 ++++-------- src/system/kernel/posix/xsi_semaphore.cpp | 11 ++++------- src/system/kernel/sem.cpp | 4 +--- src/system/kernel/thread.cpp | 13 +++++++++++++ src/system/kernel/vm/VMCache.cpp | 3 +-- src/system/kernel/vm/vm_page.cpp | 3 +-- 11 files changed, 33 insertions(+), 41 deletions(-) diff --git a/headers/private/kernel/thread.h b/headers/private/kernel/thread.h index 469e339290..ecb6245dbd 100644 --- a/headers/private/kernel/thread.h +++ b/headers/private/kernel/thread.h @@ -132,6 +132,7 @@ status_t thread_block(); status_t thread_block_with_timeout(uint32 timeoutFlags, bigtime_t timeout); status_t thread_block_with_timeout_locked(uint32 timeoutFlags, bigtime_t timeout); +void thread_unblock(Thread* thread, status_t status); // used in syscalls.c status_t _user_set_thread_priority(thread_id thread, int32 newPriority); diff --git a/src/system/kernel/debug/system_profiler.cpp b/src/system/kernel/debug/system_profiler.cpp index c2d75492cc..d0d3e22016 100644 --- a/src/system/kernel/debug/system_profiler.cpp +++ b/src/system/kernel/debug/system_profiler.cpp @@ -298,8 +298,7 @@ SystemProfiler::~SystemProfiler() // inactive. InterruptsSpinLocker locker(fLock); if (fWaitingProfilerThread != NULL) { - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - thread_unblock_locked(fWaitingProfilerThread, B_OK); + thread_unblock(fWaitingProfilerThread, B_OK); fWaitingProfilerThread = NULL; } fProfilingActive = false; diff --git a/src/system/kernel/fs/Vnode.cpp b/src/system/kernel/fs/Vnode.cpp index 890e29bf9f..cc71aae551 100644 --- a/src/system/kernel/fs/Vnode.cpp +++ b/src/system/kernel/fs/Vnode.cpp @@ -88,6 +88,5 @@ vnode::_WakeUpLocker() atomic_and(&fFlags, ~kFlagsWaitingLocker); // and wake it up - InterruptsSpinLocker threadLocker(gSchedulerLock); - thread_unblock_locked(waiter->thread, B_OK); + thread_unblock(waiter->thread, B_OK); } diff --git a/src/system/kernel/fs/fifo.cpp b/src/system/kernel/fs/fifo.cpp index 9c771ff816..fe2ffb6959 100644 --- a/src/system/kernel/fs/fifo.cpp +++ b/src/system/kernel/fs/fifo.cpp @@ -100,8 +100,7 @@ public: TRACE("ReadRequest %p::Notify(), fNotified %d\n", this, fNotified); if (!fNotified) { - SpinLocker schedulerLocker(gSchedulerLock); - thread_unblock_locked(fThread, status); + thread_unblock(fThread, status); fNotified = true; } } diff --git a/src/system/kernel/locks/lock.cpp b/src/system/kernel/locks/lock.cpp index 7f4094f953..6b3ac5ff70 100644 --- a/src/system/kernel/locks/lock.cpp +++ b/src/system/kernel/locks/lock.cpp @@ -197,9 +197,7 @@ rw_lock_unblock(rw_lock* lock) lock->holder = waiter->thread->id; // unblock thread - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - thread_unblock_locked(waiter->thread, B_OK); - schedulerLocker.Unlock(); + thread_unblock(waiter->thread, B_OK); waiter->thread = NULL; return RW_LOCK_WRITER_COUNT_BASE; @@ -216,9 +214,7 @@ rw_lock_unblock(rw_lock* lock) readerCount++; // unblock thread - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - thread_unblock_locked(waiter->thread, B_OK); - schedulerLocker.Unlock(); + thread_unblock(waiter->thread, B_OK); waiter->thread = NULL; } while ((waiter = lock->waiters) != NULL && !waiter->writer); @@ -293,8 +289,7 @@ rw_lock_destroy(rw_lock* lock) lock->waiters = waiter->next; // unblock thread - InterruptsSpinLocker _(gSchedulerLock); - thread_unblock_locked(waiter->thread, B_ERROR); + thread_unblock(waiter->thread, B_ERROR); } lock->name = NULL; @@ -637,8 +632,7 @@ mutex_destroy(mutex* lock) lock->waiters = waiter->next; // unblock thread - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - thread_unblock_locked(waiter->thread, B_ERROR); + thread_unblock(waiter->thread, B_ERROR); } lock->name = NULL; @@ -783,9 +777,7 @@ _mutex_unlock(mutex* lock) lock->waiters->last = waiter->last; // unblock thread - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - thread_unblock_locked(waiter->thread, B_OK); - schedulerLocker.Unlock(); + thread_unblock(waiter->thread, B_OK); #if KDEBUG // Already set the holder to the unblocked thread. Besides that this diff --git a/src/system/kernel/posix/xsi_message_queue.cpp b/src/system/kernel/posix/xsi_message_queue.cpp index 278c241f67..f0141b1e93 100644 --- a/src/system/kernel/posix/xsi_message_queue.cpp +++ b/src/system/kernel/posix/xsi_message_queue.cpp @@ -246,8 +246,6 @@ public: void WakeUpThread(bool waitForMessage) { - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - if (waitForMessage) { // Wake up all waiting thread for a message // TODO: this can cause starvation for any @@ -255,14 +253,14 @@ public: while (queued_thread *entry = fWaitingToReceive.RemoveHead()) { entry->queued = false; fThreadsWaitingToReceive--; - thread_unblock_locked(entry->thread, 0); + thread_unblock(entry->thread, 0); } } else { // Wake up only one thread waiting to send if (queued_thread *entry = fWaitingToSend.RemoveHead()) { entry->queued = false; fThreadsWaitingToSend--; - thread_unblock_locked(entry->thread, 0); + thread_unblock(entry->thread, 0); } } } @@ -400,15 +398,13 @@ XsiMessageQueue::~XsiMessageQueue() // Wake up any threads still waiting if (fThreadsWaitingToSend || fThreadsWaitingToReceive) { - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - while (queued_thread *entry = fWaitingToReceive.RemoveHead()) { entry->queued = false; - thread_unblock_locked(entry->thread, EIDRM); + thread_unblock(entry->thread, EIDRM); } while (queued_thread *entry = fWaitingToSend.RemoveHead()) { entry->queued = false; - thread_unblock_locked(entry->thread, EIDRM); + thread_unblock(entry->thread, EIDRM); } } diff --git a/src/system/kernel/posix/xsi_semaphore.cpp b/src/system/kernel/posix/xsi_semaphore.cpp index 212ee1b592..4c76c799cf 100644 --- a/src/system/kernel/posix/xsi_semaphore.cpp +++ b/src/system/kernel/posix/xsi_semaphore.cpp @@ -101,15 +101,13 @@ public: { // For some reason the semaphore is getting destroyed. // Wake up any remaing awaiting threads - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - while (queued_thread *entry = fWaitingToIncreaseQueue.RemoveHead()) { entry->queued = false; - thread_unblock_locked(entry->thread, EIDRM); + thread_unblock(entry->thread, EIDRM); } while (queued_thread *entry = fWaitingToBeZeroQueue.RemoveHead()) { entry->queued = false; - thread_unblock_locked(entry->thread, EIDRM); + thread_unblock(entry->thread, EIDRM); } // No need to remove any sem_undo request still // hanging. When the process exit and doesn't found @@ -218,20 +216,19 @@ public: void WakeUpThread(bool waitingForZero) { - InterruptsSpinLocker schedulerLocker(gSchedulerLock); if (waitingForZero) { // Wake up all threads waiting on zero while (queued_thread *entry = fWaitingToBeZeroQueue.RemoveHead()) { entry->queued = false; fThreadsWaitingToBeZero--; - thread_unblock_locked(entry->thread, 0); + thread_unblock(entry->thread, 0); } } else { // Wake up all threads even though they might go back to sleep while (queued_thread *entry = fWaitingToIncreaseQueue.RemoveHead()) { entry->queued = false; fThreadsWaitingToIncrease--; - thread_unblock_locked(entry->thread, 0); + thread_unblock(entry->thread, 0); } } } diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp index 0b761c2724..7f01069291 100644 --- a/src/system/kernel/sem.cpp +++ b/src/system/kernel/sem.cpp @@ -330,12 +330,10 @@ uninit_sem_locked(struct sem_entry& sem, char** _name) sem.u.used.select_infos = NULL; // free any threads waiting for this semaphore - SpinLocker schedulerLocker(gSchedulerLock); while (queued_thread* entry = sem.queue.RemoveHead()) { entry->queued = false; - thread_unblock_locked(entry->thread, B_BAD_SEM_ID); + thread_unblock(entry->thread, B_BAD_SEM_ID); } - schedulerLocker.Unlock(); int32 id = sem.id; sem.id = -1; diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 210492d15e..20bf8f79ad 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -2889,6 +2889,19 @@ thread_block_with_timeout_locked(uint32 timeoutFlags, bigtime_t timeout) } +/*! Unblocks a thread. + + Acquires the scheduler lock and calls thread_unblock_locked(). + See there for more information. +*/ +void +thread_unblock(Thread* thread, status_t status) +{ + InterruptsSpinLocker _(gSchedulerLock); + thread_unblock_locked(thread, status); +} + + /*! Unblocks a userland-blocked thread. The caller must not hold any locks. */ diff --git a/src/system/kernel/vm/VMCache.cpp b/src/system/kernel/vm/VMCache.cpp index d9efe304bd..a1d16677bf 100644 --- a/src/system/kernel/vm/VMCache.cpp +++ b/src/system/kernel/vm/VMCache.cpp @@ -1383,8 +1383,7 @@ VMCache::_NotifyPageEvents(vm_page* page, uint32 events) if (waiter->page == page && (waiter->events & events) != 0) { // remove from list and unblock *it = waiter->next; - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - thread_unblock_locked(waiter->thread, B_OK); + thread_unblock(waiter->thread, B_OK); } else it = &waiter->next; } diff --git a/src/system/kernel/vm/vm_page.cpp b/src/system/kernel/vm/vm_page.cpp index 35d1a8bfee..dd9b9b3d48 100644 --- a/src/system/kernel/vm/vm_page.cpp +++ b/src/system/kernel/vm/vm_page.cpp @@ -1447,8 +1447,7 @@ wake_up_page_reservation_waiters() sPageReservationWaiters.Remove(waiter); - InterruptsSpinLocker schedulerLocker(gSchedulerLock); - thread_unblock_locked(waiter->thread, B_OK); + thread_unblock(waiter->thread, B_OK); } }