blob: d5175015e776b2ba92c7b930ac64857267efa427 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
#include "Rts.h"
#include "StablePtr.h"
#include "TopHandler.h"
#if defined(THREADED_RTS)
static Mutex m; // Protects the operations on topHandlerPtr,
// which aren't atomic
#endif
static StgStablePtr topHandlerPtr;
void rts_setMainThread(StgWeak *weak) {
ACQUIRE_LOCK(&m);
if (topHandlerPtr != NULL) {
freeStablePtr(topHandlerPtr); // OK to do under the lock
}
topHandlerPtr = getStablePtr((StgPtr)weak);
// referent is a Weak#
ASSERT(weak->header.info == &stg_WEAK_info);
// See Note [rts_setMainThread has an unsound type] in
// libraries/base/GHC/TopHandler.hs.
ASSERT(weak->key->header.info == &stg_TSO_info);
RELEASE_LOCK(&m);
}
StgTSO *getTopHandlerThread(void) {
ACQUIRE_LOCK(&m);
StgWeak *weak = (StgWeak*)deRefStablePtr(topHandlerPtr);
RELEASE_LOCK(&m);
const StgInfoTable *info = weak->header.info;
load_load_barrier();
if (info == &stg_WEAK_info) {
StgClosure *key = ((StgWeak*)weak)->key;
// See Note [rts_setMainThread has an unsound type] in
// libraries/base/GHC/TopHandler.hs.
ASSERT(key->header.info == &stg_TSO_info);
return (StgTSO *)key;
} else if (info == &stg_DEAD_WEAK_info) {
return NULL;
} else {
barf("getTopHandlerThread: neither a WEAK nor a DEAD_WEAK: %p %p %d",
weak, info, info->type);
return NULL;
}
}
void initTopHandler(void) {
#if defined(THREADED_RTS)
initMutex(&m);
#endif
topHandlerPtr = NULL;
}
void exitTopHandler(void) {
freeStablePtr(topHandlerPtr);
topHandlerPtr = NULL;
#if defined(THREADED_RTS)
closeMutex(&m);
#endif
}
|