Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Parmap: fix deadlock in with futexes.
authorArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Wed, 8 Feb 2012 23:35:50 +0000 (00:35 +0100)
committerArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Thu, 9 Feb 2012 05:55:18 +0000 (06:55 +0100)
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

src/xbt/parmap.c

index 8219493..d163965 100644 (file)
@@ -416,8 +416,10 @@ static void xbt_parmap_futex_worker_wait(xbt_parmap_t parmap, unsigned round)
 {
   unsigned work = parmap->work;
   /* wait for more work */
 {
   unsigned work = parmap->work;
   /* wait for more work */
-  if (work != round)
+  while (work != round) {
     futex_wait(&parmap->work, work);
     futex_wait(&parmap->work, work);
+    work = parmap->work;
+  }
 }
 #endif
 
 }
 #endif