unit ProbeScheduling; {$mode objfpc}{$H+} {$ifndef ANDROID}{$fatal Decision scheduling probe is Android-only}{$endif} interface uses Classes,ProbeReport; type TDecisionSchedule=class private FReport:TProbeReport; FWorker:TThread; FCallbackSteps:Integer; FCallbackReported,FWorkerReported:Boolean; FPauses,FResumes:Integer; public constructor Create(AReport:TProbeReport); destructor Destroy;override; procedure Tick; procedure Paused; procedure Resumed; procedure ObserveInstanceCount; end; implementation uses SysUtils; type TDecisionWorker=class(TThread) public Executions:Integer; Sum:Int64; Done:Boolean; procedure Execute;override; end; var GScheduleInstances:Integer=0; procedure TDecisionWorker.Execute; var I:Integer; begin Inc(Executions);Sum:=0; try for I:=1 to 40 do begin if Terminated then Exit; Sum:=Sum+I;Sleep(100); end; finally Done:=True;end; end; constructor TDecisionSchedule.Create(AReport:TProbeReport); begin inherited Create;FReport:=AReport;Inc(GScheduleInstances); FWorker:=TDecisionWorker.Create(True);FWorker.FreeOnTerminate:=False;FWorker.Start; ObserveInstanceCount; end; destructor TDecisionSchedule.Destroy; begin if FWorker<>nil then begin FWorker.Terminate;FWorker.WaitFor;FWorker.Free; end; inherited; end; procedure TDecisionSchedule.ObserveInstanceCount; begin FReport.Add('decision.schedule.host_instance_count','OBSERVED','instances_in_process='+IntToStr(GScheduleInstances)); end; procedure TDecisionSchedule.Tick; var W:TDecisionWorker; begin if not FCallbackReported then begin Inc(FCallbackSteps); if FCallbackSteps>=120 then begin FCallbackReported:=True; FReport.Add('decision.schedule.callback_progress','OBSERVED', 'completed=true; steps='+IntToStr(FCallbackSteps)+'; pauses='+IntToStr(FPauses)+'; resumes='+IntToStr(FResumes)); end; end; if not FWorkerReported then begin W:=TDecisionWorker(FWorker); if W.Done then begin W.WaitFor;FWorkerReported:=True; FReport.Add('decision.schedule.worker_progress','OBSERVED', 'completed='+LowerCase(BoolToStr((W.Executions=1) and (W.Sum=820),True))+ '; executions='+IntToStr(W.Executions)+'; sum='+IntToStr(W.Sum)+ '; pauses='+IntToStr(FPauses)+'; resumes='+IntToStr(FResumes)); end; end; end; procedure TDecisionSchedule.Paused; begin Inc(FPauses);FReport.Add('decision.schedule.lifecycle','OBSERVED', 'event=pause; pauses='+IntToStr(FPauses)+'; resumes='+IntToStr(FResumes));end; procedure TDecisionSchedule.Resumed; begin Inc(FResumes);ObserveInstanceCount;FReport.Add('decision.schedule.lifecycle','OBSERVED', 'event=resume; pauses='+IntToStr(FPauses)+'; resumes='+IntToStr(FResumes));end; end.