kernel: Add thread_unblock() and use it where possible
This commit is contained in:
parent
d70728f54d
commit
c8dd9f7780
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user