#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 */
return --(*p);
}
+#define VOLATILE_LOAD(p) ((StgWord)*((StgWord*)(p)))
+
#endif /* !THREADED_RTS */
#endif /* SMP_H */
// 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)