Re: Correct API to implement a timer in a real-time thread
Re: Correct API to implement a timer in a real-time thread
- Subject: Re: Correct API to implement a timer in a real-time thread
- From: Stéphane Letz <email@hidden>
- Date: Fri, 6 Jan 2006 10:16:57 +0100
On Jan 5, 2006, at 2:31 PM, Herbie Robinson wrote:
At 12:08 PM -0800 1/5/06, Jeff Moore wrote:
The HAL uses the CAGuard class from the Public Utilities in the
CoreAudio SDK to handle all it's scheduling needs. CAGuard simply
wraps up a pthread mutex and cond var as a unit. CAGuard uses the
function pthread_cond_timedwait_relative_np() to handle blocking
the thread for a specified amount of time. If I remember right,
the difference between this function and the pthread_cond_timedwait
() is that in the former you pass the interval to wait and the
latter you pass the time to wake up. The reason for this is purely
because of the implementation of CAGuard. In fact, if you look at
the implementation of pthreads in Darwin, you'll find that
pthread_cond_timedwait() is implemented pretty much the same way
that CAGuard::WaitUntil() is.
Didn't one of your co-workers post that the pthreads implementation
uses a global lock that can cause priority inversion; so, at least
some pthreads calls aren't safe to use in real-time threads?
Yes. There is a spin lock in the pthread implementation that can
cause some trouble under some conditions. It isn't clear how often
this bug comes up, but it seems to be fairly rare (and almost non-
existent on MP machines). It has a particular signature in kernel
traces, so it's easy to spot and I have only ever seen one trace from
a developer that showed this bug happening (which is what led me to
it in the first place).
It has been my experience that more often than not any problems folks
have in their IOProcs are their own doing.
Has this been fixed and/or is there some safe set of pthreads calls?
The libc folks are looking at it as far as I know. In the mean time,
the HAL will continue to use the pthread calls for all it's
scheduling needs. If this particular bug is hurting you, you can
switch to using some other synchronization API like mach semaphores
or whatever you like.
At any rate, this bug does not invalidate any of the advice about the
algorithms to use to solve the problem Mr. Letz was looking at.
--
Jeff Moore
Core Audio
Apple
Here is the code I use now in the "time-constraint" thread:
static void* TimerTask(void* unused)
{
// Initialization
mach_timebase_info_data_t tbi;
mach_timebase_info(&tbi);
double invRatio = ((double)tbi.denom) / ((double)tbi.numer);
double timeResNanos = gTimeResMilli * 1000000; // In nanosecond
double nextDateNanos, curDateNanos = mach_absolute_time() / invRatio;
while (1) {
pthread_testcancel();
nextDateNanos = mach_absolute_time() / invRatio;
while (curDateNanos < nextDateNanos) {
long call = gTimeResMilli;
while (call--) ClockHandler(gMem);
curDateNanos += timeResNanos;
}
mach_wait_until(curDateNanos * invRatio);
}
return 0;
}
The strange thing is that even with a simpler version (without
pthread_testcancel and with an empty ClockHandler) :
static void* TimerTask(void* unused)
{
// Initialization
mach_timebase_info_data_t tbi;
mach_timebase_info(&tbi);
double invRatio = ((double)tbi.denom) / ((double)tbi.numer);
double timeResNanos = gTimeResMilli * 1000000; // In nanosecond
double nextDateNanos, curDateNanos = mach_absolute_time() / invRatio;
while (1) {
nextDateNanos = mach_absolute_time() / invRatio;
while (curDateNanos < nextDateNanos) {
long call = gTimeResMilli;
while (call--) EMPTYClockHandler(gMem);
curDateNanos += timeResNanos;
}
mach_wait_until(curDateNanos * invRatio);
}
return 0;
}
I get strange CPU spike on Panther: average CPU is 0.5% then every 2
or 3 minutes i get a CPU spike up yo 80% during several seconds....
but the exact same code works without problems on Tiger (on the same
machine)
I tried to "capture/profile" the CPU spike without real success....
Any idea?
Stephane Letz
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden