diff options
author | Adam Sandberg Ericsson <adam@sandbergericsson.se> | 2023-03-21 18:15:15 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-04-14 04:17:52 -0400 |
commit | a34aa8da1293f997ce9212ccdc2ec56df4a2e9c1 (patch) | |
tree | 0d9670184a3c841b136399d20d7007161c92eef5 | |
parent | 27d2978e5412f2bef4448e208182a03137dd5ee8 (diff) | |
download | haskell-a34aa8da1293f997ce9212ccdc2ec56df4a2e9c1.tar.gz |
rts: improve memory ordering and add some comments in the StablePtr implementation
-rw-r--r-- | rts/StablePtr.c | 46 |
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); |