Messages in this thread Patch in this message | | | From | Ivan Schreter <> | Subject | Re: [patch] sched_yield in 2.2.x - version 2 | Date | Wed, 30 May 2001 12:54:52 +0200 |
| |
Hello,
please CC: replies to me as I am not subscribed to the list.
> The real problem with this patch is that if a real time task yields, the > patch will cause the scheduler to pick a lower priority task or a > SCHED_OTHER task. This one is not so easy to solve. You want to scan > the run_list in the proper order so that the real time task will be the > last pick at its priority. Problem is, the pre load with the prev task > is out of order. You might try: http://rtsched.sourceforge.net/
No it's not a problem at all, since RR tasks will just be moved to the end of the queue and no SCHED_YIELD flag is set for them => no lower-priority task may be scheduled.
However, I found a bug in my own patch :-) The problem is that when a process yields and no process has a timeslice left, recalc is called. But then we lose YIELD flag once again. So the simple solution (and hopefully this time right :-) was to NOT clear YIELD flag at all before exit from schedule() and move test for this flag from goodness_prev() to goodness() function (getting rid of goodness_prev() altogether).
However, one of my tests still show strange behavior, so maybe you will get 3rd version of the patch :-) Anyway, I got good 30% performance boost for high-contention case in user-space spinlocks when sched_yield() is working right.
Another function that would be very interesting is possibility to give up our timeslice to specific other process. This way I could transfer control to other process/thread that owns the lock directly so that process/thread may finish working with the lock. This can again speed up everything. When I have now 4 processes contending for a lock, I get performance 1x. However, when there are 20 processes contending, performance is only 0.7x. I suppose this is due to excessive context switches. I will try to implement something like "sched_switchto" to switch to specific pid (from user space) and see if that helps. Or is there such a function already?
Ivan Schreter is@zapwerk.com --- kernel/sched.c.orig Wed May 30 01:17:24 2001 +++ kernel/sched.c Wed May 30 12:30:03 2001 @@ -145,6 +145,11 @@ { int weight; + if (p->policy & SCHED_YIELD) { + /* do not schedule yielded process now */ + return -1; + } + /* * Realtime process, select the first one on the * runqueue (taking priorities within processes @@ -183,25 +188,6 @@ } /* - * subtle. We want to discard a yielded process only if it's being - * considered for a reschedule. Wakeup-time 'queries' of the scheduling - * state do not count. Another optimization we do: sched_yield()-ed - * processes are runnable (and thus will be considered for scheduling) - * right when they are calling schedule(). So the only place we need - * to care about SCHED_YIELD is when we calculate the previous process' - * goodness ... - */ -static inline int prev_goodness (struct task_struct * prev, - struct task_struct * p, int this_cpu) -{ - if (p->policy & SCHED_YIELD) { - p->policy &= ~SCHED_YIELD; - return 0; - } - return goodness(prev, p, this_cpu); -} - -/* * the 'goodness value' of replacing a process on a given CPU. * positive value means 'replace', zero or negative means 'dont'. */ @@ -740,6 +726,10 @@ /* Do we need to re-calculate counters? */ if (!c) goto recalculate; + + /* clean up potential SCHED_YIELD bit */ + prev->policy &= ~SCHED_YIELD; + /* * from this point on nothing can prevent us from * switching to the next task, save this fact in @@ -809,7 +799,7 @@ } still_running: - c = prev_goodness(prev, prev, this_cpu); + c = goodness(prev, prev, this_cpu); next = prev; goto still_running_back; | |