cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=f449f0ddb6c030e1763cc549caac5e162efbca74

commit f449f0ddb6c030e1763cc549caac5e162efbca74
Author: Jean Guyomarc'h <[email protected]>
Date:   Thu Aug 21 11:23:24 2014 +0200

    eina: port Eina_Spinlock for OSX
    
    Summary: Support of Spinlocks in Eina (Eina_Spinlock) for OSX, which does 
not implement them in pthread.
    @feature
    
    Reviewers: raster, raoulh, naguirre, cedric, stefan_schmidt
    
    Subscribers: cedric
    
    Differential Revision: https://phab.enlightenment.org/D1151
    
    Signed-off-by: Cedric BAIL <[email protected]>
---
 configure.ac                          |  8 ++++-
 m4/efl_threads.m4                     | 29 ++++++++++++++++++
 src/lib/eina/eina_config.h.in         |  5 +++
 src/lib/eina/eina_inline_lock_posix.x | 57 +++++++++++++++++++++++++++++++----
 4 files changed, 92 insertions(+), 7 deletions(-)

diff --git a/configure.ac b/configure.ac
index dbd24cc..c39c550 100644
--- a/configure.ac
+++ b/configure.ac
@@ -936,6 +936,7 @@ EINA_CONFIG([HAVE_PTHREAD_BARRIER], [test 
"x${efl_have_pthread_barrier}" = "xyes
 EINA_CONFIG([HAVE_PTHREAD_AFFINITY], [test "x${efl_have_setaffinity}" = 
"xyes"])
 EINA_CONFIG([HAVE_DEBUG_THREADS], [test "x${want_debug_threads}" = "xyes"])
 EINA_CONFIG([HAVE_POSIX_SPINLOCK], [test "x${efl_have_posix_threads_spinlock}" 
= "xyes"])
+EINA_CONFIG([HAVE_OSX_SPINLOCK], [test "x${efl_have_osx_spinlock}" = "xyes"])
 
 ### Modules
 
@@ -4498,7 +4499,12 @@ elif test "${have_windows}" = "yes"; then
 fi
 EFL_ADD_FEATURE([system], [ipv6])
 
-EFL_ADD_FEATURE([thread], [spinlocks], [${efl_have_posix_threads_spinlock}])
+if test "x${efl_have_posix_threads_spinlock}" = "xyes" || test 
"x${efl_have_osx_spinlock}" = "xyes"; then
+   efl_have_spinlock="yes"
+else
+   efl_have_spinlock="no"
+fi
+EFL_ADD_FEATURE([thread], [spinlocks], [${efl_have_spinlock}])
 EFL_ADD_FEATURE([thread], [barrier], [${efl_have_pthread_barrier}])
 EFL_ADD_FEATURE([thread], [affinity], [${efl_have_setaffinity}])
 
diff --git a/m4/efl_threads.m4 b/m4/efl_threads.m4
index 04b3e64..9596908 100644
--- a/m4/efl_threads.m4
+++ b/m4/efl_threads.m4
@@ -125,8 +125,37 @@ if test "x${efl_have_posix_threads_spinlock}" = "xyes" ; 
then
    AC_DEFINE([EFL_HAVE_POSIX_THREADS_SPINLOCK], [1], [Define to mention that 
POSIX threads spinlocks are supported])
 fi
 
+
+dnl checks if the compiler supports OSX spinlock
+
+efl_have_osx_spinlock="no"
+
+if test "x${_efl_have_posix_threads}" = "xyes" ; then
+   AC_LINK_IFELSE(
+      [AC_LANG_PROGRAM([[
+#include <libkern/OSAtomic.h>
+                       ]],
+                       [[
+OSSpinLock spin_lock = 0;
+OSSpinLockTry(&spin_lock);
+                       ]])],
+      [efl_have_osx_spinlock="yes"],
+      [efl_have_osx_spinlock="no"])
+fi
+
+AC_MSG_CHECKING([whether to build OSX spinlock code])
+AC_MSG_RESULT([${efl_have_osx_spinlock}])
+
+if test "x${efl_have_osx_spinlock}" = "xyes" ; then
+   AC_DEFINE([EFL_HAVE_OSX_SPINLOCK], [1], [Define to mention that OSX 
spinlocks are supported])
+fi
+
+
+
 AS_IF([test "x$_efl_have_posix_threads" = "xyes" || test 
"x$_efl_have_win32_threads" = "xyes"],
    [$1],
    [m4_if([$2], [$2], [AC_MSG_ERROR([Threads are required.])])])
 
+
 ])
+
diff --git a/src/lib/eina/eina_config.h.in b/src/lib/eina/eina_config.h.in
index 1f6fe67..cdaf867 100644
--- a/src/lib/eina/eina_config.h.in
+++ b/src/lib/eina/eina_config.h.in
@@ -97,6 +97,11 @@
 #endif
 @EINA_CONFIGURE_HAVE_POSIX_SPINLOCK@
 
+#ifndef EINA_HAVE_OSX_SPINLOCK
+# undef EINA_HAVE_OSX_SPINLOCK
+#endif
+@EINA_CONFIGURE_HAVE_OSX_SPINLOCK@
+
 /* Do not turn the following #define as meaning EFL64. We are only 
    interested to know if sizeof (void*) == 64bits or not. Those means
    something else.
diff --git a/src/lib/eina/eina_inline_lock_posix.x 
b/src/lib/eina/eina_inline_lock_posix.x
index 0de48e5..172e571 100644
--- a/src/lib/eina/eina_inline_lock_posix.x
+++ b/src/lib/eina/eina_inline_lock_posix.x
@@ -38,6 +38,10 @@
 # include <pthread.h>
 #endif
 
+#ifdef EINA_HAVE_OSX_SPINLOCK
+# include <libkern/OSAtomic.h>
+#endif
+
 #include <semaphore.h>
 
 #include <sys/time.h>
@@ -59,8 +63,10 @@ typedef struct _Eina_RWLock Eina_RWLock;
 typedef struct _Eina_Condition Eina_Condition;
 typedef pthread_key_t Eina_TLS;
 typedef sem_t Eina_Semaphore;
-#ifdef EINA_HAVE_POSIX_SPINLOCK
+#if defined(EINA_HAVE_POSIX_SPINLOCK)
 typedef pthread_spinlock_t Eina_Spinlock;
+#elif defined(EINA_HAVE_OSX_SPINLOCK)
+typedef OSSpinLock Eina_Spinlock;
 #else
 typedef Eina_Lock Eina_Spinlock;
 #endif
@@ -603,8 +609,13 @@ eina_barrier_wait(Eina_Barrier *barrier)
 static inline Eina_Bool
 eina_spinlock_new(Eina_Spinlock *spinlock)
 {
-#ifdef EINA_HAVE_POSIX_SPINLOCK
+#if defined(EINA_HAVE_POSIX_SPINLOCK)
    return pthread_spin_init(spinlock, PTHREAD_PROCESS_PRIVATE) == 0 ? 
EINA_TRUE : 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_LOCK_SUCCEED;
 #else
    return eina_lock_new(spinlock);
 #endif
@@ -613,7 +624,7 @@ eina_spinlock_new(Eina_Spinlock *spinlock)
 static inline Eina_Lock_Result
 eina_spinlock_take(Eina_Spinlock *spinlock)
 {
-#ifdef EINA_HAVE_POSIX_SPINLOCK
+#if defined(EINA_HAVE_POSIX_SPINLOCK)
    int t;
 
    do {
@@ -626,6 +637,12 @@ eina_spinlock_take(Eina_Spinlock *spinlock)
    } while (t != 0);
 
    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;
 #else
    return eina_lock_take(spinlock);
 #endif
@@ -634,11 +651,16 @@ eina_spinlock_take(Eina_Spinlock *spinlock)
 static inline Eina_Lock_Result
 eina_spinlock_take_try(Eina_Spinlock *spinlock)
 {
-#ifdef EINA_HAVE_POSIX_SPINLOCK
+#if defined(EINA_HAVE_POSIX_SPINLOCK)
    int t;
 
    t = pthread_spin_trylock(spinlock);
    return t ? EINA_LOCK_FAIL : EINA_LOCK_SUCCEED;
+#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;
 #else
    return eina_lock_take_try(spinlock);
 #endif
@@ -647,8 +669,13 @@ eina_spinlock_take_try(Eina_Spinlock *spinlock)
 static inline Eina_Lock_Result
 eina_spinlock_release(Eina_Spinlock *spinlock)
 {
-#ifdef EINA_HAVE_POSIX_SPINLOCK
+#if defined(EINA_HAVE_POSIX_SPINLOCK)
    return pthread_spin_unlock(spinlock) ? EINA_LOCK_FAIL : EINA_LOCK_SUCCEED;
+#elif defined(EINA_HAVE_OSX_SPINLOCK)
+   /* void OSSpinLockUnlock(OSSpinLock *lock);
+    * Unconditionally unlocks the lock by zeroing it. */
+   OSSpinLockUnlock(spinlock);
+   return EINA_LOCK_SUCCEED;
 #else
    return eina_lock_release(spinlock);
 #endif
@@ -657,8 +684,11 @@ eina_spinlock_release(Eina_Spinlock *spinlock)
 static inline void
 eina_spinlock_free(Eina_Spinlock *spinlock)
 {
-#ifdef EINA_HAVE_POSIX_SPINLOCK
+#if defined(EINA_HAVE_POSIX_SPINLOCK)
    pthread_spin_destroy(spinlock);
+#elif defined(EINA_HAVE_OSX_SPINLOCK)
+   /* Not applicable */
+   (void) spinlock;
 #else
    eina_lock_free(spinlock);
 #endif
@@ -670,4 +700,19 @@ eina_spinlock_free(Eina_Spinlock *spinlock)
 # 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

-- 


Reply via email to