@@ -49,13 +49,30 @@ struct aux_data_array {
49
49
static struct aux_data_array my__aux_data ;
50
50
static void format_and_free_aux_data (struct json_writer * jw );
51
51
52
+ struct child_summary_data {
53
+ char * child_class ;
54
+ uint64_t total_ns ;
55
+ int count ;
56
+ };
57
+
58
+ struct child_summary_data_array {
59
+ struct child_summary_data * * array ;
60
+ size_t nr , alloc ;
61
+ };
62
+
63
+ static struct child_summary_data_array my__child_summary_data ;
64
+ static void format_child_summary_data (struct json_writer * jw );
65
+ static void free_child_summary_data (void );
66
+
52
67
struct child_data {
53
68
uint64_t start_ns ;
54
69
uint64_t end_ns ;
55
70
struct json_writer jw_argv ;
71
+ char * child_class ;
56
72
unsigned int is_running :1 ;
57
73
unsigned int is_git_cmd :1 ;
58
74
unsigned int use_shell :1 ;
75
+ unsigned int is_interactive :1 ;
59
76
};
60
77
61
78
struct child_data_array {
@@ -293,6 +310,12 @@ static void emit_exit_event(void)
293
310
format_and_free_aux_data (& jw );
294
311
jw_end (& jw );
295
312
}
313
+
314
+ if (my__child_summary_data .nr ) {
315
+ jw_object_inline_begin_object (& jw , "child_summary" );
316
+ format_child_summary_data (& jw );
317
+ jw_end (& jw );
318
+ }
296
319
}
297
320
jw_end (& jw );
298
321
@@ -453,6 +476,7 @@ static void do_final_steps(int in_signal)
453
476
argv_array_clear (& my__argv );
454
477
jw_release (& my__errors );
455
478
strbuf_release (& my__session_id );
479
+ free_child_summary_data ();
456
480
free_timers ();
457
481
free_children ();
458
482
}
@@ -835,6 +859,85 @@ static void format_and_free_aux_data(struct json_writer *jw)
835
859
my__aux_data .alloc = 0 ;
836
860
}
837
861
862
+ static struct child_summary_data * find_child_summary_data (
863
+ const struct child_data * cd )
864
+ {
865
+ struct child_summary_data * csd ;
866
+ char * child_class ;
867
+ int k ;
868
+
869
+ child_class = cd -> child_class ;
870
+ if (!child_class || !* child_class ) {
871
+ if (cd -> use_shell )
872
+ child_class = "shell" ;
873
+ child_class = "other" ;
874
+ }
875
+
876
+ for (k = 0 ; k < my__child_summary_data .nr ; k ++ ) {
877
+ csd = my__child_summary_data .array [k ];
878
+ if (!strcmp (child_class , csd -> child_class ))
879
+ return csd ;
880
+ }
881
+
882
+ csd = xcalloc (1 , sizeof (struct child_summary_data ));
883
+ csd -> child_class = xstrdup (child_class );
884
+
885
+ ALLOC_GROW (my__child_summary_data .array , my__child_summary_data .nr + 1 ,
886
+ my__child_summary_data .alloc );
887
+ my__child_summary_data .array [my__child_summary_data .nr ++ ] = csd ;
888
+
889
+ return csd ;
890
+ }
891
+
892
+ static void add_child_to_summary_data (const struct child_data * cd )
893
+ {
894
+ struct child_summary_data * csd = find_child_summary_data (cd );
895
+
896
+ csd -> total_ns += cd -> end_ns - cd -> start_ns ;
897
+ csd -> count ++ ;
898
+ }
899
+
900
+ static void format_child_summary_data (struct json_writer * jw )
901
+ {
902
+ int k ;
903
+
904
+ for (k = 0 ; k < my__child_summary_data .nr ; k ++ ) {
905
+ struct child_summary_data * csd = my__child_summary_data .array [k ];
906
+
907
+ jw_object_inline_begin_object (jw , csd -> child_class );
908
+ {
909
+ jw_object_intmax (jw , "total_us" , csd -> total_ns / 1000 );
910
+ jw_object_intmax (jw , "count" , csd -> count );
911
+ }
912
+ jw_end (jw );
913
+ }
914
+ }
915
+
916
+ static void free_child_summary_data (void )
917
+ {
918
+ int k ;
919
+
920
+ for (k = 0 ; k < my__child_summary_data .nr ; k ++ ) {
921
+ struct child_summary_data * csd = my__child_summary_data .array [k ];
922
+
923
+ free (csd -> child_class );
924
+ free (csd );
925
+ }
926
+
927
+ free (my__child_summary_data .array );
928
+ }
929
+
930
+ static unsigned int is_interactive (const char * child_class )
931
+ {
932
+ if (child_class && * child_class ) {
933
+ if (!strcmp (child_class , "editor" ))
934
+ return 1 ;
935
+ if (!strcmp (child_class , "pager" ))
936
+ return 1 ;
937
+ }
938
+ return 0 ;
939
+ }
940
+
838
941
static struct child_data * alloc_child_data (const struct child_process * cmd )
839
942
{
840
943
struct child_data * cd = xcalloc (1 , sizeof (struct child_data ));
@@ -843,6 +946,9 @@ static struct child_data *alloc_child_data(const struct child_process *cmd)
843
946
cd -> is_running = 1 ;
844
947
cd -> is_git_cmd = cmd -> git_cmd ;
845
948
cd -> use_shell = cmd -> use_shell ;
949
+ cd -> is_interactive = is_interactive (cmd -> slog_child_class );
950
+ if (cmd -> slog_child_class && * cmd -> slog_child_class )
951
+ cd -> child_class = xstrdup (cmd -> slog_child_class );
846
952
847
953
jw_init (& cd -> jw_argv );
848
954
@@ -895,6 +1001,11 @@ int slog_child_starting(const struct child_process *cmd)
895
1001
jw_object_intmax (& jw_data , "child_id" , child_id );
896
1002
jw_object_bool (& jw_data , "git_cmd" , cd -> is_git_cmd );
897
1003
jw_object_bool (& jw_data , "use_shell" , cd -> use_shell );
1004
+ jw_object_bool (& jw_data , "is_interactive" ,
1005
+ cd -> is_interactive );
1006
+ if (cd -> child_class )
1007
+ jw_object_string (& jw_data , "child_class" ,
1008
+ cd -> child_class );
898
1009
jw_object_sub_jw (& jw_data , "child_argv" , & cd -> jw_argv );
899
1010
}
900
1011
jw_end (& jw_data );
@@ -925,6 +1036,8 @@ void slog_child_ended(int child_id, int child_pid, int child_exit_code)
925
1036
cd -> end_ns = getnanotime ();
926
1037
cd -> is_running = 0 ;
927
1038
1039
+ add_child_to_summary_data (cd );
1040
+
928
1041
/* build data portion for a "detail" event */
929
1042
if (slog_want_detail_event ("child" )) {
930
1043
struct json_writer jw_data = JSON_WRITER_INIT ;
@@ -934,6 +1047,11 @@ void slog_child_ended(int child_id, int child_pid, int child_exit_code)
934
1047
jw_object_intmax (& jw_data , "child_id" , child_id );
935
1048
jw_object_bool (& jw_data , "git_cmd" , cd -> is_git_cmd );
936
1049
jw_object_bool (& jw_data , "use_shell" , cd -> use_shell );
1050
+ jw_object_bool (& jw_data , "is_interactive" ,
1051
+ cd -> is_interactive );
1052
+ if (cd -> child_class )
1053
+ jw_object_string (& jw_data , "child_class" ,
1054
+ cd -> child_class );
937
1055
jw_object_sub_jw (& jw_data , "child_argv" , & cd -> jw_argv );
938
1056
939
1057
jw_object_intmax (& jw_data , "child_pid" , child_pid );
@@ -957,6 +1075,7 @@ static void free_children(void)
957
1075
struct child_data * cd = my__child_data .array [k ];
958
1076
959
1077
jw_release (& cd -> jw_argv );
1078
+ free (cd -> child_class );
960
1079
free (cd );
961
1080
}
962
1081
0 commit comments