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:
@@ -919,7 +919,8 @@ release_sem_etc(sem_id id, int32 count, uint32 flags)
|
|||||||
flags |= B_RELEASE_IF_WAITING_ONLY;
|
flags |= B_RELEASE_IF_WAITING_ONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unblockedAny = false;
|
struct thread* currentThread = thread_get_current_thread();
|
||||||
|
bool reschedule = false;
|
||||||
|
|
||||||
SpinLocker threadLocker(gThreadSpinlock);
|
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.count += delta;
|
||||||
sSems[slot].u.used.net_count += delta - entry->count;
|
sSems[slot].u.used.net_count += delta - entry->count;
|
||||||
count -= delta;
|
count -= delta;
|
||||||
unblockedAny = true;
|
reschedule |= entry->thread->priority > currentThread->priority;
|
||||||
} else {
|
} else {
|
||||||
// The thread is no longer waiting, but still queued, which
|
// The thread is no longer waiting, but still queued, which
|
||||||
// means acquiration failed and we can just remove it.
|
// 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
|
// If we've unblocked another thread reschedule, if we've not explicitly
|
||||||
// been told not to.
|
// been told not to.
|
||||||
if (unblockedAny && (flags & B_DO_NOT_RESCHEDULE) == 0) {
|
if (reschedule && (flags & B_DO_NOT_RESCHEDULE) == 0) {
|
||||||
semLocker.Unlock();
|
semLocker.Unlock();
|
||||||
threadLocker.Lock();
|
threadLocker.Lock();
|
||||||
scheduler_reschedule();
|
scheduler_reschedule();
|
||||||
|
|||||||
Reference in New Issue
Block a user