eina_semaphore: OSX support

Summary:
OSX only support named semaphores. Eina_Semaphore was actually broken on OSX.
Since OSX 10.10 sem_init() and sem_destroy() (were not implemented) are also marked as
"deprecated", which adds huge pollution to the output when compiling.

Reviewers: cedric, raster, stefan_schmidt

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D1576

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
Jean Guyomarc'h 2014-10-27 09:11:19 +01:00 committed by Cedric BAIL
parent 72c576ab4e
commit 6de8e3104d
3 changed files with 90 additions and 36 deletions

View File

@ -960,6 +960,7 @@ EINA_CONFIG([HAVE_PTHREAD_AFFINITY], [test "x${efl_have_setaffinity}" = "xyes"])
EINA_CONFIG([HAVE_DEBUG_THREADS], [test "x${want_debug_threads}" = "xyes"])
EINA_CONFIG([HAVE_POSIX_SPINLOCK], [test "x${efl_have_posix_threads_spinlock}" = "xyes"])
EINA_CONFIG([HAVE_OSX_SPINLOCK], [test "x${efl_have_osx_spinlock}" = "xyes"])
EINA_CONFIG([HAVE_OSX_SEMAPHORE], [test "x${have_darwin}" = "xyes"])
### Modules

View File

@ -102,6 +102,11 @@
#endif
@EINA_CONFIGURE_HAVE_OSX_SPINLOCK@
#ifndef EINA_HAVE_OSX_SEMAPHORE
# undef EINA_HAVE_OSX_SEMAPHORE
#endif
@EINA_CONFIGURE_HAVE_OSX_SEMAPHORE@
/* Do not turn the following #define as meaning EFL64. We are only
interested to know if sizeof (void*) == 64bits or not. Those means
something else.

View File

@ -62,7 +62,7 @@ typedef struct _Eina_Lock Eina_Lock;
typedef struct _Eina_RWLock Eina_RWLock;
typedef struct _Eina_Condition Eina_Condition;
typedef pthread_key_t Eina_TLS;
typedef sem_t Eina_Semaphore;
#if defined(EINA_HAVE_POSIX_SPINLOCK)
typedef pthread_spinlock_t Eina_Spinlock;
#elif defined(EINA_HAVE_OSX_SPINLOCK)
@ -71,6 +71,29 @@ typedef OSSpinLock Eina_Spinlock;
typedef Eina_Lock Eina_Spinlock;
#endif
#if defined(EINA_HAVE_OSX_SEMAPHORE)
/* OSX supports only named semaphores.
* So, we need to be able to generate a unique string identifier for each
* semaphore we want to create.
* It seems reasonable to use a counter, which is incremented each time a
* semaphore is created. However, it needs to be atomic...
* It would be easier if we were using C11 with stdatomic, but I guess it
* will just be fine without.
* That's why there are two static variables below the struct */
struct _Eina_Semaphore
{
sem_t *sema;
char name[16];
};
typedef struct _Eina_Semaphore Eina_Semaphore;
static unsigned int _sem_ctr = 0;
static Eina_Spinlock _sem_ctr_lock = 0; // 0: not locked
#else
typedef sem_t Eina_Semaphore;
#endif
/** @privatesection @{ */
struct _Eina_Lock
{
@ -537,41 +560,6 @@ eina_tls_set(Eina_TLS key, const void *data)
return EINA_TRUE;
}
static inline Eina_Bool
eina_semaphore_new(Eina_Semaphore *sem, int count_init)
{
if (!sem || (count_init <= 0))
return EINA_FALSE;
return (sem_init(sem, count_init, 1) == 0) ? EINA_TRUE : EINA_FALSE;
}
static inline Eina_Bool
eina_semaphore_free(Eina_Semaphore *sem)
{
if (!sem)
return EINA_FALSE;
return (sem_destroy(sem) == 0) ? EINA_TRUE : EINA_FALSE;
}
static inline Eina_Bool
eina_semaphore_lock(Eina_Semaphore *sem)
{
if (!sem)
return EINA_FALSE;
return (sem_wait(sem) == 0) ? EINA_TRUE : EINA_FALSE;
}
static inline Eina_Bool
eina_semaphore_release(Eina_Semaphore *sem, int count_release EINA_UNUSED)
{
if (!sem)
return EINA_FALSE;
return (sem_post(sem) == 0) ? EINA_TRUE : EINA_FALSE;
}
#ifdef EINA_HAVE_PTHREAD_BARRIER
typedef struct _Eina_Barrier Eina_Barrier;
@ -694,6 +682,66 @@ eina_spinlock_free(Eina_Spinlock *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)
/* Atomic increment to generate the unique identifier */
eina_spinlock_take(&_sem_ctr_lock);
++_sem_ctr;
eina_spinlock_release(&_sem_ctr_lock);
snprintf(sem->name, sizeof(sem->name), "/eina_sem_%u", _sem_ctr);
sem->sema = sem_open(sem->name, O_CREAT, 0644, 1);
return (sem->sema == SEM_FAILED) ? EINA_FALSE : EINA_TRUE;
#else
return (sem_init(sem, count_init, 1) == 0) ? EINA_TRUE : EINA_FALSE;
#endif
}
static inline Eina_Bool
eina_semaphore_free(Eina_Semaphore *sem)
{
if (!sem)
return EINA_FALSE;
#if defined(EINA_HAVE_OSX_SEMAPHORE)
return ((sem_close(sem->sema) == 0) &&
(sem_unlink(sem->name)) == 0) ? EINA_TRUE : EINA_FALSE;
#else
return (sem_destroy(sem) == 0) ? EINA_TRUE : EINA_FALSE;
#endif
}
static inline Eina_Bool
eina_semaphore_lock(Eina_Semaphore *sem)
{
if (!sem)
return EINA_FALSE;
#if defined(EINA_HAVE_OSX_SEMAPHORE)
return (sem_wait(sem->sema) == 0) ? EINA_TRUE : EINA_FALSE;
#else
return (sem_wait(sem) == 0) ? EINA_TRUE : EINA_FALSE;
#endif
}
static inline Eina_Bool
eina_semaphore_release(Eina_Semaphore *sem, int count_release EINA_UNUSED)
{
if (!sem)
return EINA_FALSE;
#if defined(EINA_HAVE_OSX_SEMAPHORE)
return (sem_post(sem->sema) == 0) ? EINA_TRUE : EINA_FALSE;
#else
return (sem_post(sem) == 0) ? EINA_TRUE : EINA_FALSE;
#endif
}
#undef _XOPEN_SOURCE
// This is necessary to let third party still define this macro
#ifdef EINA_XOPEN_SOURCE