tags:

views:

164

answers:

1

I am maintaining a carbon C++ application on OS X. There is a "spin lock" in one of the objects in the code that looks like this,

while ( mState != RELEASED )
{
 sleep( 1 );
}

There is a post render maintenance callback that is fed to AudioUnitAddRenderNotify() that would set the mState of these various objects.

I was thinking about using the built-in OSSpinLock family of functions to replace this (if nothing else because they are thread safe and the above code doesn't seem to be).

Would this be a reasonable equivalent? Should I also add some lock protection in the maintenance thread which manipulates the mState of these objects?

OSSpinLock spin_lock = OS_SPINLOCK_INIT;

if (!OSSpinLockTry(&spin_lock))
 OSSpinLockLock(&spin_lock);

while (mState != RELEASED)
    OSSpinLockTry(&spin_lock);

OSSpinLockUnlock(&spin_lock);
+3  A: 

Don't use a spinlock -- spinlocks waste CPU cycles, looping endlessly until they get the lock. Spinlocks should only be used when the time that the lock will be held will be very short.

A better alternative would be to use a condition variable, such as the ones available in the pthreads library. This way, your thread will sleep and not waste any CPU cycles until the condition is satisfied. See the example listed in that link for how to use pthreads condition variables.

Adam Rosenfield
Depending on the application, spinlocks can perform better than objects that end up jumping into the kernel or worse, causing a context switch. But still, that is a limited set of applications and should be used with caution.
Torlack
Operating-system-provided spin locks such as OSSpinLock are much better to use than "trivial" spinlocks like the "while (1) {}" that they would be replacing. They're smarter than you give them credit for; for example, OSSpinLockLock uses a back-off strategy to avoid livelock. http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/spinlock.3.html
Chris Hanson
That said, a condition variable from either pthreads or Cocoa (NSConditionLock) is a far better choice for this specific situation.
Chris Hanson