diff --git a/chroprof/api.nim b/chroprof/api.nim index f72cd19..fa4db62 100644 --- a/chroprof/api.nim +++ b/chroprof/api.nim @@ -11,16 +11,18 @@ proc getMetrics*(): MetricsTotals = ## current thread. result = profilerInstance.metrics -proc enableProfiling*(callback: EventCallback = nil) = +template enableProfiling*(callback: EventCallback) = ## Enables profiling for the the event loop running in the current thread. ## The client may optionally supply a callback to be notified of `Future` ## events. attachMonitoring( - if (isNil(callback)): - proc(e: Event) {.nimcall.} = - profilerInstance.processEvent(e) - else: - proc(e: Event) {.nimcall.} = + proc(e: Event) {.nimcall, gcsafe, raises: [].} = profilerInstance.processEvent(e) callback(e) ) + +template enableProfiling*() = + attachMonitoring( + proc(e: Event) {.nimcall, gcsafe, raises: [].} = + profilerInstance.processEvent(e) + ) diff --git a/tests/testprofiler.nim b/tests/testprofiler.nim index 90b1406..84b881e 100644 --- a/tests/testprofiler.nim +++ b/tests/testprofiler.nim @@ -282,23 +282,55 @@ suite "profiler metrics": await barrier advanceTime(10.milliseconds) - proc parent(): Future[Future[void]] {.async.} = + proc parent(): Future[seq[Future[void]]] {.async.} = advanceTime(10.milliseconds) - return child() + return @[child(), child()] let childFut = waitFor parent() barrier.complete() - waitFor childFut + waitFor allFutures(childFut) var metrics = recordedMetrics() let parentMetrics = metrics.forProc("parent") let childMetrics = metrics.forProc("child") check parentMetrics.execTime == 10.milliseconds - check parentMetrics.childrenExecTime == 10.milliseconds + check parentMetrics.childrenExecTime == 20.milliseconds check parentMetrics.wallClockTime == 10.milliseconds - echo "EXE TIME ", $childMetrics.execTime + check childMetrics.execTime == 20.milliseconds + check childMetrics.wallClockTime == 30.milliseconds + check childMetrics.childrenExecTime == ZeroDuration + + test "should aggregate child execution times across nested children": + proc child() {.async.} = + advanceTime(10.milliseconds) + + proc parent() {.async.} = + advanceTime(10.milliseconds) + await child() + advanceTime(10.milliseconds) + + proc grandparent() {.async.} = + advanceTime(10.milliseconds) + await parent() + advanceTime(10.milliseconds) + + waitFor grandparent() + + var metrics = recordedMetrics() + let grandparentMetrics = metrics.forProc("grandparent") + let parentMetrics = metrics.forProc("parent") + let childMetrics = metrics.forProc("child") + + check grandparentMetrics.execTime == 20.milliseconds + check grandparentMetrics.childrenExecTime == 30.milliseconds + check grandparentMetrics.wallClockTime == 50.milliseconds + + check parentMetrics.execTime == 20.milliseconds + check parentMetrics.childrenExecTime == 10.milliseconds + check parentMetrics.wallClockTime == 30.milliseconds + check childMetrics.execTime == 10.milliseconds check childMetrics.wallClockTime == 10.milliseconds check childMetrics.childrenExecTime == ZeroDuration