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:
Pawel Dziepak
2013-10-08 04:50:23 +02:00
parent 21808e8f0b
commit 547b8c76c7
@@ -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;