What's the best equivalent? I didn't find any reasonable solution for such a simple function. Choices I'm aware of:
1) MPEnterCriticalRegion - this is unfortunately extremely ineffective, probably because despite it's name it enters kernel mode, so for repeating locks it just takes way too much time...
2) OSSpinLockLock - unusable, because apparently not recursive. If it would be recursive, it would be the correct equivalent.
3) pthread_mutex_lock - didn't try, but I don't expect much, because it will probably be just emulated using the critical region or another system resource.
Assuming you have a correctly working non-recursive lock, it's rather easy to get an efficient recursive lock (no idea about Mac APIs, so this is pseudo code):
It's simple to reason:
tid == owner
it's guaranteed that we have already acquired the lock.tid != owner
either someone else holds the lock or it's free, in both cases we try to acquire the lock and block until we get it. After we acquire the lock we set the owner to tid. So there's some time where we have acquired the lock butowner
is still illegal. But no problem since the illegal tid won't compare equal to any real thread's tid either, so they'll go into theelse
branch as well and have to wait to get it.Notice the
std::atomic
part - we do need ordering guarantees for theowner
field to make this legal. If you don't have c++11 use some compiler intrinsic for that.