!7 cmodule2 > DynPrintLogAndEnabled { switchable double interval = 1.0; // seconds sclass Entry { long threadID; S threadName; WeakRef thread; StackTraceElement[] stackTrace; bool runnable; } transient L entries; transient volatile Map stackTraces; // weakHashMap transient volatile Map runnableStackTraces; start { dm_reloadOnFieldChange enabled(); if (enabled) dm_doEvery(interval, r { if (!enabled) ret; var raw = allThreadsWithStackTraces(); setField(entries := map(raw, (t, st) -> { new Entry e; e.threadID = threadID(t); e.threadName = threadName(t); e.thread = weakRef(t); e.stackTrace = st; e.runnable = isThreadRunnable_x(t, st); ret e; })); setField(stackTraces := toWeakHashMap(raw)); setField(runnableStackTraces := mapToWeakHashMap(filter(entries, e -> e.runnable), e -> pair(e.thread!, e.stackTrace))); vmBus_send freshStackTraces(stackTraces, weakRef(me())); }); } S renderStats() { ret stackTraces == null ? "" : jlabel_centerHTML(joinWithBR( hfontsize(40, b(nThreads(runnableStackTraces))), "running", n2(l(stackTraces)-l(runnableStackTraces)) + " idle")); } visual dm_calculatedCenteredLabel renderStats(); }