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-
4432int 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
5240static 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
9280void 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
10189void 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}
0 commit comments