?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Operating System : fetch statistical data' ??
MODULE osm$fetch_statistical_data;


{
{  PURPOSE:
{     This module is used as an interface between modules in XLJ2DD
{     and those that can't be called from above ring 3.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$task_shared
*copyc cle$not_supported
*copyc cle$work_area_overflow
*copyc jme$must_be_system_job
*copyc ofe$error_codes
*copyc cmt$element_descriptor
*copyc iot$disk_usage
*copyc jmt$active_job_list
*copyc jmt$dispatching_priority
*copyc jmt$ijl_ordinal
*copyc jmt$job_class
*copyc jmt$job_scheduler_statistics
*copyc jmt$rb_service_class_statistics
*copyc jmt$service_class_index
*copyc ost$170_os_type
*copyc ost$data_id
*copyc ost$hardware_subranges
*copyc ost$i_page_fault_stats
?? POP ??
*copyc avp$configuration_administrator
*copyc avp$system_displays
*copyc cmp$get_element_information
*copyc cmp$pc_get_logical_unit
*copyc dmp$calculate_remaining_space
*copyc jmp$get_ijle_p
*copyc jmp$get_job_counts
*copyc jmp$system_job
*copyc jsp$reset_maximum_time
*copyc mmp$convert_aging_statistics
*copyc mmp$get_page_q_counts
*copyc osp$get_rvsn_by_lun
*copyc osp$set_status_abnormal
*copyc pmp$get_170_os_type
*copyc syp$fetch_system_constant
*copyc syp$get_system_constant_values
*copyc syp$reset_maximum_time
*copyc syp$restore_system_constants
*copyc syp$save_system_constants
*copyc syp$store_system_constant
*copyc tmp$fetch_job_statistics
*copyc cmv$logical_unit_table
*copyc iov$disk_pp_usage_p
*copyc iov$disk_unit_usage_p
*copyc jmv$ijl_p
*copyc jmv$job_class_table_p
*copyc jmv$job_counts
*copyc jmv$job_sched_serv_class_stats
*copyc jmv$job_scheduler_statistics
*copyc jmv$max_ajl_ordinal_in_use
*copyc jmv$max_service_class_in_use
*copyc jmv$maximum_job_class_in_use
*copyc jmv$service_classes
*copyc jmv$swapin_candidate_queue
*copyc jsv$enable_swap_file_statistics
*copyc jsv$ijl_swap_queue_list
*copyc jsv$swap_file_page_count
*copyc jsv$swap_file_statistics
*copyc jsv$swap_state_statistics
*copyc mmv$aging_statistics
*copyc mmv$df_read_server_pf_stats
*copyc mmv$paging_statistics
*copyc mmv$pf_statistics
*copyc mtv$cst0
*copyc mtv$request_table
*copyc mtv$total_nos_cpu_time
*copyc osv$cpus_physically_configured
*copyc osv$task_shared_heap
*copyc syv$nos_system_time
*copyc tmv$cpu_execution_statistics
*copyc i#call_monitor
*copyc i#move
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??


  VAR
    c170_os_type_known: [STATIC] boolean := FALSE,
    c170_os_type: [STATIC] ost$170_os_type := osc$ot7_none,
    i_last_page_stats_p: [STATIC, oss$task_shared] ^ost$i_page_fault_stats := NIL,
    i_last_server_page_stats_p: [STATIC, oss$task_shared] ^ost$i_page_fault_stats := NIL,
    last_aging_stats_p: [STATIC, oss$task_shared] ^ost$aging_stats := NIL,
    last_cpu_stats_p: [STATIC, oss$task_shared] ^ost$cpu_stats := NIL,
    last_job_stats_p: [STATIC, oss$task_shared] ^ost$job_stats := NIL,
    last_mtr_stats_p: [STATIC, oss$task_shared] ^ost$mtr_stats := NIL,
    last_page_stats_p: [STATIC, oss$task_shared] ^ost$page_fault_stats := NIL,
    last_server_page_stats_p: [STATIC, oss$task_shared] ^ost$page_fault_stats := NIL,
    last_paging_stats_p: [STATIC, oss$task_shared] ^ost$paging_stats := NIL,
    last_pio_pp_stats_p: [STATIC, oss$task_shared] ^ost$disk_pp_stats := NIL,
    last_pio_unit_stats_p: [STATIC, oss$task_shared] ^ost$disk_unit_stats := NIL,
    last_sched_stats_p: [STATIC, oss$task_shared] ^ost$sched_stats := NIL,
    last_swap_stats_p: [STATIC, oss$task_shared] ^ost$swap_stats := NIL,
    last_swap_file_stats_p: [STATIC, oss$task_shared] ^ost$swap_file_stats := NIL;

?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_AGING_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_aging_stats
    (    incremental: boolean;
     VAR user_aging_stats: ost$aging_stats;
     VAR status: ost$status);

    VAR
      local_aging_stats: ost$aging_stats,
      queue: mmt$page_frame_queue_id;

    status.normal := TRUE;
    local_aging_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;

{We need to convert the mmt$i_aging_statistics into the old mmt$aging_statistics
    mmp$convert_aging_statistics (mmv$aging_statistics, local_aging_stats.aging_stats);

    user_aging_stats := local_aging_stats;
    IF incremental AND (last_aging_stats_p <> NIL) THEN
      user_aging_stats.time := user_aging_stats.time - last_aging_stats_p^.time;
      user_aging_stats.aging_stats.force_aggressive_aging :=
            user_aging_stats.aging_stats.force_aggressive_aging -
            last_aging_stats_p^.aging_stats.force_aggressive_aging;
      user_aging_stats.aging_stats.aggressive_age_shared_queue :=
            user_aging_stats.aging_stats.aggressive_age_shared_queue -
            last_aging_stats_p^.aging_stats.aggressive_age_shared_queue;
      user_aging_stats.aging_stats.aggressive_age_job_queues :=
            user_aging_stats.aging_stats.aggressive_age_job_queues -
            last_aging_stats_p^.aging_stats.aggressive_age_job_queues;
      user_aging_stats.aging_stats.aggressive_aging_failed :=
            user_aging_stats.aging_stats.aggressive_aging_failed -
            last_aging_stats_p^.aging_stats.aggressive_aging_failed;
      user_aging_stats.aging_stats.age_cp_bound_job := user_aging_stats.aging_stats.age_cp_bound_job -
            last_aging_stats_p^.aging_stats.age_cp_bound_job;
      user_aging_stats.aging_stats.remove_unmodified_page_from_ws :=
            user_aging_stats.aging_stats.remove_unmodified_page_from_ws -
            last_aging_stats_p^.aging_stats.remove_unmodified_page_from_ws;
      user_aging_stats.aging_stats.remove_modified_page_from_ws :=
            user_aging_stats.aging_stats.remove_modified_page_from_ws -
            last_aging_stats_p^.aging_stats.remove_modified_page_from_ws;
      user_aging_stats.aging_stats.page_written_to_disk :=
            user_aging_stats.aging_stats.page_written_to_disk -
            last_aging_stats_p^.aging_stats.page_written_to_disk;
      user_aging_stats.aging_stats.multiple_pages_written_to_disk :=
            user_aging_stats.aging_stats.multiple_pages_written_to_disk -
            last_aging_stats_p^.aging_stats.multiple_pages_written_to_disk;
      user_aging_stats.aging_stats.calls_to_age_jws := user_aging_stats.aging_stats.calls_to_age_jws -
            last_aging_stats_p^.aging_stats.calls_to_age_jws;
      user_aging_stats.aging_stats.age_exceeds_aif := user_aging_stats.aging_stats.age_exceeds_aif -
            last_aging_stats_p^.aging_stats.age_exceeds_aif;
      user_aging_stats.aging_stats.age_exceeds_aic := user_aging_stats.aging_stats.age_exceeds_aic -
            last_aging_stats_p^.aging_stats.age_exceeds_aic;
      user_aging_stats.aging_stats.age_unused_page_in_shared_queue :=
            user_aging_stats.aging_stats.age_unused_page_in_shared_queue -
            last_aging_stats_p^.aging_stats.age_unused_page_in_shared_queue;
      user_aging_stats.aging_stats.write_aged_out_page := user_aging_stats.aging_stats.write_aged_out_page -
            last_aging_stats_p^.aging_stats.write_aged_out_page;
      user_aging_stats.aging_stats.write_forced_out_page :=
            user_aging_stats.aging_stats.write_forced_out_page -
            last_aging_stats_p^.aging_stats.write_forced_out_page;
      user_aging_stats.aging_stats.write_pt_full_page := user_aging_stats.aging_stats.write_pt_full_page -
            last_aging_stats_p^.aging_stats.write_pt_full_page;
      user_aging_stats.aging_stats.write_avail_mod_page :=
            user_aging_stats.aging_stats.write_avail_mod_page -
            last_aging_stats_p^.aging_stats.write_avail_mod_page;
      user_aging_stats.aging_stats.write_page_failed := user_aging_stats.aging_stats.write_page_failed -
            last_aging_stats_p^.aging_stats.write_page_failed;

      FOR queue := mmc$pq_shared_first TO mmc$pq_shared_last_sys DO
        user_aging_stats.aging_stats.age_sys_shared_queue [queue] :=
              user_aging_stats.aging_stats.age_sys_shared_queue [queue] -
              last_aging_stats_p^.aging_stats.age_sys_shared_queue [queue];
      FOREND;
    IFEND;
    IF incremental THEN
      IF last_aging_stats_p = NIL THEN
        ALLOCATE last_aging_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_aging_stats_p^ := local_aging_stats;
    IFEND;
  PROCEND osp$get_aging_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_CPU_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_cpu_stats
    (    incremental: boolean;
     VAR user_cpu_stats: ost$cpu_stats;
     VAR status: ost$status);

    VAR
      dp: jmt$dispatching_priority,
      frc: ost$free_running_clock,
      i: integer,
      idle_increment: integer,
      local_cpu_stats: ost$cpu_stats;


    frc := #FREE_RUNNING_CLOCK (0);
    local_cpu_stats.time := frc - syv$nos_system_time.corresponding_frc;

    IF NOT c170_os_type_known THEN
      pmp$get_170_os_type (c170_os_type, status);
      c170_os_type_known := TRUE;
    IFEND;

    status.normal := TRUE;
    IF c170_os_type <> osc$ot7_none THEN
      local_cpu_stats.cpu_stats.nos_stats.nos_on := TRUE;
      local_cpu_stats.cpu_stats.nos_stats.nos_time := mtv$total_nos_cpu_time.total;
      local_cpu_stats.cpu_stats.nos_stats.nos_time_ve_idle := mtv$total_nos_cpu_time.ve_idle;
    ELSE
      local_cpu_stats.cpu_stats.nos_stats.nos_on := FALSE;
    IFEND;

    FOR i := 0 TO (osv$cpus_physically_configured - 1) DO
      IF mtv$cst0 [i].processor_state = cmc$on THEN
        local_cpu_stats.cpu_stats.idle_stats [i] := mtv$cst0 [i].cpu_idle_statistics;
        local_cpu_stats.cpu_stats.processor_defined [i] := TRUE;

{ While it is clear that this code is executing in a processor, another CPU may be idle.  If so the idle
{ time must be updated to reflect the current time (i.e. an idle CPU should have a total idle time equal
{ to the idle time plus the time between the start of the current idle state and the current time.

        IF local_cpu_stats.cpu_stats.idle_stats [i].idle_type <> osc$not_idle THEN
          idle_increment := frc - local_cpu_stats.cpu_stats.idle_stats [i].idle_start_time;
          IF idle_increment > 0 THEN { should never be negative but lets be sure
            IF local_cpu_stats.cpu_stats.idle_stats [i].idle_type = osc$idle_with_io_active THEN
              local_cpu_stats.cpu_stats.idle_stats [i].idle_io_active :=
                    idle_increment + local_cpu_stats.cpu_stats.idle_stats [i].idle_io_active;
            ELSEIF local_cpu_stats.cpu_stats.idle_stats [i].idle_type = osc$idle_no_io_active THEN
              local_cpu_stats.cpu_stats.idle_stats [i].idle_no_io_active :=
                    idle_increment + local_cpu_stats.cpu_stats.idle_stats [i].idle_no_io_active;
            IFEND;
          IFEND;
        IFEND;
      ELSE
        local_cpu_stats.cpu_stats.processor_defined [i] := FALSE;
      IFEND;
    FOREND;
    local_cpu_stats.cpu_stats.cpu_count := i;
    local_cpu_stats.cpu_stats.cpu_execution_stats := tmv$cpu_execution_statistics;
    user_cpu_stats := local_cpu_stats;
    IF incremental AND (last_cpu_stats_p <> NIL) THEN
      user_cpu_stats.time := user_cpu_stats.time - last_cpu_stats_p^.time;
      FOR i := 0 TO (osv$cpus_physically_configured - 1) DO
        IF user_cpu_stats.cpu_stats.processor_defined [i] THEN
          user_cpu_stats.cpu_stats.idle_stats [i].idle_no_io_active := user_cpu_stats.cpu_stats.
                idle_stats [i].idle_no_io_active - last_cpu_stats_p^.cpu_stats.idle_stats [i].
                idle_no_io_active;
          user_cpu_stats.cpu_stats.idle_stats [i].idle_io_active :=
                user_cpu_stats.cpu_stats.idle_stats [i].idle_io_active -
                last_cpu_stats_p^.cpu_stats.idle_stats [i].idle_io_active;
          user_cpu_stats.cpu_stats.idle_stats [i].idle_count :=
                user_cpu_stats.cpu_stats.idle_stats [i].idle_count - last_cpu_stats_p^.cpu_stats.
                idle_stats [i].idle_count;
        IFEND;
      FOREND;

      IF user_cpu_stats.cpu_stats.nos_stats.nos_on THEN
        user_cpu_stats.cpu_stats.nos_stats.nos_time := user_cpu_stats.cpu_stats.nos_stats.nos_time -
              last_cpu_stats_p^.cpu_stats.nos_stats.nos_time;
        user_cpu_stats.cpu_stats.nos_stats.nos_time_ve_idle :=
              user_cpu_stats.cpu_stats.nos_stats.nos_time_ve_idle -
              last_cpu_stats_p^.cpu_stats.nos_stats.nos_time_ve_idle;
      IFEND;

      FOR dp := jmc$min_dispatching_priority TO jmc$max_dispatching_priority DO
        user_cpu_stats.cpu_stats.cpu_execution_stats [dp].time_spent_in_job_mode :=
              user_cpu_stats.cpu_stats.cpu_execution_stats [dp].time_spent_in_job_mode -
              last_cpu_stats_p^.cpu_stats.cpu_execution_stats [dp].time_spent_in_job_mode;
        user_cpu_stats.cpu_stats.cpu_execution_stats [dp].time_spent_in_mtr_mode :=
              user_cpu_stats.cpu_stats.cpu_execution_stats [dp].time_spent_in_mtr_mode -
              last_cpu_stats_p^.cpu_stats.cpu_execution_stats [dp].time_spent_in_mtr_mode;
      FOREND;
    IFEND;
    IF incremental THEN
      IF last_cpu_stats_p = NIL THEN
        ALLOCATE last_cpu_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_cpu_stats_p^ := local_cpu_stats;
    IFEND;
  PROCEND osp$get_cpu_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_SWAP_FILE_STATISTICS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_swap_file_statistics
    (    incremental: boolean;
     VAR swap_file_stats_enabled: boolean;
     VAR user_swap_file_stats: ost$swap_file_stats;
     VAR status: ost$status);

    VAR
      local_swap_file_stats: ost$swap_file_stats,
      segnum: ost$segment;

    status.normal := TRUE;
    IF jsv$enable_swap_file_statistics THEN
      swap_file_stats_enabled := TRUE;
    ELSE
      swap_file_stats_enabled := FALSE;
      RETURN;
    IFEND;

    local_swap_file_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    local_swap_file_stats.swap_file_stats := jsv$swap_file_statistics;
    user_swap_file_stats := local_swap_file_stats;

    IF incremental AND (last_swap_file_stats_p <> NIL) THEN
      user_swap_file_stats.time := user_swap_file_stats.time - last_swap_file_stats_p^.time;
      FOR segnum := 1 TO 40(16) DO
        user_swap_file_stats.swap_file_stats.total_pages_per_segment [segnum] :=
              user_swap_file_stats.swap_file_stats.total_pages_per_segment [segnum] -
              last_swap_file_stats_p^.swap_file_stats.total_pages_per_segment [segnum];
      FOREND;
      user_swap_file_stats.swap_file_stats.total_swaps := user_swap_file_stats.swap_file_stats.total_swaps -
            last_swap_file_stats_p^.swap_file_stats.total_swaps;
    IFEND;

    IF incremental THEN
      IF last_swap_file_stats_p = NIL THEN
        ALLOCATE last_swap_file_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_swap_file_stats_p^ := local_swap_file_stats;
    IFEND;
  PROCEND osp$get_swap_file_statistics;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_DISK_SPACE_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_disk_space_stats
    (VAR user_disk_space_stats: ost$disk_space_stats);

    VAR
      available_space: integer,
      element: cmt$element_descriptor,
      element_definition_p: ^cmt$element_definition,
      element_information: array [1 .. 1] of cmt$element_info_item,
      local_status: ost$status,
      logical_unit: iot$logical_unit,
      unit_found_count: integer;

    local_status.normal := TRUE;
    PUSH element_definition_p;
    unit_found_count := 0;

    FOR logical_unit := LOWERBOUND (cmv$logical_unit_table^) TO UPPERBOUND (cmv$logical_unit_table^) DO
      cmp$pc_get_logical_unit (logical_unit, element_definition_p, local_status);
      IF (local_status.normal AND (element_definition_p^.element_type = cmc$storage_device_element)) THEN
        element.element_type := cmc$storage_device_element;
        element.peripheral_descriptor.use_logical_identification := TRUE;
        element.peripheral_descriptor.element_name := element_definition_p^.element_name;
        element_information [1].selector := cmc$recorded_vsn;
        cmp$get_element_information (element, element_information, local_status);
        IF (element_information [1].item_returned AND local_status.normal) THEN
          dmp$calculate_remaining_space (logical_unit, available_space, local_status);
          IF local_status.normal THEN
            unit_found_count := unit_found_count + 1;
            IF unit_found_count > UPPERBOUND (user_disk_space_stats.disk_space) THEN
              RETURN;
            IFEND;
            user_disk_space_stats.disk_space [unit_found_count].recorded_vsn :=
                  element_information [1].recorded_vsn;
            user_disk_space_stats.disk_space [unit_found_count].available_space := available_space;
            user_disk_space_stats.disk_space [unit_found_count].unit_used := TRUE;
          IFEND;
        IFEND;
      IFEND;
    FOREND;

  PROCEND osp$get_disk_space_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_JM_MM_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_jm_mm_stats
    (    incremental: boolean;
     VAR user_jm_mm_stats: ost$jm_mm_stats;
     VAR status: ost$status);

    VAR
      from_state: jmt$ijl_swap_status,
      to_state: jmt$ijl_swap_status,
      local_jm_mm_stats: ost$jm_mm_stats;

    status.normal := TRUE;
    local_jm_mm_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    get_jm_mm_statistics (local_jm_mm_stats.jm_mm_stats, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    user_jm_mm_stats := local_jm_mm_stats;

{
{   Do not save incremental data.
{

  PROCEND osp$get_jm_mm_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_JOB_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_job_stats
    (    incremental: boolean;
     VAR user_job_stats: ost$job_stats;
     VAR status: ost$status);

    VAR
      local_job_stats: ost$job_stats;

    status.normal := TRUE;
    local_job_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    tmp$fetch_job_statistics (local_job_stats.job_data, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    user_job_stats := local_job_stats;
    IF incremental AND (last_job_stats_p <> NIL) THEN
      user_job_stats.time := user_job_stats.time - last_job_stats_p^.time;
      user_job_stats.job_data.cp_time.time_spent_in_job_mode :=
            user_job_stats.job_data.cp_time.time_spent_in_job_mode -
            last_job_stats_p^.job_data.cp_time.time_spent_in_job_mode;
      user_job_stats.job_data.cp_time.time_spent_in_mtr_mode :=
            user_job_stats.job_data.cp_time.time_spent_in_mtr_mode -
            last_job_stats_p^.job_data.cp_time.time_spent_in_mtr_mode;
      user_job_stats.job_data.paging_statistics.page_in_count :=
            user_job_stats.job_data.paging_statistics.page_in_count -
            last_job_stats_p^.job_data.paging_statistics.page_in_count;
      user_job_stats.job_data.paging_statistics.pages_reclaimed_from_queue :=
            user_job_stats.job_data.paging_statistics.pages_reclaimed_from_queue -
            last_job_stats_p^.job_data.paging_statistics.pages_reclaimed_from_queue;
      user_job_stats.job_data.paging_statistics.new_pages_assigned :=
            user_job_stats.job_data.paging_statistics.new_pages_assigned -
            last_job_stats_p^.job_data.paging_statistics.new_pages_assigned;
      user_job_stats.job_data.paging_statistics.pages_from_server :=
            user_job_stats.job_data.paging_statistics.pages_from_server -
            last_job_stats_p^.job_data.paging_statistics.pages_from_server;
      user_job_stats.job_data.paging_statistics.page_fault_count :=
            user_job_stats.job_data.paging_statistics.page_fault_count -
            last_job_stats_p^.job_data.paging_statistics.page_fault_count;
      user_job_stats.job_data.paging_statistics.working_set_max_used :=
            user_job_stats.job_data.paging_statistics.incremental_max_ws;
    IFEND;
    IF incremental THEN
      IF last_job_stats_p = NIL THEN
        ALLOCATE last_job_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_job_stats_p^ := local_job_stats;
    IFEND;
  PROCEND osp$get_job_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_MTR_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_mtr_stats
    (    incremental: boolean;
     VAR user_mtr_stats: ost$mtr_stats;
     VAR status: ost$status);

    VAR
      i: integer,
      local_mtr_stats: ost$mtr_stats;

    status.normal := TRUE;
    local_mtr_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    local_mtr_stats.mtr_reqs := mtv$request_table;
    user_mtr_stats := local_mtr_stats;
    IF incremental AND (last_mtr_stats_p <> NIL) THEN
      user_mtr_stats.time := user_mtr_stats.time - last_mtr_stats_p^.time;
      FOR i := LOWERBOUND (mtt$request_table) TO UPPERBOUND (mtt$request_table) DO
        user_mtr_stats.mtr_reqs [i].count := user_mtr_stats.mtr_reqs [i].
              count - last_mtr_stats_p^.mtr_reqs [i].count;
        user_mtr_stats.mtr_reqs [i].total_cpu_time := user_mtr_stats.mtr_reqs [i].total_cpu_time -
              last_mtr_stats_p^.mtr_reqs [i].total_cpu_time;
      FOREND;
    IFEND;
    IF incremental THEN
      IF last_mtr_stats_p = NIL THEN
        ALLOCATE last_mtr_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_mtr_stats_p^ := local_mtr_stats;
    IFEND;
  PROCEND osp$get_mtr_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_PAGE_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_page_stats
    (    incremental: boolean;
     VAR user_page_stats: ost$page_fault_stats;
     VAR user_server_page_stats: ost$page_fault_stats;
     VAR status: ost$status);

    VAR
      i: integer,
      local_page_stats: ost$page_fault_stats,
      local_server_page_stats: ost$page_fault_stats;

    status.normal := TRUE;
    local_page_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    i#move (^mmv$pf_statistics, ^local_page_stats.pf_stats, #size(local_page_stats.pf_stats));
    user_page_stats := local_page_stats;
    local_server_page_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    i#move (^mmv$df_read_server_pf_stats, ^local_server_page_stats.pf_stats,
          #size(local_page_stats.pf_stats));
    user_server_page_stats := local_server_page_stats;
    IF incremental AND (last_page_stats_p <> NIL) AND (last_server_page_stats_p <> NIL) THEN
      user_page_stats.time := user_page_stats.time - last_page_stats_p^.time;
      user_server_page_stats.time := user_server_page_stats.time - last_server_page_stats_p^.time;
      FOR i := 1 TO UPPERBOUND (local_page_stats.pf_stats) DO
        user_page_stats.pf_stats [i] := user_page_stats.pf_stats [i] - last_page_stats_p^.pf_stats [i];
        user_server_page_stats.pf_stats [i] := user_server_page_stats.pf_stats [i] -
              last_server_page_stats_p^.pf_stats [i];
      FOREND;
    IFEND;
    IF incremental THEN
      IF last_page_stats_p = NIL THEN
        ALLOCATE last_page_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_page_stats_p^ := local_page_stats;
      IF last_server_page_stats_p = NIL THEN
        ALLOCATE last_server_page_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_server_page_stats_p^ := local_server_page_stats;
    IFEND;
  PROCEND osp$get_page_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$I_GET_PAGE_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$i_get_page_stats
    (    incremental: boolean;
     VAR user_page_stats: ost$i_page_fault_stats;
     VAR user_server_page_stats: ost$i_page_fault_stats;
     VAR status: ost$status);

    VAR
      i: integer,
      local_page_stats: ost$i_page_fault_stats,
      local_server_page_stats: ost$i_page_fault_stats;

    status.normal := TRUE;
    local_page_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    local_page_stats.pf_stats := mmv$pf_statistics;
    user_page_stats := local_page_stats;
    local_server_page_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    local_server_page_stats.pf_stats := mmv$df_read_server_pf_stats;
    user_server_page_stats := local_server_page_stats;
    IF incremental AND (i_last_page_stats_p <> NIL) AND (i_last_server_page_stats_p <> NIL) THEN
      user_page_stats.time := user_page_stats.time - i_last_page_stats_p^.time;
      user_server_page_stats.time := user_server_page_stats.time - i_last_server_page_stats_p^.time;
      FOR i := 1 TO UPPERBOUND (mmv$pf_statistics) DO
        user_page_stats.pf_stats [i] := user_page_stats.pf_stats [i] - i_last_page_stats_p^.pf_stats [i];
        user_server_page_stats.pf_stats [i] := user_server_page_stats.pf_stats [i] -
              i_last_server_page_stats_p^.pf_stats [i];
      FOREND;
    IFEND;
    IF incremental THEN
      IF i_last_page_stats_p = NIL THEN
        ALLOCATE i_last_page_stats_p IN osv$task_shared_heap^;
      IFEND;
      i_last_page_stats_p^ := local_page_stats;
      IF i_last_server_page_stats_p = NIL THEN
        ALLOCATE i_last_server_page_stats_p IN osv$task_shared_heap^;
      IFEND;
      i_last_server_page_stats_p^ := local_server_page_stats;
    IFEND;

  PROCEND osp$i_get_page_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_PAGING_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_paging_stats
    (    incremental: boolean;
     VAR paging_stats: ost$paging_stats;
     VAR status: ost$status);

    VAR
      i: integer,
      local_paging_stats: ost$paging_stats;

    status.normal := TRUE;
    local_paging_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    local_paging_stats.p_stats := mmv$paging_statistics;
    paging_stats := local_paging_stats;
    IF incremental AND (last_paging_stats_p <> NIL) THEN
      paging_stats.time := paging_stats.time - last_paging_stats_p^.time;
      paging_stats.p_stats.pf_pages.disk := paging_stats.p_stats.pf_pages.disk -
            last_paging_stats_p^.p_stats.pf_pages.disk;
      paging_stats.p_stats.pf_pages.reclaim := paging_stats.p_stats.pf_pages.reclaim -
            last_paging_stats_p^.p_stats.pf_pages.reclaim;
      paging_stats.p_stats.pf_pages.new := paging_stats.p_stats.pf_pages.new -
            last_paging_stats_p^.p_stats.pf_pages.new;
      paging_stats.p_stats.pf_pages.server := paging_stats.p_stats.pf_pages.server -
            last_paging_stats_p^.p_stats.pf_pages.server;
      paging_stats.p_stats.ps_pages.disk := paging_stats.p_stats.ps_pages.disk -
            last_paging_stats_p^.p_stats.ps_pages.disk;
      paging_stats.p_stats.ps_pages.reclaim := paging_stats.p_stats.ps_pages.reclaim -
            last_paging_stats_p^.p_stats.ps_pages.reclaim;
      paging_stats.p_stats.ps_pages.new := paging_stats.p_stats.ps_pages.new -
            last_paging_stats_p^.p_stats.ps_pages.new;
      paging_stats.p_stats.ps_pages.server := paging_stats.p_stats.ps_pages.server -
            last_paging_stats_p^.p_stats.ps_pages.server;
      paging_stats.p_stats.ai_pages.disk := paging_stats.p_stats.ai_pages.disk -
            last_paging_stats_p^.p_stats.ai_pages.disk;
      paging_stats.p_stats.ai_pages.reclaim := paging_stats.p_stats.ai_pages.reclaim -
            last_paging_stats_p^.p_stats.ai_pages.reclaim;
      paging_stats.p_stats.ai_pages.new := paging_stats.p_stats.ai_pages.new -
            last_paging_stats_p^.p_stats.ai_pages.new;
      paging_stats.p_stats.ai_pages.server := paging_stats.p_stats.ai_pages.server -
            last_paging_stats_p^.p_stats.ai_pages.server;
      paging_stats.p_stats.page_streaming.initiated := paging_stats.p_stats.page_streaming.initiated -
            last_paging_stats_p^.p_stats.page_streaming.initiated;
      paging_stats.p_stats.page_streaming.prestream_only :=
            paging_stats.p_stats.page_streaming.prestream_only -
            last_paging_stats_p^.p_stats.page_streaming.prestream_only;
      paging_stats.p_stats.page_streaming.terminated := paging_stats.p_stats.page_streaming.terminated -
            last_paging_stats_p^.p_stats.page_streaming.terminated;
      paging_stats.p_stats.page_streaming.pages_prestream :=
            paging_stats.p_stats.page_streaming.pages_prestream -
            last_paging_stats_p^.p_stats.page_streaming.pages_prestream;
      paging_stats.p_stats.page_streaming.pages_streaming :=
            paging_stats.p_stats.page_streaming.pages_streaming -
            last_paging_stats_p^.p_stats.page_streaming.pages_streaming;
      paging_stats.p_stats.page_streaming.task_slow := paging_stats.p_stats.page_streaming.task_slow -
            last_paging_stats_p^.p_stats.page_streaming.task_slow;
      paging_stats.p_stats.page_streaming.page_faults_tu :=
            paging_stats.p_stats.page_streaming.page_faults_tu -
            last_paging_stats_p^.p_stats.page_streaming.page_faults_tu;
      paging_stats.p_stats.page_streaming.pages_freed_behind :=
            paging_stats.p_stats.page_streaming.pages_freed_behind -
            last_paging_stats_p^.p_stats.page_streaming.pages_freed_behind;
      paging_stats.p_stats.page_streaming.random_faults :=
            paging_stats.p_stats.page_streaming.random_faults -
            last_paging_stats_p^.p_stats.page_streaming.random_faults;
    IFEND;
    IF incremental THEN
      IF last_paging_stats_p = NIL THEN
        ALLOCATE last_paging_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_paging_stats_p^ := local_paging_stats;
    IFEND;
  PROCEND osp$get_paging_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_PIO_PP_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_pio_pp_stats
    (    incremental: boolean;
     VAR user_pio_pp_stats: ost$disk_pp_stats;
     VAR status: ost$status);

    VAR
      index: integer,
      pp_found_index: integer,
      port_index: integer,
      equip_index: integer,
      pp_count: integer,
      unit_count: integer,
      local_pio_pp_stats_p: ^ost$disk_pp_stats;

    status.normal := TRUE;
    osp$get_pp_unit_count (pp_count, unit_count, status);
    IF (UPPERBOUND (user_pio_pp_stats.disk_pp_stats) <> pp_count) OR (pp_count = 0) THEN
      status.normal := FALSE;
      RETURN;
    IFEND;
    PUSH local_pio_pp_stats_p: [1 .. pp_count];
    pp_found_index := 0;
    local_pio_pp_stats_p^.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    FOR index := 1 TO UPPERBOUND (iov$disk_pp_usage_p^) DO
      IF iov$disk_pp_usage_p^ [index] <> NIL THEN
        pp_found_index := pp_found_index + 1;
        local_pio_pp_stats_p^.disk_pp_stats [pp_found_index] := iov$disk_pp_usage_p^ [index]^;
      IFEND;
    FOREND;
    user_pio_pp_stats := local_pio_pp_stats_p^;
    IF incremental AND (last_pio_pp_stats_p <> NIL) THEN
      user_pio_pp_stats.time := user_pio_pp_stats.time - last_pio_pp_stats_p^.time;
      FOR index := 1 TO pp_count DO
        user_pio_pp_stats.disk_pp_stats [index].computed_data_transfer_time :=
              user_pio_pp_stats.disk_pp_stats [index].computed_data_transfer_time -
              last_pio_pp_stats_p^.disk_pp_stats [index].computed_data_transfer_time;
        user_pio_pp_stats.disk_pp_stats [index].seek_and_latency_time := user_pio_pp_stats.
              disk_pp_stats [index].seek_and_latency_time - last_pio_pp_stats_p^.disk_pp_stats [index].
              seek_and_latency_time;
        user_pio_pp_stats.disk_pp_stats [index].streamed_req_count_read := user_pio_pp_stats.
              disk_pp_stats [index].streamed_req_count_read - last_pio_pp_stats_p^.disk_pp_stats [index].
              streamed_req_count_read;
        user_pio_pp_stats.disk_pp_stats [index].streamed_req_failed_count_read :=
              user_pio_pp_stats.disk_pp_stats [index].streamed_req_failed_count_read -
              last_pio_pp_stats_p^.disk_pp_stats [index].streamed_req_failed_count_read;
        user_pio_pp_stats.disk_pp_stats [index].streamed_req_count_write := user_pio_pp_stats.
              disk_pp_stats [index].streamed_req_count_write -
              last_pio_pp_stats_p^.disk_pp_stats [index].streamed_req_count_write;
        user_pio_pp_stats.disk_pp_stats [index].streamed_req_failed_count_write :=
              user_pio_pp_stats.disk_pp_stats [index].streamed_req_failed_count_write -
              last_pio_pp_stats_p^.disk_pp_stats [index].streamed_req_failed_count_write;
        FOR port_index := 0 TO 1 DO
          FOR equip_index := 0 TO 7 DO
            IF user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].path_used THEN
              user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].read_requests :=
                    user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    read_requests - last_pio_pp_stats_p^.disk_pp_stats [index].path_usage [port_index]
                    [equip_index].read_requests;
              user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].read_maus :=
                    user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].read_maus -
                    last_pio_pp_stats_p^.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    read_maus;
              user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].write_requests :=
                    user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    write_requests - last_pio_pp_stats_p^.disk_pp_stats [index].path_usage [port_index]
                    [equip_index].write_requests;
              user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    written_and_preset_maus := user_pio_pp_stats.disk_pp_stats [index].
                    path_usage [port_index] [equip_index].written_and_preset_maus -
                    last_pio_pp_stats_p^.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    written_and_preset_maus;
              user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    total_request_qtime := user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index]
                    [equip_index].total_request_qtime - last_pio_pp_stats_p^.disk_pp_stats [index].
                    path_usage [port_index] [equip_index].total_request_qtime;
              user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    intermediate_errors := user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index]
                    [equip_index].intermediate_errors - last_pio_pp_stats_p^.disk_pp_stats [index].
                    path_usage [port_index] [equip_index].intermediate_errors;
              user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    recovered_errors := user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index]
                    [equip_index].recovered_errors - last_pio_pp_stats_p^.disk_pp_stats [index].
                    path_usage [port_index] [equip_index].recovered_errors;
              user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index] [equip_index].
                    unrecovered_errors := user_pio_pp_stats.disk_pp_stats [index].path_usage [port_index]
                    [equip_index].unrecovered_errors - last_pio_pp_stats_p^.disk_pp_stats [index].
                    path_usage [port_index] [equip_index].unrecovered_errors;
            IFEND;
          FOREND;
        FOREND;
      FOREND;
    IFEND;
    IF incremental THEN
      IF last_pio_pp_stats_p = NIL THEN
        ALLOCATE last_pio_pp_stats_p: [1 .. pp_count] IN osv$task_shared_heap^;
      IFEND;
      last_pio_pp_stats_p^ := local_pio_pp_stats_p^;
    IFEND;
  PROCEND osp$get_pio_pp_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_PIO_UNIT_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_pio_unit_stats
    (    incremental: boolean;
     VAR user_pio_unit_stats: ost$disk_unit_stats;
     VAR status: ost$status);

    VAR
      index: integer,
      rvsn: rmt$recorded_vsn,
      entry_found: boolean,
      unit_count: integer,
      pp_count: integer,
      unit_found_index: integer,
      local_pio_unit_stats_p: ^ost$disk_unit_stats;

    status.normal := TRUE;
    osp$get_pp_unit_count (pp_count, unit_count, status);
    IF (UPPERBOUND (user_pio_unit_stats.disk_unit_stats) <> unit_count) OR (unit_count = 0) THEN
      status.normal := FALSE;
      RETURN;
    IFEND;
    PUSH local_pio_unit_stats_p: [1 .. unit_count];
    local_pio_unit_stats_p^.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    unit_found_index := 0;
    FOR index := 1 TO UPPERBOUND (iov$disk_unit_usage_p^) DO
      IF iov$disk_unit_usage_p^ [index] <> NIL THEN
        unit_found_index := unit_found_index + 1;
        local_pio_unit_stats_p^.disk_unit_stats [unit_found_index] := iov$disk_unit_usage_p^ [index]^;
        osp$get_rvsn_by_lun (index, rvsn, entry_found);
        IF entry_found THEN
          local_pio_unit_stats_p^.disk_unit_stats [unit_found_index].recorded_vsn := rvsn;
        ELSE
          local_pio_unit_stats_p^.disk_unit_stats [unit_found_index].recorded_vsn := '     ';
        IFEND;
      IFEND;
    FOREND;
    user_pio_unit_stats := local_pio_unit_stats_p^;
    IF incremental AND (last_pio_unit_stats_p <> NIL) THEN
      user_pio_unit_stats.time := user_pio_unit_stats.time - last_pio_unit_stats_p^.time;
      FOR index := 1 TO unit_count DO
        IF user_pio_unit_stats.disk_unit_stats [index].unit_used THEN
          user_pio_unit_stats.disk_unit_stats [index].read_requests := user_pio_unit_stats.
                disk_unit_stats [index].read_requests - last_pio_unit_stats_p^.disk_unit_stats [index].
                read_requests;
          user_pio_unit_stats.disk_unit_stats [index].read_qtime := user_pio_unit_stats.
                disk_unit_stats [index].read_qtime - last_pio_unit_stats_p^.disk_unit_stats [index].
                read_qtime;
          user_pio_unit_stats.disk_unit_stats [index].read_mau_count := user_pio_unit_stats.
                disk_unit_stats [index].read_mau_count - last_pio_unit_stats_p^.disk_unit_stats [index].
                read_mau_count;
          user_pio_unit_stats.disk_unit_stats [index].write_requests := user_pio_unit_stats.
                disk_unit_stats [index].write_requests - last_pio_unit_stats_p^.disk_unit_stats [index].
                write_requests;
          user_pio_unit_stats.disk_unit_stats [index].write_qtime := user_pio_unit_stats.
                disk_unit_stats [index].write_qtime - last_pio_unit_stats_p^.disk_unit_stats [index].
                write_qtime;
          user_pio_unit_stats.disk_unit_stats [index].write_data_mau_count :=
                user_pio_unit_stats.disk_unit_stats [index].write_data_mau_count -
                last_pio_unit_stats_p^.disk_unit_stats [index].write_data_mau_count;
          user_pio_unit_stats.disk_unit_stats [index].write_data_and_preset_maus :=
                user_pio_unit_stats.disk_unit_stats [index].write_data_and_preset_maus -
                last_pio_unit_stats_p^.disk_unit_stats [index].write_data_and_preset_maus;
          user_pio_unit_stats.disk_unit_stats [index].swap_in_requests :=
                user_pio_unit_stats.disk_unit_stats [index].swap_in_requests -
                last_pio_unit_stats_p^.disk_unit_stats [index].swap_in_requests;
          user_pio_unit_stats.disk_unit_stats [index].swap_in_qtime := user_pio_unit_stats.
                disk_unit_stats [index].swap_in_qtime - last_pio_unit_stats_p^.disk_unit_stats [index].
                swap_in_qtime;
          user_pio_unit_stats.disk_unit_stats [index].swap_in_mau_count :=
                user_pio_unit_stats.disk_unit_stats [index].swap_in_mau_count -
                last_pio_unit_stats_p^.disk_unit_stats [index].swap_in_mau_count;
          user_pio_unit_stats.disk_unit_stats [index].swap_out_requests :=
                user_pio_unit_stats.disk_unit_stats [index].swap_out_requests -
                last_pio_unit_stats_p^.disk_unit_stats [index].swap_out_requests;
          user_pio_unit_stats.disk_unit_stats [index].swap_out_qtime := user_pio_unit_stats.
                disk_unit_stats [index].swap_out_qtime - last_pio_unit_stats_p^.disk_unit_stats [index].
                swap_out_qtime;
          user_pio_unit_stats.disk_unit_stats [index].swap_out_data_mau_count :=
                user_pio_unit_stats.disk_unit_stats [index].swap_out_data_mau_count -
                last_pio_unit_stats_p^.disk_unit_stats [index].swap_out_data_mau_count;
          user_pio_unit_stats.disk_unit_stats [index].swap_out_data_and_preset_maus :=
                user_pio_unit_stats.disk_unit_stats [index].swap_out_data_and_preset_maus -
                last_pio_unit_stats_p^.disk_unit_stats [index].swap_out_data_and_preset_maus;
          user_pio_unit_stats.disk_unit_stats [index].streamed_req_count_read :=
                user_pio_unit_stats.disk_unit_stats [index].streamed_req_count_read -
                last_pio_unit_stats_p^.disk_unit_stats [index].streamed_req_count_read;
          user_pio_unit_stats.disk_unit_stats [index].streamed_req_failed_count_read :=
                user_pio_unit_stats.disk_unit_stats [index].streamed_req_failed_count_read -
                last_pio_unit_stats_p^.disk_unit_stats [index].streamed_req_failed_count_read;
          user_pio_unit_stats.disk_unit_stats [index].streamed_req_count_write :=
                user_pio_unit_stats.disk_unit_stats [index].streamed_req_count_write -
                last_pio_unit_stats_p^.disk_unit_stats [index].streamed_req_count_write;
          user_pio_unit_stats.disk_unit_stats [index].streamed_req_failed_count_write :=
                user_pio_unit_stats.disk_unit_stats [index].streamed_req_failed_count_write -
                last_pio_unit_stats_p^.disk_unit_stats [index].streamed_req_failed_count_write;
          user_pio_unit_stats.disk_unit_stats [index].requests_causing_skipped_cyl :=
                user_pio_unit_stats.disk_unit_stats [index].requests_causing_skipped_cyl -
                last_pio_unit_stats_p^.disk_unit_stats [index].requests_causing_skipped_cyl;
          user_pio_unit_stats.disk_unit_stats [index].total_cylinders_skipped :=
                user_pio_unit_stats.disk_unit_stats [index].total_cylinders_skipped -
                last_pio_unit_stats_p^.disk_unit_stats [index].total_cylinders_skipped;
          user_pio_unit_stats.disk_unit_stats [index].intermediate_errors :=
                user_pio_unit_stats.disk_unit_stats [index].intermediate_errors -
                last_pio_unit_stats_p^.disk_unit_stats [index].intermediate_errors;
          user_pio_unit_stats.disk_unit_stats [index].recovered_errors :=
                user_pio_unit_stats.disk_unit_stats [index].recovered_errors -
                last_pio_unit_stats_p^.disk_unit_stats [index].recovered_errors;
          user_pio_unit_stats.disk_unit_stats [index].unrecovered_errors :=
                user_pio_unit_stats.disk_unit_stats [index].unrecovered_errors -
                last_pio_unit_stats_p^.disk_unit_stats [index].unrecovered_errors;
        IFEND;
      FOREND;
    IFEND;
    IF incremental THEN
      IF last_pio_unit_stats_p = NIL THEN
        ALLOCATE last_pio_unit_stats_p: [1 .. unit_count] IN osv$task_shared_heap^;
      IFEND;
      last_pio_unit_stats_p^ := local_pio_unit_stats_p^;
    IFEND;
  PROCEND osp$get_pio_unit_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_SCHED_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_sched_stats
    (    incremental: boolean;
     VAR user_sched_stats: ost$sched_stats;
     VAR status: ost$status);

    VAR
      sched_stat_index: jmt$sched_statistic_elements,
      local_sched_stats: ost$sched_stats;

    status.normal := TRUE;
    local_sched_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    local_sched_stats.job_scheduler_statistics := jmv$job_scheduler_statistics;
    user_sched_stats := local_sched_stats;
    IF incremental AND (last_sched_stats_p <> NIL) THEN
      user_sched_stats.time := user_sched_stats.time - last_sched_stats_p^.time;
      FOR sched_stat_index := LOWERBOUND (jmv$job_scheduler_statistics)
            TO UPPERBOUND (jmv$job_scheduler_statistics) DO
        user_sched_stats.job_scheduler_statistics [sched_stat_index] :=
              user_sched_stats.job_scheduler_statistics [sched_stat_index] -
              last_sched_stats_p^.job_scheduler_statistics [sched_stat_index];
      FOREND;
    IFEND;
    IF incremental THEN
      IF last_sched_stats_p = NIL THEN
        ALLOCATE last_sched_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_sched_stats_p^ := local_sched_stats;
    IFEND;
  PROCEND osp$get_sched_stats;

?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_JOB_CLASS_STATS', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to get job class statistics for statistics emission.
{ DESIGN:
{   The procedure has been 'stubbed' for incremental displays.  When incremental displays are
{   implemented, the code to save the last values of the statistics will have to be added.

  PROCEDURE [XDCL, #GATE] osp$get_job_class_stats
    (    incremental: boolean;
     VAR user_job_class_stats: ost$job_class_stats;
     VAR status: ost$status);

    VAR
      job_class: jmt$job_class;

    status.normal := TRUE;

    user_job_class_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;

    FOR job_class := jmc$system_job_class TO UPPERBOUND (user_job_class_stats.job_class_stats) DO
      IF job_class > jmv$maximum_job_class_in_use THEN
        RETURN;
      IFEND;
      IF jmv$job_class_table_p^ [job_class].defined THEN
        user_job_class_stats.job_class_stats [job_class].job_class_counters.queued_jobs :=
              jmv$job_counts.job_class_counts [job_class].queued_jobs;
        user_job_class_stats.job_class_stats [job_class].job_class_counters.initiated_jobs :=
              jmv$job_counts.job_class_counts [job_class].initiated_jobs;
        user_job_class_stats.job_class_stats [job_class].job_class_counters.swapped_jobs :=
              jmv$job_counts.job_class_counts [job_class].swapped_jobs;
        user_job_class_stats.job_class_stats [job_class].job_class_counters.completed_jobs :=
              jmv$job_counts.job_class_counts [job_class].completed_jobs;
        user_job_class_stats.job_class_stats [job_class].job_class_names.name :=
              jmv$job_class_table_p^ [job_class].name;
        user_job_class_stats.job_class_stats [job_class].job_class_names.abbreviation :=
              jmv$job_class_table_p^ [job_class].abbreviation;
      IFEND;
    FOREND;

  PROCEND osp$get_job_class_stats;

?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_SERVICE_CLASS_STATS', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to get service class statistics for statistics emission.
{ DESIGN:
{   The procedure has been 'stubbed' for incremental displays.  When incremental displays are
{   implemented, the code to save the last values of the statistics will have to be added.
{   A monitor request must be issued to update the monitor statistics accumulator, because
{   writing the monitor statistics variable must be synchronized via the monitor interrupt
{   processor lock.

  PROCEDURE [XDCL, #GATE] osp$get_service_class_stats
    (    incremental: boolean;
     VAR user_serv_class_stats: ost$service_class_stats;
     VAR status: ost$status);

    VAR
      request_block: jmt$rb_service_class_statistics,
      service_class: jmt$service_class_index;

    status.normal := TRUE;

    request_block.reqcode := syc$rc_service_class_statistics;
    i#call_monitor (#LOC (request_block), #SIZE (request_block));

    user_serv_class_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    FOR service_class := jmc$system_service_class TO UPPERBOUND (user_serv_class_stats.service_class_stats) DO
      IF service_class > jmv$max_service_class_in_use THEN
        RETURN;
      IFEND;
      IF (jmv$service_classes [service_class] <> NIL) AND jmv$service_classes [service_class]^.attributes.
            defined THEN
        user_serv_class_stats.service_class_stats [service_class].
              mtr_stats := jmv$service_classes [service_class]^.statistics;
        user_serv_class_stats.service_class_stats [service_class].sched_stats.active_jobs :=
              jmv$job_counts.service_class_counts [service_class].scheduler_initiated_jobs -
              jmv$job_counts.service_class_counts [service_class].swapped_jobs;
        user_serv_class_stats.service_class_stats [service_class].sched_stats.swapin_queue_size :=
              jmv$swapin_candidate_queue [service_class].number_of_jobs_in_queue;
        user_serv_class_stats.service_class_stats [service_class].sched_stats.memory_waits :=
              jmv$job_sched_serv_class_stats [service_class].memory_wait;
        user_serv_class_stats.service_class_stats [service_class].sched_stats.ajl_waits :=
              jmv$job_sched_serv_class_stats [service_class].ajl_wait;
        user_serv_class_stats.service_class_stats [service_class].
              name := jmv$service_classes [service_class]^.attributes.name;
      IFEND;
    FOREND;

  PROCEND osp$get_service_class_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_SWAP_STATS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_swap_stats
    (    incremental: boolean;
     VAR user_swap_stats: ost$swap_stats;
     VAR status: ost$status);

    VAR
      from_state: jmt$ijl_swap_status,
      to_state: jmt$ijl_swap_status,
      local_swap_stats: ost$swap_stats;

    status.normal := TRUE;
    local_swap_stats.time := #FREE_RUNNING_CLOCK (0) - syv$nos_system_time.corresponding_frc;
    local_swap_stats.swap_stats := jsv$swap_state_statistics;
    local_swap_stats.swap_file_page_count := jsv$swap_file_page_count;
    user_swap_stats := local_swap_stats;
    IF incremental AND (last_swap_stats_p <> NIL) THEN
      user_swap_stats.time := user_swap_stats.time - last_swap_stats_p^.time;
      user_swap_stats.swap_file_page_count.swap_count := user_swap_stats.swap_file_page_count.swap_count -
            last_swap_stats_p^.swap_file_page_count.swap_count;
      user_swap_stats.swap_file_page_count.page_count := user_swap_stats.swap_file_page_count.page_count -
            last_swap_stats_p^.swap_file_page_count.page_count;

      FOR from_state := LOWERVALUE (jmt$ijl_swap_status) TO UPPERVALUE (jmt$ijl_swap_status) DO
        FOR to_state := LOWERVALUE (jmt$ijl_swap_status) TO UPPERVALUE (jmt$ijl_swap_status) DO
          user_swap_stats.swap_stats [from_state] [to_state].
                count := user_swap_stats.swap_stats [from_state] [to_state].count -
                last_swap_stats_p^.swap_stats [from_state] [to_state].count;
          user_swap_stats.swap_stats [from_state] [to_state].
                total_time := user_swap_stats.swap_stats [from_state] [to_state].total_time -
                last_swap_stats_p^.swap_stats [from_state] [to_state].total_time;
        FOREND;
      FOREND;
    IFEND;
    IF incremental THEN
      IF last_swap_stats_p = NIL THEN
        ALLOCATE last_swap_stats_p IN osv$task_shared_heap^;
      IFEND;
      last_swap_stats_p^ := local_swap_stats;
    IFEND;
  PROCEND osp$get_swap_stats;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_PP_UNIT_COUNT', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_pp_unit_count
    (VAR pp_count: integer;
     VAR unit_count: integer;
     VAR status: ost$status);

    VAR
      index: integer;

    status.normal := TRUE;
    pp_count := 0;
    unit_count := 0;

    IF iov$disk_unit_usage_p <> NIL THEN
      FOR index := 1 TO UPPERBOUND (iov$disk_unit_usage_p^) DO
        IF iov$disk_unit_usage_p^ [index] <> NIL THEN
          unit_count := unit_count + 1;
        IFEND;
      FOREND;
    IFEND;

    IF iov$disk_pp_usage_p <> NIL THEN
      FOR index := 1 TO UPPERBOUND (iov$disk_pp_usage_p^) DO
        IF iov$disk_pp_usage_p^ [index] <> NIL THEN
          pp_count := pp_count + 1;
        IFEND;
      FOREND;
    IFEND;

  PROCEND osp$get_pp_unit_count;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$STORE_SYSTEM_CONSTANT', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$store_system_constant
    (    name: ost$name_reference;
         value: integer;
     VAR status: ost$status);

    IF NOT avp$configuration_administrator () THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'configuration_administration', status);
      RETURN;
    IFEND;

    syp$store_system_constant (name, value, status);

  PROCEND osp$store_system_constant;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$FETCH_SYSTEM_CONSTANT', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$fetch_system_constant
    (VAR name: ost$name_reference;
     VAR index: integer;
     VAR value: integer;
     VAR status: ost$status);

    IF NOT (avp$configuration_administrator () OR avp$system_displays ()) THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'configuration_administration or system_displays',
            status);
      RETURN;
    IFEND;

    syp$fetch_system_constant (name, index, value, status);

  PROCEND osp$fetch_system_constant;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl] OSP$GET_SYSTEM_CONSTANT', EJECT ??

  PROCEDURE [XDCL] osp$get_system_constant
    (VAR name: ost$name_reference;
     VAR index: integer;
     VAR value: integer;
     VAR status: ost$status);

    status.normal := TRUE;
    syp$fetch_system_constant (name, index, value, status);

  PROCEND osp$get_system_constant;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$GET_SYSTEM_CONSTANT_VALUES', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$get_system_constant_values
    (VAR system_constant_values: syt$system_constant_values;
     VAR work_area: ^clt$work_area;
     VAR status: ost$status);

    status.normal := TRUE;
    IF NOT (avp$configuration_administrator () OR avp$system_displays ()) THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'configuration_administration or system_displays',
            status);
      RETURN;
    IFEND;

    IF work_area = NIL THEN
      osp$set_status_abnormal ('OF', cle$work_area_overflow, 'osp$get_system_constant_values', status);
      RETURN;
    IFEND;

    syp$get_system_constant_values (system_constant_values, work_area, status);

  PROCEND osp$get_system_constant_values;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$RESTORE_SYSTEM_CONSTANTS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$restore_system_constants
    (    save_kind: syt$sys_const_saved_values_kind;
     VAR status: ost$status);

    status.normal := TRUE;
    IF NOT avp$configuration_administrator () THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'configuration_administration', status);
      RETURN;
    IFEND;

    syp$restore_system_constants (save_kind, status);

  PROCEND osp$restore_system_constants;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$SAVE_SYSTEM_CONSTANTS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$save_system_constants
    (    save_kind: syt$sys_const_saved_values_kind;
     VAR status: ost$status);

    status.normal := TRUE;
    CASE save_kind OF
    = syc$scsv_site_alternate_values =
      IF (NOT avp$configuration_administrator ()) AND (NOT jmp$system_job ()) THEN
        osp$set_status_abnormal ('OF', ofe$sou_not_active, 'configuration_administration', status);
        RETURN;
      IFEND;

    = syc$scsv_ds_complete_values =
      IF NOT jmp$system_job () THEN
        osp$set_status_abnormal ('JM', jme$must_be_system_job, 'DEADSTART_COMPLETE', status);
        RETURN;
      IFEND;

    ELSE
      osp$set_status_abnormal ('OF', cle$not_supported, 'Parameter', status);
      RETURN;
    CASEND;

    syp$save_system_constants (save_kind);

  PROCEND osp$save_system_constants;
?? OLDTITLE ??
?? NEWTITLE := 'GET_JM_MM_STATISTICS', EJECT ??

  PROCEDURE get_jm_mm_statistics
    (VAR stats: ost$jm_mm_statistics;
     VAR status: ost$status);

    VAR
      index: integer,
      ijl_bn: jmt$ijl_block_number,
      ijl_bi: jmt$ijl_block_index,
      ijl_ordinal: jmt$ijl_ordinal,
      ijle_p: ^jmt$initiated_job_list_entry,
      job_counts: jmt$job_counts;

    status.normal := TRUE;

    mmp$get_page_q_counts (stats.page_q_counts);

    stats.total_swapped_jobs := jsv$ijl_swap_queue_list [jsc$isqi_swapped_out].count;

{ Determine the number of ready tasks, ready but swapped tasks, and active jobs.

    stats.total_ready_but_swapped_tasks := 0;
    stats.total_ready_tasks := 0;
    stats.total_active_jobs := 0;

    ijle_p := NIL;

  /scan_ijl/
    FOR ijl_bn := LOWERBOUND (jmv$ijl_p.block_p^) TO jmv$ijl_p.max_block_in_use DO
      IF (jmv$ijl_p.block_p^ [ijl_bn].index_p <> NIL) THEN
        ijl_ordinal.block_number := ijl_bn;
        FOR ijl_bi := LOWERVALUE (jmt$ijl_block_index) TO UPPERVALUE (jmt$ijl_block_index) DO
          ijl_ordinal.block_index := ijl_bi;
          jmp$get_ijle_p (ijl_ordinal, ijle_p);
          IF ijle_p^.entry_status >= jmc$ies_job_swapped THEN
            stats.total_ready_but_swapped_tasks := stats.total_ready_but_swapped_tasks +
                  ijle_p^.statistics.ready_task_count;
          ELSEIF ijle_p^.entry_status >= jmc$ies_job_in_memory THEN
            stats.total_ready_tasks := stats.total_ready_tasks + ijle_p^.statistics.ready_task_count;
            IF ijle_p^.swap_status = jmc$iss_executing THEN
              stats.total_active_jobs := stats.total_active_jobs + 1;
            IFEND;
          IFEND;
        FOREND;
      IFEND;
    FOREND /scan_ijl/;

{ Determine the number of jobs for each job class

    jmp$get_job_counts (job_counts, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    stats.total_system_class := job_counts.job_class_counts [jmc$system_job_class].initiated_jobs;
    stats.total_interactive_jobs := job_counts.interactive_jobs;
    stats.total_non_interactive_jobs := job_counts.initiated_jobs - job_counts.interactive_jobs;
    IF stats.total_non_interactive_jobs < 0 THEN
      stats.total_non_interactive_jobs := 0;
    IFEND;

  PROCEND get_jm_mm_statistics;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] OSP$RESET_MAXIMUM_TIME', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$reset_maximum_time
    (    id: ost$data_id);

    CASE id OF
    = osc$mtr_requests =
      syp$reset_maximum_time;
    = osc$swap_statistics =
      jsp$reset_maximum_time;
    ELSE
      ;
    CASEND;
  PROCEND osp$reset_maximum_time;
?? OLDTITLE ??
MODEND osm$fetch_statistical_data;
