summaryrefslogtreecommitdiff
path: root/rts/Threads.c
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-10-26 13:08:39 -0400
committerBen Gamari <ben@smart-cactus.org>2022-08-06 11:48:50 -0400
commitaa818a9f83308d0742e8f8c91cb9878182dacce5 (patch)
tree48089b58289212cfdaef065ad7cc21b77c8beaaa /rts/Threads.c
parent7267cd52fb0b06479b9ceea2dc4700d949a1d75b (diff)
downloadhaskell-aa818a9f83308d0742e8f8c91cb9878182dacce5.tar.gz
Add primop to list threads
A user came to #ghc yesterday wondering how best to check whether they were leaking threads. We ended up using the eventlog but it seems to me like it would be generally useful if Haskell programs could query their own threads.
Diffstat (limited to 'rts/Threads.c')
-rw-r--r--rts/Threads.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/rts/Threads.c b/rts/Threads.c
index af1758f2ef..6b478d046f 100644
--- a/rts/Threads.c
+++ b/rts/Threads.c
@@ -855,6 +855,43 @@ loop:
return true;
}
+StgMutArrPtrs *listThreads(Capability *cap)
+{
+ ACQUIRE_LOCK(&sched_mutex);
+
+ // First count how many threads we have...
+ StgWord n_threads = 0;
+ for (unsigned g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ for (StgTSO *t = generations[g].threads; t != END_TSO_QUEUE; t = t->global_link) {
+ n_threads++;
+ }
+ }
+
+ // Allocate a suitably-sized array...
+ const StgWord size = n_threads + mutArrPtrsCardTableSize(n_threads);
+ StgMutArrPtrs *arr =
+ (StgMutArrPtrs *)allocate(cap, sizeofW(StgMutArrPtrs) + size);
+ TICK_ALLOC_PRIM(sizeofW(StgMutArrPtrs), n, 0);
+ arr->ptrs = n_threads;
+ arr->size = size;
+
+ // Populate it...
+ StgWord i = 0;
+ for (unsigned g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ for (StgTSO *t = generations[g].threads; t != END_TSO_QUEUE; t = t->global_link) {
+ // It's possible that new threads have been created since we counted.
+ // Ignore them.
+ if (i == n_threads)
+ break;
+ arr->payload[i] = (StgClosure *) t;
+ i++;
+ }
+ }
+ CHECKM(i == n_threads, "listThreads: Found too few threads");
+ RELEASE_LOCK(&sched_mutex);
+ return arr;
+}
+
/* ----------------------------------------------------------------------------
* Debugging: why is a thread blocked
* ------------------------------------------------------------------------- */