From cf83c030fca0c16732983caee233c756c30bd66e Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Thu, 9 Feb 2012 00:35:50 +0100 Subject: [PATCH] Parmap: fix deadlock in with futexes. 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 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/xbt/parmap.c b/src/xbt/parmap.c index 8219493515..d163965fe5 100644 --- a/src/xbt/parmap.c +++ b/src/xbt/parmap.c @@ -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 */ - if (work != round) + while (work != round) { futex_wait(&parmap->work, work); + work = parmap->work; + } } #endif -- 2.20.1