4 * The Static Pointer Table implementation.
6 * https://ghc.haskell.org/trac/ghc/wiki/StaticPointers
7 * https://ghc.haskell.org/trac/ghc/wiki/StaticPointers/ImplementationPlan
11 #include "StaticPtrTable.h"
17 static HashTable
* spt
= NULL
;
20 static Mutex spt_lock
;
23 /// Hash function for the SPT.
24 static int hashFingerprint(HashTable
*table
, StgWord64 key
[2]) {
25 // Take half of the key to compute the hash.
26 return hashWord(table
, (StgWord
)key
[1]);
29 /// Comparison function for the SPT.
30 static int compareFingerprint(StgWord64 ptra
[2], StgWord64 ptrb
[2]) {
31 return ptra
[0] == ptrb
[0] && ptra
[1] == ptrb
[1];
34 void hs_spt_insert_stableptr(StgWord64 key
[2], StgStablePtr
*entry
) {
35 // hs_spt_insert is called from constructor functions, so
36 // the SPT needs to be initialized here.
38 spt
= allocHashTable_( (HashFunction
*)hashFingerprint
39 , (CompareFunction
*)compareFingerprint
46 ACQUIRE_LOCK(&spt_lock
);
47 insertHashTable(spt
, (StgWord
)key
, entry
);
48 RELEASE_LOCK(&spt_lock
);
51 void hs_spt_insert(StgWord64 key
[2], void *spe_closure
) {
52 // Cannot remove this indirection yet because getStablePtr()
53 // might return NULL, in which case hs_spt_lookup() returns NULL
54 // instead of the actual closure pointer.
55 StgStablePtr
* entry
= stgMallocBytes( sizeof(StgStablePtr
)
56 , "hs_spt_insert: entry"
58 *entry
= getStablePtr(spe_closure
);
59 hs_spt_insert_stableptr(key
, entry
);
62 static void freeSptEntry(void* entry
) {
63 freeStablePtr(*(StgStablePtr
*)entry
);
67 void hs_spt_remove(StgWord64 key
[2]) {
69 ACQUIRE_LOCK(&spt_lock
);
70 StgStablePtr
* entry
= removeHashTable(spt
, (StgWord
)key
, NULL
);
71 RELEASE_LOCK(&spt_lock
);
78 StgPtr
hs_spt_lookup(StgWord64 key
[2]) {
80 ACQUIRE_LOCK(&spt_lock
);
81 const StgStablePtr
* entry
= lookupHashTable(spt
, (StgWord
)key
);
82 const StgPtr ret
= entry ?
deRefStablePtr(*entry
) : NULL
;
83 RELEASE_LOCK(&spt_lock
);
89 int hs_spt_keys(StgPtr keys
[], int szKeys
) {
91 ACQUIRE_LOCK(&spt_lock
);
92 const int ret
= keysHashTable(spt
, (StgWord
*)keys
, szKeys
);
93 RELEASE_LOCK(&spt_lock
);
99 int hs_spt_key_count() {
100 return spt ?
keyCountHashTable(spt
) : 0;
103 void exitStaticPtrTable() {
105 freeHashTable(spt
, freeSptEntry
);
108 closeMutex(&spt_lock
);