?? RIGHT := 110 ??
MODULE mmm$log_caller_monitor;

{ This module should be compiled to OSF$MONITOR and, if necessary, OSF$BOOT_MONITOR.

*copyc mmv$benchmark_run

{ The following TYPE is a version of the minimum save area.  It defines only the fields which will be
{ useful in the procedure MMP$LOG_CALLER_MONITOR.

  TYPE
    sfsa_type = record
      fillp: 0 .. 0ffff(16),
      p: ^cell,
      a0: integer,
      a1: integer,
      fill2: 0 .. 0ffff(16),
      a2: ^sfsa_type,
  recend;

  TYPE
    proc_id_type = RECORD
      fill0: 0..0ffff(16),
      p0: ^cell,
      fill1: 0..0ffff(16),
      p1: ^cell,
      fill2: 0..0ffff(16),
      p2: ^cell,
      fill3: 0..0ffff(16),
      p3: ^cell,
    RECEND,

    proc_info_type = RECORD
      id: proc_id_type,
      count: integer,
    RECEND;

  CONST
    pid_size = 300;

  VAR
    count_monitor: integer,
    mmv$log_enable_monitor: [XDCL, #GATE] integer := 0,
    max_pid_monitor: [XDCL] integer,
    pid_monitor: [XDCL] array [0 .. pid_size] of proc_info_type,
    start_time_monitor: integer,
    last_time_monitor: integer,
    mmv$log_enable_r1: [XDCL, #GATE] integer := 0,
    max_pid_r1: [XDCL, #GATE] integer,
    pid_r1: [XDCL, #GATE] array [0 .. pid_size] of proc_info_type;

?? EJECT ??

  PROCEDURE [XDCL] mmp$log_caller_monitor;

    VAR
      offset,
      i: integer,
      id: proc_id_type,
      sfsa_p: ^sfsa_type,
      null_id: [STATIC] proc_id_type := [0, NIL, 0, NIL, 0, NIL, 0, NIL];


{ If we are not specifically collecting this data at this time, return without processing.

    IF mmv$benchmark_run = 0 THEN
      RETURN;
    ELSEIF mmv$log_enable_monitor <= 1 THEN

{ Initialize the data array.

      count_monitor := 0;
      start_time_monitor := #free_running_clock (0);
      mmv$log_enable_monitor := 2;
      FOR i := 0 TO pid_size DO
        pid_monitor [i].id := null_id;
        pid_monitor [i].count := 0;
      FOREND;
      max_pid_monitor := 0;
    IFEND;

    count_monitor := count_monitor + 1;
    last_time_monitor := #free_running_clock (0);
    sfsa_p := #previous_save_area ();
    id := null_id;
    i := 0;
    WHILE (sfsa_p <> NIL) AND (i < 4) DO
      CASE i OF
      =0=
        id.p0 := sfsa_p^.p;
      =1=
        id.p1 := sfsa_p^.p;
      =2=
        id.p2 := sfsa_p^.p;
      =3=
        id.p3 := sfsa_p^.p;
      CASEND;
      sfsa_p := sfsa_p^.a2;
      i := i + 1;
    WHILEND;

    i := 0;
    WHILE pid_monitor [i].id  <> id DO
      IF i = max_pid_monitor THEN
        IF i = pid_size THEN
          RETURN;
        IFEND;
        pid_monitor [i].id := id;
        max_pid_monitor := i + 1;
      ELSE
        i := i + 1;
      IFEND;
    WHILEND;

    pid_monitor [i].count := pid_monitor [i].count + 1;

  PROCEND mmp$log_caller_monitor;
MODEND mmm$log_caller_monitor;
