• Ingo Molnar's avatar
    sched_yield() is misbehaving. · 18cb13a6
    Ingo Molnar authored
      the current implementation does the following to 'give up' the CPU:
    
       - it decreases its priority by 1 until it reaches the lowest level
       - it queues the task to the end of the priority queue
    
      this scheme works fine in most cases, but if sched_yield()-active tasks
      are mixed with CPU-using processes then it's quite likely that the
      CPU-using process is in the expired array. In that case the yield()-ing
      process only requeues itself in the active array - a true context-switch
      to the expired process will only occur once the timeslice of the
      yield()-ing process has expired: in ~150 msecs. This leads to the
      yield()-ing and CPU-using process to use up rougly the same amount of
      CPU-time, which is arguably deficient.
    
      i've fixed this problem by extending sched_yield() the following way:
    
      +        * There are three levels of how a yielding task will give up
      +        * the current CPU:
      +        *
      +        *  #1 - it decreases its priority by one. This priority loss is
      +        *       temporary, it's recovered once the current timeslice
      +        *       expires.
      +        *
      +        *  #2 - once it has reached the lowest priority level,
      +        *       it will give up timeslices one by one. (We do not
      +        *       want to give them up all at once, it's gradual,
      +        *       to protect the casual yield()er.)
      +        *
      +        *  #3 - once all timeslices are gone we put the process into
      +        *       the expired array.
      +        *
      +        *  (special rule: RT tasks do not lose any priority, they just
      +        *  roundrobin on their current priority level.)
      +        */
    18cb13a6
sched.c 44.1 KB