* src/semaphore.h (struct sxe_semaphore_s): add a generation count
* src/semaphore.h (struct sxe_msemaphore_s): ditto
* src/semaphore.h (sxe_msemaphore_init): initialize generation
* src/semaphore.h (sxe_semaphore_init): ditto
* src/semaphore.h (sxe_msemaphore_trigger): increment generation before signal
* src/semaphore.h (sxe_msemaphore_trigger): ditto
* src/semaphore.h (sxe_msemaphore_trigger_all): ditto
* src/semaphore.h (sxe_msemaphore_trigger_all): ditto
* src/semaphore.h (sxe_msemaphore_synchronise): Wait again if
generation is still the same (ie no signal occurred).
* src/semaphore.h (sxe_msemaphore_synchronise): ditto.
Signed-off-by: Nelson Ferreira <nelson.ferreira@ieee.org>
struct sxe_semaphore_s {
pthread_mutex_t mtx;
struct sxe_semaphore_s {
pthread_mutex_t mtx;
+ pthread_cond_t cnd;
+ int generation;
};
struct sxe_msemaphore_s {
pthread_mutex_t mtx;
pthread_cond_t cnd[SXE_MSEMAPH_MAX_CONDITIONS];
int num_cnd;
};
struct sxe_msemaphore_s {
pthread_mutex_t mtx;
pthread_cond_t cnd[SXE_MSEMAPH_MAX_CONDITIONS];
int num_cnd;
};
/* a thread-safe reference counter */
};
/* a thread-safe reference counter */
extern_inline void
sxe_semaphore_init(sxe_semaphore_t sem)
{
extern_inline void
sxe_semaphore_init(sxe_semaphore_t sem)
{
pthread_mutex_init(&(sem->mtx), NULL);
pthread_cond_init(&(sem->cnd), NULL);
}
pthread_mutex_init(&(sem->mtx), NULL);
pthread_cond_init(&(sem->cnd), NULL);
}
sxe_msemaphore_init(sxe_msemaphore_t sem)
{
int i;
sxe_msemaphore_init(sxe_msemaphore_t sem)
{
int i;
pthread_mutex_init(&(sem->mtx), NULL);
for (i = 0; i < SXE_MSEMAPH_MAX_CONDITIONS; i++)
pthread_cond_init(&(sem->cnd[i]), NULL);
pthread_mutex_init(&(sem->mtx), NULL);
for (i = 0; i < SXE_MSEMAPH_MAX_CONDITIONS; i++)
pthread_cond_init(&(sem->cnd[i]), NULL);
sxe_semaphore_trigger(sxe_semaphore_t sem)
{
pthread_mutex_lock(&(sem->mtx));
sxe_semaphore_trigger(sxe_semaphore_t sem)
{
pthread_mutex_lock(&(sem->mtx));
pthread_cond_signal(&(sem->cnd));
pthread_mutex_unlock(&(sem->mtx));
}
pthread_cond_signal(&(sem->cnd));
pthread_mutex_unlock(&(sem->mtx));
}
sxe_msemaphore_trigger(sxe_msemaphore_t sem, int idx)
{
pthread_mutex_lock(&(sem->mtx));
sxe_msemaphore_trigger(sxe_msemaphore_t sem, int idx)
{
pthread_mutex_lock(&(sem->mtx));
- pthread_cond_signal(&(sem->cnd[idx]));
+ sem->generation++;
+B pthread_cond_signal(&(sem->cnd[idx]));
pthread_mutex_unlock(&(sem->mtx));
}
pthread_mutex_unlock(&(sem->mtx));
}
sxe_semaphore_trigger_all(sxe_semaphore_t sem)
{
pthread_mutex_lock(&(sem->mtx));
sxe_semaphore_trigger_all(sxe_semaphore_t sem)
{
pthread_mutex_lock(&(sem->mtx));
pthread_cond_broadcast(&(sem->cnd));
pthread_mutex_unlock(&(sem->mtx));
}
pthread_cond_broadcast(&(sem->cnd));
pthread_mutex_unlock(&(sem->mtx));
}
sxe_msemaphore_trigger_all(sxe_msemaphore_t sem, int idx)
{
pthread_mutex_lock(&(sem->mtx));
sxe_msemaphore_trigger_all(sxe_msemaphore_t sem, int idx)
{
pthread_mutex_lock(&(sem->mtx));
pthread_cond_broadcast(&(sem->cnd[idx]));
pthread_mutex_unlock(&(sem->mtx));
}
pthread_cond_broadcast(&(sem->cnd[idx]));
pthread_mutex_unlock(&(sem->mtx));
}
extern_inline void
sxe_semaphore_synchronise(sxe_semaphore_t sem)
{
extern_inline void
sxe_semaphore_synchronise(sxe_semaphore_t sem)
{
pthread_mutex_lock(&(sem->mtx));
pthread_mutex_lock(&(sem->mtx));
- pthread_cond_wait(&(sem->cnd), &(sem->mtx));
+ generation = sem->generation;
+ do {
+ pthread_cond_wait(&(sem->cnd), &(sem->mtx));
+ } while(sem->generation == generation);
pthread_mutex_unlock(&(sem->mtx));
}
extern_inline void
sxe_msemaphore_synchronise(sxe_msemaphore_t sem, int idx)
{
pthread_mutex_unlock(&(sem->mtx));
}
extern_inline void
sxe_msemaphore_synchronise(sxe_msemaphore_t sem, int idx)
{
pthread_mutex_lock(&(sem->mtx));
pthread_mutex_lock(&(sem->mtx));
- pthread_cond_wait(&(sem->cnd[idx]), &(sem->mtx));
+ generation = sem->generation;
+ do {
+ pthread_cond_wait(&(sem->cnd[idx]), &(sem->mtx));
+ } while(sem->generation == generation);
pthread_mutex_unlock(&(sem->mtx));
}
pthread_mutex_unlock(&(sem->mtx));
}