summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Gardas <karel.gardas@centrum.cz>2011-07-09 18:07:00 +0200
committerManuel M T Chakravarty <chak@cse.unsw.edu.au>2011-08-10 22:03:41 +1000
commit9ebdbb27a8b26a424cab8916f5f0c2388af2ce2d (patch)
treecee2c64e7a490a947551a1c270f15c50f67ff70c
parenta9b455c4b6960d47d31e769052104a4a4fc26cf0 (diff)
downloadhaskell-9ebdbb27a8b26a424cab8916f5f0c2388af2ce2d.tar.gz
RTS: fix pushWSDeque to invoke write barrier when element is added
This patch fixes RTS' pushWSDeque function. We need to invoke write barrier after element is added to the queue and before moving bottom. The reason for this is possible write reordering on modern CPUs (e.g. ARMv7MP) where setting of element might be done later after moving bottom. When such situation happen other thread might be waiting to steal data from the queue and when bottom is moved it eagerly steals undefined data from the queue since setting of element has not happened yet.
-rw-r--r--rts/WSDeque.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/rts/WSDeque.c b/rts/WSDeque.c
index 71633d9fc3..8efd1bbe48 100644
--- a/rts/WSDeque.c
+++ b/rts/WSDeque.c
@@ -279,6 +279,15 @@ pushWSDeque (WSDeque* q, void * elem)
}
q->elements[b & sz] = elem;
+ /*
+ KG: we need to put write barrier here since otherwise we might
+ end with elem not added to q->elements, but q->bottom already
+ modified (write reordering) and with stealWSDeque_ failing
+ later when invoked from another thread since it thinks elem is
+ there (in case there is just added element in the queue). This
+ issue concretely hit me on ARMv7 multi-core CPUs
+ */
+ write_barrier();
q->bottom = b + 1;
ASSERT_WSDEQUE_INVARIANTS(q);