On Wednesday, March 5, 2003, at 03:38 PM, Vivek Balasubramanyam wrote: I am definitely not giving up the CPU, although I expected that the assert_wait() function would put my thread to sleep. Are you saying that I need to call thread_block() in addition to assert_wait() in order to fall asleep? Correct. In Mach, blocking within the kernel is a two step process. You assert your intention to wait on a particular event, and then you block. Normally, you would unlock whatever you were using for synchronization after calling assert_wait() and before giving up the CPU (with thread_block()). This two stage approach has several advantages: 1. It allows you to use whatever form of synchronization you want (because you do the unlocking manually between the assert_wait() and the thread_block(). 2. It also allows you to check the return from assert_wait() to see if you really should block. For instance, you may be aborted because of a pending signal or thread termination, and the wait may have been interruptible, in which case the assert_wait() didn't have effect. So, no need to give up the CPU, just return the interrupted status so you can get to your signal handler quickly. 3. Once you unlock, but before you try to give up the CPU, the event may get posted (by another thread on another CPU, by a thread that preempts you on this CPU, or by an interrupt handler). By giving a window for this to happen before you commit to giving up the CPU, you may avoid unnecessary context switches. There isn't a specific need to use wait queues over any other kind of synchronization, since only one thread is ever in the queue. But I do need to use something that will let this thread sleep until a separate thread sends a wakeup signal (when the buffer goes from empty to non-empty). Note that you don't have to allocate your own wait_queues. There are a standard set of them for the system. If you just call assert_wait(), your event will be hashed to select one of the standard wait_queues to put you in. You only need your own wait_queue if you are going to use the wait_queue's native locking as your wider synchronization primitive (not available outside the osfmk component, but used by both Mach message queues, semaphores, and locksets) or if you need to manage sets of related waiters and event sources (like Mach portsets or BSD select sets, etc...). --Jim _______________________________________________ darwin-kernel mailing list | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Jim Magee