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(StgWord64 key
[2],void *spe_closure
) {
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 StgStablePtr
* entry
= stgMallocBytes( sizeof(StgStablePtr
)
47 , "hs_spt_insert: entry"
49 *entry
= getStablePtr(spe_closure
);
50 ACQUIRE_LOCK(&spt_lock
);
51 insertHashTable(spt
, (StgWord
)key
, entry
);
52 RELEASE_LOCK(&spt_lock
);
55 static void freeSptEntry(void* entry
) {
56 freeStablePtr(*(StgStablePtr
*)entry
);
60 void hs_spt_remove(StgWord64 key
[2]) {
62 ACQUIRE_LOCK(&spt_lock
);
63 StgStablePtr
* entry
= removeHashTable(spt
, (StgWord
)key
, NULL
);
64 RELEASE_LOCK(&spt_lock
);
71 StgPtr
hs_spt_lookup(StgWord64 key
[2]) {
73 ACQUIRE_LOCK(&spt_lock
);
74 const StgStablePtr
* entry
= lookupHashTable(spt
, (StgWord
)key
);
75 RELEASE_LOCK(&spt_lock
);
76 const StgPtr ret
= entry ?
deRefStablePtr(*entry
) : NULL
;
82 int hs_spt_keys(StgPtr keys
[], int szKeys
) {
84 ACQUIRE_LOCK(&spt_lock
);
85 const int ret
= keysHashTable(spt
, (StgWord
*)keys
, szKeys
);
86 RELEASE_LOCK(&spt_lock
);
92 int hs_spt_key_count() {
93 return spt ?
keyCountHashTable(spt
) : 0;
96 void exitStaticPtrTable() {
98 freeHashTable(spt
, freeSptEntry
);
101 closeMutex(&spt_lock
);