0

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

  1. How to generate a method with a blocking timeout?
  2. Is the SleepWithDeadline function a usage error? why doesn't work?
  3. Is there any other function to achieve this mechanism ?
xmx
  • 51
  • 3

0 Answers0