Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_module_timer_runtime.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152open!BasemoduleGc=Caml.Gcexternal__MODULE__:string="%loc_MODULE"letam_recording_environment_variable="PPX_MODULE_TIMER"letget_am_recording_environment_variable()=(* avoid Caml.Sys.getenv_opt to preserve 4.04.x compatibility *)matchCaml.Sys.getenvam_recording_environment_variablewith|value->Somevalue|exception_->None;;letam_recording=Option.is_some(get_am_recording_environment_variable())moduleStartup_time=structmoduleGc_events=structtypet={minor_collections:int;major_collections:int;compactions:int}[@@derivingsexp_of]endtypet={module_name:string;startup_time_in_nanoseconds:Int63.t;gc_events:Gc_events.t}[@@derivingsexp_of]endletstartup_times_in_reverse_chronological_order=ref[]letcurrently_running_module_name=ref""letcurrently_running_module_start=refInt63.zeroletcurrently_running_module_gc_stats=ref(Gc.quick_stat())letreset_currently_running_module()=currently_running_module_name:="";currently_running_module_start:=Int63.zero;;letrecord_startmodule_name=ifam_recordingthen(assert(String.is_empty!currently_running_module_name);currently_running_module_name:=module_name;currently_running_module_gc_stats:=Gc.quick_stat();(* call [Time_now] as late as possible before running the module body *)currently_running_module_start:=Time_now.nanoseconds_since_unix_epoch());;letrecord_untilmodule_name=ifam_recordingthen((* compute [Time_now] as soon as possible after running the module body *)letuntil=Time_now.nanoseconds_since_unix_epoch()inletstart=!currently_running_module_startinletgc_stats_after=Gc.quick_stat()inletgc_stats_before=!currently_running_module_gc_statsinletstartup_time_in_nanoseconds=Int63.(-)untilstartinassert(String.equal!currently_running_module_namemodule_name);letgc_events:Startup_time.Gc_events.t={minor_collections=gc_stats_after.minor_collections-gc_stats_before.minor_collections;major_collections=gc_stats_after.major_collections-gc_stats_before.major_collections;compactions=gc_stats_after.compactions-gc_stats_before.compactions}inletstartup_time:Startup_time.t={module_name;startup_time_in_nanoseconds;gc_events}instartup_times_in_reverse_chronological_order:=startup_time::!startup_times_in_reverse_chronological_order;reset_currently_running_module());;letstring_of_span_in_nsnanos=Int63.to_stringnanos^"ns"letchar_is_digit_or_underscore=function|'0'..'9'|'_'->true|_->false;;letspan_in_ns_of_stringstring=matchString.chop_suffixstring~suffix:"ns"with|SomeprefixwhenString.for_allprefix~f:char_is_digit_or_underscore->Some(Int63.of_stringprefix)|_->None;;letgc_events_suffix_string({minor_collections;major_collections;compactions}:Startup_time.Gc_events.t)=letto_listdescriptioncount=ifcount=0then[]else[Int.to_stringcount^" "^description]inletstrings=to_list"minor collections"minor_collections@to_list"major collections"major_collections@to_list"compactions"compactionsinifList.is_emptystringsthen""else"; GC: "^String.concatstrings~sep:", ";;letprint_with_left_column_right_justifiedlist=letleft_column_width=List.foldlist~init:0~f:(funwidth(left,_,_)->Int.maxwidth(String.lengthleft))inList.iterlist~f:(fun(left,right,gc_events)->Stdio.printf"%*s %s%s\n"left_column_widthleftright(gc_events_suffix_stringgc_events));;letdefault_print_recorded_startup_timesstartup_times=letstartup_times=matchget_am_recording_environment_variable()|>Option.bind~f:span_in_ns_of_stringwith|None->startup_times|Someoverride->Stdio.print_endline"ppx_module_timer: overriding time measurements for testing";List.mapistartup_times~f:(funindex(startup_time:Startup_time.t)->letstartup_time_in_nanoseconds=Int63.(*)override(Int63.of_int(index+1))in{startup_timewithstartup_time_in_nanoseconds})inList.mapstartup_times~f:(fun({module_name;startup_time_in_nanoseconds;gc_events}:Startup_time.t)->string_of_span_in_nsstartup_time_in_nanoseconds,module_name,gc_events)|>print_with_left_column_right_justified;;letprint_recorded_startup_times=refdefault_print_recorded_startup_timeslet()=Caml.at_exit(fun()->!print_recorded_startup_times(List.rev!startup_times_in_reverse_chronological_order));;