{
(void) __atomic_add_fetch (sem, 1, MEMMODEL_RELEASE);
}
+
+static inline int
+gomp_sem_getcount (gomp_sem_t *sem)
+{
+ int count = __atomic_load_n (sem, MEMMODEL_RELAXED);
+ if (count < 0)
+ return -1;
+ return count;
+}
#endif /* GOMP_SEM_H */
if (__builtin_expect (count & SEM_WAIT, 0))
gomp_sem_post_slow (sem);
}
+
+static inline int
+gomp_sem_getcount (gomp_sem_t *sem)
+{
+ int count = __atomic_load_n (sem, MEMMODEL_RELAXED);
+ if ((count & SEM_WAIT) != 0)
+ return -1;
+ return count / SEM_INC;
+}
#endif /* GOMP_SEM_H */
return;
}
+
+int gomp_sem_getcount (gomp_sem_t *sem)
+{
+ int ret, count;
+
+ ret = pthread_mutex_lock (&sem->mutex);
+ if (ret)
+ return -1;
+
+ count = sem->value;
+
+ ret = pthread_mutex_unlock (&sem->mutex);
+ if (ret)
+ return -1;
+
+ if (count < 0)
+ return -1;
+
+ return count;
+}
#else /* HAVE_BROKEN_POSIX_SEMAPHORES */
void
gomp_sem_wait (gomp_sem_t *sem)
extern void gomp_sem_destroy (gomp_sem_t *sem);
+extern int gomp_sem_getcount (gomp_sem_t *sem);
+
#else /* HAVE_BROKEN_POSIX_SEMAPHORES */
typedef sem_t gomp_sem_t;
{
sem_destroy (sem);
}
+
+static inline int gomp_sem_getcount (gomp_sem_t *sem)
+{
+ int val;
+ if (sem_getvalue (sem, &val) < 0)
+ return -1;
+ return val;
+}
#endif /* doesn't HAVE_BROKEN_POSIX_SEMAPHORES */
#endif /* GOMP_SEM_H */
static bool
task_fulfilled_p (struct gomp_task *task)
{
- return __atomic_load_n (&task->completion_sem, __ATOMIC_RELAXED);
+ return gomp_sem_getcount (&task->completion_sem) > 0;
}
/* Called when encountering an explicit task directive. If IF_CLAUSE is
struct gomp_thread *thr = gomp_thread ();
struct gomp_team *team = thr ? thr->ts.team : NULL;
- if (__atomic_load_n (sem, __ATOMIC_RELAXED))
+ if (gomp_sem_getcount (sem) > 0)
gomp_fatal ("omp_fulfill_event: %p event already fulfilled!\n", sem);
gomp_debug (0, "omp_fulfill_event: %p\n", sem);