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 \ lib/eina/eina_iterator.c \ lib/eina/eina_lalloc.c \ lib/eina/eina_list.c \ +lib/eina/eina_lock.c \ lib/eina/eina_log.c \ lib/eina/eina_magic.c \ lib/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); static inline Eina_Bool eina_array_push(Eina_Array *array, const void *data) { - if (!data) return EINA_FALSE; + if (data) + { + if (EINA_UNLIKELY((array->count + 1) > array->total)) goto do_grow; +do_grow_back: - if (EINA_UNLIKELY((array->count + 1) > array->total)) - if (!eina_array_grow(array)) - return EINA_FALSE; + array->data[array->count++] = (void*) data; - array->data[array->count++] = (void*) data; - - return EINA_TRUE; + return EINA_TRUE; + } + return EINA_FALSE; +do_grow: + if (!eina_array_grow(array)) return EINA_FALSE; + goto do_grow_back; } static inline void * eina_array_pop(Eina_Array *array) { - void *ret = NULL; - - if (array->count <= 0) - goto on_empty; - - ret = array->data[--array->count]; - - on_empty: - return ret; + if (array->count > 0) return array->data[--array->count]; + return NULL; } static inline void * @@ -104,12 +101,11 @@ eina_array_foreach(Eina_Array *array, Eina_Each_Cb cb, void *fdata) Eina_Bool ret = EINA_TRUE; EINA_ARRAY_ITER_NEXT(array, i, data, iterator) - if (cb(array, data, fdata) != EINA_TRUE) - { - ret = EINA_FALSE; - break; - } - + { + if (cb(array, data, fdata) == EINA_TRUE) continue; + ret = EINA_FALSE; + break; + } return ret; } 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) unsigned int hash_num = 5381 ^ eina_seed; const unsigned char *ptr; - if (!key) return 0; - for (ptr = (unsigned char *)key; len; ptr++, len--) - hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */ - - return (int)hash_num; + if (key) + { + for (ptr = (unsigned char *)key; len; ptr++, len--) + hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */ + return (int)hash_num; + } + return 0; } static inline int @@ -47,14 +49,14 @@ eina_hash_djb2_len(const char *key, int *plen) int len = 0; const unsigned char *ptr; - if (!key) return 0; - - for (ptr = (unsigned char *)key; *ptr; ptr++, len++) - hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */ - - *plen = len + 1; - - return (int)hash_num; + if (key) + { + for (ptr = (unsigned char *)key; *ptr; ptr++, len++) + hash_num = ((hash_num << 5) + hash_num) ^ *ptr; /* hash * 33 ^ c */ + *plen = len + 1; + return (int)hash_num; + } + return 0; } static 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) { Eina_Inlist *l; - if (!list) return NULL; - - for (l = (Eina_Inlist*)list; l->prev; l = l->prev); - - return l; + if (list) + { + for (l = (Eina_Inlist*)list; l->prev; l = l->prev); + return l; + } + return NULL; } static inline Eina_Inlist * @@ -36,11 +37,12 @@ eina_inlist_last(const Eina_Inlist *list) { Eina_Inlist *l; - if (!list) return NULL; - - for (l = (Eina_Inlist*)list; l->next; l = l->next); - - return l; + if (list) + { + for (l = (Eina_Inlist*)list; l->next; l = l->next); + return l; + } + return NULL; } #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 @@ static inline Eina_List * eina_list_last(const Eina_List *list) { - if (!list) return NULL; - return list->accounting->last; + if (list) return list->accounting->last; + return NULL; } static inline Eina_List * eina_list_next(const Eina_List *list) { - if (!list) return NULL; - return list->next; + if (list) return list->next; + return NULL; } static inline Eina_List * eina_list_prev(const Eina_List *list) { - if (!list) return NULL; - return list->prev; + if (list) return list->prev; + return NULL; } static inline void * eina_list_data_get(const Eina_List *list) { - if (!list) return NULL; - return list->data; + if (list) return list->data; + return NULL; } static inline void * eina_list_data_set(Eina_List *list, const void *data) { - void *tmp; - if (!list) return NULL; - tmp = list->data; - list->data = (void*) data; - return tmp; + if (list) + { + void *tmp = list->data; + list->data = (void *) data; + return tmp; + } + return NULL; } static inline unsigned int eina_list_count(const Eina_List *list) { - if (!list) return 0; - return list->accounting->count; + if (list) return list->accounting->count; + return 0; } static inline void * eina_list_last_data_get(const Eina_List *list) { - if (!list) return NULL; - return eina_list_data_get(eina_list_last(list)); + if (list) return eina_list_data_get(eina_list_last(list)); + return NULL; } #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 @@ -9,27 +9,6 @@ struct _Eina_Barrier Eina_Condition cond; /**< The condition variable for the barrier */ }; -static inline Eina_Bool -eina_barrier_new(Eina_Barrier *barrier, int needed) -{ - barrier->needed = needed; - barrier->called = 0; - if (!eina_lock_new(&(barrier->cond_lock))) - return EINA_FALSE; - if (!eina_condition_new(&(barrier->cond), &(barrier->cond_lock))) - return EINA_FALSE; - return EINA_TRUE; -} - -static inline void -eina_barrier_free(Eina_Barrier *barrier) -{ - eina_condition_free(&(barrier->cond)); - eina_lock_free(&(barrier->cond_lock)); - barrier->needed = 0; - barrier->called = 0; -} - static inline Eina_Bool eina_barrier_wait(Eina_Barrier *barrier) { 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,21 +63,16 @@ typedef void (*Eina_Lock_Bt_Func) (); #include "eina_inlist.h" -#define EINA_LOCK_ABORT_DEBUG(err, fn, ptr) do { \ - printf("EINA ERROR: '%s' on %s %p\n", strerror(err), #fn, ptr); \ - abort(); \ -} while (0) -#define EINA_LOCK_DEADLOCK_DEBUG(fn, ptr) do { \ - printf("EINA ERROR: DEADLOCK on %s %p\n", #fn, ptr); \ - abort(); \ -} while (0) -#else -#define EINA_LOCK_ABORT_DEBUG(err, fn, ptr) \ - printf("EINA ERROR: '%s' on %s %p\n", strerror(err), #fn, ptr) -#define EINA_LOCK_DEADLOCK_DEBUG(fn, ptr) \ - printf("EINA ERROR: DEADLOCK on %s %p\n", #fn, ptr) #endif +EAPI void _eina_lock_debug_abort(int err, const char *fn, const volatile void *ptr); +EAPI void _eina_lock_debug_deadlock(const char *fn, const volatile void *ptr); + +#define EINA_LOCK_ABORT_DEBUG(err, fn, ptr) \ + _eina_lock_debug_abort(err, #fn, ptr) +#define EINA_LOCK_DEADLOCK_DEBUG(fn, ptr) \ + _eina_lock_debug_deadlock(#fn, ptr) + /* For cond_timedwait */ #include #include @@ -103,6 +98,8 @@ typedef semaphore_t Eina_Semaphore; typedef sem_t Eina_Semaphore; #endif +EAPI void eina_lock_debug(const Eina_Lock *mutex); + /** @privatesection @{ */ struct _Eina_Lock { @@ -145,91 +142,34 @@ EAPI extern pthread_mutex_t _eina_tracking_lock; EAPI extern Eina_Inlist *_eina_tracking; #endif -static inline void -eina_lock_debug(const Eina_Lock *mutex) -{ -#ifdef EINA_HAVE_DEBUG_THREADS - printf("lock %p, locked: %i, by %ti\n", - mutex, (int)mutex->locked, (ptrdiff_t)mutex->lock_thread_id); - backtrace_symbols_fd((void **)mutex->lock_bt, mutex->lock_bt_num, 1); -#else - (void) mutex; -#endif -} + +EAPI Eina_Bool _eina_lock_new(Eina_Lock *mutex, Eina_Bool recursive); +EAPI void _eina_lock_free(Eina_Lock *mutex); +EAPI Eina_Bool _eina_condition_new(Eina_Condition *cond, Eina_Lock *mutex); +EAPI void _eina_condition_free(Eina_Condition *cond); +EAPI Eina_Bool _eina_rwlock_new(Eina_RWLock *mutex); +EAPI void _eina_rwlock_free(Eina_RWLock *mutex); +EAPI Eina_Bool _eina_spinlock_new(Eina_Spinlock *spinlock); +EAPI void _eina_spinlock_free(Eina_Spinlock *spinlock); +EAPI Eina_Bool _eina_semaphore_new(Eina_Semaphore *sem, int count_init); +EAPI Eina_Bool _eina_semaphore_free(Eina_Semaphore *sem); static inline Eina_Bool eina_lock_new(Eina_Lock *mutex) { - pthread_mutexattr_t attr; - Eina_Bool ok = EINA_FALSE; - -#ifdef EINA_HAVE_DEBUG_THREADS - if (!_eina_threads_activated) - assert(pthread_equal(_eina_main_loop, pthread_self())); -#endif - - if (pthread_mutexattr_init(&attr) != 0) - return EINA_FALSE; - /* NOTE: PTHREAD_MUTEX_RECURSIVE is not allowed at all, you will break on/off - feature for sure with that change. */ -#ifdef EINA_HAVE_DEBUG_THREADS - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) - goto fail_release; - memset(mutex, 0, sizeof(Eina_Lock)); -#endif - if (pthread_mutex_init(&(mutex->mutex), &attr) != 0) - goto fail_release; - - ok = EINA_TRUE; -fail_release: - pthread_mutexattr_destroy(&attr); - return ok; + return _eina_lock_new(mutex, EINA_FALSE); } static inline Eina_Bool eina_lock_recursive_new(Eina_Lock *mutex) { - pthread_mutexattr_t attr; - Eina_Bool ok = EINA_FALSE; - -#ifdef EINA_HAVE_DEBUG_THREADS - if (!_eina_threads_activated) - assert(pthread_equal(_eina_main_loop, pthread_self())); -#endif - - if (pthread_mutexattr_init(&attr) != 0) - return EINA_FALSE; - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) - goto fail_release; -#ifdef EINA_HAVE_DEBUG_THREADS - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) - goto fail_release; - memset(mutex, 0, sizeof(Eina_Lock)); -#endif - if (pthread_mutex_init(&(mutex->mutex), &attr) != 0) - goto fail_release; - - ok = EINA_TRUE; -fail_release: - pthread_mutexattr_destroy(&attr); - return ok; + return _eina_lock_new(mutex, EINA_TRUE); } static inline void eina_lock_free(Eina_Lock *mutex) { - int ok; - -#ifdef EINA_HAVE_DEBUG_THREADS - if (!_eina_threads_activated) - assert(pthread_equal(_eina_main_loop, pthread_self())); -#endif - - ok = pthread_mutex_destroy(&(mutex->mutex)); - if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, mutex_destroy, mutex); -#ifdef EINA_HAVE_DEBUG_THREADS - memset(mutex, 0, sizeof(Eina_Lock)); -#endif + _eina_lock_free(mutex); } static inline Eina_Lock_Result @@ -278,9 +218,8 @@ eina_lock_take(Eina_Lock *mutex) if (ok == 0) ret = EINA_LOCK_SUCCEED; else if (ok == EDEADLK) { - printf("EINA ERROR: DEADLOCK on lock %p\n", mutex); eina_lock_debug(mutex); - ret = EINA_LOCK_DEADLOCK; // magic + ret = EINA_LOCK_DEADLOCK; #ifdef EINA_HAVE_DEBUG_THREADS if (_eina_threads_debug) abort(); #endif @@ -326,8 +265,8 @@ eina_lock_take_try(Eina_Lock *mutex) if (ok == 0) ret = EINA_LOCK_SUCCEED; else if (ok == EDEADLK) { - printf("EINA ERROR: DEADLOCK on trylock %p\n", mutex); - ret = EINA_LOCK_DEADLOCK; // magic + eina_lock_debug(mutex); + ret = EINA_LOCK_DEADLOCK; } else if (ok != EBUSY) EINA_LOCK_ABORT_DEBUG(ok, trylock, mutex); #ifdef EINA_HAVE_DEBUG_THREADS @@ -383,64 +322,13 @@ eina_lock_release(Eina_Lock *mutex) static inline Eina_Bool eina_condition_new(Eina_Condition *cond, Eina_Lock *mutex) { - pthread_condattr_t attr; - int ok; - -#ifdef EINA_HAVE_DEBUG_THREADS - assert(mutex != NULL); - if (!_eina_threads_activated) - assert(pthread_equal(_eina_main_loop, pthread_self())); - memset(cond, 0, sizeof (Eina_Condition)); -#endif - - cond->lock = mutex; - pthread_condattr_init(&attr); - - /* OSX doesn't provide clockid_t or clock_gettime. */ -#if defined(__clockid_t_defined) - cond->clkid = (clockid_t) 0; - /* We try here to chose the best clock for cond_timedwait */ -# if defined(CLOCK_MONOTONIC_RAW) - if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC_RAW)) - cond->clkid = CLOCK_MONOTONIC_RAW; -# endif -# if defined(CLOCK_MONOTONIC) - if (!cond->clkid && !pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) - cond->clkid = CLOCK_MONOTONIC; -# endif -# if defined(CLOCK_REALTIME) - if (!cond->clkid && !pthread_condattr_setclock(&attr, CLOCK_REALTIME)) - cond->clkid = CLOCK_REALTIME; -# endif -#endif - - ok = pthread_cond_init(&cond->condition, &attr); - if (ok != 0) - { - pthread_condattr_destroy(&attr); -#ifdef EINA_HAVE_DEBUG_THREADS - if (ok == EBUSY) - printf("eina_condition_new on already initialized Eina_Condition\n"); -#endif - return EINA_FALSE; - } - - pthread_condattr_destroy(&attr); - return EINA_TRUE; + return _eina_condition_new(cond, mutex); } static inline void eina_condition_free(Eina_Condition *cond) { -#ifdef EINA_HAVE_DEBUG_THREADS - if (!_eina_threads_activated) - assert(pthread_equal(_eina_main_loop, pthread_self())); -#endif - - pthread_cond_destroy(&(cond->condition)); -#ifdef EINA_HAVE_DEBUG_THREADS - memset(cond, 0, sizeof (Eina_Condition)); -#endif + _eina_condition_free(cond); } static inline Eina_Bool @@ -455,7 +343,7 @@ eina_condition_wait(Eina_Condition *cond) pthread_mutex_lock(&_eina_tracking_lock); _eina_tracking = eina_inlist_remove(_eina_tracking, - EINA_INLIST_GET(cond->lock)); + EINA_INLIST_GET(cond->lock)); pthread_mutex_unlock(&_eina_tracking_lock); #endif @@ -467,7 +355,7 @@ eina_condition_wait(Eina_Condition *cond) #ifdef EINA_HAVE_DEBUG_THREADS pthread_mutex_lock(&_eina_tracking_lock); _eina_tracking = eina_inlist_append(_eina_tracking, - EINA_INLIST_GET(cond->lock)); + EINA_INLIST_GET(cond->lock)); pthread_mutex_unlock(&_eina_tracking_lock); #endif @@ -483,69 +371,60 @@ eina_condition_timedwait(Eina_Condition *cond, double t) int err; Eina_Bool r = EINA_FALSE; - if (t < 0) + if (t >= 0.0) { - errno = EINVAL; - return EINA_FALSE; - } - #if defined(__clockid_t_defined) - if (cond->clkid) - { - if (clock_gettime(cond->clkid, &ts) != 0) - return EINA_FALSE; - } - else + if (cond->clkid) + { + if (clock_gettime(cond->clkid, &ts) != 0) return EINA_FALSE; + } + else #endif - { - /* Obsolete for Linux. - * TODO: use pthread_cond_timedwait_relative_np for OSX. */ - struct timeval tv; - if (gettimeofday(&tv, NULL) != 0) - return EINA_FALSE; - - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000L; - } + { + /* Obsolete for Linux. + * TODO: use pthread_cond_timedwait_relative_np for OSX. */ + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) return EINA_FALSE; + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000L; + } #ifdef EINA_HAVE_DEBUG_THREADS - assert(_eina_threads_activated); - assert(cond->lock != NULL); + assert(_eina_threads_activated); + assert(cond->lock != NULL); - pthread_mutex_lock(&_eina_tracking_lock); - _eina_tracking = eina_inlist_remove(_eina_tracking, - EINA_INLIST_GET(cond->lock)); - pthread_mutex_unlock(&_eina_tracking_lock); + pthread_mutex_lock(&_eina_tracking_lock); + _eina_tracking = eina_inlist_remove(_eina_tracking, + EINA_INLIST_GET(cond->lock)); + pthread_mutex_unlock(&_eina_tracking_lock); #endif - sec = (time_t)t; - nsec = (t - (double) sec) * 1000000000L; - ts.tv_sec += sec; - ts.tv_nsec += nsec; - if (ts.tv_nsec > 1000000000L) - { - ts.tv_sec++; - ts.tv_nsec -= 1000000000L; - } + sec = (time_t)t; + nsec = (t - (double)sec) * 1000000000L; + ts.tv_sec += sec; + ts.tv_nsec += nsec; + if (ts.tv_nsec > 1000000000L) + { + ts.tv_sec++; + ts.tv_nsec -= 1000000000L; + } - err = pthread_cond_timedwait(&(cond->condition), - &(cond->lock->mutex), - &ts); - if (err == 0) - r = EINA_TRUE; - else if (err == EPERM) - eina_error_set(EPERM); - else if (err == ETIMEDOUT) - eina_error_set(ETIMEDOUT); - else EINA_LOCK_ABORT_DEBUG(err, cond_timedwait, cond); + err = pthread_cond_timedwait(&(cond->condition), + &(cond->lock->mutex), + &ts); + if (err == 0) r = EINA_TRUE; + else if (err == EPERM) eina_error_set(EPERM); + else if (err == ETIMEDOUT) eina_error_set(ETIMEDOUT); + else EINA_LOCK_ABORT_DEBUG(err, cond_timedwait, cond); #ifdef EINA_HAVE_DEBUG_THREADS - pthread_mutex_lock(&_eina_tracking_lock); - _eina_tracking = eina_inlist_append(_eina_tracking, - EINA_INLIST_GET(cond->lock)); - pthread_mutex_unlock(&_eina_tracking_lock); + pthread_mutex_lock(&_eina_tracking_lock); + _eina_tracking = eina_inlist_append(_eina_tracking, + EINA_INLIST_GET(cond->lock)); + pthread_mutex_unlock(&_eina_tracking_lock); #endif - + } + errno = EINVAL; return r; } @@ -584,29 +463,13 @@ eina_condition_signal(Eina_Condition *cond) static inline Eina_Bool eina_rwlock_new(Eina_RWLock *mutex) { - int ok; - -#ifdef EINA_HAVE_DEBUG_THREADS - if (!_eina_threads_activated) - assert(pthread_equal(_eina_main_loop, pthread_self())); -#endif - - ok = pthread_rwlock_init(&(mutex->mutex), NULL); - if (ok == 0) return EINA_TRUE; - else if (ok == EAGAIN || ok == ENOMEM) return EINA_FALSE; - else EINA_LOCK_ABORT_DEBUG(ok, rwlock_init, mutex); - return EINA_FALSE; + return _eina_rwlock_new(mutex); } static inline void eina_rwlock_free(Eina_RWLock *mutex) { -#ifdef EINA_HAVE_DEBUG_THREADS - if (!_eina_threads_activated) - assert(pthread_equal(_eina_main_loop, pthread_self())); -#endif - - pthread_rwlock_destroy(&(mutex->mutex)); + _eina_rwlock_free(mutex); } static inline Eina_Lock_Result @@ -680,9 +543,8 @@ eina_rwlock_release(Eina_RWLock *mutex) static inline Eina_Bool eina_tls_cb_new(Eina_TLS *key, Eina_TLS_Delete_Cb delete_cb) { - if (pthread_key_create(key, delete_cb) != 0) - return EINA_FALSE; - return EINA_TRUE; + if (pthread_key_create(key, delete_cb) == 0) return EINA_TRUE; + return EINA_FALSE; } static inline Eina_Bool @@ -691,24 +553,23 @@ eina_tls_new(Eina_TLS *key) return eina_tls_cb_new(key, NULL); } -static inline void +static inline void eina_tls_free(Eina_TLS key) { pthread_key_delete(key); } -static inline void * +static inline void * eina_tls_get(Eina_TLS key) { return pthread_getspecific(key); } -static inline Eina_Bool +static inline Eina_Bool eina_tls_set(Eina_TLS key, const void *data) { - if (pthread_setspecific(key, data) != 0) - return EINA_FALSE; - return EINA_TRUE; + if (pthread_setspecific(key, data) == 0) return EINA_TRUE; + return EINA_FALSE; } @@ -720,31 +581,12 @@ struct _Eina_Barrier pthread_barrier_t barrier; }; -static inline Eina_Bool -eina_barrier_new(Eina_Barrier *barrier, int needed) -{ - int ok; - ok = pthread_barrier_init(&(barrier->barrier), NULL, needed); - if (ok == 0) return EINA_TRUE; - else if (ok == EAGAIN || ok == ENOMEM) return EINA_FALSE; - else EINA_LOCK_ABORT_DEBUG(ok, barrier_init, barrier); - return EINA_FALSE; -} - -static inline void -eina_barrier_free(Eina_Barrier *barrier) -{ - int ok; - ok = pthread_barrier_destroy(&(barrier->barrier)); - if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, barrier_destroy, barrier); -} - static inline Eina_Bool eina_barrier_wait(Eina_Barrier *barrier) { - int ok; - ok = pthread_barrier_wait(&(barrier->barrier)); - if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, barrier_wait, barrier); + int ok = pthread_barrier_wait(&(barrier->barrier)); + if (ok == 0) return EINA_TRUE; + else EINA_LOCK_ABORT_DEBUG(ok, barrier_wait, barrier); return EINA_TRUE; } @@ -752,24 +594,32 @@ eina_barrier_wait(Eina_Barrier *barrier) #include "eina_inline_lock_barrier.x" #endif +EAPI Eina_Bool _eina_barrier_new(Eina_Barrier *barrier, int needed); +EAPI void _eina_barrier_free(Eina_Barrier *barrier); + +static inline Eina_Bool +eina_barrier_new(Eina_Barrier *barrier, int needed) +{ + return _eina_barrier_new(barrier, needed); +} + +static inline void +eina_barrier_free(Eina_Barrier *barrier) +{ + _eina_barrier_free(barrier); +} + + static inline Eina_Bool eina_spinlock_new(Eina_Spinlock *spinlock) { -#if defined(EINA_HAVE_POSIX_SPINLOCK) - int ok; - ok = pthread_spin_init(spinlock, PTHREAD_PROCESS_PRIVATE); - if (ok == 0) return EINA_TRUE; - else if (ok == EAGAIN || ok == ENOMEM) return EINA_FALSE; - else EINA_LOCK_ABORT_DEBUG(ok, spin_init, spinlock); - return 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_TRUE; -#else - return eina_lock_new(spinlock); -#endif + return _eina_spinlock_new(spinlock); +} + +static inline void +eina_spinlock_free(Eina_Spinlock *spinlock) +{ + _eina_spinlock_free(spinlock); } static inline Eina_Lock_Result @@ -778,12 +628,11 @@ eina_spinlock_take(Eina_Spinlock *spinlock) #if defined(EINA_HAVE_POSIX_SPINLOCK) int t; - while (EINA_TRUE) + for (;;) { - t = pthread_spin_trylock(spinlock); + t = pthread_spin_lock(spinlock); if (t == 0) break; - else if (t == EBUSY) sched_yield(); - else EINA_LOCK_ABORT_DEBUG(t, spin_trylock, spinlock); + else EINA_LOCK_ABORT_DEBUG(t, spin_lock, spinlock); } return EINA_LOCK_SUCCEED; @@ -802,9 +651,7 @@ static inline Eina_Lock_Result eina_spinlock_take_try(Eina_Spinlock *spinlock) { #if defined(EINA_HAVE_POSIX_SPINLOCK) - int t; - - t = pthread_spin_trylock(spinlock); + int t = pthread_spin_trylock(spinlock); if (t == 0) return EINA_LOCK_SUCCEED; else if (t == EBUSY) return EINA_LOCK_FAIL; else EINA_LOCK_ABORT_DEBUG(t, spin_trylock, spinlock); @@ -823,8 +670,7 @@ static inline Eina_Lock_Result eina_spinlock_release(Eina_Spinlock *spinlock) { #if defined(EINA_HAVE_POSIX_SPINLOCK) - int ok; - ok = pthread_spin_unlock(spinlock); + int ok = pthread_spin_unlock(spinlock); if (ok == 0) return EINA_LOCK_SUCCEED; else if (ok == EPERM) return EINA_LOCK_FAIL; else EINA_LOCK_ABORT_DEBUG(ok, spin_unlock, spinlock); @@ -839,96 +685,52 @@ eina_spinlock_release(Eina_Spinlock *spinlock) #endif } -static inline void -eina_spinlock_free(Eina_Spinlock *spinlock) -{ -#if defined(EINA_HAVE_POSIX_SPINLOCK) - int ok; - ok = pthread_spin_destroy(spinlock); - if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, spin_destroy, spinlock); -#elif defined(EINA_HAVE_OSX_SPINLOCK) - /* Not applicable */ - (void) spinlock; -#else - eina_lock_free(spinlock); -#endif -} - static inline Eina_Bool eina_semaphore_new(Eina_Semaphore *sem, int count_init) { - if (!sem || (count_init < 0)) - return EINA_FALSE; - -#if defined(EINA_HAVE_OSX_SEMAPHORE) - kern_return_t kr; - - kr = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, count_init); - return (kr == KERN_SUCCESS) ? EINA_TRUE : EINA_FALSE; -#else - return (sem_init(sem, 0, count_init) == 0) ? EINA_TRUE : EINA_FALSE; -#endif + return _eina_semaphore_new(sem, count_init); } static inline Eina_Bool eina_semaphore_free(Eina_Semaphore *sem) { - if (!sem) - return EINA_FALSE; - -#if defined(EINA_HAVE_OSX_SEMAPHORE) - return (semaphore_destroy(*sem, mach_task_self()) == KERN_SUCCESS) - ? EINA_TRUE : EINA_FALSE; -#else - return (sem_destroy(sem) == 0) ? EINA_TRUE : EINA_FALSE; -#endif + return _eina_semaphore_free(sem); } static inline Eina_Bool eina_semaphore_lock(Eina_Semaphore *sem) { - Eina_Bool ok = EINA_FALSE; - - if (!sem) - return EINA_FALSE; - - for (;;) + if (sem) { - if ( + for (;;) + { + if ( #if defined(EINA_HAVE_OSX_SEMAPHORE) - semaphore_wait(*sem) + semaphore_wait(*sem) #else - sem_wait(sem) + sem_wait(sem) #endif - == 0) - { - ok = EINA_TRUE; - break; - } - else - { - if (errno != EINTR) - { - if (errno == EDEADLK) - EINA_LOCK_DEADLOCK_DEBUG(sem_wait, sem); - break; - } + == 0) + return EINA_TRUE; + else if (errno != EINTR) goto err; } } - return ok; + return EINA_FALSE; +err: + if (errno == EDEADLK) EINA_LOCK_DEADLOCK_DEBUG(sem_wait, sem); + return EINA_FALSE; } static inline Eina_Bool eina_semaphore_release(Eina_Semaphore *sem, int count_release EINA_UNUSED) { - if (!sem) - return EINA_FALSE; - + if (sem) #if defined(EINA_HAVE_OSX_SEMAPHORE) - return (semaphore_signal(*sem) == KERN_SUCCESS) ? EINA_TRUE : EINA_FALSE; + return (semaphore_signal(*sem) == KERN_SUCCESS) ? EINA_TRUE : EINA_FALSE; #else - return (sem_post(sem) == 0) ? EINA_TRUE : EINA_FALSE; + return (sem_post(sem) == 0) ? EINA_TRUE : EINA_FALSE; #endif + return EINA_FALSE; } #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 eina_log_domain_level_check(int domain, int level) { int dom_level = eina_log_domain_registered_level_get(domain); - if (EINA_UNLIKELY(dom_level == EINA_LOG_LEVEL_UNKNOWN)) - return EINA_FALSE; - return dom_level >= level; + if (EINA_LIKELY(dom_level != EINA_LOG_LEVEL_UNKNOWN)) + return dom_level >= level; + return EINA_FALSE; } /** 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 * eina_mempool_calloc(Eina_Mempool *mp, unsigned int size) { void *r = mp->backend.alloc(mp->backend_data, size); - if (!r) return NULL; - memset(r, 0, size); + if (r) memset(r, 0, size); return r; } static inline void eina_mempool_free(Eina_Mempool *mp, void *element) { - if (!element) return ; - mp->backend.free(mp->backend_data, element); + if (element) mp->backend.free(mp->backend_data, element); } static inline unsigned int @@ -111,31 +109,33 @@ eina_mempool_alignof(unsigned int size) { unsigned int align; - if (EINA_UNLIKELY(size <= 2)) - { - align = 2; - } - else if (EINA_UNLIKELY(size < 8)) - { - align = 4; - } - else #if __WORDSIZE == 32 + if (size >= 8) { align = 8; +calc: + return ((size / align) + (size % align ? 1 : 0)) * align; } -#else - if (EINA_UNLIKELY(size < 16)) - { - align = 8; - } - else +#else // __WORDSIZE == 64 + if (size >= 16) { align = 16; +calc: + return ((size / align) + (size % align ? 1 : 0)) * align; + } + else if (size >= 8) + { + align = 8; + goto calc; } #endif - - return ((size / align) + (size % align ? 1 : 0)) * align; + else if (size >= 4) + { + align = 4; + goto calc; + } + align = 2; + goto calc; } #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, while (root) { - result = cmp(root, key, length, (void*) data); - if (result == 0) return (Eina_Rbtree*) root; - - root = root->son[result < 0 ? 0 : 1]; + result = cmp(root, key, length, (void *)data); + if (result != 0) root = root->son[result < 0 ? 0 : 1]; + else break; } - - return NULL; + return (Eina_Rbtree *)root; } /** 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 @@ static inline Eina_Bool eina_rectangle_is_valid(const Eina_Rectangle *r) { - if (r->w <= 0 || r->h <= 0) - return EINA_FALSE; - return EINA_TRUE; + if ((r->w > 0) && (r->h > 0)) return EINA_TRUE; + return EINA_FALSE; } static inline int @@ -36,7 +35,7 @@ eina_spans_intersect(int c1, int l1, int c2, int l2) static inline Eina_Bool eina_rectangle_is_empty(const Eina_Rectangle *r) { - return ((r->w < 1) || (r->h < 1)) ? EINA_TRUE : EINA_FALSE; + return !eina_rectangle_is_valid(r); } static inline void @@ -98,39 +97,34 @@ eina_rectangle_union(Eina_Rectangle *dst, const Eina_Rectangle *src) static inline Eina_Bool eina_rectangle_intersection(Eina_Rectangle *dst, const Eina_Rectangle *src) { - if (!(eina_rectangle_is_valid(dst)) || !(eina_rectangle_is_valid(src))) - return EINA_FALSE; + if (eina_rectangle_is_valid(dst) && eina_rectangle_is_valid(src) && + eina_rectangles_intersect(dst, src)) + { + /* left */ + if (dst->x < src->x) + { + dst->w += dst->x - src->x; + dst->x = src->x; + if (dst->w < 0) dst->w = 0; + } + /* right */ + if ((dst->x + dst->w) > (src->x + src->w)) + dst->w = src->x + src->w - dst->x; + /* top */ + if (dst->y < src->y) + { + dst->h += dst->y - src->y; + dst->y = src->y; + if (dst->h < 0) dst->h = 0; + } + /* bottom */ + if ((dst->y + dst->h) > (src->y + src->h)) + dst->h = src->y + src->h - dst->y; - if (!(eina_rectangles_intersect(dst, src))) - return EINA_FALSE; - - /* left */ - if (dst->x < src->x) - { - dst->w += dst->x - src->x; - dst->x = src->x; - if (dst->w < 0) - dst->w = 0; - } - /* right */ - if ((dst->x + dst->w) > (src->x + src->w)) - dst->w = src->x + src->w - dst->x; - /* top */ - if (dst->y < src->y) - { - dst->h += dst->y - src->y; - dst->y = src->y; - if (dst->h < 0) - dst->h = 0; - } - /* bottom */ - if ((dst->y + dst->h) > (src->y + src->h)) - dst->h = src->y + src->h - dst->y; - - if (dst->w == 0 || dst->h == 0) - return EINA_FALSE; - - return EINA_TRUE; + if ((dst->w == 0) || (dst->h == 0)) return EINA_FALSE; + return EINA_TRUE; + } + return EINA_FALSE; } static inline void @@ -218,57 +212,57 @@ eina_rectangle_height_cut(Eina_Rectangle *thiz, Eina_Rectangle *slice, Eina_Rect static inline Eina_Bool eina_rectangle_subtract(Eina_Rectangle *thiz, Eina_Rectangle *other, Eina_Rectangle out[4]) { - Eina_Rectangle intersection; - Eina_Rectangle leftover = EINA_RECTANGLE_INIT; - Eina_Rectangle tmp; - int cut = 0; + Eina_Rectangle intersection; + Eina_Rectangle leftover = EINA_RECTANGLE_INIT; + Eina_Rectangle tmp; + int cut = 0; - if (!eina_rectangle_is_valid(thiz)) - return EINA_FALSE; + if (eina_rectangle_is_valid(thiz)) + { + eina_rectangle_coords_from(&out[0], 0, 0, 0, 0); + eina_rectangle_coords_from(&out[1], 0, 0, 0, 0); + eina_rectangle_coords_from(&out[2], 0, 0, 0, 0); + eina_rectangle_coords_from(&out[3], 0, 0, 0, 0); + intersection = *thiz; + if (!eina_rectangle_intersection(&intersection, other)) + { + out[0] = *thiz; + return EINA_TRUE; + } - eina_rectangle_coords_from(&out[0], 0, 0, 0, 0); - eina_rectangle_coords_from(&out[1], 0, 0, 0, 0); - eina_rectangle_coords_from(&out[2], 0, 0, 0, 0); - eina_rectangle_coords_from(&out[3], 0, 0, 0, 0); - intersection = *thiz; - if (!eina_rectangle_intersection(&intersection, other)) - { - out[0] = *thiz; - return EINA_TRUE; - } - - /* cut in height */ - { - cut = thiz->h - (intersection.y - thiz->y); - if (cut > thiz->h) { cut = thiz->h; } - eina_rectangle_height_cut(thiz, &leftover, &out[0], cut); - } - /* cut in y */ - tmp = leftover; - if (eina_rectangle_intersection(&tmp, &intersection)) - { - cut = leftover.h - (eina_rectangle_max_y(&leftover) - eina_rectangle_max_y(&tmp)); - if (cut > leftover.h) { cut = leftover.h; } - eina_rectangle_y_cut(&leftover, &leftover, &out[1], cut); - } - /* cut in width */ - tmp = leftover; - if (eina_rectangle_intersection(&tmp, &intersection)) - { - cut = leftover.w - (tmp.x - leftover.x); - if (cut > leftover.w) { cut = leftover.w; } - eina_rectangle_width_cut(&leftover, &leftover, &out[2], cut); - } - /* cut in x */ - tmp = leftover; - if (eina_rectangle_intersection(&tmp, &intersection)) - { - cut = leftover.w - (eina_rectangle_max_x(&leftover) - eina_rectangle_max_x(&tmp)); - if (cut > leftover.w) { cut = leftover.w; } - eina_rectangle_x_cut(&leftover, &leftover, &out[3], cut); - } - - return EINA_TRUE; + /* cut in height */ + { + cut = thiz->h - (intersection.y - thiz->y); + if (cut > thiz->h) cut = thiz->h; + eina_rectangle_height_cut(thiz, &leftover, &out[0], cut); + } + /* cut in y */ + tmp = leftover; + if (eina_rectangle_intersection(&tmp, &intersection)) + { + cut = leftover.h - (eina_rectangle_max_y(&leftover) - eina_rectangle_max_y(&tmp)); + if (cut > leftover.h) cut = leftover.h; + eina_rectangle_y_cut(&leftover, &leftover, &out[1], cut); + } + /* cut in width */ + tmp = leftover; + if (eina_rectangle_intersection(&tmp, &intersection)) + { + cut = leftover.w - (tmp.x - leftover.x); + if (cut > leftover.w) cut = leftover.w; + eina_rectangle_width_cut(&leftover, &leftover, &out[2], cut); + } + /* cut in x */ + tmp = leftover; + if (eina_rectangle_intersection(&tmp, &intersection)) + { + cut = leftover.w - (eina_rectangle_max_x(&leftover) - eina_rectangle_max_x(&tmp)); + if (cut > leftover.w) cut = leftover.w; + eina_rectangle_x_cut(&leftover, &leftover, &out[3], cut); + } + return EINA_TRUE; + } + return EINA_FALSE; } #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) if (ret.len == 0) return ret; ret.mem = malloc(ret.len); - if (!ret.mem) - ret.len = 0; - else - memcpy(ret.mem, slice.mem, ret.len); + if (ret.mem) memcpy(ret.mem, slice.mem, ret.len); + else ret.len = 0; return ret; } @@ -99,16 +97,13 @@ eina_slice_seek(const Eina_Slice slice, ssize_t offset, int whence) offset += slice.len; } - if (whence != SEEK_SET) - return ret; - - if (offset < 0) - offset = 0; - else if ((size_t)offset > slice.len) - offset = slice.len; - - ret.len = slice.len - offset; - ret.mem = (const void *)(slice.bytes + offset); + if (whence == SEEK_SET) + { + if ((size_t)offset > slice.len) offset = slice.len; + else if (offset < 0) offset = 0; + ret.len = slice.len - offset; + ret.mem = (const void *)(slice.bytes + offset); + } return ret; } @@ -126,88 +121,88 @@ eina_rw_slice_seek(const Eina_Rw_Slice rw_slice, ssize_t offset, int whence) offset += rw_slice.len; } - if (whence != SEEK_SET) - return ret; - - if (offset < 0) - offset = 0; - else if ((size_t)offset > rw_slice.len) - offset = rw_slice.len; - - ret.len = rw_slice.len - offset; - ret.mem = (void *)(rw_slice.bytes + offset); + if (whence == SEEK_SET) + { + if ((size_t)offset > rw_slice.len) offset = rw_slice.len; + else if (offset < 0) offset = 0; + ret.len = rw_slice.len - offset; + ret.mem = (void *)(rw_slice.bytes + offset); + } return ret; } static inline const void * eina_slice_strchr(const Eina_Slice slice, int c) { - if (slice.len == 0) return NULL; - return memchr(slice.mem, c, slice.len); + if (slice.len != 0) return memchr(slice.mem, c, slice.len); + return NULL; } + static inline const void * eina_slice_find(const Eina_Slice slice, const Eina_Slice needle) { Eina_Slice s, n; uint8_t c; - if (slice.len == 0) return NULL; - if (needle.len == 0) return NULL; - if (slice.len < needle.len) return NULL; - if (needle.len == 1) return eina_slice_strchr(slice, needle.bytes[0]); - if ((slice.len == needle.len) && - (memcmp(slice.mem, needle.mem, needle.len) == 0)) - return slice.mem; - - s.mem = slice.mem; - s.len = slice.len - (needle.len - 1); - - c = needle.bytes[0]; - n.mem = (const void *)(needle.bytes + 1); - n.len = needle.len - 1; - - while (s.len > 0) + if ((slice.len != 0) && (needle.len != 0) && (slice.len >= needle.len)) { - const uint8_t *p = (const uint8_t *)eina_slice_strchr(s, c); - size_t offset; + if (needle.len == 1) return eina_slice_strchr(slice, needle.bytes[0]); + if ((slice.len == needle.len) && + (memcmp(slice.mem, needle.mem, needle.len) == 0)) + return slice.mem; - if (!p) return NULL; + s.mem = slice.mem; + s.len = slice.len - (needle.len - 1); - p++; - if (memcmp(p, n.mem, n.len) == 0) - return (const void *)(p - 1); + c = needle.bytes[0]; + n.mem = (const void *)(needle.bytes + 1); + n.len = needle.len - 1; - offset = p - s.bytes; - s.bytes += offset; - s.len -= offset; + while (s.len > 0) + { + const uint8_t *p = (const uint8_t *)eina_slice_strchr(s, c); + size_t offset; + + if (p) + { + p++; + if (memcmp(p, n.mem, n.len) == 0) + return (const void *)(p - 1); + + offset = p - s.bytes; + s.bytes += offset; + s.len -= offset; + continue; + } + break; + } } - return NULL; } static inline Eina_Bool eina_slice_startswith(const Eina_Slice slice, const Eina_Slice prefix) { - if (prefix.len == 0) return EINA_FALSE; - if (slice.len < prefix.len) return EINA_FALSE; - return memcmp(slice.mem, prefix.mem, prefix.len) == 0; + if ((prefix.len != 0) && (slice.len >= prefix.len)) + return memcmp(slice.mem, prefix.mem, prefix.len) == 0; + return EINA_FALSE; } static inline Eina_Bool eina_slice_endswith(const Eina_Slice slice, const Eina_Slice suffix) { - if (suffix.len == 0) return EINA_FALSE; - if (slice.len < suffix.len) return EINA_FALSE; - return memcmp(slice.bytes + slice.len - suffix.len, - suffix.mem, suffix.len) == 0; + if ((suffix.len != 0) && (slice.len > suffix.len)) + return memcmp(slice.bytes + slice.len - suffix.len, + suffix.mem, suffix.len) == 0; + return EINA_FALSE; } static inline void * eina_rw_slice_strchr(const Eina_Rw_Slice rw_slice, int c) { - if (rw_slice.len == 0) return NULL; - return memchr(rw_slice.mem, c, rw_slice.len); + if (rw_slice.len != 0) return memchr(rw_slice.mem, c, rw_slice.len); + return NULL; } static inline void * @@ -219,18 +214,18 @@ eina_rw_slice_find(const Eina_Rw_Slice rw_slice, const Eina_Slice needle) static inline Eina_Bool eina_rw_slice_startswith(const Eina_Rw_Slice rw_slice, const Eina_Slice prefix) { - if (prefix.len == 0) return EINA_FALSE; - if (rw_slice.len < prefix.len) return EINA_FALSE; - return memcmp(rw_slice.mem, prefix.mem, prefix.len) == 0; + if ((prefix.len != 0) && (rw_slice.len >= prefix.len)) + return memcmp(rw_slice.mem, prefix.mem, prefix.len) == 0; + return EINA_FALSE; } static inline Eina_Bool eina_rw_slice_endswith(const Eina_Rw_Slice rw_slice, const Eina_Slice suffix) { - if (suffix.len == 0) return EINA_FALSE; - if (rw_slice.len < suffix.len) return EINA_FALSE; - return memcmp(rw_slice.bytes + rw_slice.len - suffix.len, - suffix.mem, suffix.len) == 0; + if ((suffix.len != 0) && (rw_slice.len >= suffix.len)) + return memcmp(rw_slice.bytes + rw_slice.len - suffix.len, + suffix.mem, suffix.len) == 0; + return EINA_FALSE; } static inline const void * @@ -248,19 +243,17 @@ eina_rw_slice_end_get(const Eina_Rw_Slice rw_slice) static inline char * eina_slice_strdup(const Eina_Slice slice) { - if (slice.len == 0) - return strdup(""); - else + if (slice.len != 0) return strndup((const char *)slice.mem, slice.len); + return strdup(""); } static inline char * eina_rw_slice_strdup(const Eina_Rw_Slice rw_slice) { - if (rw_slice.len == 0) - return strdup(""); - else + if (rw_slice.len != 0) return strndup((const char *)rw_slice.mem, rw_slice.len); + return strdup(""); } #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 eina_streq(const char *a, const char *b) { if (a == b) return EINA_TRUE; - if (!a) return EINA_FALSE; - if (!b) return EINA_FALSE; + if ((!a) || (!b)) return EINA_FALSE; return !strcmp(a, b); } 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 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include "eina_config.h" +#include "Eina.h" + +EAPI void +_eina_lock_debug_abort(int err, const char *fn, const volatile void *ptr) +{ + fprintf(stderr, "EINA ERROR: '%s' on %s %p\n", strerror(err), fn, ptr); +#ifdef EINA_HAVE_DEBUG_THREADS + abort(); +#endif +} + +EAPI void +_eina_lock_debug_deadlock(const char *fn, const volatile void *ptr) +{ + fprintf(stderr, "EINA ERROR: DEADLOCK on %s %p\n", fn, ptr); +#ifdef EINA_HAVE_DEBUG_THREADS + abort(); +#endif +} + +EAPI void +eina_lock_debug(const Eina_Lock *mutex) +{ +#ifdef EINA_HAVE_DEBUG_THREADS + fprintf(stderr, "EINA ERROR: DEADLOCK on lock %p, locked: %i, by %ti\n", + mutex, (int)mutex->locked, (ptrdiff_t)mutex->lock_thread_id); + backtrace_symbols_fd((void **)mutex->lock_bt, mutex->lock_bt_num, 1); +#else + fprintf(stderr, "EINA ERROR: DEADLOCK on lock %p\n", mutex); +#endif +} + +EAPI Eina_Bool +_eina_lock_new(Eina_Lock *mutex, Eina_Bool recursive) +{ + pthread_mutexattr_t attr; + Eina_Bool ok = EINA_FALSE; + +#ifdef EINA_HAVE_DEBUG_THREADS + if (!_eina_threads_activated) + assert(pthread_equal(_eina_main_loop, pthread_self())); +#endif + + if (pthread_mutexattr_init(&attr) != 0) return EINA_FALSE; + if (recursive) + { + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) goto fail_release; + } +#ifdef EINA_HAVE_DEBUG_THREADS + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) goto fail_release; + memset(mutex, 0, sizeof(Eina_Lock)); +#endif + if (pthread_mutex_init(&(mutex->mutex), &attr) != 0) goto fail_release; + ok = EINA_TRUE; +fail_release: + pthread_mutexattr_destroy(&attr); + return ok; +} + +EAPI void +_eina_lock_free(Eina_Lock *mutex) +{ + int ok; + +#ifdef EINA_HAVE_DEBUG_THREADS + if (!_eina_threads_activated) + assert(pthread_equal(_eina_main_loop, pthread_self())); +#endif + + ok = pthread_mutex_destroy(&(mutex->mutex)); + if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, mutex_destroy, mutex); +#ifdef EINA_HAVE_DEBUG_THREADS + memset(mutex, 0, sizeof(Eina_Lock)); +#endif +} + +EAPI Eina_Bool +_eina_condition_new(Eina_Condition *cond, Eina_Lock *mutex) +{ + pthread_condattr_t attr; + int ok; + +#ifdef EINA_HAVE_DEBUG_THREADS + assert(mutex != NULL); + if (!_eina_threads_activated) + assert(pthread_equal(_eina_main_loop, pthread_self())); + memset(cond, 0, sizeof (Eina_Condition)); +#endif + + cond->lock = mutex; + pthread_condattr_init(&attr); + + /* OSX doesn't provide clockid_t or clock_gettime. */ +#if defined(__clockid_t_defined) + cond->clkid = (clockid_t) 0; + /* We try here to chose the best clock for cond_timedwait */ +# if defined(CLOCK_MONOTONIC_RAW) + if (!pthread_condattr_setclock(&attr, CLOCK_MONOTONIC_RAW)) + cond->clkid = CLOCK_MONOTONIC_RAW; +# endif +# if defined(CLOCK_MONOTONIC) + if (!cond->clkid && !pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) + cond->clkid = CLOCK_MONOTONIC; +# endif +# if defined(CLOCK_REALTIME) + if (!cond->clkid && !pthread_condattr_setclock(&attr, CLOCK_REALTIME)) + cond->clkid = CLOCK_REALTIME; +# endif +#endif + + ok = pthread_cond_init(&cond->condition, &attr); + if (ok != 0) + { + pthread_condattr_destroy(&attr); +#ifdef EINA_HAVE_DEBUG_THREADS + if (ok == EBUSY) + fprintf(stderr, "EINA ERROR: eina_condition_new on already initialized Eina_Condition\n"); +#endif + return EINA_FALSE; + } + + pthread_condattr_destroy(&attr); + return EINA_TRUE; +} + +EAPI void +_eina_condition_free(Eina_Condition *cond) +{ +#ifdef EINA_HAVE_DEBUG_THREADS + if (!_eina_threads_activated) + assert(pthread_equal(_eina_main_loop, pthread_self())); +#endif + + pthread_cond_destroy(&(cond->condition)); +#ifdef EINA_HAVE_DEBUG_THREADS + memset(cond, 0, sizeof (Eina_Condition)); +#endif +} + +EAPI Eina_Bool +_eina_rwlock_new(Eina_RWLock *mutex) +{ + int ok; + +#ifdef EINA_HAVE_DEBUG_THREADS + if (!_eina_threads_activated) + assert(pthread_equal(_eina_main_loop, pthread_self())); +#endif + + ok = pthread_rwlock_init(&(mutex->mutex), NULL); + if (ok == 0) return EINA_TRUE; + else if ((ok == EAGAIN) || (ok == ENOMEM)) return EINA_FALSE; + else EINA_LOCK_ABORT_DEBUG(ok, rwlock_init, mutex); + return EINA_FALSE; +} + +EAPI void +_eina_rwlock_free(Eina_RWLock *mutex) +{ +#ifdef EINA_HAVE_DEBUG_THREADS + if (!_eina_threads_activated) + assert(pthread_equal(_eina_main_loop, pthread_self())); +#endif + pthread_rwlock_destroy(&(mutex->mutex)); +} + +EAPI Eina_Bool +_eina_barrier_new(Eina_Barrier *barrier, int needed) +{ +#ifdef EINA_HAVE_PTHREAD_BARRIER + int ok = pthread_barrier_init(&(barrier->barrier), NULL, needed); + if (ok == 0) return EINA_TRUE; + else if ((ok == EAGAIN) || (ok == ENOMEM)) return EINA_FALSE; + else EINA_LOCK_ABORT_DEBUG(ok, barrier_init, barrier); + return EINA_FALSE; +#else + barrier->needed = needed; + barrier->called = 0; + if (eina_lock_new(&(barrier->cond_lock))) + { + if (eina_condition_new(&(barrier->cond), &(barrier->cond_lock))) + return EINA_TRUE; + } + return EINA_FALSE; +#endif +} + +EAPI void +_eina_barrier_free(Eina_Barrier *barrier) +{ +#ifdef EINA_HAVE_PTHREAD_BARRIER + int ok = pthread_barrier_destroy(&(barrier->barrier)); + if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, barrier_destroy, barrier); +#else + eina_condition_free(&(barrier->cond)); + eina_lock_free(&(barrier->cond_lock)); + barrier->needed = 0; + barrier->called = 0; +#endif +} + +EAPI Eina_Bool +_eina_spinlock_new(Eina_Spinlock *spinlock) +{ +#if defined(EINA_HAVE_POSIX_SPINLOCK) + int ok = pthread_spin_init(spinlock, PTHREAD_PROCESS_PRIVATE); + if (ok == 0) return EINA_TRUE; + else if ((ok == EAGAIN) || (ok == ENOMEM)) return EINA_FALSE; + else EINA_LOCK_ABORT_DEBUG(ok, spin_init, spinlock); + return 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_TRUE; +#else + return eina_lock_new(spinlock); +#endif +} + +EAPI void +_eina_spinlock_free(Eina_Spinlock *spinlock) +{ +#if defined(EINA_HAVE_POSIX_SPINLOCK) + int ok = pthread_spin_destroy(spinlock); + if (ok != 0) EINA_LOCK_ABORT_DEBUG(ok, spin_destroy, spinlock); +#elif defined(EINA_HAVE_OSX_SPINLOCK) + /* Not applicable */ + (void) spinlock; +#else + eina_lock_free(spinlock); +#endif +} + +EAPI Eina_Bool +_eina_semaphore_new(Eina_Semaphore *sem, int count_init) +{ + if (sem && (count_init >= 0)) + { +#if defined(EINA_HAVE_OSX_SEMAPHORE) + kern_return_t kr = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, count_init); + return (kr == KERN_SUCCESS) ? EINA_TRUE : EINA_FALSE; +#else + return (sem_init(sem, 0, count_init) == 0) ? EINA_TRUE : EINA_FALSE; +#endif + } + return EINA_FALSE; +} + +EAPI Eina_Bool +_eina_semaphore_free(Eina_Semaphore *sem) +{ + if (sem) + { +#if defined(EINA_HAVE_OSX_SEMAPHORE) + return (semaphore_destroy(*sem, mach_task_self()) == KERN_SUCCESS) + ? EINA_TRUE : EINA_FALSE; +#else + return (sem_destroy(sem) == 0) ? EINA_TRUE : EINA_FALSE; +#endif + } + return EINA_FALSE; +} 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); * * @note If @c EINA_HAVE_DEBUG_THREADS is not defined, this function does nothing. */ -static inline void eina_lock_debug(const Eina_Lock *mutex); +EAPI void eina_lock_debug(const Eina_Lock *mutex); /** * @brief Initializes a new condition variable.