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@well-typed.com>2020-12-01 12:48:54 -0500
commit78a5bdff108a369588a50ab69d4f927344164f40 (patch)
tree9eacf23a0d163f4c3a257665f51b4327fdf6e83b /rts/StablePtr.c
parent2ecc569370d521eccd5fb1cfcfc69707e853a962 (diff)
downloadhaskell-78a5bdff108a369588a50ab69d4f927344164f40.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 2181b83d90..1b2be2d50e 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);
}