static new MultiSet poorMansProfiling_results; static int poorMansProfiling_samples; static java.util.Timer poorMansProfiling_timer; static Lock poorMansProfiling_lock = lock(); static Thread poorMansProfiling_threadToSample; // otherwise sample all threads static void poorMansProfiling() { poorMansProfiling(poorMansProfiling_defaultInterval()); } static void poorMansProfiling(Thread thread) { poorMansProfiling(poorMansProfiling_defaultInterval(), thread); } static void poorMansProfiling(int interval) { poorMansProfiling(interval, null); } static void poorMansProfiling(int interval, Thread thread) { lock poorMansProfiling_lock; poorMansProfiling_threadToSample = thread; poorMansProfiling_stop(); poorMansProfiling_clear(); poorMansProfiling_timer = doEvery_daemon(interval, r { Map map = poorMansProfiling_threadToSample != null ? litmap(poorMansProfiling_threadToSample, poorMansProfiling_threadToSample.getStackTrace()) : runnableThreadsWithStackTraces(); lock poorMansProfiling_lock; poorMansProfiling_samples++; for (Thread t : keys(map)) { continue if isSystemThread(t); new StringBuilder buf; for (StackTraceElement e : map.get(t)) buf.append(e).append("\n"); poorMansProfiling_results.add(str(buf)); } }); } static void poorMansProfiling_stop() { lock poorMansProfiling_lock; if (poorMansProfiling_timer != null) { stopTimer(poorMansProfiling_timer); poorMansProfiling_timer = null; } } static void poorMansProfiling_clear() { lock poorMansProfiling_lock; poorMansProfiling_results.clear(); poorMansProfiling_samples = 0; } static MultiSet poorMansProfiling_results() { ret new MultiSet(poorMansProfiling_results); } static MultiSet poorMansProfiling_stopAndGetResults() { lock poorMansProfiling_lock; poorMansProfiling_stop(); ret poorMansProfiling_results(); }