kernel: Cancel penalty only if the thread actually waits
Require the thread to give up CPU for at least one time slice before cancelling its penalty.
This commit is contained in:
@@ -59,6 +59,8 @@ struct scheduler_thread_data {
|
|||||||
bigtime_t time_left;
|
bigtime_t time_left;
|
||||||
bigtime_t stolen_time;
|
bigtime_t stolen_time;
|
||||||
bigtime_t quantum_start;
|
bigtime_t quantum_start;
|
||||||
|
|
||||||
|
bigtime_t went_sleep;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -71,6 +73,8 @@ scheduler_thread_data::Init()
|
|||||||
time_left = 0;
|
time_left = 0;
|
||||||
stolen_time = 0;
|
stolen_time = 0;
|
||||||
|
|
||||||
|
went_sleep = 0;
|
||||||
|
|
||||||
lost_cpu = false;
|
lost_cpu = false;
|
||||||
cpu_bound = true;
|
cpu_bound = true;
|
||||||
}
|
}
|
||||||
@@ -156,9 +160,14 @@ simple_cancel_penalty(Thread *thread)
|
|||||||
{
|
{
|
||||||
scheduler_thread_data* schedulerThreadData
|
scheduler_thread_data* schedulerThreadData
|
||||||
= reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
|
= reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
|
||||||
|
|
||||||
|
if (schedulerThreadData->went_sleep < 0
|
||||||
|
|| system_time() - schedulerThreadData->went_sleep <= kThreadQuantum)
|
||||||
|
return;
|
||||||
if (schedulerThreadData->priority_penalty != 0)
|
if (schedulerThreadData->priority_penalty != 0)
|
||||||
TRACE("cancelling thread %ld penalty\n", thread->id);
|
TRACE("cancelling thread %ld penalty\n", thread->id);
|
||||||
schedulerThreadData->priority_penalty = 0;
|
schedulerThreadData->priority_penalty = 0;
|
||||||
|
schedulerThreadData->forced_yield_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -170,6 +179,8 @@ simple_enqueue_in_run_queue(Thread *thread)
|
|||||||
{
|
{
|
||||||
thread->state = thread->next_state = B_THREAD_READY;
|
thread->state = thread->next_state = B_THREAD_READY;
|
||||||
|
|
||||||
|
simple_cancel_penalty(thread);
|
||||||
|
|
||||||
int32 threadPriority = simple_get_effective_priority(thread);
|
int32 threadPriority = simple_get_effective_priority(thread);
|
||||||
T(EnqueueThread(thread, threadPriority));
|
T(EnqueueThread(thread, threadPriority));
|
||||||
|
|
||||||
@@ -339,6 +350,8 @@ simple_reschedule(void)
|
|||||||
schedulerOldThreadData->cpu_bound = false;
|
schedulerOldThreadData->cpu_bound = false;
|
||||||
|
|
||||||
if (simple_quantum_ended(oldThread, oldThread->cpu->preempted)) {
|
if (simple_quantum_ended(oldThread, oldThread->cpu->preempted)) {
|
||||||
|
schedulerOldThreadData->went_sleep = -1;
|
||||||
|
|
||||||
if (schedulerOldThreadData->cpu_bound)
|
if (schedulerOldThreadData->cpu_bound)
|
||||||
simple_increase_penalty(oldThread);
|
simple_increase_penalty(oldThread);
|
||||||
else
|
else
|
||||||
@@ -356,13 +369,13 @@ simple_reschedule(void)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case B_THREAD_SUSPENDED:
|
case B_THREAD_SUSPENDED:
|
||||||
simple_cancel_penalty(oldThread);
|
schedulerOldThreadData->went_sleep = system_time();
|
||||||
TRACE("reschedule(): suspending thread %ld\n", oldThread->id);
|
TRACE("reschedule(): suspending thread %ld\n", oldThread->id);
|
||||||
break;
|
break;
|
||||||
case THREAD_STATE_FREE_ON_RESCHED:
|
case THREAD_STATE_FREE_ON_RESCHED:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
simple_cancel_penalty(oldThread);
|
schedulerOldThreadData->went_sleep = system_time();
|
||||||
TRACE("not enqueueing thread %ld into run queue next_state = %ld\n",
|
TRACE("not enqueueing thread %ld into run queue next_state = %ld\n",
|
||||||
oldThread->id, oldThread->next_state);
|
oldThread->id, oldThread->next_state);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user