Question

I didn't find it in Mac, but almost all Linux os support it.. Any one knows how to port it to mac?

Was it helpful?

OTHER TIPS

Here is drop in replacement code. You should be able to put this in a header file and drop it in your project.

typedef int pthread_spinlock_t;

int pthread_spin_init(pthread_spinlock_t *lock, int pshared) {
    __asm__ __volatile__ ("" ::: "memory");
    *lock = 0;
    return 0;
}

int pthread_spin_destroy(pthread_spinlock_t *lock) {
    return 0;
}

int pthread_spin_lock(pthread_spinlock_t *lock) {
    while (1) {
        int i;
        for (i=0; i < 10000; i++) {
            if (__sync_bool_compare_and_swap(lock, 0, 1)) {
                return 0;
            }
        }
        sched_yield();
    }
}

int pthread_spin_trylock(pthread_spinlock_t *lock) {
    if (__sync_bool_compare_and_swap(lock, 0, 1)) {
        return 0;
    }
    return EBUSY;
}

int pthread_spin_unlock(pthread_spinlock_t *lock) {
    __asm__ __volatile__ ("" ::: "memory");
    *lock = 0;
    return 0;
}

See discussion, and Github source

EDIT: Here's a class that works on all OSes that includes a workaround for missing pthread spinlocks on OSX:

class Spinlock
{
private:    //private copy-ctor and assignment operator ensure the lock never gets copied, which might cause issues.
    Spinlock operator=(const Spinlock & asdf);
    Spinlock(const Spinlock & asdf);
#ifdef __APPLE__
    OSSpinLock m_lock;
public:
    Spinlock()
    : m_lock(0)
    {}
    void lock() {
        OSSpinLockLock(&m_lock);
    }
    bool try_lock() {
        return OSSpinLockTry(&m_lock);
    }
    void unlock() {
        OSSpinLockUnlock(&m_lock);
    }
#else
    pthread_spinlock_t m_lock;
public:
    Spinlock() {
        pthread_spin_init(&m_lock, 0);
    }

    void lock() {
        pthread_spin_lock(&m_lock);
    }
    bool try_lock() {
        int ret = pthread_spin_trylock(&m_lock);
        return ret != 16;   //EBUSY == 16, lock is already taken
    }
    void unlock() {
        pthread_spin_unlock(&m_lock);
    }
    ~Spinlock() {
        pthread_spin_destroy(&m_lock);
    }
#endif
};

If the performance of your lock is not critical, pthread_mutex_t can be used as a drop replacement for pthread_spinlock_t, which makes porting easy.

I have used instead (that is natively supported by OS X intel)

  1. pthread_rwlock_t lock;
  2. pthread_rwlock_init
  3. pthread_rwlock_wrlock
  4. pthread_rwlock_unlock

And that works very fine as well

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top