Re: Yielding the processor in a kext?
site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com Hi Régis, <quote from bsd/vfs/vfs_journal.c> lock_oldstart(jnl); while ((jnl->old_start[0] & 0x8000000000000000LL) != 0) { if (jnl->flush) { unlock_oldstart(jnl); if (jnl->flush) { jnl->flush(jnl->flush_arg); } (void)tsleep(NULL, PZERO, NULL, 0); or if you want "ps" to report something sensible in WCHAN column, then: (void)tsleep(NULL, PZERO, "my message", 0); (void)thread_block(THREAD_CONTINUE_NULL); Best regards, Anton On 7 Sep 2007, at 18:22, Régis Duchesne wrote: Michael, The problem here is that you are conflating "thread" with "work". I have perfect control on Windows where Sleep(0) is documented to do exactly what I want. I have perfect control on Linux where cond_resched() is documented to do exactly what I want. I'm trying to have perfect control on Mac OS by finding an API that is documented to do exactly what I want :) Thanks, -- hpreg _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/aia21%40cam.ac.uk -- 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 (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... Have you looked at using tsleep()? It appears to do more or less what you (and I) want. I just came across it... Here is one place in the kernel that uses it: // yield the cpu so others can get in to clear the lock bit (void)tsleep((void *)jnl, PRIBIO, "jnl-old- start-sleep", 1); lock_oldstart(jnl); } if (i++ >= 500) { panic("jnl: transaction that started at 0x% llx is not completing! jnl %p\n", jnl->old_start[0] & (~0x8000000000000000LL), jnl); } } </quote> tsleep() is exported (admittedly in Unsupported.exports but given your email address you are probably using other functions from there already!) (-: Looking at tsleep() you should be able to do: Actually, looking at the code and followed it through into the scheduler (DISCLAIMER: I don't claim to understand it just from such a quick look!) you can try doing in your kext: This is essentially what the above tsleep() call would boil down to doing... And best of all thread_block() is exported in Mach.exports so it is a stable kernel API. Definitely worth a try I would think! If it hangs (I don't think it will but I may have misunderstood!) or if it always schedules the same process back (I don't think it will do that either!) then you haven't lost anything but if my reading of the scheduling code is correct this will indeed perform a context switch to the next in line task on the run queue and will keep doing this until your task gets to be the next in line and the context switch then brings your task back and thread_block() returns. Note as I read the code when your task is the only task on the run queue thread_block() will simply return immediately. PS. If you try this I would be very grateful if you tell me how it worked out as I have already spent too long looking at the code when I have lots of other work to do! Ideally you would parcel your work out in well-ordered units, and schedule those units to threads in such a fashion that progress happens with the desired balance. That is great in an ideal world where you write the code that the threads execute. But we don't live in an ideal world: in my case each thread is like a black box: I control the initial input to these threads, but then they go do their heavy computation, and just report progress. What they do precisely to perform their computation is unknown to me. All I know is that if I make them progress at the same rate, whatever they compute will be computed faster overall (and more accurately). We are wondering which API can be used to do that. Would an IOSleep(0) (which is the way you do it on Windows) work or will it just be ignored? You don't want to do this, on either platform. You have no control over what "slow it down" actually means, and you aren't communicating what you really want to the scheduler. This email sent to aia21@cam.ac.uk This email sent to site_archiver@lists.apple.com
participants (1)
-
Anton Altaparmakov