EventLog: Factor out ensureRoomFor*Event
[ghc.git] / rts / StaticPtrTable.c
1 /*
2 * (c)2014 Tweag I/O
3 *
4 * The Static Pointer Table implementation.
5 *
6 * https://ghc.haskell.org/trac/ghc/wiki/StaticPointers
7 * https://ghc.haskell.org/trac/ghc/wiki/StaticPointers/ImplementationPlan
8 *
9 */
10
11 #include "StaticPtrTable.h"
12 #include "Rts.h"
13 #include "RtsUtils.h"
14 #include "Hash.h"
15 #include "Stable.h"
16
17 static HashTable * spt = NULL;
18
19 #ifdef THREADED_RTS
20 static Mutex spt_lock;
21 #endif
22
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]);
27 }
28
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];
32 }
33
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.
37 if (spt == NULL) {
38 spt = allocHashTable_( (HashFunction *)hashFingerprint
39 , (CompareFunction *)compareFingerprint
40 );
41 #ifdef THREADED_RTS
42 initMutex(&spt_lock);
43 #endif
44 }
45
46 StgStablePtr * entry = stgMallocBytes( sizeof(StgStablePtr)
47 , "hs_spt_insert: entry"
48 );
49 *entry = getStablePtr(spe_closure);
50 ACQUIRE_LOCK(&spt_lock);
51 insertHashTable(spt, (StgWord)key, entry);
52 RELEASE_LOCK(&spt_lock);
53 }
54
55 static void freeSptEntry(void* entry) {
56 freeStablePtr(*(StgStablePtr*)entry);
57 stgFree(entry);
58 }
59
60 void hs_spt_remove(StgWord64 key[2]) {
61 if (spt) {
62 ACQUIRE_LOCK(&spt_lock);
63 StgStablePtr* entry = removeHashTable(spt, (StgWord)key, NULL);
64 RELEASE_LOCK(&spt_lock);
65
66 if (entry)
67 freeSptEntry(entry);
68 }
69 }
70
71 StgPtr hs_spt_lookup(StgWord64 key[2]) {
72 if (spt) {
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;
77 return ret;
78 } else
79 return NULL;
80 }
81
82 int hs_spt_keys(StgPtr keys[], int szKeys) {
83 if (spt) {
84 ACQUIRE_LOCK(&spt_lock);
85 const int ret = keysHashTable(spt, (StgWord*)keys, szKeys);
86 RELEASE_LOCK(&spt_lock);
87 return ret;
88 } else
89 return 0;
90 }
91
92 int hs_spt_key_count() {
93 return spt ? keyCountHashTable(spt) : 0;
94 }
95
96 void exitStaticPtrTable() {
97 if (spt) {
98 freeHashTable(spt, freeSptEntry);
99 spt = NULL;
100 #ifdef THREADED_RTS
101 closeMutex(&spt_lock);
102 #endif
103 }
104 }