From 537d0818170525281422c4a5c31ef7ae887eb377 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 4 Sep 2008 00:32:12 +0000 Subject: [PATCH] release_sem_etc(): Reschedule only when a thread with a priority greater than that of the current thread has been woken up. I didn't see the reason why the thread should otherwise relinquish the rest of its quantum. I noticed for instance that client and app server window threads were ping-ponging more than seemed necessary. In most cases when the client sent a port message it would be unscheduled although it had run only for a few microseconds and had still stuff to do. I measured a relatively Terminal-heavy "find /boot" (second run), which does now take 5-10% less time. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27314 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/sem.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/system/kernel/sem.cpp b/src/system/kernel/sem.cpp index 1416c02c22..c6fd0f2844 100644 --- a/src/system/kernel/sem.cpp +++ b/src/system/kernel/sem.cpp @@ -919,7 +919,8 @@ release_sem_etc(sem_id id, int32 count, uint32 flags) flags |= B_RELEASE_IF_WAITING_ONLY; } - bool unblockedAny = false; + struct thread* currentThread = thread_get_current_thread(); + bool reschedule = false; SpinLocker threadLocker(gThreadSpinlock); @@ -948,7 +949,7 @@ release_sem_etc(sem_id id, int32 count, uint32 flags) sSems[slot].u.used.count += delta; sSems[slot].u.used.net_count += delta - entry->count; count -= delta; - unblockedAny = true; + reschedule |= entry->thread->priority > currentThread->priority; } else { // The thread is no longer waiting, but still queued, which // means acquiration failed and we can just remove it. @@ -966,7 +967,7 @@ release_sem_etc(sem_id id, int32 count, uint32 flags) // If we've unblocked another thread reschedule, if we've not explicitly // been told not to. - if (unblockedAny && (flags & B_DO_NOT_RESCHEDULE) == 0) { + if (reschedule && (flags & B_DO_NOT_RESCHEDULE) == 0) { semLocker.Unlock(); threadLocker.Lock(); scheduler_reschedule();