It's a software modem driver. Most of the driver was written using IOKit, but we have some logging and status monitoring functionality that I was hoping not to have to rewrite. We accomplished this on Linux by creating and feeding character devices from inside the driver, so that a user-level script could pipe those device files to a screen or regular file. I've taken that code, which uses wrapper functions (prefixed by 'lkvi') around anything OS-specific, and tried to rewrite the specific code to use BSD/mach equivalents. When I load the driver, a status char device gets created. If I try to do a "cat /dev/status_device", this locks the system in the device Read function, which includes this while loop: while (1) { /* synchronize with other reads */ while(lkvi_use_lock_use_when_unused(&(device->rLock)) != 0) {}; bytesAvailable = device->bufWrIdx - device->bufRdIdx; if (bytesAvailable < 0) bytesAvailable += device->bufSize; if ((device->buf != NULL) && ((bytesAvailable > 0) || (device->flags & SMD_OUTPUT_DEVICE_FLAG_TRAILING_EOF))) break; /* keep the lock since we'll need it anyway */ lkvi_use_lock_unuse(&(device->rLock)); /* SMD_PRINT_DEBUG_INFO (("Going to sleep")); */ lkvi_wait_queue_sleep_interruptible (&device->readQueue); /* SMD_PRINT_DEBUG_INFO (("Woken up")); */ } A function internal to the driver writes to device->buf. We use separate read and write locks, although in OS X there will only be one reader and one writer, and the circular buffer code is written so that reads and writes don't need to be atomic (writing only modifies the write pointer, and reading only modifies the read pointer). I also don't know much about character devices, so I assume that the read function must be all-or-nothing. This is why I wait in the first place. 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? 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). Thanks for your help, Vivek On Wednesday, March 5, 2003, at 11:47 AM, Jim Magee wrote: On Wednesday, March 5, 2003, at 01:37 PM, Vivek Balasubramanyam wrote: Hi. I'm porting some driver code from Linux, and having trouble using the wait_queue API (in kern/wait_queue.h). I use "wq = wait_queue_alloc(SYNC_POLICY_FIFO);" to set things up, "wait_queue_assert_wait(&wq, NO_EVENT, THREAD_INTERRUPTIBLE)" to add my single thread to the queue, and wakeup_one to wake it up. It looks like my driver is locking the machine in a loop containing the assert_wait() call: while (1) { ..check if there's data ready to be processed.. ..if so, break ..else, assert_wait } The waiting thread is only woken up by me when new data is ready to be processed, and yet execution in this thread never leaves that >> loop. I haven't been able to find much information on wait_queues. Is there something obvious I'm missing about their initialization or >> use? What kind of driver are you porting. Usually, higher level synchronization is used in drivers (command gates in IOKit drivers, tsleep is BSD drivers, etc...). The wait_queue mechanism is pretty low-level for drivers. Wait queues alone are not enough to provide the synchronization that the code above needs. You must use some sort of lock to protect the atomicity of the "check if there's data, otherwise assert_wait" operation. Once you have firmly asserted your intention to wait, you can unlock whatever form of lock you chose and then volunteer to give up the CPU (when working at this low a level, that would usually be with thread_block()). It sounds like you aren't giving up the CPU (and therefore would only get taken off the CPU to be preempted by a realtime thread). --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)
-
Vivek Balasubramanyam