Also anticipate the possibility for futex_wait to return early with EINTR.
In the following scenario, the first wake(parmap.work) should not have
unlocked the second xbt_parmap_futex_worker_wait().
Master Worker
====== ========
xbt_parmap_futex_master_signal() {
parmap.thread_counter = 1
++parmap.work
xbt_parmap_futex_worker_wait();
xbt_parmap_work();
xbt_parmap_futex_worker_signal();
xbt_parmap_futex_worker_wait();
wake(parmap.work) -- unlock -------->
}
xbt_parmap_work();
xbt_parmap_futex_master_wait();
xbt_parmap_work();
xbt_parmap_futex_worker_signal();
xbt_parmap_futex_master_signal();
xbt_parmap_work();
xbt_parmap_futex_master_wait();
===> LOCKED
xbt_parmap_futex_worker_wait();
===> LOCKED
{
unsigned work = parmap->work;
/* wait for more work */
- if (work != round)
+ while (work != round) {
futex_wait(&parmap->work, work);
+ work = parmap->work;
+ }
}
#endif