diff options
author | David Eichmann <EichmannD@gmail.com> | 2020-11-02 13:53:28 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-11-13 14:30:16 -0500 |
commit | de7ec9dd2bd573d5950ae294747d2bdb45051000 (patch) | |
tree | 3a054a6b5bd6b8a467ac4605fae40b8d6c42efa6 /rts/RtsAPI.c | |
parent | 197d59facbe8f9799df47e86c99f401ced487040 (diff) | |
download | haskell-de7ec9dd2bd573d5950ae294747d2bdb45051000.tar.gz |
Add rts_listThreads and rts_listMiscRoots to RtsAPI.h
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) |