MODULE tmm$manage_system_tasks;
?? RIGHT := 110 ??

{ PURPOSE:
{  This module contains three procedures to manage a system task list.  This is list is used to find
{  system tasks and wake them up when needed.
{
{  TMP$MTR_READY_SYSTEM_TASK is the handler for the requests from job mode to wake up or define a system task.
{  TMP$MONITOR_READY_SYSTEM_TASK is used to wake up a system task from the system monitor.
{  TMP$UPDATE_SYSTEM_TASK_LIST is used to delete a system task from the table when it terminates.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc tme$monitor_mode_exceptions
*copyc ost$cpu_state_table
*copyc ost$execution_control_block
*copyc syt$monitor_request_code
*copyc tmt$rb_manage_system_tasks
*copyc tmt$system_task_id
?? POP ??
*copyc mtf$cst_p
*copyc mtp$error_stop
*copyc mtp$set_status_abnormal
*copyc tmp$clear_lock
*copyc tmp$set_lock
*copyc tmp$set_task_ready
*copyc tmv$ptl_lock
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    tmv$system_task_ids: array [tmt$system_task_id] of ost$global_task_id :=
          [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
          [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
          [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]],
    null_task_id: ost$global_task_id := [0, 0];

?? OLDTITLE ??
?? NEWTITLE := 'p$monitor_ready_system_task', EJECT ??

  PROCEDURE [INLINE] p$monitor_ready_system_task
    (    stid: tmt$system_task_id;
     VAR status: syt$monitor_status);

    status.normal := TRUE;
    tmp$set_lock (tmv$ptl_lock {, mtc$ignore} );

    IF tmv$system_task_ids [stid] = null_task_id THEN
      mtp$set_status_abnormal ('TM', tme$system_task_missing, status);
    ELSE
      tmp$set_task_ready (tmv$system_task_ids [stid], 0 {readying_task_priority} ,
            tmc$rc_ready_conditional_wi);
    IFEND;

    tmp$clear_lock (tmv$ptl_lock);

  PROCEND p$monitor_ready_system_task;
?? OLDTITLE ??
?? NEWTITLE := 'tmp$mtr_ready_system_task', EJECT ??

  PROCEDURE [XDCL] tmp$mtr_ready_system_task
    (VAR rb: tmt$rb_manage_system_tasks);

*copyc tmhrmst

    VAR
      critical_task: boolean;

    IF rb.save_task_id THEN
      critical_task := (rb.stid = tmc$stid_job_scheduler) OR (rb.stid = tmc$stid_volume_space_managemnt) OR
            (rb.stid = tmc$stid_job_monitor);
      save_task_id (rb.stid, critical_task, rb.status);
    ELSE
      p$monitor_ready_system_task (rb.stid, rb.status);
    IFEND;

  PROCEND tmp$mtr_ready_system_task;
?? OLDTITLE ??
?? NEWTITLE := 'tmp$monitor_ready_system_task', EJECT ??

  PROCEDURE [XDCL] tmp$monitor_ready_system_task
    (    stid: tmt$system_task_id;
     VAR status: syt$monitor_status);

    p$monitor_ready_system_task (stid, status);

  PROCEND tmp$monitor_ready_system_task;
?? OLDTITLE ??
?? NEWTITLE := 'tmp$update_system_task_list', EJECT ??

  PROCEDURE [XDCL] tmp$update_system_task_list
    (    xcb_p: ^ost$execution_control_block);

    VAR
      stid: tmt$system_task_id;

    stid := xcb_p^.system_task_id;
    IF stid = tmc$stid_null_task THEN
      RETURN; {----->
    IFEND;

    tmp$set_lock (tmv$ptl_lock {, mtc$ignore} );
    IF tmv$system_task_ids [stid] <> xcb_p^.global_task_id THEN
      tmp$clear_lock (tmv$ptl_lock);
      mtp$error_stop ('TM11 - system task list error');
    IFEND;

    IF xcb_p^.critical_task THEN
      tmp$clear_lock (tmv$ptl_lock);
      mtp$error_stop ('TM12 - illegal system task exit');
    IFEND;

    xcb_p^.system_task_id := tmc$stid_null_task;
    tmv$system_task_ids [stid] := null_task_id;
    tmp$clear_lock (tmv$ptl_lock);

  PROCEND tmp$update_system_task_list;
?? OLDTITLE ??
?? NEWTITLE := 'SAVE_TASK_ID', EJECT ??

  PROCEDURE [INLINE] save_task_id
    (    stid: tmt$system_task_id;
         critical_task: boolean;
     VAR status: syt$monitor_status);

    VAR
      cst_p: ^ost$cpu_state_table;

    status.normal := TRUE;
    cst_p := mtf$cst_p ();
    IF cst_p^.xcb_p^.system_task_id <> tmc$stid_null_task THEN
      mtp$set_status_abnormal ('TM', tme$task_already_system_task, status);
      RETURN; {----->
    IFEND;

    tmp$set_lock (tmv$ptl_lock {, mtc$ignore} );

    IF tmv$system_task_ids [stid] <> null_task_id THEN
      mtp$set_status_abnormal ('TM', tme$duplicate_system_task, status);
    ELSE
      cst_p^.xcb_p^.system_task_id := stid;
      cst_p^.xcb_p^.critical_task := critical_task;
      tmv$system_task_ids [stid] := cst_p^.xcb_p^.global_task_id;
    IFEND;

    tmp$clear_lock (tmv$ptl_lock);

  PROCEND save_task_id;
?? OLDTITLE ??
MODEND tmm$manage_sustem_tasks;
