forked from enlightenment/efl
eina: fix macos spinlocks and upgrade API to sierra
This commit is contained in:
parent
7b3e7ecc1f
commit
519207c7eb
|
@ -38,10 +38,6 @@
|
|||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef EINA_HAVE_OSX_SPINLOCK
|
||||
# include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
#ifdef EINA_HAVE_OSX_SEMAPHORE
|
||||
# include <mach/mach.h>
|
||||
#endif
|
||||
|
@ -87,7 +83,7 @@ typedef pthread_key_t Eina_TLS;
|
|||
#if defined(EINA_HAVE_POSIX_SPINLOCK)
|
||||
typedef pthread_spinlock_t Eina_Spinlock;
|
||||
#elif defined(EINA_HAVE_OSX_SPINLOCK)
|
||||
typedef OSSpinLock Eina_Spinlock;
|
||||
typedef uintptr_t Eina_Spinlock;
|
||||
#else
|
||||
typedef Eina_Lock Eina_Spinlock;
|
||||
#endif
|
||||
|
@ -153,6 +149,11 @@ EAPI Eina_Bool _eina_spinlock_new(Eina_Spinlock *spinlock);
|
|||
EAPI void _eina_spinlock_free(Eina_Spinlock *spinlock);
|
||||
EAPI Eina_Bool _eina_semaphore_new(Eina_Semaphore *sem, int count_init);
|
||||
EAPI Eina_Bool _eina_semaphore_free(Eina_Semaphore *sem);
|
||||
#ifdef EINA_HAVE_OSX_SPINLOCK
|
||||
EAPI Eina_Lock_Result _eina_spinlock_macos_take(Eina_Spinlock *spinlock);
|
||||
EAPI Eina_Lock_Result _eina_spinlock_macos_take_try(Eina_Spinlock *spinlock);
|
||||
EAPI Eina_Lock_Result _eina_spinlock_macos_release(Eina_Spinlock *spinlock);
|
||||
#endif
|
||||
|
||||
static inline Eina_Bool
|
||||
eina_lock_new(Eina_Lock *mutex)
|
||||
|
@ -637,11 +638,7 @@ eina_spinlock_take(Eina_Spinlock *spinlock)
|
|||
|
||||
return EINA_LOCK_SUCCEED;
|
||||
#elif defined(EINA_HAVE_OSX_SPINLOCK)
|
||||
/* void OSSpinLockLock(OSSpinLock *lock);
|
||||
* Will spin if the lock is already held, but employs various strategies to
|
||||
* back off, making it immune to most priority-inversion livelocks. */
|
||||
OSSpinLockLock(spinlock);
|
||||
return EINA_LOCK_SUCCEED;
|
||||
return _eina_spinlock_macos_take(spinlock);
|
||||
#else
|
||||
return eina_lock_take(spinlock);
|
||||
#endif
|
||||
|
@ -657,10 +654,7 @@ eina_spinlock_take_try(Eina_Spinlock *spinlock)
|
|||
else EINA_LOCK_ABORT_DEBUG(t, spin_trylock, spinlock);
|
||||
return EINA_LOCK_FAIL;
|
||||
#elif defined(EINA_HAVE_OSX_SPINLOCK)
|
||||
/* bool OSSpinLockTry(OSSpinLock *lock);
|
||||
* Immediately returns false if the lock was held, true if it took the
|
||||
* lock. It does not spin. */
|
||||
return (OSSpinLockTry(spinlock)) ? EINA_LOCK_SUCCEED : EINA_LOCK_FAIL;
|
||||
return _eina_spinlock_macos_take_try(spinlock);
|
||||
#else
|
||||
return eina_lock_take_try(spinlock);
|
||||
#endif
|
||||
|
@ -676,10 +670,7 @@ eina_spinlock_release(Eina_Spinlock *spinlock)
|
|||
else EINA_LOCK_ABORT_DEBUG(ok, spin_unlock, spinlock);
|
||||
return EINA_LOCK_FAIL;
|
||||
#elif defined(EINA_HAVE_OSX_SPINLOCK)
|
||||
/* void OSSpinLockUnlock(OSSpinLock *lock);
|
||||
* Unconditionally unlocks the lock by zeroing it. */
|
||||
OSSpinLockUnlock(spinlock);
|
||||
return EINA_LOCK_SUCCEED;
|
||||
return _eina_spinlock_macos_release(spinlock);
|
||||
#else
|
||||
return eina_lock_release(spinlock);
|
||||
#endif
|
||||
|
@ -739,19 +730,4 @@ eina_semaphore_release(Eina_Semaphore *sem, int count_release EINA_UNUSED)
|
|||
# define _XOPEN_SOURCE EINA_XOPEN_SOURCE
|
||||
#endif
|
||||
|
||||
#ifdef EINA_HAVE_OSX_SPINLOCK
|
||||
/* The inclusion of libkern/OSAtomic.h is a mess because it includes stdbool
|
||||
* which #defines bool. #undef bool is not sufficient because then other
|
||||
* headers (dlfcn.h) require it and #include stdbool.h to get it. It is
|
||||
* therefore important to "undo" the whole stdbool.h inclusion. */
|
||||
# undef true
|
||||
# undef false
|
||||
# undef bool
|
||||
# undef __bool_true_false_are_defined
|
||||
# undef _STDBOOL_H_ // OSX SDK
|
||||
# undef __STDBOOL_H // Clang 5.1
|
||||
# undef _STDBOOL_H // GCC
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,51 @@
|
|||
#include "eina_config.h"
|
||||
#include "Eina.h"
|
||||
|
||||
#ifdef EINA_HAVE_OSX_SPINLOCK
|
||||
|
||||
/*
|
||||
* macOS 10.12 introduced the os_unfair_lock API which
|
||||
* deprecates OSSpinLock, while keeping compatible.
|
||||
*
|
||||
* The Spinlock API is not inlined because it would imply including
|
||||
* stdbool.h, which is not wanted: it would introduce new macros,
|
||||
* and break compilation of existing programs.
|
||||
*/
|
||||
# ifdef __MAC_10_12
|
||||
# include <os/lock.h>
|
||||
# define SPINLOCK_GET(LCK) ((os_unfair_lock_t)(LCK))
|
||||
# else
|
||||
# include <libkern/OSAtomic.h>
|
||||
# define SPINLOCK_GET(LCK) ((OSSpinLock *)(LCK))
|
||||
# define os_unfair_lock_lock(LCK) OSSpinLockLock(LCK)
|
||||
# define os_unfair_lock_unlock(LCK) OSSpinLockUnlock(LCK)
|
||||
# define os_unfair_lock_trylock(LCK) OSSpinLockTry(LCK)
|
||||
# endif
|
||||
|
||||
EAPI Eina_Lock_Result
|
||||
_eina_spinlock_macos_take(Eina_Spinlock *spinlock)
|
||||
{
|
||||
os_unfair_lock_lock(SPINLOCK_GET(spinlock));
|
||||
return EINA_LOCK_SUCCEED;
|
||||
}
|
||||
|
||||
EAPI Eina_Lock_Result
|
||||
_eina_spinlock_macos_take_try(Eina_Spinlock *spinlock)
|
||||
{
|
||||
return (os_unfair_lock_trylock(SPINLOCK_GET(spinlock)) == true)
|
||||
? EINA_LOCK_SUCCEED
|
||||
: EINA_LOCK_FAIL;
|
||||
}
|
||||
|
||||
EAPI Eina_Lock_Result
|
||||
_eina_spinlock_macos_release(Eina_Spinlock *spinlock)
|
||||
{
|
||||
os_unfair_lock_unlock(SPINLOCK_GET(spinlock));
|
||||
return EINA_LOCK_SUCCEED;
|
||||
}
|
||||
#endif /* EINA_HAVE_OSX_SPINLOCK */
|
||||
|
||||
|
||||
EAPI void
|
||||
_eina_lock_debug_abort(int err, const char *fn, const volatile void *ptr)
|
||||
{
|
||||
|
@ -216,8 +261,6 @@ _eina_spinlock_new(Eina_Spinlock *spinlock)
|
|||
else EINA_LOCK_ABORT_DEBUG(ok, spin_init, spinlock);
|
||||
return EINA_FALSE;
|
||||
#elif defined(EINA_HAVE_OSX_SPINLOCK)
|
||||
/* OSSpinLock is an integer type. The convention is that unlocked is
|
||||
* * zero, and locked is nonzero. */
|
||||
*spinlock = 0;
|
||||
return EINA_TRUE;
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue