summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorAdam Sandberg Ericsson <adam@sandbergericsson.se>2023-03-21 18:15:15 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2023-04-14 04:17:52 -0400
commita34aa8da1293f997ce9212ccdc2ec56df4a2e9c1 (patch)
tree0d9670184a3c841b136399d20d7007161c92eef5 /rts
parent27d2978e5412f2bef4448e208182a03137dd5ee8 (diff)
downloadhaskell-a34aa8da1293f997ce9212ccdc2ec56df4a2e9c1.tar.gz
rts: improve memory ordering and add some comments in the StablePtr implementation
Diffstat (limited to 'rts')
-rw-r--r--rts/StablePtr.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/rts/StablePtr.c b/rts/StablePtr.c
index c2e7cda2c3..bc5fa1981c 100644
--- a/rts/StablePtr.c
+++ b/rts/StablePtr.c
@@ -98,8 +98,13 @@
*/
+// the global stable pointer entry table
spEntry *stable_ptr_table = NULL;
+
+// the next free stable ptr, the free entries form a linked list where spEntry.addr points to the next after
static spEntry *stable_ptr_free = NULL;
+
+// current stable pointer table size
static unsigned int SPT_size = 0;
#define INIT_SPT_SIZE 64
@@ -117,6 +122,7 @@ static unsigned int SPT_size = 0;
#error unknown SIZEOF_VOID_P
#endif
+// old stable pointer tables
static spEntry *old_SPTs[MAX_N_OLD_SPTS];
static uint32_t n_old_SPTs = 0;
@@ -149,8 +155,9 @@ stablePtrUnlock(void)
* -------------------------------------------------------------------------- */
STATIC_INLINE void
-initSpEntryFreeList(spEntry *table, uint32_t n, spEntry *free)
+initSpEntryFreeList(spEntry *table, uint32_t n)
{
+ spEntry* free = NULL;
spEntry *p;
for (p = table + n - 1; p >= table; p--) {
p->addr = (P_)free;
@@ -166,7 +173,7 @@ initStablePtrTable(void)
SPT_size = INIT_SPT_SIZE;
stable_ptr_table = stgMallocBytes(SPT_size * sizeof(spEntry),
"initStablePtrTable");
- initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE,NULL);
+ initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE);
#if defined(THREADED_RTS)
initMutex(&stable_ptr_mutex);
@@ -181,6 +188,8 @@ initStablePtrTable(void)
static void
enlargeStablePtrTable(void)
{
+ ASSERT_LOCK_HELD(&stable_ptr_mutex);
+
uint32_t old_SPT_size = SPT_size;
spEntry *new_stable_ptr_table;
@@ -206,7 +215,8 @@ enlargeStablePtrTable(void)
*/
RELEASE_STORE(&stable_ptr_table, new_stable_ptr_table);
- initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL);
+ // add the new entries to the free list
+ initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size);
}
/* Note [Enlarging the stable pointer table]
@@ -245,6 +255,7 @@ exitStablePtrTable(void)
{
if (stable_ptr_table)
stgFree(stable_ptr_table);
+
stable_ptr_table = NULL;
SPT_size = 0;
@@ -265,12 +276,17 @@ freeSpEntry(spEntry *sp)
void
freeStablePtrUnsafe(StgStablePtr sp)
{
+ ASSERT_LOCK_HELD(&stable_ptr_mutex);
+
// see Note [NULL StgStablePtr]
if (sp == NULL) {
return;
}
+
StgWord spw = (StgWord)sp - 1;
+
ASSERT(spw < SPT_size);
+
freeSpEntry(&stable_ptr_table[spw]);
}
@@ -278,25 +294,35 @@ void
freeStablePtr(StgStablePtr sp)
{
stablePtrLock();
+
freeStablePtrUnsafe(sp);
+
stablePtrUnlock();
}
/* -----------------------------------------------------------------------------
- * Looking up
+ * Allocating stable pointers
* -------------------------------------------------------------------------- */
StgStablePtr
getStablePtr(StgPtr p)
{
- StgWord sp;
-
stablePtrLock();
- if (!stable_ptr_free) enlargeStablePtrTable();
- sp = stable_ptr_free - stable_ptr_table;
- stable_ptr_free = (spEntry*)(stable_ptr_free->addr);
- RELAXED_STORE(&stable_ptr_table[sp].addr, p);
+
+ if (!stable_ptr_free)
+ enlargeStablePtrTable();
+
+ // find the index of free stable ptr
+ StgWord sp = stable_ptr_free - stable_ptr_table;
+
+ // unlink the table entry we grabbed from the free list
+ stable_ptr_free = (spEntry*)(stable_ptr_free->addr);
+
+ // release store to pair with acquire load in deRefStablePtr
+ RELEASE_STORE(&stable_ptr_table[sp].addr, p);
+
stablePtrUnlock();
+
// see Note [NULL StgStablePtr]
sp = sp + 1;
return (StgStablePtr)(sp);