Skip to content

Commit e5bfb75

Browse files
committed
Improved timing measurements, and handling of return events.
1 parent efda136 commit e5bfb75

1 file changed

Lines changed: 25 additions & 6 deletions

File tree

ext/fiber/profiler/capture.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,11 @@ int Fiber_Profiler_Capture_Call_finish(struct Fiber_Profiler_Capture *capture, s
372372
// Don't filter calls if we're not running:
373373
if (DEBUG_FILTERED) return 0;
374374

375+
if (event_flag_return_p(call->event_flag)) {
376+
// We don't filter return statements, as they are always part of the call stack:
377+
return 0;
378+
}
379+
375380
if (call->duration < capture->filter_threshold) {
376381
// We can only remove calls from the end of the deque, otherwise they might be referenced by other calls:
377382
if (call == Fiber_Profiler_Deque_last(&capture->calls)) {
@@ -427,15 +432,21 @@ static void Fiber_Profiler_Capture_callback(rb_event_flag_t event_flag, VALUE da
427432
struct Fiber_Profiler_Capture_Call *last_call = Fiber_Profiler_Deque_last(&capture->calls);
428433
call = Fiber_Profiler_Capture_Call_new(capture, event_flag, id, klass);
429434

435+
struct timespec call_time;
436+
430437
if (last_call) {
431-
call->enter_time = last_call->enter_time;
438+
call_time = last_call->enter_time;
432439
} else {
433-
call->enter_time = capture->switch_time;
440+
call_time = capture->switch_time;
434441
}
442+
443+
// For return statements, we record the current time as the enter time:
444+
Fiber_Profiler_Time_current(&call->enter_time);
445+
call->duration = Fiber_Profiler_Time_delta(&call_time, &call->enter_time);
446+
} else {
447+
call->duration = Fiber_Profiler_Time_delta_current(&call->enter_time);
435448
}
436449

437-
call->duration = Fiber_Profiler_Time_delta_current(&call->enter_time);
438-
439450
capture->current = call->parent;
440451

441452
// We may encounter returns without a preceeding call.
@@ -617,7 +628,9 @@ static size_t Fiber_Profiler_Capture_absolute_nesting(struct Fiber_Profiler_Capt
617628
static const double Fiber_Profiler_Capture_SKIP_THRESHOLD = 0.98;
618629

619630
void Fiber_Profiler_Capture_print_tty(struct Fiber_Profiler_Capture *capture, FILE *restrict stream, double duration) {
620-
fprintf(stderr, "## Fiber stalled for %.3f seconds (switches=%zu, samples=%zu, stalls=%zu start_time=" Fiber_Profiler_TIME_PRINTF_TIMESPEC ")\n", duration, capture->switches, capture->samples, capture->stalls, Fiber_Profiler_TIME_PRINTF_TIMESPEC_ARGUMENTS(capture->start_time));
631+
double start_time = Fiber_Profiler_Time_delta(&capture->start_time, &capture->switch_time);
632+
633+
fprintf(stderr, "## Fiber stalled for %.3f seconds (switches=%zu, samples=%zu, stalls=%zu, T+%0.3fs)\n", duration, capture->switches, capture->samples, capture->stalls, start_time);
621634

622635
size_t skipped = 0;
623636

@@ -684,12 +697,18 @@ void Fiber_Profiler_Capture_print_tty(struct Fiber_Profiler_Capture *capture, FI
684697
fprintf(stream, "... filtered %zu direct calls ...\e[0m\n", call->filtered);
685698
}
686699
}
700+
701+
if (skipped) {
702+
fprintf(stream, "\e[2m... skipped %zu calls ...\e[0m\n", skipped);
703+
}
687704
}
688705

689706
void Fiber_Profiler_Capture_print_json(struct Fiber_Profiler_Capture *capture, FILE *restrict stream, double duration) {
707+
double start_time = Fiber_Profiler_Time_delta(&capture->start_time, &capture->switch_time);
708+
690709
fputc('{', stream);
691710

692-
fprintf(stream, "\"start_time\":" Fiber_Profiler_TIME_PRINTF_TIMESPEC ",\"duration\":%0.6f", Fiber_Profiler_TIME_PRINTF_TIMESPEC_ARGUMENTS(capture->start_time), duration);
711+
fprintf(stream, "\"start_time\":%0.3f,\"duration\":%0.6f", start_time, duration);
693712

694713
size_t skipped = 0;
695714

0 commit comments

Comments
 (0)