summaryrefslogtreecommitdiff
path: root/rts/TopHandler.c
diff options
context:
space:
mode:
authorDemi Obenour <demiobenour@gmail.com>2017-01-10 13:33:31 -0500
committerBen Gamari <ben@smart-cactus.org>2017-01-10 13:33:38 -0500
commit12ad4d417b89462ba8e19a3c7772a931b3a93f0e (patch)
tree97b5c7e3ba6329ecf99e7431c10d43ee66758d1b /rts/TopHandler.c
parente8d74321b5b24afcb4230510fd6e4c4ecf6f3e19 (diff)
downloadhaskell-12ad4d417b89462ba8e19a3c7772a931b3a93f0e.tar.gz
Throw an exception on heap overflow
This changes heap overflow to throw a HeapOverflow exception instead of killing the process. Test Plan: GHC CI Reviewers: simonmar, austin, hvr, erikd, bgamari Reviewed By: simonmar, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2790 GHC Trac Issues: #1791
Diffstat (limited to 'rts/TopHandler.c')
-rw-r--r--rts/TopHandler.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/rts/TopHandler.c b/rts/TopHandler.c
new file mode 100644
index 0000000000..ff53b32338
--- /dev/null
+++ b/rts/TopHandler.c
@@ -0,0 +1,62 @@
+#include "Rts.h"
+#include "Stable.h"
+#include "TopHandler.h"
+
+#ifdef 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;
+ 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) {
+#ifdef THREADED_RTS
+ initMutex(&m);
+#endif
+ topHandlerPtr = NULL;
+}
+
+void exitTopHandler(void) {
+ freeStablePtr(topHandlerPtr);
+ topHandlerPtr = NULL;
+#ifdef THREADED_RTS
+ closeMutex(&m);
+#endif
+}