?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Program Management : Job/Task Statistics Services' ??
MODULE pmm$get_job_task_statistics;

{ PURPOSE:
{   This module contains procedures which return job or task performance statistics
{   to the user.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cle$work_area_overflow
*copyc clt$data_value
*copyc clt$parameter_list
*copyc clt$work_area
*copyc oss$job_paged_literal
*copyc ost$data_id
*copyc ost$status
*copyc pmt$job_task_statistics
*copyc pmt$task_cp_time
*copyc pmt$task_jobmode_statistics
?? POP ??
*copyc clp$evaluate_parameters
*copyc clp$make_integer_value
*copyc osp$copy_local_status_to_status
*copyc osp$get_job_stats
*copyc osp$set_status_abnormal
*copyc pmp$get_task_cp_time
*copyc pmp$get_task_jobmode_statistics

?? TITLE := '[XDCL] pmp$$cpu_time', EJECT ??

{ PURPOSE:
{   This procedure provides the SCL $CPU_TIME function processor.

  PROCEDURE [XDCL] pmp$$cpu_time
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);

{ FUNCTION (osm$$cpu_time) $cpu_time (
{   accumulator: key
{       (job, j)
{       (job_monitor_mode, jmm)
{       (job_job_mode, jjm)
{       (task, t)
{       (task_monitor_mode, tmm)
{       (task_job_mode, tjm)
{     keyend = job
{   )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 12] of clt$keyword_specification,
        default_value: string (3),
      recend,
    recend := [
    [1,
    [88, 12, 12, 14, 16, 43, 175],
    clc$function, 1, 1, 0, 0, 0, 0, 0, 'OSM$$CPU_TIME'], [
    ['ACCUMULATOR                    ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 451,
  clc$optional_default_parameter, 0, 3]],
{ PARAMETER 1
    [[1, 0, clc$keyword_type], [12], [
    ['J                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
    ['JJM                            ', clc$abbreviation_entry, clc$normal_usage_entry, 3],
    ['JMM                            ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
    ['JOB                            ', clc$nominal_entry, clc$normal_usage_entry, 1],
    ['JOB_JOB_MODE                   ', clc$nominal_entry, clc$normal_usage_entry, 3],
    ['JOB_MONITOR_MODE               ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['T                              ', clc$abbreviation_entry, clc$normal_usage_entry, 4],
    ['TASK                           ', clc$nominal_entry, clc$normal_usage_entry, 4],
    ['TASK_JOB_MODE                  ', clc$nominal_entry, clc$normal_usage_entry, 6],
    ['TASK_MONITOR_MODE              ', clc$nominal_entry, clc$normal_usage_entry, 5],
    ['TJM                            ', clc$abbreviation_entry, clc$normal_usage_entry, 6],
    ['TMM                            ', clc$abbreviation_entry, clc$normal_usage_entry, 5]]
    ,
    'job']];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$accumulator = 1;

    VAR
      pvt: array [1 .. 1] of clt$parameter_value;

    CONST
      keywords_supported = 6;

    VAR
      accumulator_list: [STATIC, READ, oss$job_paged_literal] array [1 .. keywords_supported] of record
        accumulator_name: ost$name,
        statistic_key: pmt$job_task_statistics_key,
      recend := [['JOB                            ', pmc$jts_job_cpu],
            ['JOB_JOB_MODE                   ', pmc$jts_job_job_cpu],
            ['JOB_MONITOR_MODE               ', pmc$jts_job_monitor_cpu],
            ['TASK                           ', pmc$jts_task_cpu],
            ['TASK_JOB_MODE                  ', pmc$jts_task_job_cpu],
            ['TASK_MONITOR_MODE              ', pmc$jts_task_monitor_cpu]],
      get_statistic_p: ^array [1 .. * ] of pmt$job_task_statistics,
      i: 1 .. keywords_supported;

    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    PUSH get_statistic_p: [1 .. 1];
    IF pvt [p$accumulator].specified THEN

    /find_key/
      FOR i := 1 TO keywords_supported DO
        IF pvt [p$accumulator].value^.keyword_value = accumulator_list [i].accumulator_name THEN
          get_statistic_p^ [1].key := accumulator_list [i].statistic_key;
          EXIT /find_key/;
        IFEND;
      FOREND /find_key/;
    ELSE
      get_statistic_p^ [1].key := pmc$jts_job_cpu;
    IFEND;

    pmp$get_job_task_statistics (get_statistic_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    CASE get_statistic_p^ [1].key OF
    = pmc$jts_job_cpu =
      clp$make_integer_value (get_statistic_p^ [1].job_cpu_time, 10, FALSE, work_area, result);
    = pmc$jts_job_job_cpu =
      clp$make_integer_value (get_statistic_p^ [1].job_job_cpu_time, 10, FALSE, work_area, result);
    = pmc$jts_job_monitor_cpu =
      clp$make_integer_value (get_statistic_p^ [1].job_monitor_cpu_time, 10, FALSE, work_area, result);
    = pmc$jts_task_cpu =
      clp$make_integer_value (get_statistic_p^ [1].task_cpu_time, 10, FALSE, work_area, result);
    = pmc$jts_task_job_cpu =
      clp$make_integer_value (get_statistic_p^ [1].task_job_cpu_time, 10, FALSE, work_area, result);
    = pmc$jts_task_monitor_cpu =
      clp$make_integer_value (get_statistic_p^ [1].task_monitor_cpu_time, 10, FALSE, work_area, result);
    ELSE;
    CASEND;
    IF result = NIL THEN
      osp$set_status_abnormal ('CL', cle$work_area_overflow, '', status);
    IFEND;
  PROCEND pmp$$cpu_time;

?? TITLE := '[XDCL, #GATE] pmp$get_job_task_statistics', EJECT ??
*copy pmh$get_job_task_statistics

  PROCEDURE [XDCL, #GATE] pmp$get_job_task_statistics
    (    statistic_data_p: ^array [1 .. * ] of pmt$job_task_statistics;
     VAR status: ost$status);

    VAR
      i: integer,
      job_stats: boolean,
      local_status: ost$status,
      task_cpu: boolean,
      task_cp_time: pmt$task_cp_time,
      task_job_cpu: boolean,
      task_jobmode_stats: pmt$task_jobmode_statistics,
      user_job_stats: ost$job_stats;

    IF statistic_data_p <> NIL THEN
      local_status.normal := TRUE;

    /local_status_control/
      BEGIN
        job_stats := FALSE;
        task_cpu := FALSE;
        task_job_cpu := FALSE;

{ Determine statistic functions to call.

        FOR i := 1 TO UPPERBOUND (statistic_data_p^) DO
          CASE statistic_data_p^ [i].key OF
          = pmc$jts_task_job_cpu =
            task_job_cpu := TRUE;
          = pmc$jts_task_cpu, pmc$jts_task_monitor_cpu =
            task_cpu := TRUE;
          = pmc$jts_job_cpu, pmc$jts_job_job_cpu, pmc$jts_job_monitor_cpu, pmc$jts_paging_statistics,
                pmc$jts_ready_task_count, pmc$jts_working_set_size =
            job_stats := TRUE;
          = pmc$jts_null_statistic =
            ;
          ELSE;
          CASEND;
        FOREND;

{ Call required statistic functions.

        IF task_cpu THEN
          pmp$get_task_cp_time (task_cp_time, local_status);
        ELSEIF task_job_cpu THEN
          pmp$get_task_jobmode_statistics (task_jobmode_stats, local_status);
        IFEND;
        IF job_stats THEN
          osp$get_job_stats (FALSE, user_job_stats, local_status);
          IF NOT local_status.normal THEN
            EXIT /local_status_control/;
          IFEND;
        IFEND;

{ Store requested statistics in the callers array.

        FOR i := 1 TO UPPERBOUND (statistic_data_p^) DO
          CASE statistic_data_p^ [i].key OF
          = pmc$jts_job_cpu =
            statistic_data_p^ [i].job_cpu_time := user_job_stats.job_data.cp_time.time_spent_in_job_mode +
                  user_job_stats.job_data.cp_time.time_spent_in_mtr_mode;
          = pmc$jts_job_job_cpu =
            statistic_data_p^ [i].job_job_cpu_time := user_job_stats.job_data.cp_time.time_spent_in_job_mode;
          = pmc$jts_job_monitor_cpu =
            statistic_data_p^ [i].job_monitor_cpu_time := user_job_stats.job_data.cp_time.
                  time_spent_in_mtr_mode;
          = pmc$jts_null_statistic =
            ;
          = pmc$jts_paging_statistics =
            statistic_data_p^ [i].paging_statistics.page_in_count :=
                  user_job_stats.job_data.paging_statistics.page_in_count;
            statistic_data_p^ [i].paging_statistics.pages_reclaimed_from_queue :=
                  user_job_stats.job_data.paging_statistics.pages_reclaimed_from_queue;
            statistic_data_p^ [i].paging_statistics.new_pages_assigned :=
                  user_job_stats.job_data.paging_statistics.new_pages_assigned;
            statistic_data_p^ [i].paging_statistics.pages_from_server :=
                  user_job_stats.job_data.paging_statistics.pages_from_server;
            statistic_data_p^ [i].paging_statistics.page_fault_count :=
                  user_job_stats.job_data.paging_statistics.page_fault_count;
            statistic_data_p^ [i].paging_statistics.working_set_max_used :=
                  user_job_stats.job_data.paging_statistics.working_set_max_used;
          = pmc$jts_ready_task_count =
            statistic_data_p^ [i].ready_task_count := user_job_stats.job_data.ready_task_count;
          = pmc$jts_task_cpu =
            statistic_data_p^ [i].task_cpu_time := task_cp_time.task_time + task_cp_time.monitor_time;
          = pmc$jts_task_job_cpu =
            IF task_cpu THEN
              statistic_data_p^ [i].task_job_cpu_time := task_cp_time.task_time;
            ELSE
              statistic_data_p^ [i].task_job_cpu_time := task_jobmode_stats.jobmode_cptime;
            IFEND;
          = pmc$jts_task_monitor_cpu =
            statistic_data_p^ [i].task_monitor_cpu_time := task_cp_time.monitor_time;
          = pmc$jts_working_set_size =
            statistic_data_p^ [i].working_set_size := user_job_stats.job_data.working_set_size;
          ELSE;
          CASEND;
        FOREND;
      END /local_status_control/;
      osp$copy_local_status_to_status (local_status, status);
    IFEND;

  PROCEND pmp$get_job_task_statistics;

MODEND pmm$get_job_task_statistics;

