diff options
Diffstat (limited to '')
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | m4/efl_threads.m4 | 2 | ||||
-rw-r--r-- | src/lib/eina/eina_config.h.in | 5 | ||||
-rw-r--r-- | src/lib/eina/eina_inline_lock_posix.x | 83 | ||||
-rw-r--r-- | src/lib/eina/eina_inline_lock_win32.x | 32 | ||||
-rw-r--r-- | src/lib/eina/eina_inline_lock_wince.x | 31 | ||||
-rw-r--r-- | src/lib/eina/eina_lock.h | 10 |
9 files changed, 170 insertions, 1 deletions
@@ -1,3 +1,7 @@ | |||
1 | 2013-10-11 Cedric Bail | ||
2 | |||
3 | * Eina: add Eina_Spinlock API. | ||
4 | |||
1 | 2013-10-10 Carsten Haitzler (The Rasterman) | 5 | 2013-10-10 Carsten Haitzler (The Rasterman) |
2 | 6 | ||
3 | * Ecore-con: use dlopen/dlsym (eina_module) to load libcurl to | 7 | * Ecore-con: use dlopen/dlsym (eina_module) to load libcurl to |
@@ -41,6 +41,7 @@ Additions: | |||
41 | EINA_RECTANGLE_INIT, EINA_RECTANGLE_FORMAT, EINA_RECTANGLE_ARGS. | 41 | EINA_RECTANGLE_INIT, EINA_RECTANGLE_FORMAT, EINA_RECTANGLE_ARGS. |
42 | - Add eina_f16p16_double_from(), eina_f16p16_double_to(). | 42 | - Add eina_f16p16_double_from(), eina_f16p16_double_to(). |
43 | - Add eina_swap16(), eina_swap32(), eina_swap64(). | 43 | - Add eina_swap16(), eina_swap32(), eina_swap64(). |
44 | - Add Eina_Spinlock API. | ||
44 | * Eet: | 45 | * Eet: |
45 | - Add eet_mmap() | 46 | - Add eet_mmap() |
46 | - Add eet_data_descriptor_name_get() | 47 | - Add eet_data_descriptor_name_get() |
diff --git a/configure.ac b/configure.ac index f9e61b38be..8938381bcc 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -825,7 +825,8 @@ EFL_ADD_CFLAGS([EINA], [${EFL_PTHREAD_CFLAGS}]) | |||
825 | 825 | ||
826 | EINA_CONFIG([HAVE_PTHREAD_BARRIER], [test "x${efl_have_pthread_barrier}" = "xyes"]) | 826 | EINA_CONFIG([HAVE_PTHREAD_BARRIER], [test "x${efl_have_pthread_barrier}" = "xyes"]) |
827 | EINA_CONFIG([HAVE_PTHREAD_AFFINITY], [test "x${efl_have_setaffinity}" = "xyes"]) | 827 | EINA_CONFIG([HAVE_PTHREAD_AFFINITY], [test "x${efl_have_setaffinity}" = "xyes"]) |
828 | EINA_CONFIG([HAVE_DEBUG_THREADS], [test "$want_debug_threads" = "yes"]) | 828 | EINA_CONFIG([HAVE_DEBUG_THREADS], [test "x${want_debug_threads}" = "xyes"]) |
829 | EINA_CONFIG([HAVE_POSIX_SPINLOCK], [test "x${efl_have_posix_threads_spinlock}" = "xyes"]) | ||
829 | 830 | ||
830 | ### Modules | 831 | ### Modules |
831 | 832 | ||
diff --git a/m4/efl_threads.m4 b/m4/efl_threads.m4 index a657500434..e7a84b36c0 100644 --- a/m4/efl_threads.m4 +++ b/m4/efl_threads.m4 | |||
@@ -116,11 +116,13 @@ if test "x${_efl_have_posix_threads}" = "xyes" ; then | |||
116 | AC_LINK_IFELSE( | 116 | AC_LINK_IFELSE( |
117 | [AC_LANG_PROGRAM([[ | 117 | [AC_LANG_PROGRAM([[ |
118 | #include <pthread.h> | 118 | #include <pthread.h> |
119 | #include <sched.h> | ||
119 | ]], | 120 | ]], |
120 | [[ | 121 | [[ |
121 | pthread_spinlock_t lock; | 122 | pthread_spinlock_t lock; |
122 | int res; | 123 | int res; |
123 | res = pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE); | 124 | res = pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE); |
125 | sched_yield(); | ||
124 | ]])], | 126 | ]])], |
125 | [efl_have_posix_threads_spinlock="yes"], | 127 | [efl_have_posix_threads_spinlock="yes"], |
126 | [efl_have_posix_threads_spinlock="no"]) | 128 | [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 27acdf72b6..72e3ed3eeb 100644 --- a/src/lib/eina/eina_config.h.in +++ b/src/lib/eina/eina_config.h.in | |||
@@ -92,4 +92,9 @@ | |||
92 | #endif | 92 | #endif |
93 | @EINA_CONFIGURE_HAVE_BYTESWAP_H@ | 93 | @EINA_CONFIGURE_HAVE_BYTESWAP_H@ |
94 | 94 | ||
95 | #ifdef EINA_HAVE_POSIX_SPINLOCK | ||
96 | # undef EINA_HAVE_POSIX_SPINLOCK | ||
97 | #endif | ||
98 | @EINA_CONFIGURE_HAVE_POSIX_SPINLOCK@ | ||
99 | |||
95 | #endif /* EINA_CONFIG_H_ */ | 100 | #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 88c4b61c11..472717774f 100644 --- a/src/lib/eina/eina_inline_lock_posix.x +++ b/src/lib/eina/eina_inline_lock_posix.x | |||
@@ -19,6 +19,10 @@ | |||
19 | #ifndef EINA_INLINE_LOCK_POSIX_X_ | 19 | #ifndef EINA_INLINE_LOCK_POSIX_X_ |
20 | #define EINA_INLINE_LOCK_POSIX_X_ | 20 | #define EINA_INLINE_LOCK_POSIX_X_ |
21 | 21 | ||
22 | #ifdef EINA_HAVE_POSIX_SPINLOCK | ||
23 | # include <sched.h> | ||
24 | #endif | ||
25 | |||
22 | #include <errno.h> | 26 | #include <errno.h> |
23 | #ifndef __USE_UNIX98 | 27 | #ifndef __USE_UNIX98 |
24 | # define __USE_UNIX98 | 28 | # define __USE_UNIX98 |
@@ -49,6 +53,11 @@ typedef struct _Eina_RWLock Eina_RWLock; | |||
49 | typedef struct _Eina_Condition Eina_Condition; | 53 | typedef struct _Eina_Condition Eina_Condition; |
50 | typedef pthread_key_t Eina_TLS; | 54 | typedef pthread_key_t Eina_TLS; |
51 | typedef sem_t Eina_Semaphore; | 55 | typedef sem_t Eina_Semaphore; |
56 | #ifdef EINA_HAVE_POSIX_SPINLOCK | ||
57 | typedef pthread_spinlock_t Eina_Spinlock; | ||
58 | #else | ||
59 | typedef Eina_Lock Eina_Spinlock; | ||
60 | #endif | ||
52 | 61 | ||
53 | struct _Eina_Lock | 62 | struct _Eina_Lock |
54 | { | 63 | { |
@@ -577,5 +586,79 @@ eina_barrier_wait(Eina_Barrier *barrier) | |||
577 | #include "eina_inline_lock_barrier.x" | 586 | #include "eina_inline_lock_barrier.x" |
578 | #endif | 587 | #endif |
579 | 588 | ||
589 | static inline Eina_Bool | ||
590 | eina_spinlock_new(Eina_Spinlock *spinlock) | ||
591 | { | ||
592 | #ifdef EINA_HAVE_POSIX_SPINLOCK | ||
593 | return pthread_spin_init(spinlock, PTHREAD_PROCESS_PRIVATE) == 0 ? EINA_TRUE : EINA_FALSE; | ||
594 | #else | ||
595 | return eina_lock_new(spinlock); | ||
596 | #endif | ||
597 | } | ||
598 | |||
599 | static inline Eina_Lock_Result | ||
600 | eina_spinlock_take(Eina_Spinlock *spinlock) | ||
601 | { | ||
602 | #ifdef EINA_HAVE_POSIX_SPINLOCK | ||
603 | Eina_Bool yield; | ||
604 | int t; | ||
605 | |||
606 | do { | ||
607 | yield = EINA_FALSE; | ||
608 | |||
609 | t = pthread_spin_trylock(spinlock); | ||
610 | if (t != 0) | ||
611 | { | ||
612 | if (errno == EBUSY) | ||
613 | { | ||
614 | sched_yield(); | ||
615 | yield = EINA_TRUE; | ||
616 | } | ||
617 | else if (errno == EDEADLK) | ||
618 | { | ||
619 | return EINA_LOCK_DEADLOCK; | ||
620 | } | ||
621 | } | ||
622 | |||
623 | } while (t != 0 && yield); | ||
624 | |||
625 | return t ? EINA_LOCK_FAIL : EINA_LOCK_SUCCEED; | ||
626 | #else | ||
627 | return eina_lock_take(spinlock); | ||
628 | #endif | ||
629 | } | ||
630 | |||
631 | static inline Eina_Lock_Result | ||
632 | eina_spinlock_take_try(Eina_Spinlock *spinlock) | ||
633 | { | ||
634 | #ifdef EINA_HAVE_POSIX_SPINLOCK | ||
635 | int t; | ||
636 | |||
637 | t = pthread_spin_trylock(spinlock); | ||
638 | return t ? EINA_LOCK_FAIL : EINA_LOCK_SUCCEED; | ||
639 | #else | ||
640 | return eina_lock_take_try(spinlock); | ||
641 | #endif | ||
642 | } | ||
643 | |||
644 | static inline Eina_Lock_Result | ||
645 | eina_spinlock_release(Eina_Spinlock *spinlock) | ||
646 | { | ||
647 | #ifdef EINA_HAVE_POSIX_SPINLOCK | ||
648 | return pthread_spin_unlock(spinlock) ? EINA_LOCK_FAIL : EINA_LOCK_SUCCEED; | ||
649 | #else | ||
650 | return eina_lock_release(spinlock); | ||
651 | #endif | ||
652 | } | ||
653 | |||
654 | static inline void | ||
655 | eina_spinlock_free(Eina_Spinlock *spinlock) | ||
656 | { | ||
657 | #ifdef EINA_HAVE_POSIX_SPINLOCK | ||
658 | pthread_spin_destroy(spinlock); | ||
659 | #else | ||
660 | eina_lock_free(spinlock); | ||
661 | #endif | ||
662 | } | ||
580 | 663 | ||
581 | #endif | 664 | #endif |
diff --git a/src/lib/eina/eina_inline_lock_win32.x b/src/lib/eina/eina_inline_lock_win32.x index 383a543f98..3c637affb1 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; | |||
30 | typedef struct _Eina_RWLock Eina_RWLock; | 30 | typedef struct _Eina_RWLock Eina_RWLock; |
31 | typedef DWORD Eina_TLS; | 31 | typedef DWORD Eina_TLS; |
32 | typedef HANDLE Eina_Semaphore; | 32 | typedef HANDLE Eina_Semaphore; |
33 | typedef Eina_Lock Eina_Spinlock; | ||
33 | 34 | ||
34 | #if _WIN32_WINNT >= 0x0600 | 35 | #if _WIN32_WINNT >= 0x0600 |
35 | struct _Eina_Condition | 36 | struct _Eina_Condition |
@@ -551,6 +552,37 @@ eina_semaphore_release(Eina_Semaphore *sem, int count_release) | |||
551 | return ReleaseSemaphore(*sem, count_release, NULL) ? EINA_TRUE : EINA_FALSE; | 552 | return ReleaseSemaphore(*sem, count_release, NULL) ? EINA_TRUE : EINA_FALSE; |
552 | } | 553 | } |
553 | 554 | ||
555 | // FIXME: Implement proper spinlock = http://www.codeproject.com/Articles/184046/Spin-Lock-in-C | ||
556 | static inline Eina_Bool | ||
557 | eina_spinlock_new(Eina_Spinlock *spinlock) | ||
558 | { | ||
559 | return eina_lock_new(spinlock); | ||
560 | } | ||
561 | |||
562 | static inline Eina_Lock_Result | ||
563 | eina_spinlock_take(Eina_Spinlock *spinlock) | ||
564 | { | ||
565 | return eina_lock_take(spinlock); | ||
566 | } | ||
567 | |||
568 | static inline Eina_Lock_Result | ||
569 | eina_spinlock_take_try(Eina_Spinlock *spinlock) | ||
570 | { | ||
571 | return eina_lock_take_try(spinlock); | ||
572 | } | ||
573 | |||
574 | static inline Eina_Lock_Result | ||
575 | eina_spinlock_release(Eina_Spinlock *spinlock) | ||
576 | { | ||
577 | return eina_lock_release(spinlock); | ||
578 | } | ||
579 | |||
580 | static inline void | ||
581 | eina_spinlock_free(Eina_Spinlock *spinlock) | ||
582 | { | ||
583 | eina_lock_free(spinlock); | ||
584 | } | ||
585 | |||
554 | #include "eina_inline_lock_barrier.x" | 586 | #include "eina_inline_lock_barrier.x" |
555 | 587 | ||
556 | #endif | 588 | #endif |
diff --git a/src/lib/eina/eina_inline_lock_wince.x b/src/lib/eina/eina_inline_lock_wince.x index 787795977f..3b732568da 100644 --- a/src/lib/eina/eina_inline_lock_wince.x +++ b/src/lib/eina/eina_inline_lock_wince.x | |||
@@ -28,6 +28,7 @@ | |||
28 | EAPI extern Eina_Bool _threads_activated; | 28 | EAPI extern Eina_Bool _threads_activated; |
29 | 29 | ||
30 | typedef HANDLE Eina_Lock; | 30 | typedef HANDLE Eina_Lock; |
31 | typedef Eina_Lock Eina_Spinlock; | ||
31 | typedef Eina_Lock Eina_RWLock; | 32 | typedef Eina_Lock Eina_RWLock; |
32 | typedef DWORD Eina_TLS; | 33 | typedef DWORD Eina_TLS; |
33 | typedef void * Eina_Semaphore; | 34 | typedef void * Eina_Semaphore; |
@@ -204,6 +205,36 @@ eina_semaphore_release(Eina_Semaphore *sem EINA_UNUSED, | |||
204 | return EINA_FALSE; | 205 | return EINA_FALSE; |
205 | } | 206 | } |
206 | 207 | ||
208 | static inline Eina_Bool | ||
209 | eina_spinlock_new(Eina_Spinlock *spinlock) | ||
210 | { | ||
211 | return eina_lock_new(spinlock); | ||
212 | } | ||
213 | |||
214 | static inline void | ||
215 | eina_spinlock_free(Eina_Spinlock *spinlock) | ||
216 | { | ||
217 | eina_lock_free(spinlock); | ||
218 | } | ||
219 | |||
220 | static inline Eina_Lock_Result | ||
221 | eina_spinlock_take(Eina_Spinlock *spinlock) | ||
222 | { | ||
223 | return eina_lock_take(spinlock); | ||
224 | } | ||
225 | |||
226 | static inline Eina_Lock_Result | ||
227 | eina_spinlock_take_try(Eina_Spinlock *spinlock) | ||
228 | { | ||
229 | return eina_lock_take_try(spinlock); | ||
230 | } | ||
231 | |||
232 | static inline Eina_Lock_Result | ||
233 | eina_spinlock_release(Eina_Spinlock *spinlock) | ||
234 | { | ||
235 | return eina_lock_release(spinlock); | ||
236 | } | ||
237 | |||
207 | #include "eina_inline_lock_barrier.x" | 238 | #include "eina_inline_lock_barrier.x" |
208 | 239 | ||
209 | #endif | 240 | #endif |
diff --git a/src/lib/eina/eina_lock.h b/src/lib/eina/eina_lock.h index ceb19d7b71..3e4a510252 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); | |||
113 | /** @relates static Eina_Bool eina_barrier_wait(Eina_Barrier *barrier); @since 1.8 */ | 113 | /** @relates static Eina_Bool eina_barrier_wait(Eina_Barrier *barrier); @since 1.8 */ |
114 | static inline Eina_Bool eina_barrier_wait(Eina_Barrier *barrier); | 114 | static inline Eina_Bool eina_barrier_wait(Eina_Barrier *barrier); |
115 | 115 | ||
116 | /** @relates static Eina_Bool eina_spinlock_new(Eina_Spinlock *spinlock); @since 1.8 */ | ||
117 | static inline Eina_Bool eina_spinlock_new(Eina_Spinlock *spinlock); | ||
118 | /** @relates static Eina_Lock_Result eina_spinlock_take(Eina_Spinlock *spinlock); @since 1.8 */ | ||
119 | static inline Eina_Lock_Result eina_spinlock_take(Eina_Spinlock *spinlock); | ||
120 | /** @relates static Eina_Lock_Result eina_spinlock_take(Eina_Spinlock *spinlock); @since 1.8 */ | ||
121 | static inline Eina_Lock_Result eina_spinlock_take_try(Eina_Spinlock *spinlock); | ||
122 | /** @relates static Eina_Lock_Result eina_spinlock_release(Eina_Spinlock *spinlock); @since 1.8 */ | ||
123 | static inline Eina_Lock_Result eina_spinlock_release(Eina_Spinlock *spinlock); | ||
124 | /** @relates static void eina_spinlock_free(Eina_Spinlock *spinlock); @since 1.8 */ | ||
125 | static inline void eina_spinlock_free(Eina_Spinlock *spinlock); | ||
116 | 126 | ||
117 | #ifdef EINA_HAVE_DEBUG_THREADS | 127 | #ifdef EINA_HAVE_DEBUG_THREADS |
118 | # define EINA_MAIN_LOOP_CHECK_RETURN_VAL(val) \ | 128 | # define EINA_MAIN_LOOP_CHECK_RETURN_VAL(val) \ |