diff options
author | David Eichmann <EichmannD@gmail.com> | 2020-11-02 13:53:28 +0000 |
---|---|---|
committer | David Eichmann <EichmannD@gmail.com> | 2020-11-09 11:02:32 +0000 |
commit | b624c806746d6b375ade398a13695f5e2294b083 (patch) | |
tree | b0b1c49dc766f8b588afe340a79c0b438e28b8e9 /rts/RtsAPI.c | |
parent | 1370eda7a53f5dfc88afe705b2ffecb1d5544ec7 (diff) | |
download | haskell-wip/ghc-debug_gc_roots.tar.gz |
Add rts_listThreads and rts_listMiscRoots to RtsAPI.hwip/ghc-debug_gc_roots
These are used to find the current roots of the garbage collector.
Co-authored-by: Sven Tennie's avatarSven Tennie <sven.tennie@gmail.com>
Co-authored-by: Matthew Pickering's avatarMatthew Pickering <matthewtpickering@gmail.com>
Co-authored-by: default avatarBen Gamari <bgamari.foss@gmail.com>
Diffstat (limited to 'rts/RtsAPI.c')
-rw-r--r-- | rts/RtsAPI.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/rts/RtsAPI.c b/rts/RtsAPI.c index bf58f53735..aaea838f72 100644 --- a/rts/RtsAPI.c +++ b/rts/RtsAPI.c @@ -15,6 +15,7 @@ #include "Prelude.h" #include "Schedule.h" #include "Capability.h" +#include "StableName.h" #include "StablePtr.h" #include "Threads.h" #include "Weak.h" @@ -809,6 +810,46 @@ static void assert_isPausedOnMyTask(const char *functionName) } } +// See RtsAPI.h +void rts_listThreads(ListThreadsCb cb, void *user) +{ + assert_isPausedOnMyTask("rts_listThreads"); + + // The rts is paused and can only be resumed by the current thread. Hence it + // is safe to read global thread data. + + for (uint32_t g=0; g < RtsFlags.GcFlags.generations; g++) { + StgTSO *tso = generations[g].threads; + while (tso != END_TSO_QUEUE) { + cb(user, tso); + tso = tso->global_link; + } + } +} + +struct list_roots_ctx { + ListRootsCb cb; + void *user; +}; + +// This is an evac_fn. +static void list_roots_helper(void *user, StgClosure **p) { + struct list_roots_ctx *ctx = (struct list_roots_ctx *) user; + ctx->cb(ctx->user, *p); +} + +// See RtsAPI.h +void rts_listMiscRoots (ListRootsCb cb, void *user) +{ + assert_isPausedOnMyTask("rts_listMiscRoots"); + + struct list_roots_ctx ctx; + ctx.cb = cb; + ctx.user = user; + + threadStableNameTable(&list_roots_helper, (void *)&ctx); + threadStablePtrTable(&list_roots_helper, (void *)&ctx); +} #else PauseToken GNU_ATTRIBUTE(__noreturn__) @@ -833,6 +874,18 @@ bool rts_isPaused() "multithreaded RTS."); return false; } + +// See RtsAPI.h +void rts_listThreads(ListThreadsCb cb STG_UNUSED, void *user STG_UNUSED) +{ + errorBelch("Warning: rts_listThreads is only possible for multithreaded RTS."); +} + +// See RtsAPI.h +void rts_listMiscRoots (ListRootsCb cb STG_UNUSED, void *user STG_UNUSED) +{ + errorBelch("Warning: rts_listMiscRoots is only possible for multithreaded RTS."); +} #endif void rts_done (void) |