Re: Yielding the processor in a kext?
Re: Yielding the processor in a kext?
- Subject: Re: Yielding the processor in a kext?
- From: Anton Altaparmakov <email@hidden>
- Date: Fri, 7 Sep 2007 11:18:44 +0100
Hi,
On 7 Sep 2007, at 11:06, Terry Lambert wrote:
On Sep 7, 2007, at 1:08 AM, Anton Altaparmakov wrote:
On 7 Sep 2007, at 03:55, Michael Smith wrote:
On Sep 6, 2007, at 5:03 PM, Régis Duchesne wrote:
Is there a way to make the current thread yield the processor in
a kext?
Not in the fashion you describe. If you have work, do it. If
the scheduler has more important work that has to be done, it
will take the CPU away from your thread.
But for example from a file system kext we don't know what
priority the thread is and we don't own the thread either so we
should not be messing with priorities...
And what if we have work to do but can't do it because we need
another thread to do work first? It is stupid to hang onto our
time slice in at this point...
You block on the mutex held by the other thread that you know you
need to wait for because it holds the mutex.
Then the scheduler does it's normal priority lending trick, and you
implicitly yield anyway, and the other thread gets the priority
boost necessary to get its work done ASAP and get you unblocked ASAP.
Yes that of course works as long as you don't get an AB-BA deadlock
as in my example...
The only reason to want to do this is if you are performing a
long-running low priority task on the wrong (high-priority) thread.
Don't do that. Do the work on a thread whose priority reflects
the true priority of the task. It's not your business to make
scheduling decisions; don't even try.
Your view is too limited. This is not true at all. I will give
you a concrete example of when I would like to yield the CPU from
my file system kext:
I need to take a lock but I can't do it safely because of holding
other locks so I do a try-lock. The try-lock fails so I have to
drop my locks and try again. It is totally brain damaged to try
again immediately. It would be far more sensible to yield the CPU
to give the other process holding my lock to finish its work and
release it and when the scheduler next gets to my process for me
to try again and if I fail again to yield again, etc... And
trying again immediately is actually MUCH worse than the fact that
CPU is just being burned unnecessarily because the other process
might be trying to take the lock I just dropped so if I take it
again immediately the chances of the other process taking that
lock successfully and hence making progress thus releasing both
locks so my process can make progress are close to zero at this
point! )-:
Except that the scheduler is going to raise your priority until it
eclipses everything else because you constantly fail to utilize
your full quantum, yet are constantly runnable. I expect that you
would be unable to actually rool your state back forward
immediately, though, since, having backed out your state, the other
thread is able to make progress, and you won't be able to
immediately acquire your mutex any more.
But assuming instead that you aren't trying to fight a lock order
inversion with a scheduler hack here, the answer would be "call
IOSleep or consider refactoring your code so that this doesn't
become an issue in the first place". Like maybe use a deadicated
worker thread and an IOWorkQueue.
And another example: In a critical path when a memory allocation
fails, I want to yield the CPU and try again later when the system
hopefully has more memory available as failing the allocation is a
disaster for file system consistency at this point. At the moment
I just do it in a busy loop trying again and again and again till
the scheduler decides to reschedule me. That's got to be totally
insane... )-:
Set the M_WAIT flag so the allocation blocks until it can be
satisfied or the heat death of the universe, whichever comes first.
How do you do that with OSMalloc()? Is there some way to maybe set
this in the tag supplied to OSMalloc() or something? Or are you
suggesting I should be using a different allocator altogether? I
have been told that OSMalloc() is the only allocator I should be
using from a file system kext (that comes straight from the guys
working on the memory allocators).
I would very much like to know how I can tell the scheduler "I am
done, hand CPU to someone else now"...
Generally, by blocking on something that, when there is work for
you to do, will wake you up (or by returning to your caller, if you
are on a user space thread context instead of your own worker thread).
The kernel either lets you run, preempts you, because you are
interruptible, or lets you block waiting for a resource ("more work
to do" is a resource).
Thanks for the suggestions.
Best regards,
Anton
--
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer, http://www.linux-ntfs.org/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden