+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
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()
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
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"])
#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_ */
#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
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
{
#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
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
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
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;
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
/** @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) \