diff --git a/src/job_queue.ml b/src/job_queue.ml index 998f954..9962246 100644 --- a/src/job_queue.ml +++ b/src/job_queue.ml @@ -167,7 +167,10 @@ let run_jobs (type a) t scheduler = the job out of the queue and decrement [jobs_left_this_cycle]. [run_job] or [run_external_jobs] may side effect [t], either by enqueueing jobs, or by clearing [t]. *) + let start = Time_ns.now () in run_job t scheduler execution_context f a; + let this_job_time = Time_ns.(diff (now ()) start) in + if Time_ns.Span.to_sec this_job_time >= 2. then t.long_jobs_last_cycle <- (execution_context, this_job_time) :: t.long_jobs_last_cycle; (* [run_external_jobs] at each iteration of the [while] loop, for fairness. *) run_external_jobs t scheduler done; diff --git a/src/scheduler.ml b/src/scheduler.ml index 12a9bcd..a34dd9e 100644 --- a/src/scheduler.ml +++ b/src/scheduler.ml @@ -54,6 +54,12 @@ let long_cycles_with_context t ~at_least = then Tail.extend tail (t.last_cycle_time,t.current_execution_context))) ;; +let long_jobs_with_context t = + Stream.create (fun tail -> + run_every_cycle_start t ~f:(fun () -> + List.iter t.long_jobs_last_cycle ~f:(fun job -> Tail.extend tail job))) +;; + let cycle_num_jobs t = Stream.create (fun tail -> run_every_cycle_start t ~f:(fun () -> Tail.extend tail t.last_cycle_num_jobs)) diff --git a/src/scheduler.mli b/src/scheduler.mli index 9f711c1..e9bb92d 100644 --- a/src/scheduler.mli +++ b/src/scheduler.mli @@ -43,6 +43,7 @@ val set_record_backtraces : t -> bool -> unit val run_every_cycle_start : t -> f:(unit -> unit) -> unit val long_cycles : t -> at_least:Time_ns.Span.t -> Time_ns.Span.t Async_stream.t val long_cycles_with_context : t -> at_least:Time_ns.Span.t -> (Time_ns.Span.t * Execution_context.t) Async_stream.t +val long_jobs_with_context : t -> (Execution_context.t * Time_ns.Span.t) Async_stream.t val can_run_a_job : t -> bool val create_alarm : t -> (unit -> unit) -> Gc.Expert.Alarm.t val add_finalizer : t -> 'a Heap_block.t -> ('a Heap_block.t -> unit) -> unit diff --git a/src/scheduler1.ml b/src/scheduler1.ml index f18988c..851c8eb 100644 --- a/src/scheduler1.ml +++ b/src/scheduler1.ml @@ -115,6 +115,7 @@ type t = Scheduler0.t = ; mutable record_backtraces : bool ; mutable on_start_of_cycle : unit -> unit ; mutable on_end_of_cycle : unit -> unit + ; mutable long_jobs_last_cycle : (Execution_context.t * Time_ns.Span.t) list ; mutable cycle_started : bool } [@@deriving fields, sexp_of] diff --git a/src/types.ml b/src/types.ml index 45b1649..ae3c85f 100644 --- a/src/types.ml +++ b/src/types.ml @@ -200,6 +200,7 @@ and Scheduler : sig ; mutable record_backtraces : bool ; mutable on_start_of_cycle : unit -> unit ; mutable on_end_of_cycle : unit -> unit + ; mutable long_jobs_last_cycle : (Execution_context.t * Time_ns.Span.t) list ; mutable cycle_started : bool } end = @@ -248,6 +249,6 @@ end = Very_low_priority_worker and Tracing : sig - type tracing_fns = + type tracing_fns = { trace_thread_switch : Execution_context.t -> unit } end = Tracing