summaryrefslogtreecommitdiff
path: root/rts/StablePtr.c
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-09-28 17:35:41 +0000
committerBen Gamari <ben@smart-cactus.org>2020-10-24 21:00:57 -0400
commit9e5c7f6de8e3d4cda0c07e0f210d9d5004fc6131 (patch)
tree75a5efa75ba0ac49def00bbf1b943795d9a163e9 /rts/StablePtr.c
parentd0d07cffeded2b1d1b4ffed1f8b06eddc9f06600 (diff)
downloadhaskell-9e5c7f6de8e3d4cda0c07e0f210d9d5004fc6131.tar.gz
rts: Avoid data races in StablePtr implementation
This fixes two potentially problematic data races in the StablePtr implementation: * We would fail to RELEASE the stable pointer table when enlarging it, causing other cores to potentially see uninitialized memory. * We would fail to ACQUIRE when dereferencing a stable pointer.
Diffstat (limited to 'rts/StablePtr.c')
-rw-r--r--rts/StablePtr.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/rts/StablePtr.c b/rts/StablePtr.c
index edcd863183..469a17a5b9 100644
--- a/rts/StablePtr.c
+++ b/rts/StablePtr.c
@@ -191,9 +191,10 @@ enlargeStablePtrTable(void)
/* When using the threaded RTS, the update of stable_ptr_table is assumed to
* be atomic, so that another thread simultaneously dereferencing a stable
- * pointer will always read a valid address.
+ * pointer will always read a valid address. Release ordering to ensure
+ * that the new table is visible to others.
*/
- stable_ptr_table = new_stable_ptr_table;
+ RELEASE_STORE(&stable_ptr_table, new_stable_ptr_table);
initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL);
}
@@ -247,7 +248,7 @@ exitStablePtrTable(void)
STATIC_INLINE void
freeSpEntry(spEntry *sp)
{
- sp->addr = (P_)stable_ptr_free;
+ RELAXED_STORE(&sp->addr, (P_)stable_ptr_free);
stable_ptr_free = sp;
}
@@ -279,7 +280,7 @@ getStablePtr(StgPtr p)
if (!stable_ptr_free) enlargeStablePtrTable();
sp = stable_ptr_free - stable_ptr_table;
stable_ptr_free = (spEntry*)(stable_ptr_free->addr);
- stable_ptr_table[sp].addr = p;
+ RELAXED_STORE(&stable_ptr_table[sp].addr, p);
stablePtrUnlock();
return (StgStablePtr)(sp);
}