summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-09-19 08:58:56 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-09-20 14:53:05 +0900
commit41c332b7263a43132d5373760c88d09bc6e6dc80 (patch)
treeb6f0ded25f670cc70d6b25d9001850b8e5d0bb60 /src
parent3efdd5df54b3fb26b5aaaf7252865d748411188f (diff)
eina - redo a lot of the static inlines to have better instr cache usage
this moves a lot of logic that is rare away from the linear/flat asm path of code so we et fewer l1 cache misses when executing chuncks of our code. this also reduces the code size and takes some funcs like in eina_inline_lock_posix.x and makes them real functions to reduce code size thus better l1 cache usage - only for new/free of locks. spinlocks, semaphores etc. as these will have no advantage being inlined but simply bloat out code size instead. overall this actually reduces efl lib binary sizes 0.4%, so that's a good sign. this passes make check and i think i got it right... let me know if i didn't. i'm also not sure i should just keep the static inlines and not make the formerly static inline funcs full EAPI ones now... good q.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Eina.am1
-rw-r--r--src/lib/eina/eina_inline_array.x44
-rw-r--r--src/lib/eina/eina_inline_hash.x28
-rw-r--r--src/lib/eina/eina_inline_inlist.x22
-rw-r--r--src/lib/eina/eina_inline_list.x36
-rw-r--r--src/lib/eina/eina_inline_lock_barrier.x21
-rw-r--r--src/lib/eina/eina_inline_lock_posix.x456
-rw-r--r--src/lib/eina/eina_inline_log.x6
-rw-r--r--src/lib/eina/eina_inline_mempool.x40
-rw-r--r--src/lib/eina/eina_inline_rbtree.x10
-rw-r--r--src/lib/eina/eina_inline_rectangle.x164
-rw-r--r--src/lib/eina/eina_inline_slice.x147
-rw-r--r--src/lib/eina/eina_inline_str.x3
-rw-r--r--src/lib/eina/eina_lock.c270
-rw-r--r--src/lib/eina/eina_lock.h2
15 files changed, 644 insertions, 606 deletions
diff --git a/src/Makefile_Eina.am b/src/Makefile_Eina.am
index b442635ccd..96ff37657f 100644
--- a/src/Makefile_Eina.am
+++ b/src/Makefile_Eina.am
@@ -136,6 +136,7 @@ lib/eina/eina_inlist.c \
136lib/eina/eina_iterator.c \ 136lib/eina/eina_iterator.c \
137lib/eina/eina_lalloc.c \ 137lib/eina/eina_lalloc.c \
138lib/eina/eina_list.c \ 138lib/eina/eina_list.c \
139lib/eina/eina_lock.c \
139lib/eina/eina_log.c \ 140lib/eina/eina_log.c \
140lib/eina/eina_magic.c \ 141lib/eina/eina_magic.c \
141lib/eina/eina_main.c \ 142lib/eina/eina_main.c \
diff --git a/src/lib/eina/eina_inline_array.x b/src/lib/eina/eina_inline_array.x
index c191218d03..40a6e0dcc7 100644
--- a/src/lib/eina/eina_inline_array.x
+++ b/src/lib/eina/eina_inline_array.x
@@ -44,29 +44,26 @@ EAPI Eina_Bool eina_array_grow(Eina_Array *array);
44static inline Eina_Bool 44static inline Eina_Bool
45eina_array_push(Eina_Array *array, const void *data) 45eina_array_push(Eina_Array *array, const void *data)
46{ 46{
47 if (!data) return EINA_FALSE; 47 if (data)
48 48 {
49 if (EINA_UNLIKELY((array->count + 1) > array->total)) 49 if (EINA_UNLIKELY((array->count + 1) > array->total)) goto do_grow;
50 if (!eina_array_grow(array)) 50do_grow_back:
51 return EINA_FALSE; 51
52 52 array->data[array->count++] = (void*) data;
53 array->data[array->count++] = (void*) data; 53
54 54 return EINA_TRUE;
55 return EINA_TRUE; 55 }
56 return EINA_FALSE;
57do_grow:
58 if (!eina_array_grow(array)) return EINA_FALSE;
59 goto do_grow_back;
56} 60}
57 61
58static inline void * 62static inline void *
59eina_array_pop(Eina_Array *array) 63eina_array_pop(Eina_Array *array)
60{ 64{
61 void *ret = NULL; 65 if (array->count > 0) return array->data[--array->count];
62 66 return NULL;
63 if (array->count <= 0)
64 goto on_empty;
65
66 ret = array->data[--array->count];
67
68 on_empty:
69 return ret;
70} 67}
71 68
72static inline void * 69static inline void *
@@ -104,12 +101,11 @@ eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata)
104 Eina_Bool ret = EINA_TRUE; 101 Eina_Bool ret = EINA_TRUE;
105 102
106 EINA_ARRAY_ITER_NEXT(array, i, data, iterator) 103 EINA_ARRAY_ITER_NEXT(array, i, data, iterator)
107 if (cb(array, data, fdata) != EINA_TRUE) 104 {
108 { 105 if (cb(array, data, fdata) == EINA_TRUE) continue;
109 ret = EINA_FALSE; 106 ret = EINA_FALSE;
110 break; 107 break;
111 } 108 }
112
113 return ret; 109 return ret;
114} 110}
115 111
diff --git a/src/lib/eina/eina_inline_hash.x b/src/lib/eina/eina_inline_hash.x
index ab87960d33..114b584eee 100644
--- a/src/lib/eina/eina_inline_hash.x
+++ b/src/lib/eina/eina_inline_hash.x
@@ -33,11 +33,13 @@ eina_hash_djb2(const char *key, int len)
33 unsigned int hash_num = 5381 ^ eina_seed; 33 unsigned int hash_num = 5381 ^ eina_seed;
34 const unsigned char *ptr; 34 const unsigned char *ptr;
35 35
36 if (!key) return 0; 36 if (key)
37 for (ptr = (unsigned char *)key; len; ptr++, len--) 37 {
38 hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */ 38 for (ptr = (unsigned char *)key; len; ptr++, len--)
39 39 hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */
40 return (int)hash_num; 40 return (int)hash_num;
41 }
42 return 0;
41} 43}
42 44
43static inline int 45static inline int
@@ -47,14 +49,14 @@ eina_hash_djb2_len(const char *key, int *plen)
47 int len = 0; 49 int len = 0;
48 const unsigned char *ptr; 50 const unsigned char *ptr;
49 51
50 if (!key) return 0; 52 if (key)
51 53 {
52 for (ptr = (unsigned char *)key; *ptr; ptr++, len++) 54 for (ptr = (unsigned char *)key; *ptr; ptr++, len++)
53 hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */ 55 hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */
54 56 *plen = len + 1;
55 *plen = len + 1; 57 return (int)hash_num;
56 58 }
57 return (int)hash_num; 59 return 0;
58} 60}
59 61
60static inline int 62static inline int
diff --git a/src/lib/eina/eina_inline_inlist.x b/src/lib/eina/eina_inline_inlist.x
index f4cd95e7dd..98ba18faec 100644
--- a/src/lib/eina/eina_inline_inlist.x
+++ b/src/lib/eina/eina_inline_inlist.x
@@ -24,11 +24,12 @@ eina_inlist_first(const Eina_Inlist *list)
24{ 24{
25 Eina_Inlist *l; 25 Eina_Inlist *l;
26 26
27 if (!list) return NULL; 27 if (list)
28 28 {
29 for (l = (Eina_Inlist*)list; l->prev; l = l->prev); 29 for (l = (Eina_Inlist*)list; l->prev; l = l->prev);
30 30 return l;
31 return l; 31 }
32 return NULL;
32} 33}
33 34
34static inline Eina_Inlist * 35static inline Eina_Inlist *
@@ -36,11 +37,12 @@ eina_inlist_last(const Eina_Inlist *list)
36{ 37{
37 Eina_Inlist *l; 38 Eina_Inlist *l;
38 39
39 if (!list) return NULL; 40 if (list)
40 41 {
41 for (l = (Eina_Inlist*)list; l->next; l = l->next); 42 for (l = (Eina_Inlist*)list; l->next; l = l->next);
42 43 return l;
43 return l; 44 }
45 return NULL;
44} 46}
45 47
46#endif /* EINA_INLIST_INLINE_H_ */ 48#endif /* EINA_INLIST_INLINE_H_ */
diff --git a/src/lib/eina/eina_inline_list.x b/src/lib/eina/eina_inline_list.x
index 6d03e38533..01f2af8c58 100644
--- a/src/lib/eina/eina_inline_list.x
+++ b/src/lib/eina/eina_inline_list.x
@@ -22,53 +22,55 @@
22static inline Eina_List * 22static inline Eina_List *
23eina_list_last(const Eina_List *list) 23eina_list_last(const Eina_List *list)
24{ 24{
25 if (!list) return NULL; 25 if (list) return list->accounting->last;
26 return list->accounting->last; 26 return NULL;
27} 27}
28 28
29static inline Eina_List * 29static inline Eina_List *
30eina_list_next(const Eina_List *list) 30eina_list_next(const Eina_List *list)
31{ 31{
32 if (!list) return NULL; 32 if (list) return list->next;
33 return list->next; 33 return NULL;
34} 34}
35 35
36static inline Eina_List * 36static inline Eina_List *
37eina_list_prev(const Eina_List *list) 37eina_list_prev(const Eina_List *list)
38{ 38{
39 if (!list) return NULL; 39 if (list) return list->prev;
40 return list->prev; 40 return NULL;
41} 41}
42 42
43static inline void * 43static inline void *
44eina_list_data_get(const Eina_List *list) 44eina_list_data_get(const Eina_List *list)
45{ 45{
46 if (!list) return NULL; 46 if (list) return list->data;
47 return list->data; 47 return NULL;
48} 48}
49 49
50static inline void * 50static inline void *
51eina_list_data_set(Eina_List *list, const void *data) 51eina_list_data_set(Eina_List *list, const void *data)
52{ 52{
53 void *tmp; 53 if (list)
54 if (!list) return NULL; 54 {
55 tmp = list->data; 55 void *tmp = list->data;
56 list->data = (void*) data; 56 list->data = (void *) data;
57 return tmp; 57 return tmp;
58 }
59 return NULL;
58} 60}
59 61
60static inline unsigned int 62static inline unsigned int
61eina_list_count(const Eina_List *list) 63eina_list_count(const Eina_List *list)
62{ 64{
63 if (!list) return 0; 65 if (list) return list->accounting->count;
64 return list->accounting->count; 66 return 0;
65} 67}
66 68
67static inline void * 69static inline void *
68eina_list_last_data_get(const Eina_List *list) 70eina_list_last_data_get(const Eina_List *list)
69{ 71{
70 if (!list) return NULL; 72 if (list) return eina_list_data_get(eina_list_last(list));
71 return eina_list_data_get(eina_list_last(list)); 73 return NULL;
72} 74}
73 75
74#endif /* EINA_LIST_INLINE_H_ */ 76#endif /* EINA_LIST_INLINE_H_ */
diff --git a/src/lib/eina/eina_inline_lock_barrier.x b/src/lib/eina/eina_inline_lock_barrier.x
index 416fccf4e4..02f4bdc20d 100644
--- a/src/lib/eina/eina_inline_lock_barrier.x
+++ b/src/lib/eina/eina_inline_lock_barrier.x
@@ -10,27 +10,6 @@ struct _Eina_Barrier
10}; 10};
11 11
12static inline Eina_Bool 12static inline Eina_Bool
13eina_barrier_new(Eina_Barrier *barrier, int needed)
14{
15 barrier->needed = needed;
16 barrier->called = 0;
17 if (!eina_lock_new(&(barrier->cond_lock)))
18 return EINA_FALSE;
19 if (!eina_condition_new(&(barrier->cond), &(barrier->cond_lock)))
20 return EINA_FALSE;
21 return EINA_TRUE;
22}
23
24static inline void
25eina_barrier_free(Eina_Barrier *barrier)
26{
27 eina_condition_free(&(barrier->cond));
28 eina_lock_free(&(barrier->cond_lock));
29 barrier->needed = 0;
30 barrier->called = 0;
31}
32
33static inline Eina_Bool
34eina_barrier_wait(Eina_Barrier *barrier) 13eina_barrier_wait(Eina_Barrier *barrier)
35{ 14{
36 eina_lock_take(&(barrier->cond_lock)); 15 eina_lock_take(&(barrier->cond_lock));
diff --git a/src/lib/eina/eina_inline_lock_posix.x b/src/lib/eina/eina_inline_lock_posix.x
index 05babd52e1..51760caeed 100644
--- a/src/lib/eina/eina_inline_lock_posix.x
+++ b/src/lib/eina/eina_inline_lock_posix.x
@@ -63,20 +63,15 @@
63typedef void (*Eina_Lock_Bt_Func) (); 63typedef void (*Eina_Lock_Bt_Func) ();
64 64
65#include "eina_inlist.h" 65#include "eina_inlist.h"
66#define EINA_LOCK_ABORT_DEBUG(err, fn, ptr) do { \ 66#endif
67 printf("EINA ERROR: '%s' on %s %p\n", strerror(err), #fn, ptr); \ 67
68 abort(); \ 68EAPI void _eina_lock_debug_abort(int err, const char *fn, const volatile void *ptr);
69} while (0) 69EAPI void _eina_lock_debug_deadlock(const char *fn, const volatile void *ptr);
70#define EINA_LOCK_DEADLOCK_DEBUG(fn, ptr) do { \ 70
71 printf("EINA ERROR: DEADLOCK on %s %p\n", #fn, ptr); \
72 abort(); \
73} while (0)
74#else
75#define EINA_LOCK_ABORT_DEBUG(err, fn, ptr) \ 71#define EINA_LOCK_ABORT_DEBUG(err, fn, ptr) \
76 printf("EINA ERROR: '%s' on %s %p\n", strerror(err), #fn, ptr) 72 _eina_lock_debug_abort(err, #fn, ptr)
77#define EINA_LOCK_DEADLOCK_DEBUG(fn, ptr) \ 73#define EINA_LOCK_DEADLOCK_DEBUG(fn, ptr) \
78 printf("EINA ERROR: DEADLOCK on %s %p\n", #fn, ptr) 74 _eina_lock_debug_deadlock(#fn, ptr)
79#endif
80 75
81/* For cond_timedwait */ 76/* For cond_timedwait */
82#include <time.h> 77#include <time.h>
@@ -103,6 +98,8 @@ typedef semaphore_t Eina_Semaphore;
103typedef sem_t Eina_Semaphore; 98typedef sem_t Eina_Semaphore;
104#endif 99#endif
105 100
101EAPI void eina_lock_debug(const Eina_Lock *mutex);
102
106/** @privatesection @{ */ 103/** @privatesection @{ */
107struct _Eina_Lock 104struct _Eina_Lock
108{ 105{
@@ -145,91 +142,34 @@ EAPI extern pthread_mutex_t _eina_tracking_lock;
145EAPI extern Eina_Inlist *_eina_tracking; 142EAPI extern Eina_Inlist *_eina_tracking;
146#endif 143#endif
147 144
148static inline void 145
149eina_lock_debug(const Eina_Lock *mutex) 146EAPI Eina_Bool _eina_lock_new(Eina_Lock *mutex, Eina_Bool recursive);
150{ 147EAPI void _eina_lock_free(Eina_Lock *mutex);
151#ifdef EINA_HAVE_DEBUG_THREADS 148EAPI Eina_Bool _eina_condition_new(Eina_Condition *cond, Eina_Lock *mutex);
152 printf("lock %p, locked: %i, by %ti\n", 149EAPI void _eina_condition_free(Eina_Condition *cond);
153 mutex, (int)mutex->locked, (ptrdiff_t)mutex->lock_thread_id); 150EAPI Eina_Bool _eina_rwlock_new(Eina_RWLock *mutex);
154 backtrace_symbols_fd((void **)mutex->lock_bt, mutex->lock_bt_num, 1); 151EAPI void _eina_rwlock_free(Eina_RWLock *mutex);
155#else 152EAPI Eina_Bool _eina_spinlock_new(Eina_Spinlock *spinlock);
156 (void) mutex; 153EAPI void _eina_spinlock_free(Eina_Spinlock *spinlock);
157#endif 154EAPI Eina_Bool _eina_semaphore_new(Eina_Semaphore *sem, int count_init);
158} 155EAPI Eina_Bool _eina_semaphore_free(Eina_Semaphore *sem);
159 156
160static inline Eina_Bool 157static inline Eina_Bool
161eina_lock_new(Eina_Lock *mutex) 158eina_lock_new(Eina_Lock *mutex)
162{ 159{
163 pthread_mutexattr_t attr; 160 return _eina_lock_new(mutex, EINA_FALSE);
164 Eina_Bool ok = EINA_FALSE;
165
166#ifdef EINA_HAVE_DEBUG_THREADS
167 if (!_eina_threads_activated)
168 assert(pthread_equal(_eina_main_loop, pthread_self()));
169#endif
170
171 if (pthread_mutexattr_init(&attr) != 0)
172 return EINA_FALSE;
173 /* NOTE: PTHREAD_MUTEX_RECURSIVE is not allowed at all, you will break on/off
174 feature for sure with that change. */
175#ifdef EINA_HAVE_DEBUG_THREADS
176 if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
177 goto fail_release;
178 memset(mutex, 0, sizeof(Eina_Lock));
179#endif
180 if (pthread_mutex_init(&(mutex->mutex), &attr) != 0)
181 goto fail_release;
182
183 ok = EINA_TRUE;
184fail_release:
185 pthread_mutexattr_destroy(&attr);
186 return ok;
187} 161}
188 162
189static inline Eina_Bool 163static inline Eina_Bool
190eina_lock_recursive_new(Eina_Lock *mutex) 164eina_lock_recursive_new(Eina_Lock *mutex)
191{ 165{
192 pthread_mutexattr_t attr; 166 return _eina_lock_new(mutex, EINA_TRUE);
193 Eina_Bool ok = EINA_FALSE;
194
195#ifdef EINA_HAVE_DEBUG_THREADS
196 if (!_eina_threads_activated)
197 assert(pthread_equal(_eina_main_loop, pthread_self()));
198#endif
199
200 if (pthread_mutexattr_init(&attr) != 0)
201 return EINA_FALSE;
202 if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
203 goto fail_release;
204#ifdef EINA_HAVE_DEBUG_THREADS
205 if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
206 goto fail_release;
207 memset(mutex, 0, sizeof(Eina_Lock));
208#endif
209 if (pthread_mutex_init(&(mutex->mutex), &attr) != 0)
210 goto fail_release;
211
212 ok = EINA_TRUE;
213fail_release:
214 pthread_mutexattr_destroy(&attr);
215 return ok;
216} 167}
217 168
218static inline void 169static inline void
219eina_lock_free(Eina_Lock *mutex) 170eina_lock_free(Eina_Lock *mutex)
220{ 171{
221 int ok; 172 _eina_lock_free(mutex);
222
223#ifdef EINA_HAVE_DEBUG_THREADS
224 if (!_eina_threads_activated)
225 assert(pthread_equal(_eina_main_loop, pthread_self()));
226#endif
227
228 ok = pthread_mutex_destroy(&(mutex->mutex));
229 if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, mutex_destroy, mutex);
230#ifdef EINA_HAVE_DEBUG_THREADS
231 memset(mutex, 0, sizeof(Eina_Lock));
232#endif
233} 173}
234 174
235static inline Eina_Lock_Result 175static inline Eina_Lock_Result
@@ -278,9 +218,8 @@ eina_lock_take(Eina_Lock *mutex)
278 if (ok == 0) ret = EINA_LOCK_SUCCEED; 218 if (ok == 0) ret = EINA_LOCK_SUCCEED;
279 else if (ok == EDEADLK) 219 else if (ok == EDEADLK)
280 { 220 {
281 printf("EINA ERROR: DEADLOCK on lock %p\n", mutex);
282 eina_lock_debug(mutex); 221 eina_lock_debug(mutex);
283 ret = EINA_LOCK_DEADLOCK; // magic 222 ret = EINA_LOCK_DEADLOCK;
284#ifdef EINA_HAVE_DEBUG_THREADS 223#ifdef EINA_HAVE_DEBUG_THREADS
285 if (_eina_threads_debug) abort(); 224 if (_eina_threads_debug) abort();
286#endif 225#endif
@@ -326,8 +265,8 @@ eina_lock_take_try(Eina_Lock *mutex)
326 if (ok == 0) ret = EINA_LOCK_SUCCEED; 265 if (ok == 0) ret = EINA_LOCK_SUCCEED;
327 else if (ok == EDEADLK) 266 else if (ok == EDEADLK)
328 { 267 {
329 printf("EINA ERROR: DEADLOCK on trylock %p\n", mutex); 268 eina_lock_debug(mutex);
330 ret = EINA_LOCK_DEADLOCK; // magic 269 ret = EINA_LOCK_DEADLOCK;
331 } 270 }
332 else if (ok != EBUSY) EINA_LOCK_ABORT_DEBUG(ok, trylock, mutex); 271 else if (ok != EBUSY) EINA_LOCK_ABORT_DEBUG(ok, trylock, mutex);
333#ifdef EINA_HAVE_DEBUG_THREADS 272#ifdef EINA_HAVE_DEBUG_THREADS
@@ -383,64 +322,13 @@ eina_lock_release(Eina_Lock *mutex)
383static inline Eina_Bool 322static inline Eina_Bool
384eina_condition_new(Eina_Condition *cond, Eina_Lock *mutex) 323eina_condition_new(Eina_Condition *cond, Eina_Lock *mutex)
385{ 324{
386 pthread_condattr_t attr; 325 return _eina_condition_new(cond, mutex);
387 int ok;
388
389#ifdef EINA_HAVE_DEBUG_THREADS
390 assert(mutex != NULL);
391 if (!_eina_threads_activated)
392 assert(pthread_equal(_eina_main_loop, pthread_self()));
393 memset(cond, 0, sizeof (Eina_Condition));
394#endif
395
396 cond->lock = mutex;
397 pthread_condattr_init(&attr);
398
399 /* OSX doesn't provide clockid_t or clock_gettime. */
400#if defined(__clockid_t_defined)
401 cond->clkid = (clockid_t) 0;
402 /* We try here to chose the best clock for cond_timedwait */
403# if defined(CLOCK_MONOTONIC_RAW)
404 if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC_RAW))
405 cond->clkid = CLOCK_MONOTONIC_RAW;
406# endif
407# if defined(CLOCK_MONOTONIC)
408 if (!cond->clkid && !pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
409 cond->clkid = CLOCK_MONOTONIC;
410# endif
411# if defined(CLOCK_REALTIME)
412 if (!cond->clkid && !pthread_condattr_setclock(&attr, CLOCK_REALTIME))
413 cond->clkid = CLOCK_REALTIME;
414# endif
415#endif
416
417 ok = pthread_cond_init(&cond->condition, &attr);
418 if (ok != 0)
419 {
420 pthread_condattr_destroy(&attr);
421#ifdef EINA_HAVE_DEBUG_THREADS
422 if (ok == EBUSY)
423 printf("eina_condition_new on already initialized Eina_Condition\n");
424#endif
425 return EINA_FALSE;
426 }
427
428 pthread_condattr_destroy(&attr);
429 return EINA_TRUE;
430} 326}
431 327
432static inline void 328static inline void
433eina_condition_free(Eina_Condition *cond) 329eina_condition_free(Eina_Condition *cond)
434{ 330{
435#ifdef EINA_HAVE_DEBUG_THREADS 331 _eina_condition_free(cond);
436 if (!_eina_threads_activated)
437 assert(pthread_equal(_eina_main_loop, pthread_self()));
438#endif
439
440 pthread_cond_destroy(&(cond->condition));
441#ifdef EINA_HAVE_DEBUG_THREADS
442 memset(cond, 0, sizeof (Eina_Condition));
443#endif
444} 332}
445 333
446static inline Eina_Bool 334static inline Eina_Bool
@@ -455,7 +343,7 @@ eina_condition_wait(Eina_Condition *cond)
455 343
456 pthread_mutex_lock(&_eina_tracking_lock); 344 pthread_mutex_lock(&_eina_tracking_lock);
457 _eina_tracking = eina_inlist_remove(_eina_tracking, 345 _eina_tracking = eina_inlist_remove(_eina_tracking,
458 EINA_INLIST_GET(cond->lock)); 346 EINA_INLIST_GET(cond->lock));
459 pthread_mutex_unlock(&_eina_tracking_lock); 347 pthread_mutex_unlock(&_eina_tracking_lock);
460#endif 348#endif
461 349
@@ -467,7 +355,7 @@ eina_condition_wait(Eina_Condition *cond)
467#ifdef EINA_HAVE_DEBUG_THREADS 355#ifdef EINA_HAVE_DEBUG_THREADS
468 pthread_mutex_lock(&_eina_tracking_lock); 356 pthread_mutex_lock(&_eina_tracking_lock);
469 _eina_tracking = eina_inlist_append(_eina_tracking, 357 _eina_tracking = eina_inlist_append(_eina_tracking,
470 EINA_INLIST_GET(cond->lock)); 358 EINA_INLIST_GET(cond->lock));
471 pthread_mutex_unlock(&_eina_tracking_lock); 359 pthread_mutex_unlock(&_eina_tracking_lock);
472#endif 360#endif
473 361
@@ -483,69 +371,60 @@ eina_condition_timedwait(Eina_Condition *cond, double t)
483 int err; 371 int err;
484 Eina_Bool r = EINA_FALSE; 372 Eina_Bool r = EINA_FALSE;
485 373
486 if (t < 0) 374 if (t >= 0.0)
487 { 375 {
488 errno = EINVAL;
489 return EINA_FALSE;
490 }
491
492#if defined(__clockid_t_defined) 376#if defined(__clockid_t_defined)
493 if (cond->clkid) 377 if (cond->clkid)
494 { 378 {
495 if (clock_gettime(cond->clkid, &ts) != 0) 379 if (clock_gettime(cond->clkid, &ts) != 0) return EINA_FALSE;
496 return EINA_FALSE; 380 }
497 } 381 else
498 else
499#endif 382#endif
500 { 383 {
501 /* Obsolete for Linux. 384 /* Obsolete for Linux.
502 * TODO: use pthread_cond_timedwait_relative_np for OSX. */ 385 * TODO: use pthread_cond_timedwait_relative_np for OSX. */
503 struct timeval tv; 386 struct timeval tv;
504 if (gettimeofday(&tv, NULL) != 0) 387 if (gettimeofday(&tv, NULL) != 0) return EINA_FALSE;
505 return EINA_FALSE; 388 ts.tv_sec = tv.tv_sec;
506 389 ts.tv_nsec = tv.tv_usec * 1000L;
507 ts.tv_sec = tv.tv_sec; 390 }
508 ts.tv_nsec = tv.tv_usec * 1000L;
509 }
510 391
511#ifdef EINA_HAVE_DEBUG_THREADS 392#ifdef EINA_HAVE_DEBUG_THREADS
512 assert(_eina_threads_activated); 393 assert(_eina_threads_activated);
513 assert(cond->lock != NULL); 394 assert(cond->lock != NULL);
514 395
515 pthread_mutex_lock(&_eina_tracking_lock); 396 pthread_mutex_lock(&_eina_tracking_lock);
516 _eina_tracking = eina_inlist_remove(_eina_tracking, 397 _eina_tracking = eina_inlist_remove(_eina_tracking,
517 EINA_INLIST_GET(cond->lock)); 398 EINA_INLIST_GET(cond->lock));
518 pthread_mutex_unlock(&_eina_tracking_lock); 399 pthread_mutex_unlock(&_eina_tracking_lock);
519#endif 400#endif
520 401
521 sec = (time_t)t; 402 sec = (time_t)t;
522 nsec = (t - (double) sec) * 1000000000L; 403 nsec = (t - (double)sec) * 1000000000L;
523 ts.tv_sec += sec; 404 ts.tv_sec += sec;
524 ts.tv_nsec += nsec; 405 ts.tv_nsec += nsec;
525 if (ts.tv_nsec > 1000000000L) 406 if (ts.tv_nsec > 1000000000L)
526 { 407 {
527 ts.tv_sec++; 408 ts.tv_sec++;
528 ts.tv_nsec -= 1000000000L; 409 ts.tv_nsec -= 1000000000L;
529 } 410 }
530 411
531 err = pthread_cond_timedwait(&(cond->condition), 412 err = pthread_cond_timedwait(&(cond->condition),
532 &(cond->lock->mutex), 413 &(cond->lock->mutex),
533 &ts); 414 &ts);
534 if (err == 0) 415 if (err == 0) r = EINA_TRUE;
535 r = EINA_TRUE; 416 else if (err == EPERM) eina_error_set(EPERM);
536 else if (err == EPERM) 417 else if (err == ETIMEDOUT) eina_error_set(ETIMEDOUT);
537 eina_error_set(EPERM); 418 else EINA_LOCK_ABORT_DEBUG(err, cond_timedwait, cond);
538 else if (err == ETIMEDOUT)
539 eina_error_set(ETIMEDOUT);
540 else EINA_LOCK_ABORT_DEBUG(err, cond_timedwait, cond);
541 419
542#ifdef EINA_HAVE_DEBUG_THREADS 420#ifdef EINA_HAVE_DEBUG_THREADS
543 pthread_mutex_lock(&_eina_tracking_lock); 421 pthread_mutex_lock(&_eina_tracking_lock);
544 _eina_tracking = eina_inlist_append(_eina_tracking, 422 _eina_tracking = eina_inlist_append(_eina_tracking,
545 EINA_INLIST_GET(cond->lock)); 423 EINA_INLIST_GET(cond->lock));
546 pthread_mutex_unlock(&_eina_tracking_lock); 424 pthread_mutex_unlock(&_eina_tracking_lock);
547#endif 425#endif
548 426 }
427 errno = EINVAL;
549 return r; 428 return r;
550} 429}
551 430
@@ -584,29 +463,13 @@ eina_condition_signal(Eina_Condition *cond)
584static inline Eina_Bool 463static inline Eina_Bool
585eina_rwlock_new(Eina_RWLock *mutex) 464eina_rwlock_new(Eina_RWLock *mutex)
586{ 465{
587 int ok; 466 return _eina_rwlock_new(mutex);
588
589#ifdef EINA_HAVE_DEBUG_THREADS
590 if (!_eina_threads_activated)
591 assert(pthread_equal(_eina_main_loop, pthread_self()));
592#endif
593
594 ok = pthread_rwlock_init(&(mutex->mutex), NULL);
595 if (ok == 0) return EINA_TRUE;
596 else if (ok == EAGAIN || ok == ENOMEM) return EINA_FALSE;
597 else EINA_LOCK_ABORT_DEBUG(ok, rwlock_init, mutex);
598 return EINA_FALSE;
599} 467}
600 468
601static inline void 469static inline void
602eina_rwlock_free(Eina_RWLock *mutex) 470eina_rwlock_free(Eina_RWLock *mutex)
603{ 471{
604#ifdef EINA_HAVE_DEBUG_THREADS 472 _eina_rwlock_free(mutex);
605 if (!_eina_threads_activated)
606 assert(pthread_equal(_eina_main_loop, pthread_self()));
607#endif
608
609 pthread_rwlock_destroy(&(mutex->mutex));
610} 473}
611 474
612static inline Eina_Lock_Result 475static inline Eina_Lock_Result
@@ -680,9 +543,8 @@ eina_rwlock_release(Eina_RWLock *mutex)
680static inline Eina_Bool 543static inline Eina_Bool
681eina_tls_cb_new(Eina_TLS *key, Eina_TLS_Delete_Cb delete_cb) 544eina_tls_cb_new(Eina_TLS *key, Eina_TLS_Delete_Cb delete_cb)
682{ 545{
683 if (pthread_key_create(key, delete_cb) != 0) 546 if (pthread_key_create(key, delete_cb) == 0) return EINA_TRUE;
684 return EINA_FALSE; 547 return EINA_FALSE;
685 return EINA_TRUE;
686} 548}
687 549
688static inline Eina_Bool 550static inline Eina_Bool
@@ -691,24 +553,23 @@ eina_tls_new(Eina_TLS *key)
691 return eina_tls_cb_new(key, NULL); 553 return eina_tls_cb_new(key, NULL);
692} 554}
693 555
694static inline void 556static inline void
695eina_tls_free(Eina_TLS key) 557eina_tls_free(Eina_TLS key)
696{ 558{
697 pthread_key_delete(key); 559 pthread_key_delete(key);
698} 560}
699 561
700static inline void * 562static inline void *
701eina_tls_get(Eina_TLS key) 563eina_tls_get(Eina_TLS key)
702{ 564{
703 return pthread_getspecific(key); 565 return pthread_getspecific(key);
704} 566}
705 567
706static inline Eina_Bool 568static inline Eina_Bool
707eina_tls_set(Eina_TLS key, const void *data) 569eina_tls_set(Eina_TLS key, const void *data)
708{ 570{
709 if (pthread_setspecific(key, data) != 0) 571 if (pthread_setspecific(key, data) == 0) return EINA_TRUE;
710 return EINA_FALSE; 572 return EINA_FALSE;
711 return EINA_TRUE;
712} 573}
713 574
714 575
@@ -721,55 +582,44 @@ struct _Eina_Barrier
721}; 582};
722 583
723static inline Eina_Bool 584static inline Eina_Bool
724eina_barrier_new(Eina_Barrier *barrier, int needed) 585eina_barrier_wait(Eina_Barrier *barrier)
725{ 586{
726 int ok; 587 int ok = pthread_barrier_wait(&(barrier->barrier));
727 ok = pthread_barrier_init(&(barrier->barrier), NULL, needed);
728 if (ok == 0) return EINA_TRUE; 588 if (ok == 0) return EINA_TRUE;
729 else if (ok == EAGAIN || ok == ENOMEM) return EINA_FALSE; 589 else EINA_LOCK_ABORT_DEBUG(ok, barrier_wait, barrier);
730 else EINA_LOCK_ABORT_DEBUG(ok, barrier_init, barrier); 590 return EINA_TRUE;
731 return EINA_FALSE;
732} 591}
733 592
734static inline void 593#else
735eina_barrier_free(Eina_Barrier *barrier) 594#include "eina_inline_lock_barrier.x"
595#endif
596
597EAPI Eina_Bool _eina_barrier_new(Eina_Barrier *barrier, int needed);
598EAPI void _eina_barrier_free(Eina_Barrier *barrier);
599
600static inline Eina_Bool
601eina_barrier_new(Eina_Barrier *barrier, int needed)
736{ 602{
737 int ok; 603 return _eina_barrier_new(barrier, needed);
738 ok = pthread_barrier_destroy(&(barrier->barrier));
739 if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, barrier_destroy, barrier);
740} 604}
741 605
742static inline Eina_Bool 606static inline void
743eina_barrier_wait(Eina_Barrier *barrier) 607eina_barrier_free(Eina_Barrier *barrier)
744{ 608{
745 int ok; 609 _eina_barrier_free(barrier);
746 ok = pthread_barrier_wait(&(barrier->barrier));
747 if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, barrier_wait, barrier);
748 return EINA_TRUE;
749} 610}
750 611
751#else
752#include "eina_inline_lock_barrier.x"
753#endif
754 612
755static inline Eina_Bool 613static inline Eina_Bool
756eina_spinlock_new(Eina_Spinlock *spinlock) 614eina_spinlock_new(Eina_Spinlock *spinlock)
757{ 615{
758#if defined(EINA_HAVE_POSIX_SPINLOCK) 616 return _eina_spinlock_new(spinlock);
759 int ok; 617}
760 ok = pthread_spin_init(spinlock, PTHREAD_PROCESS_PRIVATE); 618
761 if (ok == 0) return EINA_TRUE; 619static inline void
762 else if (ok == EAGAIN || ok == ENOMEM) return EINA_FALSE; 620eina_spinlock_free(Eina_Spinlock *spinlock)
763 else EINA_LOCK_ABORT_DEBUG(ok, spin_init, spinlock); 621{
764 return EINA_FALSE; 622 _eina_spinlock_free(spinlock);
765#elif defined(EINA_HAVE_OSX_SPINLOCK)
766 /* OSSpinLock is an integer type. The convention is that unlocked is
767 * zero, and locked is nonzero. */
768 *spinlock = 0;
769 return EINA_TRUE;
770#else
771 return eina_lock_new(spinlock);
772#endif
773} 623}
774 624
775static inline Eina_Lock_Result 625static inline Eina_Lock_Result
@@ -778,12 +628,11 @@ eina_spinlock_take(Eina_Spinlock *spinlock)
778#if defined(EINA_HAVE_POSIX_SPINLOCK) 628#if defined(EINA_HAVE_POSIX_SPINLOCK)
779 int t; 629 int t;
780 630
781 while (EINA_TRUE) 631 for (;;)
782 { 632 {
783 t = pthread_spin_trylock(spinlock); 633 t = pthread_spin_lock(spinlock);
784 if (t == 0) break; 634 if (t == 0) break;
785 else if (t == EBUSY) sched_yield(); 635 else EINA_LOCK_ABORT_DEBUG(t, spin_lock, spinlock);
786 else EINA_LOCK_ABORT_DEBUG(t, spin_trylock, spinlock);
787 } 636 }
788 637
789 return EINA_LOCK_SUCCEED; 638 return EINA_LOCK_SUCCEED;
@@ -802,9 +651,7 @@ static inline Eina_Lock_Result
802eina_spinlock_take_try(Eina_Spinlock *spinlock) 651eina_spinlock_take_try(Eina_Spinlock *spinlock)
803{ 652{
804#if defined(EINA_HAVE_POSIX_SPINLOCK) 653#if defined(EINA_HAVE_POSIX_SPINLOCK)
805 int t; 654 int t = pthread_spin_trylock(spinlock);
806
807 t = pthread_spin_trylock(spinlock);
808 if (t == 0) return EINA_LOCK_SUCCEED; 655 if (t == 0) return EINA_LOCK_SUCCEED;
809 else if (t == EBUSY) return EINA_LOCK_FAIL; 656 else if (t == EBUSY) return EINA_LOCK_FAIL;
810 else EINA_LOCK_ABORT_DEBUG(t, spin_trylock, spinlock); 657 else EINA_LOCK_ABORT_DEBUG(t, spin_trylock, spinlock);
@@ -823,8 +670,7 @@ static inline Eina_Lock_Result
823eina_spinlock_release(Eina_Spinlock *spinlock) 670eina_spinlock_release(Eina_Spinlock *spinlock)
824{ 671{
825#if defined(EINA_HAVE_POSIX_SPINLOCK) 672#if defined(EINA_HAVE_POSIX_SPINLOCK)
826 int ok; 673 int ok = pthread_spin_unlock(spinlock);
827 ok = pthread_spin_unlock(spinlock);
828 if (ok == 0) return EINA_LOCK_SUCCEED; 674 if (ok == 0) return EINA_LOCK_SUCCEED;
829 else if (ok == EPERM) return EINA_LOCK_FAIL; 675 else if (ok == EPERM) return EINA_LOCK_FAIL;
830 else EINA_LOCK_ABORT_DEBUG(ok, spin_unlock, spinlock); 676 else EINA_LOCK_ABORT_DEBUG(ok, spin_unlock, spinlock);
@@ -839,96 +685,52 @@ eina_spinlock_release(Eina_Spinlock *spinlock)
839#endif 685#endif
840} 686}
841 687
842static inline void
843eina_spinlock_free(Eina_Spinlock *spinlock)
844{
845#if defined(EINA_HAVE_POSIX_SPINLOCK)
846 int ok;
847 ok = pthread_spin_destroy(spinlock);
848 if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, spin_destroy, spinlock);
849#elif defined(EINA_HAVE_OSX_SPINLOCK)
850 /* Not applicable */
851 (void) spinlock;
852#else
853 eina_lock_free(spinlock);
854#endif
855}
856
857static inline Eina_Bool 688static inline Eina_Bool
858eina_semaphore_new(Eina_Semaphore *sem, int count_init) 689eina_semaphore_new(Eina_Semaphore *sem, int count_init)
859{ 690{
860 if (!sem || (count_init < 0)) 691 return _eina_semaphore_new(sem, count_init);
861 return EINA_FALSE;
862
863#if defined(EINA_HAVE_OSX_SEMAPHORE)
864 kern_return_t kr;
865
866 kr = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, count_init);
867 return (kr == KERN_SUCCESS) ? EINA_TRUE : EINA_FALSE;
868#else
869 return (sem_init(sem, 0, count_init) == 0) ? EINA_TRUE : EINA_FALSE;
870#endif
871} 692}
872 693
873static inline Eina_Bool 694static inline Eina_Bool
874eina_semaphore_free(Eina_Semaphore *sem) 695eina_semaphore_free(Eina_Semaphore *sem)
875{ 696{
876 if (!sem) 697 return _eina_semaphore_free(sem);
877 return EINA_FALSE;
878
879#if defined(EINA_HAVE_OSX_SEMAPHORE)
880 return (semaphore_destroy(*sem, mach_task_self()) == KERN_SUCCESS)
881 ? EINA_TRUE : EINA_FALSE;
882#else
883 return (sem_destroy(sem) == 0) ? EINA_TRUE : EINA_FALSE;
884#endif
885} 698}
886 699
887static inline Eina_Bool 700static inline Eina_Bool
888eina_semaphore_lock(Eina_Semaphore *sem) 701eina_semaphore_lock(Eina_Semaphore *sem)
889{ 702{
890 Eina_Bool ok = EINA_FALSE; 703 if (sem)
891
892 if (!sem)
893 return EINA_FALSE;
894
895 for (;;)
896 { 704 {
897 if ( 705 for (;;)
706 {
707 if (
898#if defined(EINA_HAVE_OSX_SEMAPHORE) 708#if defined(EINA_HAVE_OSX_SEMAPHORE)
899 semaphore_wait(*sem) 709 semaphore_wait(*sem)
900#else 710#else
901 sem_wait(sem) 711 sem_wait(sem)
902#endif 712#endif
903 == 0) 713 == 0)
904 { 714 return EINA_TRUE;
905 ok = EINA_TRUE; 715 else if (errno != EINTR) goto err;
906 break;
907 }
908 else
909 {
910 if (errno != EINTR)
911 {
912 if (errno == EDEADLK)
913 EINA_LOCK_DEADLOCK_DEBUG(sem_wait, sem);
914 break;
915 }
916 } 716 }
917 } 717 }
918 return ok; 718 return EINA_FALSE;
719err:
720 if (errno == EDEADLK) EINA_LOCK_DEADLOCK_DEBUG(sem_wait, sem);
721 return EINA_FALSE;
919} 722}
920 723
921static inline Eina_Bool 724static inline Eina_Bool
922eina_semaphore_release(Eina_Semaphore *sem, int count_release EINA_UNUSED) 725eina_semaphore_release(Eina_Semaphore *sem, int count_release EINA_UNUSED)
923{ 726{
924 if (!sem) 727 if (sem)
925 return EINA_FALSE;
926
927#if defined(EINA_HAVE_OSX_SEMAPHORE) 728#if defined(EINA_HAVE_OSX_SEMAPHORE)
928 return (semaphore_signal(*sem) == KERN_SUCCESS) ? EINA_TRUE : EINA_FALSE; 729 return (semaphore_signal(*sem) == KERN_SUCCESS) ? EINA_TRUE : EINA_FALSE;
929#else 730#else
930 return (sem_post(sem) == 0) ? EINA_TRUE : EINA_FALSE; 731 return (sem_post(sem) == 0) ? EINA_TRUE : EINA_FALSE;
931#endif 732#endif
733 return EINA_FALSE;
932} 734}
933 735
934#undef _XOPEN_SOURCE 736#undef _XOPEN_SOURCE
diff --git a/src/lib/eina/eina_inline_log.x b/src/lib/eina/eina_inline_log.x
index 7f44643b0b..ff61644649 100644
--- a/src/lib/eina/eina_inline_log.x
+++ b/src/lib/eina/eina_inline_log.x
@@ -84,9 +84,9 @@ static inline Eina_Bool
84eina_log_domain_level_check(int domain, int level) 84eina_log_domain_level_check(int domain, int level)
85{ 85{
86 int dom_level = eina_log_domain_registered_level_get(domain); 86 int dom_level = eina_log_domain_registered_level_get(domain);
87 if (EINA_UNLIKELY(dom_level == EINA_LOG_LEVEL_UNKNOWN)) 87 if (EINA_LIKELY(dom_level != EINA_LOG_LEVEL_UNKNOWN))
88 return EINA_FALSE; 88 return dom_level >= level;
89 return dom_level >= level; 89 return EINA_FALSE;
90} 90}
91 91
92/** 92/**
diff --git a/src/lib/eina/eina_inline_mempool.x b/src/lib/eina/eina_inline_mempool.x
index 59bf523e1e..f8afda8c83 100644
--- a/src/lib/eina/eina_inline_mempool.x
+++ b/src/lib/eina/eina_inline_mempool.x
@@ -94,16 +94,14 @@ static inline void *
94eina_mempool_calloc(Eina_Mempool *mp, unsigned int size) 94eina_mempool_calloc(Eina_Mempool *mp, unsigned int size)
95{ 95{
96 void *r = mp->backend.alloc(mp->backend_data, size); 96 void *r = mp->backend.alloc(mp->backend_data, size);
97 if (!r) return NULL; 97 if (r) memset(r, 0, size);
98 memset(r, 0, size);
99 return r; 98 return r;
100} 99}
101 100
102static inline void 101static inline void
103eina_mempool_free(Eina_Mempool *mp, void *element) 102eina_mempool_free(Eina_Mempool *mp, void *element)
104{ 103{
105 if (!element) return ; 104 if (element) mp->backend.free(mp->backend_data, element);
106 mp->backend.free(mp->backend_data, element);
107} 105}
108 106
109static inline unsigned int 107static inline unsigned int
@@ -111,31 +109,33 @@ eina_mempool_alignof(unsigned int size)
111{ 109{
112 unsigned int align; 110 unsigned int align;
113 111
114 if (EINA_UNLIKELY(size <= 2))
115 {
116 align = 2;
117 }
118 else if (EINA_UNLIKELY(size < 8))
119 {
120 align = 4;
121 }
122 else
123#if __WORDSIZE == 32 112#if __WORDSIZE == 32
113 if (size >= 8)
124 { 114 {
125 align = 8; 115 align = 8;
116calc:
117 return ((size / align) + (size % align ? 1 : 0)) * align;
126 } 118 }
127#else 119#else // __WORDSIZE == 64
128 if (EINA_UNLIKELY(size < 16)) 120 if (size >= 16)
129 { 121 {
130 align = 8; 122 align = 16;
123calc:
124 return ((size / align) + (size % align ? 1 : 0)) * align;
131 } 125 }
132 else 126 else if (size >= 8)
133 { 127 {
134 align = 16; 128 align = 8;
129 goto calc;
135 } 130 }
136#endif 131#endif
137 132 else if (size >= 4)
138 return ((size / align) + (size % align ? 1 : 0)) * align; 133 {
134 align = 4;
135 goto calc;
136 }
137 align = 2;
138 goto calc;
139} 139}
140 140
141#endif 141#endif
diff --git a/src/lib/eina/eina_inline_rbtree.x b/src/lib/eina/eina_inline_rbtree.x
index 954774b851..6ebbb98642 100644
--- a/src/lib/eina/eina_inline_rbtree.x
+++ b/src/lib/eina/eina_inline_rbtree.x
@@ -34,13 +34,11 @@ eina_rbtree_inline_lookup(const Eina_Rbtree *root, const void *key, int length,
34 34
35 while (root) 35 while (root)
36 { 36 {
37 result = cmp(root, key, length, (void*) data); 37 result = cmp(root, key, length, (void *)data);
38 if (result == 0) return (Eina_Rbtree*) root; 38 if (result != 0) root = root->son[result < 0 ? 0 : 1];
39 39 else break;
40 root = root->son[result < 0 ? 0 : 1];
41 } 40 }
42 41 return (Eina_Rbtree *)root;
43 return NULL;
44} 42}
45 43
46/** 44/**
diff --git a/src/lib/eina/eina_inline_rectangle.x b/src/lib/eina/eina_inline_rectangle.x
index 5956291dd3..af257495eb 100644
--- a/src/lib/eina/eina_inline_rectangle.x
+++ b/src/lib/eina/eina_inline_rectangle.x
@@ -22,9 +22,8 @@
22static inline Eina_Bool 22static inline Eina_Bool
23eina_rectangle_is_valid(const Eina_Rectangle *r) 23eina_rectangle_is_valid(const Eina_Rectangle *r)
24{ 24{
25 if (r->w <= 0 || r->h <= 0) 25 if ((r->w > 0) && (r->h > 0)) return EINA_TRUE;
26 return EINA_FALSE; 26 return EINA_FALSE;
27 return EINA_TRUE;
28} 27}
29 28
30static inline int 29static inline int
@@ -36,7 +35,7 @@ eina_spans_intersect(int c1, int l1, int c2, int l2)
36static inline Eina_Bool 35static inline Eina_Bool
37eina_rectangle_is_empty(const Eina_Rectangle *r) 36eina_rectangle_is_empty(const Eina_Rectangle *r)
38{ 37{
39 return ((r->w < 1) || (r->h < 1)) ? EINA_TRUE : EINA_FALSE; 38 return !eina_rectangle_is_valid(r);
40} 39}
41 40
42static inline void 41static inline void
@@ -98,39 +97,34 @@ eina_rectangle_union(Eina_Rectangle *dst, const Eina_Rectangle *src)
98static inline Eina_Bool 97static inline Eina_Bool
99eina_rectangle_intersection(Eina_Rectangle *dst, const Eina_Rectangle *src) 98eina_rectangle_intersection(Eina_Rectangle *dst, const Eina_Rectangle *src)
100{ 99{
101 if (!(eina_rectangle_is_valid(dst)) || !(eina_rectangle_is_valid(src))) 100 if (eina_rectangle_is_valid(dst) && eina_rectangle_is_valid(src) &&
102 return EINA_FALSE; 101 eina_rectangles_intersect(dst, src))
103 102 {
104 if (!(eina_rectangles_intersect(dst, src))) 103 /* left */
105 return EINA_FALSE; 104 if (dst->x < src->x)
105 {
106 dst->w += dst->x - src->x;
107 dst->x = src->x;
108 if (dst->w < 0) dst->w = 0;
109 }
110 /* right */
111 if ((dst->x + dst->w) > (src->x + src->w))
112 dst->w = src->x + src->w - dst->x;
113 /* top */
114 if (dst->y < src->y)
115 {
116 dst->h += dst->y - src->y;
117 dst->y = src->y;
118 if (dst->h < 0) dst->h = 0;
119 }
120 /* bottom */
121 if ((dst->y + dst->h) > (src->y + src->h))
122 dst->h = src->y + src->h - dst->y;
106 123
107 /* left */ 124 if ((dst->w == 0) || (dst->h == 0)) return EINA_FALSE;
108 if (dst->x < src->x) 125 return EINA_TRUE;
109 { 126 }
110 dst->w += dst->x - src->x; 127 return EINA_FALSE;
111 dst->x = src->x;
112 if (dst->w < 0)
113 dst->w = 0;
114 }
115 /* right */
116 if ((dst->x + dst->w) > (src->x + src->w))
117 dst->w = src->x + src->w - dst->x;
118 /* top */
119 if (dst->y < src->y)
120 {
121 dst->h += dst->y - src->y;
122 dst->y = src->y;
123 if (dst->h < 0)
124 dst->h = 0;
125 }
126 /* bottom */
127 if ((dst->y + dst->h) > (src->y + src->h))
128 dst->h = src->y + src->h - dst->y;
129
130 if (dst->w == 0 || dst->h == 0)
131 return EINA_FALSE;
132
133 return EINA_TRUE;
134} 128}
135 129
136static inline void 130static inline void
@@ -218,57 +212,57 @@ eina_rectangle_height_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rect
218static inline Eina_Bool 212static inline Eina_Bool
219eina_rectangle_subtract(Eina_Rectangle *thiz, Eina_Rectangle *other, Eina_Rectangle out[4]) 213eina_rectangle_subtract(Eina_Rectangle *thiz, Eina_Rectangle *other, Eina_Rectangle out[4])
220{ 214{
221 Eina_Rectangle intersection; 215 Eina_Rectangle intersection;
222 Eina_Rectangle leftover = EINA_RECTANGLE_INIT; 216 Eina_Rectangle leftover = EINA_RECTANGLE_INIT;
223 Eina_Rectangle tmp; 217 Eina_Rectangle tmp;
224 int cut = 0; 218 int cut = 0;
225
226 if (!eina_rectangle_is_valid(thiz))
227 return EINA_FALSE;
228
229 eina_rectangle_coords_from(&out[0], 0, 0, 0, 0);
230 eina_rectangle_coords_from(&out[1], 0, 0, 0, 0);
231 eina_rectangle_coords_from(&out[2], 0, 0, 0, 0);
232 eina_rectangle_coords_from(&out[3], 0, 0, 0, 0);
233 intersection = *thiz;
234 if (!eina_rectangle_intersection(&intersection, other))
235 {
236 out[0] = *thiz;
237 return EINA_TRUE;
238 }
239 219
240 /* cut in height */ 220 if (eina_rectangle_is_valid(thiz))
241 { 221 {
242 cut = thiz->h - (intersection.y - thiz->y); 222 eina_rectangle_coords_from(&out[0], 0, 0, 0, 0);
243 if (cut > thiz->h) { cut = thiz->h; } 223 eina_rectangle_coords_from(&out[1], 0, 0, 0, 0);
244 eina_rectangle_height_cut(thiz, &leftover, &out[0], cut); 224 eina_rectangle_coords_from(&out[2], 0, 0, 0, 0);
245 } 225 eina_rectangle_coords_from(&out[3], 0, 0, 0, 0);
246 /* cut in y */ 226 intersection = *thiz;
247 tmp = leftover; 227 if (!eina_rectangle_intersection(&intersection, other))
248 if (eina_rectangle_intersection(&tmp, &intersection)) 228 {
249 { 229 out[0] = *thiz;
250 cut = leftover.h - (eina_rectangle_max_y(&leftover) - eina_rectangle_max_y(&tmp)); 230 return EINA_TRUE;
251 if (cut > leftover.h) { cut = leftover.h; } 231 }
252 eina_rectangle_y_cut(&leftover, &leftover, &out[1], cut);
253 }
254 /* cut in width */
255 tmp = leftover;
256 if (eina_rectangle_intersection(&tmp, &intersection))
257 {
258 cut = leftover.w - (tmp.x - leftover.x);
259 if (cut > leftover.w) { cut = leftover.w; }
260 eina_rectangle_width_cut(&leftover, &leftover, &out[2], cut);
261 }
262 /* cut in x */
263 tmp = leftover;
264 if (eina_rectangle_intersection(&tmp, &intersection))
265 {
266 cut = leftover.w - (eina_rectangle_max_x(&leftover) - eina_rectangle_max_x(&tmp));
267 if (cut > leftover.w) { cut = leftover.w; }
268 eina_rectangle_x_cut(&leftover, &leftover, &out[3], cut);
269 }
270 232
271 return EINA_TRUE; 233 /* cut in height */
234 {
235 cut = thiz->h - (intersection.y - thiz->y);
236 if (cut > thiz->h) cut = thiz->h;
237 eina_rectangle_height_cut(thiz, &leftover, &out[0], cut);
238 }
239 /* cut in y */
240 tmp = leftover;
241 if (eina_rectangle_intersection(&tmp, &intersection))
242 {
243 cut = leftover.h - (eina_rectangle_max_y(&leftover) - eina_rectangle_max_y(&tmp));
244 if (cut > leftover.h) cut = leftover.h;
245 eina_rectangle_y_cut(&leftover, &leftover, &out[1], cut);
246 }
247 /* cut in width */
248 tmp = leftover;
249 if (eina_rectangle_intersection(&tmp, &intersection))
250 {
251 cut = leftover.w - (tmp.x - leftover.x);
252 if (cut > leftover.w) cut = leftover.w;
253 eina_rectangle_width_cut(&leftover, &leftover, &out[2], cut);
254 }
255 /* cut in x */
256 tmp = leftover;
257 if (eina_rectangle_intersection(&tmp, &intersection))
258 {
259 cut = leftover.w - (eina_rectangle_max_x(&leftover) - eina_rectangle_max_x(&tmp));
260 if (cut > leftover.w) cut = leftover.w;
261 eina_rectangle_x_cut(&leftover, &leftover, &out[3], cut);
262 }
263 return EINA_TRUE;
264 }
265 return EINA_FALSE;
272} 266}
273 267
274#endif 268#endif
diff --git a/src/lib/eina/eina_inline_slice.x b/src/lib/eina/eina_inline_slice.x
index a66d753779..67d535386f 100644
--- a/src/lib/eina/eina_inline_slice.x
+++ b/src/lib/eina/eina_inline_slice.x
@@ -38,10 +38,8 @@ eina_slice_dup(const Eina_Slice slice)
38 if (ret.len == 0) return ret; 38 if (ret.len == 0) return ret;
39 39
40 ret.mem = malloc(ret.len); 40 ret.mem = malloc(ret.len);
41 if (!ret.mem) 41 if (ret.mem) memcpy(ret.mem, slice.mem, ret.len);
42 ret.len = 0; 42 else ret.len = 0;
43 else
44 memcpy(ret.mem, slice.mem, ret.len);
45 43
46 return ret; 44 return ret;
47} 45}
@@ -99,16 +97,13 @@ eina_slice_seek(const Eina_Slice slice, ssize_t offset, int whence)
99 offset += slice.len; 97 offset += slice.len;
100 } 98 }
101 99
102 if (whence != SEEK_SET) 100 if (whence == SEEK_SET)
103 return ret; 101 {
104 102 if ((size_t)offset > slice.len) offset = slice.len;
105 if (offset < 0) 103 else if (offset < 0) offset = 0;
106 offset = 0; 104 ret.len = slice.len - offset;
107 else if ((size_t)offset > slice.len) 105 ret.mem = (const void *)(slice.bytes + offset);
108 offset = slice.len; 106 }
109
110 ret.len = slice.len - offset;
111 ret.mem = (const void *)(slice.bytes + offset);
112 return ret; 107 return ret;
113} 108}
114 109
@@ -126,88 +121,88 @@ eina_rw_slice_seek(const Eina_Rw_Slice rw_slice, ssize_t offset, int whence)
126 offset += rw_slice.len; 121 offset += rw_slice.len;
127 } 122 }
128 123
129 if (whence != SEEK_SET) 124 if (whence == SEEK_SET)
130 return ret; 125 {
131 126 if ((size_t)offset > rw_slice.len) offset = rw_slice.len;
132 if (offset < 0) 127 else if (offset < 0) offset = 0;
133 offset = 0; 128 ret.len = rw_slice.len - offset;
134 else if ((size_t)offset > rw_slice.len) 129 ret.mem = (void *)(rw_slice.bytes + offset);
135 offset = rw_slice.len; 130 }
136
137 ret.len = rw_slice.len - offset;
138 ret.mem = (void *)(rw_slice.bytes + offset);
139 return ret; 131 return ret;
140} 132}
141 133
142static inline const void * 134static inline const void *
143eina_slice_strchr(const Eina_Slice slice, int c) 135eina_slice_strchr(const Eina_Slice slice, int c)
144{ 136{
145 if (slice.len == 0) return NULL; 137 if (slice.len != 0) return memchr(slice.mem, c, slice.len);
146 return memchr(slice.mem, c, slice.len); 138 return NULL;
147} 139}
148 140
141
149static inline const void * 142static inline const void *
150eina_slice_find(const Eina_Slice slice, const Eina_Slice needle) 143eina_slice_find(const Eina_Slice slice, const Eina_Slice needle)
151{ 144{
152 Eina_Slice s, n; 145 Eina_Slice s, n;
153 uint8_t c; 146 uint8_t c;
154 147
155 if (slice.len == 0) return NULL; 148 if ((slice.len != 0) && (needle.len != 0) && (slice.len >= needle.len))
156 if (needle.len == 0) return NULL;
157 if (slice.len < needle.len) return NULL;
158 if (needle.len == 1) return eina_slice_strchr(slice, needle.bytes[0]);
159 if ((slice.len == needle.len) &&
160 (memcmp(slice.mem, needle.mem, needle.len) == 0))
161 return slice.mem;
162
163 s.mem = slice.mem;
164 s.len = slice.len - (needle.len - 1);
165
166 c = needle.bytes[0];
167 n.mem = (const void *)(needle.bytes + 1);
168 n.len = needle.len - 1;
169
170 while (s.len > 0)
171 { 149 {
172 const uint8_t *p = (const uint8_t *)eina_slice_strchr(s, c); 150 if (needle.len == 1) return eina_slice_strchr(slice, needle.bytes[0]);
173 size_t offset; 151 if ((slice.len == needle.len) &&
174 152 (memcmp(slice.mem, needle.mem, needle.len) == 0))
175 if (!p) return NULL; 153 return slice.mem;
176 154
177 p++; 155 s.mem = slice.mem;
178 if (memcmp(p, n.mem, n.len) == 0) 156 s.len = slice.len - (needle.len - 1);
179 return (const void *)(p - 1); 157
180 158 c = needle.bytes[0];
181 offset = p - s.bytes; 159 n.mem = (const void *)(needle.bytes + 1);
182 s.bytes += offset; 160 n.len = needle.len - 1;
183 s.len -= offset; 161
162 while (s.len > 0)
163 {
164 const uint8_t *p = (const uint8_t *)eina_slice_strchr(s, c);
165 size_t offset;
166
167 if (p)
168 {
169 p++;
170 if (memcmp(p, n.mem, n.len) == 0)
171 return (const void *)(p - 1);
172
173 offset = p - s.bytes;
174 s.bytes += offset;
175 s.len -= offset;
176 continue;
177 }
178 break;
179 }
184 } 180 }
185
186 return NULL; 181 return NULL;
187} 182}
188 183
189static inline Eina_Bool 184static inline Eina_Bool
190eina_slice_startswith(const Eina_Slice slice, const Eina_Slice prefix) 185eina_slice_startswith(const Eina_Slice slice, const Eina_Slice prefix)
191{ 186{
192 if (prefix.len == 0) return EINA_FALSE; 187 if ((prefix.len != 0) && (slice.len >= prefix.len))
193 if (slice.len < prefix.len) return EINA_FALSE; 188 return memcmp(slice.mem, prefix.mem, prefix.len) == 0;
194 return memcmp(slice.mem, prefix.mem, prefix.len) == 0; 189 return EINA_FALSE;
195} 190}
196 191
197static inline Eina_Bool 192static inline Eina_Bool
198eina_slice_endswith(const Eina_Slice slice, const Eina_Slice suffix) 193eina_slice_endswith(const Eina_Slice slice, const Eina_Slice suffix)
199{ 194{
200 if (suffix.len == 0) return EINA_FALSE; 195 if ((suffix.len != 0) && (slice.len > suffix.len))
201 if (slice.len < suffix.len) return EINA_FALSE; 196 return memcmp(slice.bytes + slice.len - suffix.len,
202 return memcmp(slice.bytes + slice.len - suffix.len, 197 suffix.mem, suffix.len) == 0;
203 suffix.mem, suffix.len) == 0; 198 return EINA_FALSE;
204} 199}
205 200
206static inline void * 201static inline void *
207eina_rw_slice_strchr(const Eina_Rw_Slice rw_slice, int c) 202eina_rw_slice_strchr(const Eina_Rw_Slice rw_slice, int c)
208{ 203{
209 if (rw_slice.len == 0) return NULL; 204 if (rw_slice.len != 0) return memchr(rw_slice.mem, c, rw_slice.len);
210 return memchr(rw_slice.mem, c, rw_slice.len); 205 return NULL;
211} 206}
212 207
213static inline void * 208static inline void *
@@ -219,18 +214,18 @@ eina_rw_slice_find(const Eina_Rw_Slice rw_slice, const Eina_Slice needle)
219static inline Eina_Bool 214static inline Eina_Bool
220eina_rw_slice_startswith(const Eina_Rw_Slice rw_slice, const Eina_Slice prefix) 215eina_rw_slice_startswith(const Eina_Rw_Slice rw_slice, const Eina_Slice prefix)
221{ 216{
222 if (prefix.len == 0) return EINA_FALSE; 217 if ((prefix.len != 0) && (rw_slice.len >= prefix.len))
223 if (rw_slice.len < prefix.len) return EINA_FALSE; 218 return memcmp(rw_slice.mem, prefix.mem, prefix.len) == 0;
224 return memcmp(rw_slice.mem, prefix.mem, prefix.len) == 0; 219 return EINA_FALSE;
225} 220}
226 221
227static inline Eina_Bool 222static inline Eina_Bool
228eina_rw_slice_endswith(const Eina_Rw_Slice rw_slice, const Eina_Slice suffix) 223eina_rw_slice_endswith(const Eina_Rw_Slice rw_slice, const Eina_Slice suffix)
229{ 224{
230 if (suffix.len == 0) return EINA_FALSE; 225 if ((suffix.len != 0) && (rw_slice.len >= suffix.len))
231 if (rw_slice.len < suffix.len) return EINA_FALSE; 226 return memcmp(rw_slice.bytes + rw_slice.len - suffix.len,
232 return memcmp(rw_slice.bytes + rw_slice.len - suffix.len, 227 suffix.mem, suffix.len) == 0;
233 suffix.mem, suffix.len) == 0; 228 return EINA_FALSE;
234} 229}
235 230
236static inline const void * 231static inline const void *
@@ -248,19 +243,17 @@ eina_rw_slice_end_get(const Eina_Rw_Slice rw_slice)
248static inline char * 243static inline char *
249eina_slice_strdup(const Eina_Slice slice) 244eina_slice_strdup(const Eina_Slice slice)
250{ 245{
251 if (slice.len == 0) 246 if (slice.len != 0)
252 return strdup("");
253 else
254 return strndup((const char *)slice.mem, slice.len); 247 return strndup((const char *)slice.mem, slice.len);
248 return strdup("");
255} 249}
256 250
257static inline char * 251static inline char *
258eina_rw_slice_strdup(const Eina_Rw_Slice rw_slice) 252eina_rw_slice_strdup(const Eina_Rw_Slice rw_slice)
259{ 253{
260 if (rw_slice.len == 0) 254 if (rw_slice.len != 0)
261 return strdup("");
262 else
263 return strndup((const char *)rw_slice.mem, rw_slice.len); 255 return strndup((const char *)rw_slice.mem, rw_slice.len);
256 return strdup("");
264} 257}
265 258
266#endif /* _EINA_INLINE_SLICE_H */ 259#endif /* _EINA_INLINE_SLICE_H */
diff --git a/src/lib/eina/eina_inline_str.x b/src/lib/eina/eina_inline_str.x
index 917bcc382f..3b75591e78 100644
--- a/src/lib/eina/eina_inline_str.x
+++ b/src/lib/eina/eina_inline_str.x
@@ -92,8 +92,7 @@ static inline Eina_Bool
92eina_streq(const char *a, const char *b) 92eina_streq(const char *a, const char *b)
93{ 93{
94 if (a == b) return EINA_TRUE; 94 if (a == b) return EINA_TRUE;
95 if (!a) return EINA_FALSE; 95 if ((!a) || (!b)) return EINA_FALSE;
96 if (!b) return EINA_FALSE;
97 return !strcmp(a, b); 96 return !strcmp(a, b);
98} 97}
99 98
diff --git a/src/lib/eina/eina_lock.c b/src/lib/eina/eina_lock.c
new file mode 100644
index 0000000000..a01571c2ff
--- /dev/null
+++ b/src/lib/eina/eina_lock.c
@@ -0,0 +1,270 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <stdio.h>
6#include <string.h>
7#include "eina_config.h"
8#include "Eina.h"
9
10EAPI void
11_eina_lock_debug_abort(int err, const char *fn, const volatile void *ptr)
12{
13 fprintf(stderr, "EINA ERROR: '%s' on %s %p\n", strerror(err), fn, ptr);
14#ifdef EINA_HAVE_DEBUG_THREADS
15 abort();
16#endif
17}
18
19EAPI void
20_eina_lock_debug_deadlock(const char *fn, const volatile void *ptr)
21{
22 fprintf(stderr, "EINA ERROR: DEADLOCK on %s %p\n", fn, ptr);
23#ifdef EINA_HAVE_DEBUG_THREADS
24 abort();
25#endif
26}
27
28EAPI void
29eina_lock_debug(const Eina_Lock *mutex)
30{
31#ifdef EINA_HAVE_DEBUG_THREADS
32 fprintf(stderr, "EINA ERROR: DEADLOCK on lock %p, locked: %i, by %ti\n",
33 mutex, (int)mutex->locked, (ptrdiff_t)mutex->lock_thread_id);
34 backtrace_symbols_fd((void **)mutex->lock_bt, mutex->lock_bt_num, 1);
35#else
36 fprintf(stderr, "EINA ERROR: DEADLOCK on lock %p\n", mutex);
37#endif
38}
39
40EAPI Eina_Bool
41_eina_lock_new(Eina_Lock *mutex, Eina_Bool recursive)
42{
43 pthread_mutexattr_t attr;
44 Eina_Bool ok = EINA_FALSE;
45
46#ifdef EINA_HAVE_DEBUG_THREADS
47 if (!_eina_threads_activated)
48 assert(pthread_equal(_eina_main_loop, pthread_self()));
49#endif
50
51 if (pthread_mutexattr_init(&attr) != 0) return EINA_FALSE;
52 if (recursive)
53 {
54 if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) goto fail_release;
55 }
56#ifdef EINA_HAVE_DEBUG_THREADS
57 if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) goto fail_release;
58 memset(mutex, 0, sizeof(Eina_Lock));
59#endif
60 if (pthread_mutex_init(&(mutex->mutex), &attr) != 0) goto fail_release;
61 ok = EINA_TRUE;
62fail_release:
63 pthread_mutexattr_destroy(&attr);
64 return ok;
65}
66
67EAPI void
68_eina_lock_free(Eina_Lock *mutex)
69{
70 int ok;
71
72#ifdef EINA_HAVE_DEBUG_THREADS
73 if (!_eina_threads_activated)
74 assert(pthread_equal(_eina_main_loop, pthread_self()));
75#endif
76
77 ok = pthread_mutex_destroy(&(mutex->mutex));
78 if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, mutex_destroy, mutex);
79#ifdef EINA_HAVE_DEBUG_THREADS
80 memset(mutex, 0, sizeof(Eina_Lock));
81#endif
82}
83
84EAPI Eina_Bool
85_eina_condition_new(Eina_Condition *cond, Eina_Lock *mutex)
86{
87 pthread_condattr_t attr;
88 int ok;
89
90#ifdef EINA_HAVE_DEBUG_THREADS
91 assert(mutex != NULL);
92 if (!_eina_threads_activated)
93 assert(pthread_equal(_eina_main_loop, pthread_self()));
94 memset(cond, 0, sizeof (Eina_Condition));
95#endif
96
97 cond->lock = mutex;
98 pthread_condattr_init(&attr);
99
100 /* OSX doesn't provide clockid_t or clock_gettime. */
101#if defined(__clockid_t_defined)
102 cond->clkid = (clockid_t) 0;
103 /* We try here to chose the best clock for cond_timedwait */
104# if defined(CLOCK_MONOTONIC_RAW)
105 if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC_RAW))
106 cond->clkid = CLOCK_MONOTONIC_RAW;
107# endif
108# if defined(CLOCK_MONOTONIC)
109 if (!cond->clkid && !pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
110 cond->clkid = CLOCK_MONOTONIC;
111# endif
112# if defined(CLOCK_REALTIME)
113 if (!cond->clkid && !pthread_condattr_setclock(&attr, CLOCK_REALTIME))
114 cond->clkid = CLOCK_REALTIME;
115# endif
116#endif
117
118 ok = pthread_cond_init(&cond->condition, &attr);
119 if (ok != 0)
120 {
121 pthread_condattr_destroy(&attr);
122#ifdef EINA_HAVE_DEBUG_THREADS
123 if (ok == EBUSY)
124 fprintf(stderr, "EINA ERROR: eina_condition_new on already initialized Eina_Condition\n");
125#endif
126 return EINA_FALSE;
127 }
128
129 pthread_condattr_destroy(&attr);
130 return EINA_TRUE;
131}
132
133EAPI void
134_eina_condition_free(Eina_Condition *cond)
135{
136#ifdef EINA_HAVE_DEBUG_THREADS
137 if (!_eina_threads_activated)
138 assert(pthread_equal(_eina_main_loop, pthread_self()));
139#endif
140
141 pthread_cond_destroy(&(cond->condition));
142#ifdef EINA_HAVE_DEBUG_THREADS
143 memset(cond, 0, sizeof (Eina_Condition));
144#endif
145}
146
147EAPI Eina_Bool
148_eina_rwlock_new(Eina_RWLock *mutex)
149{
150 int ok;
151
152#ifdef EINA_HAVE_DEBUG_THREADS
153 if (!_eina_threads_activated)
154 assert(pthread_equal(_eina_main_loop, pthread_self()));
155#endif
156
157 ok = pthread_rwlock_init(&(mutex->mutex), NULL);
158 if (ok == 0) return EINA_TRUE;
159 else if ((ok == EAGAIN) || (ok == ENOMEM)) return EINA_FALSE;
160 else EINA_LOCK_ABORT_DEBUG(ok, rwlock_init, mutex);
161 return EINA_FALSE;
162}
163
164EAPI void
165_eina_rwlock_free(Eina_RWLock *mutex)
166{
167#ifdef EINA_HAVE_DEBUG_THREADS
168 if (!_eina_threads_activated)
169 assert(pthread_equal(_eina_main_loop, pthread_self()));
170#endif
171 pthread_rwlock_destroy(&(mutex->mutex));
172}
173
174EAPI Eina_Bool
175_eina_barrier_new(Eina_Barrier *barrier, int needed)
176{
177#ifdef EINA_HAVE_PTHREAD_BARRIER
178 int ok = pthread_barrier_init(&(barrier->barrier), NULL, needed);
179 if (ok == 0) return EINA_TRUE;
180 else if ((ok == EAGAIN) || (ok == ENOMEM)) return EINA_FALSE;
181 else EINA_LOCK_ABORT_DEBUG(ok, barrier_init, barrier);
182 return EINA_FALSE;
183#else
184 barrier->needed = needed;
185 barrier->called = 0;
186 if (eina_lock_new(&(barrier->cond_lock)))
187 {
188 if (eina_condition_new(&(barrier->cond), &(barrier->cond_lock)))
189 return EINA_TRUE;
190 }
191 return EINA_FALSE;
192#endif
193}
194
195EAPI void
196_eina_barrier_free(Eina_Barrier *barrier)
197{
198#ifdef EINA_HAVE_PTHREAD_BARRIER
199 int ok = pthread_barrier_destroy(&(barrier->barrier));
200 if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, barrier_destroy, barrier);
201#else
202 eina_condition_free(&(barrier->cond));
203 eina_lock_free(&(barrier->cond_lock));
204 barrier->needed = 0;
205 barrier->called = 0;
206#endif
207}
208
209EAPI Eina_Bool
210_eina_spinlock_new(Eina_Spinlock *spinlock)
211{
212#if defined(EINA_HAVE_POSIX_SPINLOCK)
213 int ok = pthread_spin_init(spinlock, PTHREAD_PROCESS_PRIVATE);
214 if (ok == 0) return EINA_TRUE;
215 else if ((ok == EAGAIN) || (ok == ENOMEM)) return EINA_FALSE;
216 else EINA_LOCK_ABORT_DEBUG(ok, spin_init, spinlock);
217 return EINA_FALSE;
218#elif defined(EINA_HAVE_OSX_SPINLOCK)
219 /* OSSpinLock is an integer type. The convention is that unlocked is
220 * * zero, and locked is nonzero. */
221 *spinlock = 0;
222 return EINA_TRUE;
223#else
224 return eina_lock_new(spinlock);
225#endif
226}
227
228EAPI void
229_eina_spinlock_free(Eina_Spinlock *spinlock)
230{
231#if defined(EINA_HAVE_POSIX_SPINLOCK)
232 int ok = pthread_spin_destroy(spinlock);
233 if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, spin_destroy, spinlock);
234#elif defined(EINA_HAVE_OSX_SPINLOCK)
235 /* Not applicable */
236 (void) spinlock;
237#else
238 eina_lock_free(spinlock);
239#endif
240}
241
242EAPI Eina_Bool
243_eina_semaphore_new(Eina_Semaphore *sem, int count_init)
244{
245 if (sem && (count_init >= 0))
246 {
247#if defined(EINA_HAVE_OSX_SEMAPHORE)
248 kern_return_t kr = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, count_init);
249 return (kr == KERN_SUCCESS) ? EINA_TRUE : EINA_FALSE;
250#else
251 return (sem_init(sem, 0, count_init) == 0) ? EINA_TRUE : EINA_FALSE;
252#endif
253 }
254 return EINA_FALSE;
255}
256
257EAPI Eina_Bool
258_eina_semaphore_free(Eina_Semaphore *sem)
259{
260 if (sem)
261 {
262#if defined(EINA_HAVE_OSX_SEMAPHORE)
263 return (semaphore_destroy(*sem, mach_task_self()) == KERN_SUCCESS)
264 ? EINA_TRUE : EINA_FALSE;
265#else
266 return (sem_destroy(sem) == 0) ? EINA_TRUE : EINA_FALSE;
267#endif
268 }
269 return EINA_FALSE;
270}
diff --git a/src/lib/eina/eina_lock.h b/src/lib/eina/eina_lock.h
index 2a347ae019..62dd5280f8 100644
--- a/src/lib/eina/eina_lock.h
+++ b/src/lib/eina/eina_lock.h
@@ -211,7 +211,7 @@ static inline Eina_Lock_Result eina_lock_release(Eina_Lock *mutex);
211 * 211 *
212 * @note If @c EINA_HAVE_DEBUG_THREADS is not defined, this function does nothing. 212 * @note If @c EINA_HAVE_DEBUG_THREADS is not defined, this function does nothing.
213 */ 213 */
214static inline void eina_lock_debug(const Eina_Lock *mutex); 214EAPI void eina_lock_debug(const Eina_Lock *mutex);
215 215
216/** 216/**
217 * @brief Initializes a new condition variable. 217 * @brief Initializes a new condition variable.