?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Operator Facility : VED GS Display' ??
MODULE ofm$general_statistics_display;
?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clt$value
*copyc clt$display_control
*copyc jmt$system_supplied_name
*copyc jst$ijl_swap_queue_list
*copyc jsv$ijl_swap_queue_list
*copyc osc$multiprocessor_constants
*copyc oss$job_paged_literal
*copyc oss$task_private
*copyc oss$task_shared
*copyc ost$cpu_idle_statistics
*copyc ost$data_id
*copyc ost$status
*copyc ost$string
*copyc osv$task_shared_heap
?? POP ??
*copyc jmv$ijl_p
*copyc jmv$known_job_list
*copyc jmv$known_output_list
*copyc jmv$known_qfile_list
*copyc jmv$maximum_known_jobs
*copyc jmv$maximum_known_outputs
*copyc mtv$cst0
*copyc mtv$total_nos_cpu_time
*copyc tmv$total_task_count
*copyc qfv$current_kjl_limit
*copyc qfv$current_kol_limit
*copyc qfv$current_kql_limit
*copyc clp$close_display
*copy  clp$new_display_line
*copy  clp$put_display
*copyc dpp$clear_window
*copyc dpp$put_next_line
*copyc jmp$get_job_counts
*copyc ofp$build_system_line
*copyc ofp$open_display
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$get_pp_unit_count
*copyc osp$get_jm_mm_stats
*copyc osp$get_page_stats
*copyc osp$get_pio_unit_stats
*copyc osp$get_swap_stats
*copyc pmp$binary_to_ascii_fit
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ofp$general_statistics_display', EJECT ??

  PROCEDURE [XDCL] ofp$general_statistics_display
    (    wid: dpt$window_id;
         display_name: ost$name;
         file_name: amt$local_file_name;
         initial_call: boolean;
     VAR status: ost$status);

?? NEWTITLE := 'abort_handler', EJECT ??

{ PURPOSE:
{   This procedure provides clean-up processing when a task abort occurs.

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           save_area_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      IF wid = 0 THEN
        clp$close_display (display_control, ignore_status);
      IFEND;

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    CONST
      max_lines = 21,
      non_incremental = FALSE;

    VAR
       iov$total_queue_calls: [XREF] integer,
       iov$actual_requests_resolved: [XREF] integer,
       iov$read_priority_invoked: [XREF] integer;

    VAR
      display_control: clt$display_control,
      pp_count, unit_count,
      i, j,
      swap_ins,
      swap_outs,
      total_tasks,
      total_reads,
      total_writes,
      total_disk_recovered_errors,
      total_disk_intermediate_errors,
      total_disk_unrecovered_errors,
      other_pf_data,
      queue_count,
      swap_file_size: integer,
      ignore_status: ost$status,
      job_counts: jmt$job_counts,
      jobs_in_long_wait_count: 0 .. jmc$max_ijl_entries,
      jobs_in_long_wait_cant_init_io: 0 .. jmc$max_ijl_entries,
      swapped_jobs_count: 0 .. jmc$max_ijl_entries,
      swap_resident_job_count: 0 .. jmc$max_ijl_entries,
      task_index: tmt$task_status,
      from_state: jmt$ijl_swap_status,
      pfd_p: ^ost$page_fault_stats,
      preads: integer,
      ptotal: integer,
      pactual: integer,
      server_pfd_p: ^ost$page_fault_stats,
      pio_unit_p: ^ost$disk_unit_stats,
      swapd_p: ^ost$swap_stats,
      jmmmd_p: ^ost$jm_mm_stats,
      title: [READ, oss$job_paged_literal] string (18) := 'General Statistics',
      str: array [1 .. max_lines] of string (80),
      previous_pf_data: [STATIC, oss$task_shared] ^ost$page_fault_stats := NIL,
      previous_server_pf_data: [STATIC, oss$task_shared] ^ost$page_fault_stats := NIL,
      previous_swap_data: [STATIC, oss$task_shared] ^ost$swap_stats := NIL,
      previous_total_reads: [STATIC, oss$task_shared] integer := 0,
      previous_total_writes: [STATIC, oss$task_shared] integer := 0,
      previous_data_for_display: [STATIC, oss$task_shared] boolean := FALSE,
      read_summary: integer,
      system_line_info: [STATIC, oss$task_shared] ^oft$system_line_info := NIL;

    status.normal := TRUE;

    IF wid = 0 THEN
      osp$establish_block_exit_hndlr (^abort_handler);
    IFEND;
    IF initial_call THEN
      ofp$open_display (file_name, wid, dpc$wc_sharing, dpc$wk_table, title, display_control, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

{ Set up the labels.

    str [2] :=  ' PAGE QUEUES             JOBS                   SWAPPED JOBS';
    str [3] :=
                '        free:              interactive:            jobs in long wait:';
    str [4] :=
                '   available:          non-interactive:         long wait, disk down:';
    str [5] :=
                '   avail-mod:              input queue:           swap resident jobs:';
    str [6] :=  '       wired:                   active:              swapped to disk:';
    str [7] :=  '      shared:               known jobs:';
    str [8] :=  '      IO err:             output files:          number of swap outs:';
    str [9] :=  '       fixed:              queue files:               swap file size:';
    str [10] := '         JWS:';
    str [11] := '    swap-res:            TASKS                  DISK ERRORS';
    str [12] := '   long wait:                    total:              total_recovered:';
    str [13] := '                                 ready:           total_intermediate:';
    str [14] := ' PAGE FAULTS                ready/swap:            total_unrecovered:';
    str [15] := '   avail-mod:';
    str [16] := '         new:            INPUT/OUTPUT';
    str [17] := '        disk:                   writes:';
    str [18] := '       other:                    reads:';
    str [19] := ' I/O PRIORITY';
    str [20] := 'read prempts:             total calls:           actual issued:';
    str [21] := ' ';

    total_tasks := 0;
    PUSH jmmmd_p;

    osp$get_jm_mm_stats (non_incremental, jmmmd_p^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    PUSH pfd_p;
    PUSH server_pfd_p;
    osp$get_page_stats (non_incremental, pfd_p^, server_pfd_p^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    total_reads := 0;
    total_writes := 0;
    total_disk_recovered_errors := 0;
    total_disk_intermediate_errors := 0;
    total_disk_unrecovered_errors := 0;
    osp$get_pp_unit_count (pp_count, unit_count, status);
    IF unit_count = 0 THEN
      RETURN;
    IFEND;
    PUSH pio_unit_p: [1 .. unit_count];
    osp$get_pio_unit_stats (non_incremental, pio_unit_p^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    swap_file_size := 0;
    swap_ins := 0;
    swap_outs := 0;
    PUSH swapd_p;
    osp$get_swap_stats (non_incremental, swapd_p^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Establish base values for the general statistics display if they do not already
{ exist.

    IF NOT previous_data_for_display THEN
      ALLOCATE previous_pf_data IN osv$task_shared_heap^;
      previous_pf_data^ := pfd_p^;
      ALLOCATE system_line_info IN osv$task_shared_heap^;
      system_line_info^.initialized := FALSE;
      ALLOCATE previous_server_pf_data IN osv$task_shared_heap^;
      previous_server_pf_data^ := server_pfd_p^;
      ALLOCATE previous_swap_data IN osv$task_shared_heap^;
      previous_swap_data^ := swapd_p^;
      previous_data_for_display := TRUE;
    IFEND;

{ Set up the cpu idle-statistics and the NOS percentage.

    ofp$build_system_line (system_line_info^, str [1]);

{ Set up the page queue statistics.

    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.page_q_counts.q_counts[mmc$pq_free],
          10, 7, 7, str[3](16, 7));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.page_q_counts.q_counts[mmc$pq_avail],
          10, 7, 7, str[4](16, 7));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.page_q_counts.q_counts[mmc$pq_avail_modified],
          10, 7, 7, str[5](16, 7));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.page_q_counts.q_counts[mmc$pq_wired],
          10, 7, 7, str[6](16, 7));
    j := 0;
    FOR i := mmc$pq_shared_first TO mmc$pq_shared_last DO
      j := j + jmmmd_p^.jm_mm_stats.page_q_counts.q_counts [i]; {get sum of all shared queues}
    FOREND;
    pmp$binary_to_ascii_fit (j, 10, 7, 7, str[7](16, 7));
    j := jmmmd_p^.jm_mm_stats.page_q_counts.q_counts [mmc$pq_job_io_error] +
         jmmmd_p^.jm_mm_stats.page_q_counts.q_counts [mmc$pq_shared_io_error] +
         jmmmd_p^.jm_mm_stats.page_q_counts.q_counts [mmc$pq_swapped_io_error] +
         jmmmd_p^.jm_mm_stats.page_q_counts.q_counts [mmc$pq_flawed];
    pmp$binary_to_ascii_fit (j, 10, 7, 7, str[8](16, 7));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.page_q_counts.q_counts[mmc$pq_job_fixed],
          10, 7, 7, str[9](16, 7));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.page_q_counts.q_counts[mmc$pq_job_working_set],
          10, 7, 7, str[10](16, 7));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.page_q_counts.swap_resident_count,
          10, 7, 7, str [11] (16, 7));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.page_q_counts.long_wait_count,
          10, 7, 7, str [12] (16, 7));

{ Set up the page fault statistics.  Currently, SERVER page_fault statistics are not displayed.

    pmp$binary_to_ascii_fit ((pfd_p^.pf_stats [1] +
          pfd_p^.pf_stats [2] - previous_pf_data^.pf_stats [1]
          - previous_pf_data^.pf_stats [2]), 10, 7, 7, str [15] (16, 7));
    pmp$binary_to_ascii_fit ((pfd_p^.pf_stats [10] -
          previous_pf_data^.pf_stats [10]), 10, 7, 7, str [16] (16, 7));
    pmp$binary_to_ascii_fit ((pfd_p^.pf_stats [7] -
          previous_pf_data^.pf_stats [7]), 10, 7, 7, str [17] (16, 7));
    other_pf_data := pfd_p^.pf_stats [3] +
          pfd_p^.pf_stats [4] + pfd_p^.pf_stats
          [5] + pfd_p^.pf_stats [6] + pfd_p^.pf_stats [8] +
          pfd_p^.pf_stats [9] + pfd_p^.pf_stats
          [11] + pfd_p^.pf_stats [12] + pfd_p^.
          pf_stats [13] + pfd_p^.pf_stats [14] +
          pfd_p^.pf_stats [15] - previous_pf_data^.pf_stats [3]
          - previous_pf_data^.pf_stats [4] - previous_pf_data^.pf_stats [5] -
          previous_pf_data^.pf_stats [6] - previous_pf_data^.pf_stats [8] -
          previous_pf_data^.pf_stats [9] - previous_pf_data^.pf_stats [11] -
          previous_pf_data^.pf_stats [12] - previous_pf_data^.pf_stats [13] -
          previous_pf_data^.pf_stats [14] - previous_pf_data^.pf_stats [15];
    pmp$binary_to_ascii_fit (other_pf_data, 10, 7, 7, str [18] (16, 7));

{ Set up the job statistics.

    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.
          total_interactive_jobs, 10, 5, 5, str [3] (41, 5));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.
          total_non_interactive_jobs, 10, 5, 5, str [4] (41, 5));
    jmp$get_job_counts (job_counts, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    pmp$binary_to_ascii_fit (job_counts.queued_jobs, 10, 5, 5, str [5] (41, 5));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.
          total_active_jobs, 10, 5, 5, str [6] (41, 5));

{ Set up the input/output/generic queue statistics.

    queue_count := qfv$current_kjl_limit - jmv$known_job_list.state_data
          [jmc$kjl_unused_entry].number_of_entries;
    pmp$binary_to_ascii_fit (queue_count, 10, 5, 5, str [7] (41, 5));
    IF (queue_count >= jmv$maximum_known_jobs) THEN
      str [7] (46, 1) := '*';
    IFEND;

    queue_count := qfv$current_kol_limit - jmv$known_output_list.state_data
          [jmc$kol_unused_entry].number_of_entries;
    pmp$binary_to_ascii_fit (queue_count, 10, 5, 5, str [8] (41, 5));
    IF (queue_count >= jmv$maximum_known_outputs) THEN
      str [8] (46, 1) := '*';
    IFEND;

    queue_count := qfv$current_kql_limit - jmv$known_qfile_list.state_data
          [jmc$kql_unused_entry].number_of_entries;
    pmp$binary_to_ascii_fit (queue_count, 10, 5, 5, str [9] (41, 5));

{ Set up the task statistics.

    total_tasks := total_tasks + tmv$total_task_count;
    pmp$binary_to_ascii_fit (total_tasks, 10, 5, 5, str [12] (41, 5));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.
          total_ready_tasks, 10, 5, 5, str [13] (41, 5));
    pmp$binary_to_ascii_fit (jmmmd_p^.jm_mm_stats.
          total_ready_but_swapped_tasks, 10, 5, 5, str [14] (41, 5));

{ Set up the input/output statistics.

    FOR i := 1 TO unit_count DO
      IF pio_unit_p^.disk_unit_stats [i].unit_used THEN
        total_writes := total_writes + pio_unit_p^.disk_unit_stats [i].write_requests +
                        pio_unit_p^.disk_unit_stats [i].swap_out_requests;
        total_reads := total_reads + pio_unit_p^.disk_unit_stats [i].read_requests +
                        pio_unit_p^.disk_unit_stats [i].swap_in_requests;
        total_disk_recovered_errors := total_disk_recovered_errors +
                        pio_unit_p^.disk_unit_stats [i].recovered_errors;
        total_disk_intermediate_errors := total_disk_intermediate_errors +
                        pio_unit_p^.disk_unit_stats [i].intermediate_errors;
        total_disk_unrecovered_errors := total_disk_unrecovered_errors +
                        pio_unit_p^.disk_unit_stats [i].unrecovered_errors;
      IFEND;
    FOREND;

    IF previous_total_reads = 0 THEN {First time through the display for this task}
      previous_total_reads := total_reads;
      previous_total_writes := total_writes;
    IFEND;

    pmp$binary_to_ascii_fit (total_writes - previous_total_writes, 10, 5, 5, str [17] (41, 5));
    pmp$binary_to_ascii_fit (total_reads - previous_total_reads, 10, 5, 5, str [18] (41, 5));
    pmp$binary_to_ascii_fit (total_disk_recovered_errors, 10, 5, 5, str [12] (71, 5));
    pmp$binary_to_ascii_fit (total_disk_intermediate_errors, 10, 5, 5, str [13] (71, 5));
    pmp$binary_to_ascii_fit (total_disk_unrecovered_errors, 10, 5, 5, str [14] (71, 5));

{ Set up the swapping statistics.

    IF (swapd_p^.swap_file_page_count.swap_count -
          previous_swap_data^.swap_file_page_count.swap_count) > 0 THEN
      swap_file_size := (swapd_p^.swap_file_page_count.
            page_count - previous_swap_data^.swap_file_page_count.page_count)
            DIV (swapd_p^.swap_file_page_count.swap_count -
            previous_swap_data^.swap_file_page_count.swap_count);
      pmp$binary_to_ascii_fit (swap_file_size, 10, 5, 5, str [9] (71, 5));
    ELSE
      swap_file_size := 0;
      pmp$binary_to_ascii_fit (swap_file_size, 10, 5, 5, str [9] (71, 5));
    IFEND;

    swap_outs := swapd_p^.swap_stats [jmc$iss_executing]
          [jmc$iss_job_idle_tasks_complete].count - previous_swap_data^.swap_stats
          [jmc$iss_executing] [jmc$iss_job_idle_tasks_complete].count +
          swapd_p^.swap_stats [jmc$iss_executing]
          [jmc$iss_swapped_no_io].count - previous_swap_data^.swap_stats
          [jmc$iss_executing] [jmc$iss_swapped_no_io].count +
          swapd_p^.swap_stats [jmc$iss_executing]
          [jmc$iss_flush_am_pages].count - previous_swap_data^.swap_stats
          [jmc$iss_executing] [jmc$iss_flush_am_pages].count;
    pmp$binary_to_ascii_fit (swap_outs, 10, 5, 5, str [8] (71, 5));

    jobs_in_long_wait_count := jsv$ijl_swap_queue_list [jsc$isqi_swapped_io_not_init].count;
    pmp$binary_to_ascii_fit (jobs_in_long_wait_count, 10, 5, 5, str [3] (71, 5));
    jobs_in_long_wait_cant_init_io := jsv$ijl_swap_queue_list [jsc$isqi_swapped_io_cannot_init].count;
    pmp$binary_to_ascii_fit (jobs_in_long_wait_cant_init_io, 10, 5, 5, str [4] (71, 5));
    swap_resident_job_count := jsv$ijl_swap_queue_list [jsc$isqi_swapped_io_completed].count;
    pmp$binary_to_ascii_fit (swap_resident_job_count, 10, 5, 5, str [5] (71, 5));
    swapped_jobs_count := jsv$ijl_swap_queue_list [jsc$isqi_swapped_out].count;
    pmp$binary_to_ascii_fit (swapped_jobs_count, 10, 5, 5, str [6] (71, 5));

{ Display I/O Priority information

    preads := iov$read_priority_invoked;
    pmp$binary_to_ascii_fit (preads, 10,10,10, str [20] (14,10));
    ptotal := iov$total_queue_calls;
    pmp$binary_to_ascii_fit (ptotal, 10,10,10, str [20] (39,10));
    pactual := iov$total_queue_calls - iov$actual_requests_resolved;
    pmp$binary_to_ascii_fit (pactual, 10,10,10, str [20] (64,10));

    previous_pf_data^ := pfd_p^;
    previous_server_pf_data^ := server_pfd_p^;
    previous_total_reads := total_reads;
    previous_total_writes := total_writes;
    previous_swap_data^ := swapd_p^;

{ Display the results.

    IF wid <> 0 THEN
      dpp$clear_window (wid, status);
      FOR i := 1 TO max_lines DO
        dpp$put_next_line (wid, str [i], status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      FOREND
    ELSE
      FOR i := 1 TO max_lines DO
        clp$put_display (display_control, str [i], clc$trim, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      FOREND;
      clp$close_display (display_control, status);
      osp$disestablish_cond_handler;
    IFEND;

  PROCEND ofp$general_statistics_display;
?? OLDTITLE ??
?? OLDTITLE ??
MODEND ofm$general_statistics_display
