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
This commit is contained in:
Ingo Weinhold
2008-09-04 00:32:12 +00:00
parent f88e298ec7
commit 537d081817
+4 -3
View File
@@ -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();