• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY


  • Subject: USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
  • From: Vyacheslav Matyushin <email@hidden>
  • Date: Fri, 16 Dec 2011 07:01:06 -0800 (PST)

Hi.
I'm writing an USB Audio driver.
To move data between CoreAudio and USB buffers I've created my own high-priority kernel thread.
(I can't use clipOutputSamples and convertInputSamples because of the driver design constraints).
To manage it's work my thread needs to be near-realtime so I set its priority to THREAD_TIME_CONSTRAINT_POLICY via thread_policy_set (the code is below).

The problem is that the streaming works fine without gaps only for some number of streaming launches.
Then starting from some random streaming start it stops working.
During loopback test I can receive huge gaps or receive no data at all.
The width of gaps varies from one streaming launch to another.

If I reload the driver and/or replug the device the streaming still produce various gaps.
But if I reboot with the same version of kext it starts to work perfect, but only until the streaming breaks again.

I suspect that after some number of successful streaming launches my kernel thread
can't become realtime anymore. thread_policy_set() returns with KERN_SUCCESS although.

Here is the code of thread creation and thread function:

startWorkerThread()
{
        kern_return_t result;
        thread_time_constraint_policy_data_t thread_policy;
        uint64_t nsec, absunit;

        // 150 microseconds for computation
        nsec = 150000;
        nanoseconds_to_absolutetime(nsec, &absunit);
        thread_policy.computation = absunit;
       
        // maximum of 300 microseconds for computation
        nsec = 300000;
        nanoseconds_to_absolutetime(nsec, &absunit);
        thread_policy.constraint = absunit;
       
        // period of 500 microseconds
        nsec = 500000;
        nanoseconds_to_absolutetime(nsec, &absunit);
        thread_policy.period = absunit;

        // allow preemtion of the thread
        thread_policy.preemptible = TRUE;

        result = kernel_thread_start((thread_continue_t) &WorkerThread,
                               this, &mWorkerThread);
       
        if (KERN_SUCCESS != result) {
                return kIOReturnError;
        }
       
        result = thread_policy_set(mWorkerThread,
                             THREAD_TIME_CONSTRAINT_POLICY,
                             (thread_policy_t) &thread_policy,
                             THREAD_TIME_CONSTRAINT_POLICY_COUNT);
       
        if (KERN_SUCCESS != result) {
          // I never get here
        }
       
        thread_deallocate(mWorkerThread);
       
        return kIOReturnSuccess;
}

WorkerThread(void *arg, wait_result_t wait_result)
{
        //...

        while (true) {
                clock_get_uptime(&time1);

                IOLockLock(mThreadLock);
                if (false == mThreadMustWork) {
                        IOLockUnlock(mThreadLock);
                        return;
                }
               
                if (true == mProcessSamples) {
                        processSamples();
                }
                IOLockUnlock(mThreadLock);
            
                clock_get_uptime(&time2);
               
                if (true == mProcessSamples) {
                        // wait so the cycle iterates with the period of about 500 microseconds
                        IODelay(500 - ((time2 - time1) / 1000));
                } else {
                        IODelay(500); // just wait 500 microseconds
                }
        }
}

Can it be so that starting from some point Mac OS X won't grant my thread realtime priority even if thread_policy_set() returns successfully?
I can't imagine any other reasons of why my streaming breaks and doesn't restore until I reboot even if I reload the driver and replug the device.

Thanks,
Vyacheslav Matyushin.

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
      • From: Vyacheslav Matyushin <email@hidden>
    • Re: USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
      • From: Ross Bencina <email@hidden>
    • Re: USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
      • From: Vyacheslav Matyushin <email@hidden>
  • Prev by Date: 64bits cocoa UI issue in Mainstage and Logic
  • Next by Date: What happened to the Public Utility in Xcode 4.3?
  • Previous by thread: Re: 64bits cocoa UI issue in Mainstage and Logic
  • Next by thread: Re: USB Audio driver and THREAD_TIME_CONSTRAINT_POLICY
  • Index(es):
    • Date
    • Thread