Background
The function I want to achieve is that after calling a pcie hardware dma, it needs to be blocked until the hardware generates a pcie interrupt before it can run normally. If no interrupt is generated, just wait to timeout and exit.
IOkit
In IOkit, I can use
IOLockSleepDeadline
to accomplish this function.Driverkit
In driverkit, although there is
IOLock
, it lacks a timeout mechanism, and cannot exit correctly when no interrupt is generated.
Test
I found that there are SleepWithDeadline
and Wakeup
functions in IODispatchQueue
class. I think these two functions can allow me to implement the function of exiting with timeout.
I checked a lot of information, but did not find how to use these two functions correctly. The following code I wrote myself also fails to run.
IODispatchQueue with SleepWithDeadline and Wakeup
Log("QueueSleep Before"); uint32_t test_event = 0; // main thread sleep const uint64_t oneSecond = 1000000000; uint64_t currentTime = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); kern_return_t rt = ivars->testQueue->SleepWithDeadline(&test_event, kIOTimerClockMonotonicRaw, currentTime + oneSecond); Log("rt = 0x%x", rt); ivars->testQueue->DispatchAsync(^{ int i = 10; uint32_t test_event = 0; do{ // Async thread sleep const uint64_t oneSecond = 1000000000; uint64_t currentTime = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); kern_return_t rt = ivars->testQueue->SleepWithDeadline(&test_event, kIOTimerClockMonotonicRaw, currentTime + oneSecond); Log("delay %d! rt = 0x%x", i--, rt); }while(i > 0); Log("QueueSleep over"); });
output after running
[124916.582399]: NullDriver - QueueSleep Before [124916.582406]: NullDriver - rt = 0xe00002d8 [124916.582457]: NullDriver - QueueSleep After [124916.582502]: NullDriver - delay 10! rt = 0xe00002d8 [124916.582509]: NullDriver - delay 9! rt = 0xe00002d8 [124916.582512]: NullDriver - delay 8! rt = 0xe00002d8 [124916.582515]: NullDriver - delay 7! rt = 0xe00002d8 [124916.582517]: NullDriver - delay 6! rt = 0xe00002d8 [124916.582519]: NullDriver - delay 5! rt = 0xe00002d8 [124916.582522]: NullDriver - delay 4! rt = 0xe00002d8 [124916.582525]: NullDriver - delay 3! rt = 0xe00002d8 [124916.582527]: NullDriver - delay 2! rt = 0xe00002d8 [124916.582529]: NullDriver - delay 1! rt = 0xe00002d8 [124916.582532]: NullDriver - QueueSleep over
There is no delay between the main thread and the asynchronous thread, and the function returns failure.
#define kIOReturnNotReady iokit_common_err(0x2d8) // not ready
Issue
- How to generate a method with a blocking timeout?
- Is the
SleepWithDeadline
function a usage error? why doesn't work? - Is there any other function to achieve this mechanism ?