Skip to content

Commit 06fab4c

Browse files
committed
Initial rework of call tracking.
1 parent 6ef650b commit 06fab4c

File tree

2 files changed

+47
-58
lines changed

2 files changed

+47
-58
lines changed

ext/io/event/profile.c

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88

99
#include <stdio.h>
1010

11-
void IO_Event_Profile_Event_initialize(struct IO_Event_Profile_Event *event) {
12-
event->time.tv_sec = 0;
13-
event->time.tv_nsec = 0;
11+
void IO_Event_Profile_Call_initialize(struct IO_Event_Profile_Call *event) {
12+
event->enter_time.tv_sec = 0;
13+
event->enter_time.tv_nsec = 0;
14+
event->exit_time.tv_sec = 0;
15+
event->exit_time.tv_nsec = 0;
16+
1417
event->nesting = 0;
1518

1619
event->event_flag = 0;
@@ -20,27 +23,12 @@ void IO_Event_Profile_Event_initialize(struct IO_Event_Profile_Event *event) {
2023
event->line = 0;
2124
}
2225

23-
void IO_Event_Profile_Event_free(struct IO_Event_Profile_Event *event) {
26+
void IO_Event_Profile_Call_free(struct IO_Event_Profile_Call *event) {
2427
if (event->path) {
2528
free((void*)event->path);
2629
}
2730
}
2831

29-
static const char *event_flag_name(rb_event_flag_t event_flag) {
30-
switch (event_flag) {
31-
case RUBY_EVENT_LINE:
32-
return "line";
33-
case RUBY_EVENT_CALL:
34-
case RUBY_EVENT_C_CALL:
35-
return "call";
36-
case RUBY_EVENT_RETURN:
37-
case RUBY_EVENT_C_RETURN:
38-
return "return";
39-
default:
40-
return "unknown";
41-
}
42-
}
43-
4432
int event_flag_call_p(rb_event_flag_t event_flags) {
4533
return event_flags & (RUBY_EVENT_CALL | RUBY_EVENT_C_CALL);
4634
}
@@ -51,13 +39,13 @@ int event_flag_return_p(rb_event_flag_t event_flags) {
5139

5240
static void profile_event_callback(rb_event_flag_t event_flag, VALUE data, VALUE self, ID id, VALUE klass) {
5341
struct IO_Event_Profile *profile = (struct IO_Event_Profile*)data;
54-
struct IO_Event_Profile_Event *event = IO_Event_Array_push(&profile->events);
55-
56-
IO_Event_Time_current(&event->time);
57-
58-
event->event_flag = event_flag;
5942

6043
if (event_flag_call_p(event_flag)) {
44+
struct IO_Event_Profile_Call *event = IO_Event_Array_push(&profile->events);
45+
IO_Event_Time_current(&event->enter_time);
46+
47+
event->event_flag = event_flag;
48+
6149
event->parent = profile->current;
6250
profile->current = event;
6351

@@ -77,25 +65,25 @@ static void profile_event_callback(rb_event_flag_t event_flag, VALUE data, VALUE
7765
}
7866
event->line = rb_sourceline();
7967
} else if (event_flag_return_p(event_flag)) {
80-
// Set up the call/return pair:
81-
profile->current->pair = event;
82-
event->pair = profile->current;
68+
struct IO_Event_Profile_Call *event = profile->current;
8369

84-
profile->current = profile->current->parent;
85-
event->parent = profile->current;
70+
// Bad event sequence?
71+
if (event == NULL) return;
8672

73+
IO_Event_Time_current(&event->exit_time);
74+
75+
profile->current = event->parent;
8776
profile->nesting -= 1;
88-
event->nesting = profile->nesting;
8977
}
9078
}
9179

9280
void IO_Event_Profile_initialize(struct IO_Event_Profile *profile, VALUE fiber) {
9381
profile->fiber = fiber;
9482

95-
profile->events.element_initialize = (void (*)(void*))IO_Event_Profile_Event_initialize;
96-
profile->events.element_free = (void (*)(void*))IO_Event_Profile_Event_free;
83+
profile->events.element_initialize = (void (*)(void*))IO_Event_Profile_Call_initialize;
84+
profile->events.element_free = (void (*)(void*))IO_Event_Profile_Call_free;
9785

98-
IO_Event_Array_initialize(&profile->events, 0, sizeof(struct IO_Event_Profile_Event));
86+
IO_Event_Array_initialize(&profile->events, 0, sizeof(struct IO_Event_Profile_Call));
9987
}
10088

10189
void IO_Event_Profile_start(struct IO_Event_Profile *profile) {
@@ -128,27 +116,27 @@ void IO_Event_Profile_print(FILE *restrict stream, struct IO_Event_Profile *prof
128116
size_t skipped = 0;
129117

130118
for (size_t i = 0; i < profile->events.limit; i += 1) {
131-
struct IO_Event_Profile_Event *event = profile->events.base[i];
119+
struct IO_Event_Profile_Call *event = profile->events.base[i];
120+
121+
struct timespec duration = {};
132122

133-
if (event_flag_call_p(event->event_flag)) {
134-
struct timespec duration = {};
135-
136-
if (event->pair) {
137-
IO_Event_Time_elapsed(&event->time, &event->pair->time, &duration);
138-
139-
// Skip events that are too short to be meaningful:
140-
if (IO_Event_Time_proportion(&duration, &total_duration) < IO_EVENT_PROFILE_PRINT_MINIMUM_PROPORTION) {
141-
skipped += 1;
142-
continue;
143-
}
144-
}
145-
146-
for (size_t i = 0; i < event->nesting; i += 1) {
147-
fputc('\t', stream);
148-
}
149-
150-
const char *name = rb_id2name(event->id);
151-
fprintf(stream, "\t%s:%d in '%s#%s' (" IO_EVENT_TIME_PRINTF_TIMESPEC "s)\n", event->path, event->line, RSTRING_PTR(rb_inspect(event->klass)), name, IO_EVENT_TIME_PRINTF_TIMESPEC_ARGUMENTS(duration));
123+
IO_Event_Time_elapsed(&event->enter_time, &event->exit_time, &duration);
124+
125+
// Skip events that are too short to be meaningful:
126+
if (IO_Event_Time_proportion(&duration, &total_duration) < IO_EVENT_PROFILE_PRINT_MINIMUM_PROPORTION) {
127+
skipped += 1;
128+
continue;
152129
}
130+
131+
for (size_t i = 0; i < event->nesting; i += 1) {
132+
fputc('\t', stream);
133+
}
134+
135+
const char *name = rb_id2name(event->id);
136+
fprintf(stream, "\t%s:%d in '%s#%s' (" IO_EVENT_TIME_PRINTF_TIMESPEC "s)\n", event->path, event->line, RSTRING_PTR(rb_inspect(event->klass)), name, IO_EVENT_TIME_PRINTF_TIMESPEC_ARGUMENTS(duration));
137+
}
138+
139+
if (skipped > 0) {
140+
fprintf(stream, "Skipped %zu events that were too short to be meaningful.\n", skipped);
153141
}
154142
}

ext/io/event/profile.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
#include "array.h"
88
#include "time.h"
99

10-
struct IO_Event_Profile_Event {
11-
struct timespec time;
10+
struct IO_Event_Profile_Call {
11+
struct timespec enter_time;
12+
struct timespec exit_time;
13+
1214
size_t nesting;
1315

1416
rb_event_flag_t event_flag;
@@ -18,8 +20,7 @@ struct IO_Event_Profile_Event {
1820
const char *path;
1921
int line;
2022

21-
struct IO_Event_Profile_Event *parent;
22-
struct IO_Event_Profile_Event *pair;
23+
struct IO_Event_Profile_Call *parent;
2324
};
2425

2526
struct IO_Event_Profile {
@@ -32,7 +33,7 @@ struct IO_Event_Profile {
3233
size_t nesting;
3334

3435
// The current call frame:
35-
struct IO_Event_Profile_Event *current;
36+
struct IO_Event_Profile_Call *current;
3637

3738
struct IO_Event_Array events;
3839
};

0 commit comments

Comments
 (0)