summaryrefslogtreecommitdiffstats
path: root/test/thread_id.c
diff options
context:
space:
mode:
authorDavid Young <dyoung@hdfgroup.org>2020-02-27 17:27:45 (GMT)
committerDavid Young <dyoung@hdfgroup.org>2020-05-11 20:34:31 (GMT)
commitc149f4ca16db6ae9538490041f3145d50585e65b (patch)
tree905cbdb0dea8723474246c1d3af4e16c517fd04f /test/thread_id.c
parente5f459d86d7f566fb57c324305c7cb365ac5ad08 (diff)
downloadhdf5-c149f4ca16db6ae9538490041f3145d50585e65b.zip
hdf5-c149f4ca16db6ae9538490041f3145d50585e65b.tar.gz
hdf5-c149f4ca16db6ae9538490041f3145d50585e65b.tar.bz2
The first implementation seemed to allow for the possibility that a thread
could block at the barrier, wake and exit the barrier, re-acquire the barrier lock and increase `nentered` before the other blocked threads woke and checked `nentered % count == 0`. Then the other blocked threads would check `nentered % count == 0` and, finding it false, go back to sleep in the barrier. This new implementation waits for a looser condition to obtain so that threads don't go back to sleep in the barrier.
Diffstat (limited to 'test/thread_id.c')
-rw-r--r--test/thread_id.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/test/thread_id.c b/test/thread_id.c
index 49e3710..e3cf42e 100644
--- a/test/thread_id.c
+++ b/test/thread_id.c
@@ -143,6 +143,7 @@ int
pthread_barrier_wait(pthread_barrier_t *barrier)
{
int rc;
+ uint64_t threshold;
if (barrier == NULL)
return EINVAL;
@@ -152,8 +153,14 @@ pthread_barrier_wait(pthread_barrier_t *barrier)
rc = EINVAL;
goto out;
}
+ /* Compute the release `threshold`. All threads entering with count = 5
+ * and `nentered` in [0, 4] should be released once `nentered` reaches 5:
+ * call 5 the release `threshold`. All threads entering with count = 5
+ * and `nentered` in [5, 9] should be released once `nentered` reaches 10.
+ */
+ threshold = (barrier->nentered / barrier->count + 1) * barrier->count;
barrier->nentered++;
- while (barrier->nentered % barrier->count != 0) {
+ while (barrier->nentered < threshold) {
if ((rc = pthread_cond_wait(&barrier->cv, &barrier->mtx)) != 0)
goto out;
}