Skip to content

Instantly share code, notes, and snippets.

@ykst
Created January 28, 2015 14:14
Show Gist options
  • Save ykst/ad59cac8a911c80df77c to your computer and use it in GitHub Desktop.
Save ykst/ad59cac8a911c80df77c to your computer and use it in GitHub Desktop.
iOSでスピンロック

iOSでスピンロック

何も考えずに@synchronizedを使っていると次第に心が蝕まれていくので、 時にはスピンロックを使いたくなる事があると思います。 幸いな事に自作しなくてもiOSがAPIを提供してくれているので、それを使いましょう。

OSAtomic.hでスピンロック

基本的な使い方を以下のサンプルコードで示します。 ヘッダ名が如何にもリジェクトされそうな雰囲気を醸し出していますが、大丈夫だそうです

#include <libkern/OSAtomic.h>

static volatile OSSpinLock lock = OS_SPINLOCK_INIT;

void spinlock_lock() 
{
    OSSpinLockLock(&lock);
}

void spinlock_unlock() 
{
    OSSpinLockUnlock(&lock);
}

これをmutexの代わりに使うだけです。OSSpinLock型の実体はただのint32_tです。

@synchronizedっぽくしてみる

マクロを使って疑似ブロックを作るなら例えば次のようになります。

#define SPINLOCK(lock) for (int ___do = ({ OSSpinLockLock(&(lock)); 1; }); ___do || ({ OSSpinLockUnlock(&(lock)); 0; }); ___do = 0)

... 
    SPINLOCK(a_lock) {
        do_something();
    }
...

補足

当然ですが、スピンロック一般の注意点として

  1. ロックされる時間が極めて短いこと
  2. 中でコンテキストスイッチが起きない事
  3. 再帰ロックしないこと

等を考慮して使う必要が有ります。特に2はシングルコアで致命傷を負う事にもなるので要注意です。

かなり過激に使わない限りパフォーマンスは@synchronizedとさほど変わらなかったりするので、 必ず計測してから導入する事をお勧めします。

参考

http://www.celsiusgs.com/blog/tag/spinlock/ https://developer.apple.com/library/mac/documentation/System/Reference/OSAtomic_header_reference/Reference/reference.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment