cedric pushed a commit to branch master.

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

commit 1b07350a460fd7177d894116f422577325842225
Author: Cedric Bail <cedric.b...@samsung.com>
Date:   Thu Oct 10 17:22:28 2013 +0900

    eina: add Eina_Spinlock API.
---
 ChangeLog                             |  4 ++
 NEWS                                  |  1 +
 configure.ac                          |  3 +-
 m4/efl_threads.m4                     |  2 +
 src/lib/eina/eina_config.h.in         |  5 +++
 src/lib/eina/eina_inline_lock_posix.x | 83 +++++++++++++++++++++++++++++++++++
 src/lib/eina/eina_inline_lock_win32.x | 32 ++++++++++++++
 src/lib/eina/eina_inline_lock_wince.x | 31 +++++++++++++
 src/lib/eina/eina_lock.h              | 10 +++++
 9 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index f81b139..808f62d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-10-11  Cedric Bail
+
+       * Eina: add Eina_Spinlock API.
+
 2013-10-10  Carsten Haitzler (The Rasterman)
 
         * Ecore-con: use dlopen/dlsym (eina_module) to load libcurl to
diff --git a/NEWS b/NEWS
index fa99192..91d5bd1 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,7 @@ Additions:
      EINA_RECTANGLE_INIT, EINA_RECTANGLE_FORMAT, EINA_RECTANGLE_ARGS.
      - Add eina_f16p16_double_from(), eina_f16p16_double_to().
      - Add eina_swap16(), eina_swap32(), eina_swap64().
+     - Add Eina_Spinlock API.
     * Eet:
      - Add eet_mmap()
      - Add eet_data_descriptor_name_get()
diff --git a/configure.ac b/configure.ac
index f9e61b3..8938381 100644
--- a/configure.ac
+++ b/configure.ac
@@ -825,7 +825,8 @@ EFL_ADD_CFLAGS([EINA], [${EFL_PTHREAD_CFLAGS}])
 
 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 "$want_debug_threads" = "yes"])
+EINA_CONFIG([HAVE_DEBUG_THREADS], [test "x${want_debug_threads}" = "xyes"])
+EINA_CONFIG([HAVE_POSIX_SPINLOCK], [test "x${efl_have_posix_threads_spinlock}" 
= "xyes"])
 
 ### Modules
 
diff --git a/m4/efl_threads.m4 b/m4/efl_threads.m4
index a657500..e7a84b3 100644
--- a/m4/efl_threads.m4
+++ b/m4/efl_threads.m4
@@ -116,11 +116,13 @@ if test "x${_efl_have_posix_threads}" = "xyes" ; then
    AC_LINK_IFELSE(
       [AC_LANG_PROGRAM([[
 #include <pthread.h>
+#include <sched.h>
                        ]],
                        [[
 pthread_spinlock_t lock;
 int res;
 res = pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE);
+sched_yield();
                        ]])],
       [efl_have_posix_threads_spinlock="yes"],
       [efl_have_posix_threads_spinlock="no"])
diff --git a/src/lib/eina/eina_config.h.in b/src/lib/eina/eina_config.h.in
index 27acdf7..72e3ed3 100644
--- a/src/lib/eina/eina_config.h.in
+++ b/src/lib/eina/eina_config.h.in
@@ -92,4 +92,9 @@
 #endif
 @EINA_CONFIGURE_HAVE_BYTESWAP_H@
 
+#ifdef EINA_HAVE_POSIX_SPINLOCK
+# undef EINA_HAVE_POSIX_SPINLOCK
+#endif
+@EINA_CONFIGURE_HAVE_POSIX_SPINLOCK@
+
 #endif /* EINA_CONFIG_H_ */
diff --git a/src/lib/eina/eina_inline_lock_posix.x 
b/src/lib/eina/eina_inline_lock_posix.x
index 88c4b61..4727177 100644
--- a/src/lib/eina/eina_inline_lock_posix.x
+++ b/src/lib/eina/eina_inline_lock_posix.x
@@ -19,6 +19,10 @@
 #ifndef EINA_INLINE_LOCK_POSIX_X_
 #define EINA_INLINE_LOCK_POSIX_X_
 
+#ifdef EINA_HAVE_POSIX_SPINLOCK
+# include <sched.h>
+#endif
+
 #include <errno.h>
 #ifndef __USE_UNIX98
 # define __USE_UNIX98
@@ -49,6 +53,11 @@ 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
+typedef pthread_spinlock_t Eina_Spinlock;
+#else
+typedef Eina_Lock Eina_Spinlock;
+#endif
 
 struct _Eina_Lock
 {
@@ -577,5 +586,79 @@ eina_barrier_wait(Eina_Barrier *barrier)
 #include "eina_inline_lock_barrier.x"
 #endif
 
+static inline Eina_Bool
+eina_spinlock_new(Eina_Spinlock *spinlock)
+{
+#ifdef EINA_HAVE_POSIX_SPINLOCK
+   return pthread_spin_init(spinlock, PTHREAD_PROCESS_PRIVATE) == 0 ? 
EINA_TRUE : EINA_FALSE;
+#else
+   return eina_lock_new(spinlock);
+#endif
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_take(Eina_Spinlock *spinlock)
+{
+#ifdef EINA_HAVE_POSIX_SPINLOCK
+   Eina_Bool yield;
+   int t;
+
+   do {
+      yield = EINA_FALSE;
+
+      t = pthread_spin_trylock(spinlock);
+      if (t != 0)
+        {
+           if (errno == EBUSY)
+             {
+                sched_yield();
+                yield = EINA_TRUE;
+             }
+           else if (errno == EDEADLK)
+             {
+                return EINA_LOCK_DEADLOCK;
+             }
+        }
+
+   } while (t != 0 && yield);
+
+   return t ? EINA_LOCK_FAIL : EINA_LOCK_SUCCEED;
+#else
+   return eina_lock_take(spinlock);
+#endif
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_take_try(Eina_Spinlock *spinlock)
+{
+#ifdef EINA_HAVE_POSIX_SPINLOCK
+   int t;
+
+   t = pthread_spin_trylock(spinlock);
+   return t ? EINA_LOCK_FAIL : EINA_LOCK_SUCCEED;
+#else
+   return eina_lock_take_try(spinlock);
+#endif
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_release(Eina_Spinlock *spinlock)
+{
+#ifdef EINA_HAVE_POSIX_SPINLOCK
+   return pthread_spin_unlock(spinlock) ? EINA_LOCK_FAIL : EINA_LOCK_SUCCEED;
+#else
+   return eina_lock_release(spinlock);
+#endif
+}
+
+static inline void
+eina_spinlock_free(Eina_Spinlock *spinlock)
+{
+#ifdef EINA_HAVE_POSIX_SPINLOCK
+   pthread_spin_destroy(spinlock);
+#else
+   eina_lock_free(spinlock);
+#endif
+}
 
 #endif
diff --git a/src/lib/eina/eina_inline_lock_win32.x 
b/src/lib/eina/eina_inline_lock_win32.x
index 383a543..3c637af 100644
--- a/src/lib/eina/eina_inline_lock_win32.x
+++ b/src/lib/eina/eina_inline_lock_win32.x
@@ -30,6 +30,7 @@ typedef struct _Eina_Condition Eina_Condition;
 typedef struct _Eina_RWLock    Eina_RWLock;
 typedef DWORD                  Eina_TLS;
 typedef HANDLE                 Eina_Semaphore;
+typedef Eina_Lock              Eina_Spinlock;
 
 #if _WIN32_WINNT >= 0x0600
 struct _Eina_Condition
@@ -551,6 +552,37 @@ eina_semaphore_release(Eina_Semaphore *sem, int 
count_release)
    return ReleaseSemaphore(*sem, count_release, NULL) ? EINA_TRUE : EINA_FALSE;
 }
 
+// FIXME: Implement proper spinlock = 
http://www.codeproject.com/Articles/184046/Spin-Lock-in-C
+static inline Eina_Bool
+eina_spinlock_new(Eina_Spinlock *spinlock)
+{
+   return eina_lock_new(spinlock);
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_take(Eina_Spinlock *spinlock)
+{
+   return eina_lock_take(spinlock);
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_take_try(Eina_Spinlock *spinlock)
+{
+   return eina_lock_take_try(spinlock);
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_release(Eina_Spinlock *spinlock)
+{
+   return eina_lock_release(spinlock);
+}
+
+static inline void
+eina_spinlock_free(Eina_Spinlock *spinlock)
+{
+   eina_lock_free(spinlock);
+}
+
 #include "eina_inline_lock_barrier.x"
 
 #endif
diff --git a/src/lib/eina/eina_inline_lock_wince.x 
b/src/lib/eina/eina_inline_lock_wince.x
index 7877959..3b73256 100644
--- a/src/lib/eina/eina_inline_lock_wince.x
+++ b/src/lib/eina/eina_inline_lock_wince.x
@@ -28,6 +28,7 @@
 EAPI extern Eina_Bool _threads_activated;
 
 typedef HANDLE    Eina_Lock;
+typedef Eina_Lock Eina_Spinlock;
 typedef Eina_Lock Eina_RWLock;
 typedef DWORD     Eina_TLS;
 typedef void *    Eina_Semaphore;
@@ -204,6 +205,36 @@ eina_semaphore_release(Eina_Semaphore *sem EINA_UNUSED,
    return EINA_FALSE;
 }
 
+static inline Eina_Bool
+eina_spinlock_new(Eina_Spinlock *spinlock)
+{
+   return eina_lock_new(spinlock);
+}
+
+static inline void
+eina_spinlock_free(Eina_Spinlock *spinlock)
+{
+   eina_lock_free(spinlock);
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_take(Eina_Spinlock *spinlock)
+{
+   return eina_lock_take(spinlock);
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_take_try(Eina_Spinlock *spinlock)
+{
+   return eina_lock_take_try(spinlock);
+}
+
+static inline Eina_Lock_Result
+eina_spinlock_release(Eina_Spinlock *spinlock)
+{
+   return eina_lock_release(spinlock);
+}
+
 #include "eina_inline_lock_barrier.x"
 
 #endif
diff --git a/src/lib/eina/eina_lock.h b/src/lib/eina/eina_lock.h
index ceb19d7..3e4a510 100644
--- a/src/lib/eina/eina_lock.h
+++ b/src/lib/eina/eina_lock.h
@@ -113,6 +113,16 @@ static inline void eina_barrier_free(Eina_Barrier 
*barrier);
 /** @relates static Eina_Bool eina_barrier_wait(Eina_Barrier *barrier); @since 
1.8 */
 static inline Eina_Bool eina_barrier_wait(Eina_Barrier *barrier);
 
+/** @relates static Eina_Bool eina_spinlock_new(Eina_Spinlock *spinlock); 
@since 1.8 */
+static inline Eina_Bool eina_spinlock_new(Eina_Spinlock *spinlock);
+/** @relates static Eina_Lock_Result eina_spinlock_take(Eina_Spinlock 
*spinlock); @since 1.8 */
+static inline Eina_Lock_Result eina_spinlock_take(Eina_Spinlock *spinlock);
+/** @relates static Eina_Lock_Result eina_spinlock_take(Eina_Spinlock 
*spinlock); @since 1.8 */
+static inline Eina_Lock_Result eina_spinlock_take_try(Eina_Spinlock *spinlock);
+/** @relates static Eina_Lock_Result eina_spinlock_release(Eina_Spinlock 
*spinlock); @since 1.8 */
+static inline Eina_Lock_Result eina_spinlock_release(Eina_Spinlock *spinlock);
+/** @relates static void eina_spinlock_free(Eina_Spinlock *spinlock); @since 
1.8 */
+static inline void eina_spinlock_free(Eina_Spinlock *spinlock);
 
 #ifdef EINA_HAVE_DEBUG_THREADS
 # define EINA_MAIN_LOOP_CHECK_RETURN_VAL(val)                          \

-- 


Reply via email to