?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Operating System : System job monitor main loop' ??
MODULE osm$run_virtual_system;

{ PURPOSE:
{   This module contains the main system job_monitor routine which monitors system tasks and acts
{   upon requests to change their status'.  It also is the starting point of system idle-down and resume.

?? NEWTITLE := 'Global Declarations Referenced by this Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ose$system_task_exceptions
?? POP ??
*copyc cap$prepare_for_idle_system
*copyc clp$log_comment
*copyc clp$put_job_command_response
*copyc clp$set_primary_task
*copyc dfp$prepare_for_idle_system
*copyc dsp$check_interval_23d
*copyc jmp$idle_system
*copyc jmp$resume_system
*copyc jmp$system_job
*copyc jmp$update_last_used_ssn
*copyc osp$activate_system_task
*copyc osp$executing_in_job_monitor
*copyc osp$generate_message
*copyc osp$get_cause_of_idle_r3
*copyc osp$idle_requested
*copyc osp$log_idle_resume
*copyc osp$manage_system_tasks
*copyc osp$set_status_abnormal
*copyc osp$update_idle_state
*copyc pmp$get_microsecond_clock
*copyc pmp$wait
?? OLDTITLE ??
?? NEWTITLE := 'osp$run_virtual_system', EJECT ??

{ PURPOSE:
{   The purpose of this request is to manage system tasks while waiting for a request to
{   idle the system.

  PROCEDURE [XDCL] osp$run_virtual_system
    (    system_restart: boolean;
     VAR status: ost$status);

    CONST
      c$one_hour_wait = 3600000,    {one hour in milleseconds.
      c$one_second_wait = 1000,     {one second in milleseconds.
      c$ten_second_wait = 10000;    {ten seconds in milleseconds.

    VAR
      current_time: integer,
      first_time_for_message: boolean,
      idle_code: syt$180_idle_code,
      ignore_status: ost$status,
      log_name_selections: ARRAY [1 .. 1] OF ost$name,
      short_wait: boolean,
      task_name: ost$name,
      time_to_check_interval: integer,
      wait_time: integer,
      work_was_done: boolean;

    IF NOT (jmp$system_job () AND osp$executing_in_job_monitor ()) THEN
      osp$set_status_abnormal ('  ', ose$not_system_job_monitor, 'osp$run_virtual_system', status);
      RETURN;
    IFEND;

    log_name_selections [1] := 'SYSTEM';
    work_was_done := TRUE;
    first_time_for_message := TRUE;
    short_wait := FALSE;

    IF NOT system_restart THEN

      { Activate the console interaction task. This system task is defined by OSP$INITIALIZE_VIRTUAL_SYSTEM.

      task_name := 'CONSOLE_INTERACTION';
      osp$activate_system_task (task_name, status);
      IF NOT status.normal THEN
        osp$generate_message (status, ignore_status);
        status.normal := TRUE;
      IFEND;
    IFEND;

    osp$update_idle_state (osc$system_not_idle, status);
    IF NOT status.normal THEN
      osp$generate_message (status, ignore_status);
    IFEND;

    time_to_check_interval := 0;

  /run_system/
    WHILE TRUE DO

      { Check if the System Operation Interval has expired, if it has then the system will step.

      pmp$get_microsecond_clock (current_time, ignore_status);
      IF current_time >= time_to_check_interval THEN
        dsp$check_interval_23d;
        time_to_check_interval := current_time + (c$one_hour_wait * 1000);
      IFEND;

      IF work_was_done THEN
        work_was_done := FALSE;
        IF NOT first_time_for_message THEN
          pmp$wait (c$one_second_wait, c$one_second_wait);
        IFEND;
      ELSE
        IF system_restart AND first_time_for_message THEN
          clp$log_comment ('----------   Resume_System Completed   ----------', log_name_selections, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          clp$put_job_command_response (' ----- RESUME_SYSTEM COMPLETE  -----', status);
          clp$put_job_command_response (' /', status);
          osp$update_idle_state (osc$system_not_idle, status);

          { Log the time for the resume.

          osp$log_idle_resume (osc$resume_statistic, syc$ic_null, status);
        IFEND;
        first_time_for_message := FALSE;
        IF short_wait THEN
          wait_time := c$ten_second_wait;
        ELSE
          wait_time := c$one_hour_wait;
        IFEND;
        pmp$wait (wait_time, wait_time);
      IFEND;

      { The following request should proceed IDLE - The reason being that if a job gets submitted and
      { routed to another mainframe and the last system_supplied_name assigned does not get updated
      { we may, inadvertently, re-assign the same name - this is fatal.

      jmp$update_last_used_ssn (status);

      IF osp$idle_requested () THEN
        osp$update_idle_state (osc$idle_system_in_progress, status);
        EXIT /run_system/
      IFEND;

      { Perform any actions necessary to support system task execution.

      osp$manage_system_tasks (short_wait, ignore_status);

      jmp$resume_system (ignore_status);
    WHILEND /run_system/;

    clp$set_primary_task (status);

    osp$get_cause_of_idle_r3 (idle_code);
    dfp$prepare_for_idle_system (idle_code, ignore_status);
    cap$prepare_for_idle_system (idle_code, ignore_status);

    jmp$idle_system (ignore_status);

  PROCEND osp$run_virtual_system;
?? OLDTITLE ??
MODEND osm$run_virtual_system;
