From 565f3c753ccedeb19b5b8190090241a2185eb0cb Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Thu, 10 Jun 2010 08:06:36 +0000 Subject: [PATCH] messageBlackHole: fix deadlock bug caused by a missing 'volatile' --- includes/stg/SMP.h | 8 ++++++++ rts/Messages.c | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h index b302f48..ad8c0ba 100644 --- a/includes/stg/SMP.h +++ b/includes/stg/SMP.h @@ -293,6 +293,12 @@ load_load_barrier(void) { #endif } +// Load a pointer from a memory location that might be being modified +// concurrently. This prevents the compiler from optimising away +// multiple loads of the memory location, as it might otherwise do in +// a busy wait loop for example. +#define VOLATILE_LOAD(p) (*((StgVolatilePtr)(p))) + /* ---------------------------------------------------------------------- */ #else /* !THREADED_RTS */ @@ -331,6 +337,8 @@ atomic_dec(StgVolatilePtr p) return --(*p); } +#define VOLATILE_LOAD(p) ((StgWord)*((StgWord*)(p))) + #endif /* !THREADED_RTS */ #endif /* SMP_H */ diff --git a/rts/Messages.c b/rts/Messages.c index 91ee9a6..7a37a86 100644 --- a/rts/Messages.c +++ b/rts/Messages.c @@ -186,7 +186,9 @@ nat messageBlackHole(Capability *cap, MessageBlackHole *msg) // The blackhole must indirect to a TSO, a BLOCKING_QUEUE, an IND, // or a value. loop: - p = UNTAG_CLOSURE(((StgInd*)bh)->indirectee); + // NB. VOLATILE_LOAD(), because otherwise gcc hoists the load + // and turns this into an infinite loop. + p = UNTAG_CLOSURE((StgClosure*)VOLATILE_LOAD(&((StgInd*)bh)->indirectee)); info = p->header.info; if (info == &stg_IND_info) -- 1.7.10.4