?? RIGHT := 110 ??
*copyc osd$default_pragmats
?? NEWTITLE := 'NOS/VE Program Control Services' ??
?? NEWTITLE := '  PMM$PROGRAM_CONTROL_SERVICES' ??
MODULE pmm$program_control_services;

{   PURPOSE:
{     The purpose of this module is to package contained procedures
{     so that they execute with the privileges necessary to read the
{     job private fixed and job private pageable sections; modify
{     task private section; and issue monitor requests.

{   DESIGN:
{     The procedures contained in this module have an execution bracket
{     of 1, 3 and a call bracket of 3.  The module is designed to execute
{     in the system core.

?? NEWTITLE := '    Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc OST$EXECUTION_CONTROL_BLOCK
*copyc PME$DEFINE_HANDLER_EXCEPTIONS
*copyc PME$HUNG_RECIPIENT_TASK
*copyc PME$INSUFFICIENT_PRIVILEGE
*copyc PME$INVALID_TASK_ORIGIN_FLAG
*copyc PME$INVALID_TASK_ORIGIN_SIGNAL
*copyc PME$UNKNOWN_RECIPIENT_TASK
*copyc SYC$MONITOR_REQUEST_CODES
*copyc TMT$PREEMPTED_REASON
*copyc TMT$RB_SEND_SIGNAL
*copyc TMT$RB_SET_SYSTEM_FLAG
*copyc tmc$signal_identifiers
*copyc TME$MONITOR_MODE_EXCEPTIONS
?? POP ??

*copyc I#CALL_MONITOR
*copyc OSP$SET_STATUS_ABNORMAL
*copyc PMP$CYCLE
*copyc TMP$POST_MAINFRAME_SIGNAL

?? TITLE := '    PMP$SEND_SIGNAL', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc pmh$send_signal
?? POP ??

  PROCEDURE [XDCL, #GATE] pmp$send_signal (recipient: ost$global_task_id;
        signal: pmt$signal;
    VAR status: ost$status);

    TYPE
      signal_ids = set of pmt$signal_id;

    VAR
      tmv$valid_task_origin_signals: signal_ids;

    VAR
      send: tmt$rb_send_signal,
      ignore_status: ost$status;

    IF signal.identifier > tmc$last_signal_id_assigned THEN
      osp$set_status_abnormal(pmc$program_management_id, pme$invalid_identifier, '', status);
      RETURN;
    IFEND;

    tmv$valid_task_origin_signals := - $signal_ids [pmc$ss_child_terminated];
    status.normal := TRUE;
    IF (signal.identifier IN tmv$valid_task_origin_signals) THEN
      send.reqcode := syc$rc_mtr_send_signal;
      send.task_id := recipient;
      send.signal := signal;
      i#call_monitor (#LOC (send), #SIZE (send));
      IF NOT send.status.normal THEN
        CASE send.status.condition OF

        = tme$job_swapped_out, tme$mtr_signal_buffers_full =
          tmp$post_mainframe_signal (recipient, signal, status);
          IF status.normal THEN
            pmp$set_system_flag (tmc$mainframe_linked_signals, recipient, status);
          ELSE
            pmp$cycle (ignore_status);
            pmp$send_signal (recipient, signal, status);
          IFEND;

        = tme$invalid_global_taskid =
          osp$set_status_abnormal (pmc$program_management_id, pme$unknown_recipient_task, '', status);

        = tme$insufficient_privilege =
          osp$set_status_abnormal (pmc$program_management_id, pme$insufficient_privilege, '', status);

        = pme$hung_recipient_task =
          osp$set_status_abnormal (pmc$program_management_id, pme$hung_recipient_task, '', status);

        ELSE
        CASEND;
      IFEND;
    ELSE
      osp$set_status_abnormal (pmc$program_management_id, pme$invalid_task_origin_signal, '', status);
    IFEND;
  PROCEND pmp$send_signal;

?? TITLE := '    PMP$SET_SYSTEM_FLAG', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc pmh$set_system_flag
?? POP ??

  PROCEDURE [XDCL, #GATE] pmp$set_system_flag (flag_id: ost$system_flag;
        recipient: ost$global_task_id;
    VAR status: ost$status);

    VAR
      tmv$valid_task_origin_flags: tmt$system_flags;

    VAR
      set_system_flag: tmt$rb_set_system_flag;

    status.normal := TRUE;

    IF flag_id > tmc$last_system_flag THEN
      osp$set_status_abnormal (pmc$program_management_id, pme$invalid_identifier, '', status);
      RETURN;
    IFEND;

    tmv$valid_task_origin_flags := - $tmt$system_flags [];
    IF (flag_id IN tmv$valid_task_origin_flags) THEN
      set_system_flag.reqcode := syc$rc_set_system_flag;
      set_system_flag.task_id := recipient;
      set_system_flag.flag_id := flag_id;
      i#call_monitor (#LOC (set_system_flag), #SIZE (set_system_flag));
      IF NOT set_system_flag.status.normal THEN
        CASE set_system_flag.status.condition OF
        = tme$invalid_global_taskid =
          osp$set_status_abnormal (pmc$program_management_id, pme$unknown_recipient_task, '', status);
        = tme$insufficient_privilege =
          osp$set_status_abnormal (pmc$program_management_id, pme$insufficient_privilege, '', status);
        ELSE
        CASEND;
      IFEND;
    ELSE
      osp$set_status_abnormal (pmc$program_management_id, pme$invalid_task_origin_flag, '', status);
    IFEND;
  PROCEND pmp$set_system_flag;
?? OLDTITLE ??
MODEND pmm$program_control_services;
