struct sxe_semaphore_s {
pthread_mutex_t mtx;
- pthread_cond_t cnd;
+ 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;
+ int generation;
};
/* a thread-safe reference counter */
extern_inline void
sxe_semaphore_init(sxe_semaphore_t sem)
{
+ sem->generation = 0;
pthread_mutex_init(&(sem->mtx), NULL);
pthread_cond_init(&(sem->cnd), NULL);
}
sxe_msemaphore_init(sxe_msemaphore_t sem)
{
int i;
+ sem->generation = 0;
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));
+ sem->generation++;
pthread_cond_signal(&(sem->cnd));
pthread_mutex_unlock(&(sem->mtx));
}
sxe_msemaphore_trigger(sxe_msemaphore_t sem, int idx)
{
pthread_mutex_lock(&(sem->mtx));
+ sem->generation++;
pthread_cond_signal(&(sem->cnd[idx]));
pthread_mutex_unlock(&(sem->mtx));
}
sxe_semaphore_trigger_all(sxe_semaphore_t sem)
{
pthread_mutex_lock(&(sem->mtx));
+ sem->generation++;
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));
+ sem->generation++;
pthread_cond_broadcast(&(sem->cnd[idx]));
pthread_mutex_unlock(&(sem->mtx));
}
extern_inline void
sxe_semaphore_synchronise(sxe_semaphore_t sem)
{
+ int generation;
+
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)
{
+ int generation;
+
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));
}
sxe_refcounter_init(sxe_refcounter_t rc)
{
pthread_mutex_init(&(rc->mtx), NULL);
+ pthread_mutex_lock(&(rc->mtx));
rc->refcnt = 0;
+ pthread_mutex_unlock(&(rc->mtx));
}
extern_inline void
sxe_refcounter_finish(sxe_refcounter_t rc)
{
pthread_mutex_lock(&(rc->mtx));
+ rc->refcnt = 0;
pthread_mutex_unlock(&(rc->mtx));
pthread_mutex_destroy(&(rc->mtx));
- rc->refcnt = 0;
}
extern_inline sxe_refcounter_t
sxe_refcounter_new(void)
#endif
#endif /* INCLUDED_semaphore_h */
-