?? SET (LISTCTS := OFF) ??
?? LEFT := 1, RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE: Program Control - Preemptive Communications' ??
?? NEWTITLE := '  tmm$manage_preemptive_buffers - Global System Declarations' ??
{   PURPOSE:
{     The purpose of this module is to package the contained with the
{     privileges necessary to modify signal and flag structures in job
{     private fixed and mainframe pageable.

{   DESIGN:
{    The procedures contained in this module have an execution bracket
{    of 1, 1 and a call bracket of 3.

?? EJECT ??
MODULE tmm$manage_preemptive_buffers;
?? PUSH (LISTEXT := ON) ??
*copyc OST$EXECUTION_CONTROL_BLOCK
?? POP ??
*copyc OSE$HEAP_FULL_EXCEPTIONS
*copyc OSV$MAINFRAME_PAGEABLE_HEAP
*copyc PMC$PROGRAM_MANAGEMENT_ID
*copyc ost$signature_lock
*copyc TMT$SIGNAL_STATUS
*copyc TMT$FLAG_STATUS
?? TITLE := '  tmm$manage_preemptive_buffers - Global External Procedures' ??
?? EJECT ??

*copyc I#DISABLE_TRAPS
*copyc I#RESTORE_TRAPS
*copyc I#ENABLE_TRAPS
*copyc PMP$GET_EXECUTING_TASK_GTID
*copyc OSH$SET_STATUS_ABNORMAL
*copyc OSP$SET_STATUS_ABNORMAL
*copyc OSH$SET_SIGNATURE_LOCK
*copyc OSP$SET_MAINFRAME_SIG_LOCK
*copyc OSH$CLEAR_SIGNATURE_LOCK
*copyc OSP$CLEAR_MAINFRAME_SIG_LOCK
*copyc PMP$FIND_EXECUTING_TASK_XCB
?? TITLE := '  Internal Declarations' ??
?? EJECT ??

  CONST
    unlocked = 0;

  TYPE
    tmt$mainframe_signal_list = record
      lock: ost$signature_lock,
      delink: ^tmt$mainframe_linked_signal,
      link: ^^tmt$mainframe_linked_signal,
    recend;


*copyc TMT$MAINFRAME_LINKED_SIGNAL
*copyc TMT$SIGNAL_BUFFER
*copyc OST$GLOBAL_TASK_ID

  VAR
    tmv$mainframe_signal_list: [STATIC, oss$mainframe_pageable] tmt$mainframe_signal_list := [[0],
       NIL, NIL];

?? TITLE := '  [XDCL, #GATE] tmp$get_signal' ??
?? EJECT ??

  PROCEDURE [XDCL, #GATE] tmp$get_signal (buffer_index: tmt$signal_buffers;
    VAR signal: tmt$signal;
    VAR signal_status: tmt$signal_status);
*copyc TMH$GET_SIGNAL

    VAR
      traps: 0 .. 3,
      xcb: ^ost$execution_control_block;

    pmp$find_executing_task_xcb (xcb);
    i#disable_traps (traps);

    IF (buffer_index >= LOWERVALUE (tmt$signal_buffers)) AND (buffer_index <= UPPERVALUE (tmt$signal_buffers))
          THEN
      IF xcb^.signals.present [buffer_index] THEN
        signal := xcb^.signals.buffer [buffer_index];
        xcb^.signals.present [buffer_index] := FALSE;
        xcb^.signals.reserved [buffer_index] := FALSE;
        signal_status := tmc$normal_signal_status;
      ELSE
        signal_status := tmc$no_signal_present;
      IFEND;
    ELSE
      signal_status := tmc$invalid_buffer_index;
    IFEND;
    i#restore_traps (traps);
  PROCEND tmp$get_signal;
?? TITLE := '  [XDCL, #GATE] tmp$find_mainframe_signal' ??
?? EJECT ??

  PROCEDURE [XDCL, #GATE] tmp$find_mainframe_signal
    (    gtid: ost$global_task_id;
     VAR signal_found: boolean;
     VAR signal: tmt$signal);
*copyc TMH$FIND_MAINFRAME_SIGNAL

    VAR
      mf_signal_found: boolean,
      free_signal: ^tmt$mainframe_linked_signal,
      delink: ^^tmt$mainframe_linked_signal,
      traps: 0 .. 3,
      ignore_status: ost$status;

    signal_found := FALSE;
    i#disable_traps (traps);
    osp$set_mainframe_sig_lock (tmv$mainframe_signal_list.lock);
    IF (tmv$mainframe_signal_list.delink <> NIL) THEN
      delink := ^tmv$mainframe_signal_list.delink;
      mf_signal_found := FALSE;
      WHILE NOT mf_signal_found AND (delink^ <> NIL) DO
        IF (delink^^.recipient.index = gtid.index) THEN
          IF (delink^^.recipient.seqno = gtid.seqno) THEN
            signal := delink^^.linked;
            mf_signal_found := TRUE;
            free_signal := delink^;
            delink^ := delink^^.next_linked_signal;
            FREE free_signal IN osv$mainframe_pageable_heap^;
            IF (delink^ = NIL) THEN
              tmv$mainframe_signal_list.link := delink;
            IFEND;
          ELSE
            free_signal := delink^;
            delink^ := delink^^.next_linked_signal;
            FREE free_signal IN osv$mainframe_pageable_heap^;
            IF (delink^ = NIL) THEN
              tmv$mainframe_signal_list.link := delink;
            IFEND;
          IFEND;
        ELSE
          delink := ^delink^^.next_linked_signal;
        IFEND;
      WHILEND;
      signal_found := mf_signal_found;
    IFEND;
    osp$clear_mainframe_sig_lock (tmv$mainframe_signal_list.lock);
    i#restore_traps (traps);
  PROCEND tmp$find_mainframe_signal;
?? TITLE := '  [XDCL, #GATE] tmp$post_mainframe_signal' ??
?? EJECT ??

  PROCEDURE [XDCL, #GATE] tmp$post_mainframe_signal (recipient: ost$global_task_id;
        signal: pmt$signal;
    VAR status: ost$status);
*copyc TMH$POST_MAINFRAME_SIGNAL

    VAR
      traps: 0 .. 3,
      executing_task: ost$global_task_id,
      ignore_status: ost$status;

    status.normal := TRUE;
    pmp$get_executing_task_gtid (executing_task);
    i#disable_traps (traps);
    osp$set_mainframe_sig_lock (tmv$mainframe_signal_list.lock);
    IF (tmv$mainframe_signal_list.link = NIL) THEN
      tmv$mainframe_signal_list.link := ^tmv$mainframe_signal_list.delink;
    IFEND;
    ALLOCATE tmv$mainframe_signal_list.link^ IN osv$mainframe_pageable_heap^;
    IF (tmv$mainframe_signal_list.link^ <> NIL) THEN
      tmv$mainframe_signal_list.link^^.linked.signal := signal;
      tmv$mainframe_signal_list.link^^.linked.originator := executing_task;
      tmv$mainframe_signal_list.link^^.recipient := recipient;
      tmv$mainframe_signal_list.link^^.next_linked_signal := NIL;
      tmv$mainframe_signal_list.link := ^tmv$mainframe_signal_list.link^^.next_linked_signal;
    ELSE
      osp$set_status_abnormal (pmc$program_management_id, ose$mainframe_pageable_full, 'signal processor',
            status);
    IFEND;
    osp$clear_mainframe_sig_lock (tmv$mainframe_signal_list.lock);
    i#restore_traps (traps);
  PROCEND tmp$post_mainframe_signal;
?? TITLE := '  [XDCL, #GATE] tmp$clear_system_flag' ??
?? EJECT ??

  PROCEDURE [XDCL, #GATE] tmp$clear_system_flag (flag_id: ost$system_flag;
    VAR flag_status: tmt$flag_status);
*copyc TMH$CLEAR_SYSTEM_FLAG

    VAR
      traps: 0 .. 3,
      system_flags: ^packed array [tmc$first_system_flag .. tmc$last_system_flag] of boolean,
      xcb: ^ost$execution_control_block;

    pmp$find_executing_task_xcb (xcb);
    i#disable_traps (traps);

    IF (flag_id >= LOWERVALUE (ost$system_flag)) AND (flag_id <= UPPERVALUE (ost$system_flag)) THEN
      IF (flag_id IN xcb^.system_flags) THEN
        system_flags := #LOC (xcb^.system_flags);
        system_flags^ [flag_id] := FALSE;
        flag_status := tmc$normal_flag_status;
      ELSE
        flag_status := tmc$flag_not_set;
      IFEND;
    ELSE
      flag_status := tmc$invalid_flag_id;
    IFEND;
    i#restore_traps (traps);
  PROCEND tmp$clear_system_flag;
?? TITLE := '  [XDCL, #GATE] tmp$clear_wait_inhibited' ??
?? EJECT ??

  PROCEDURE [XDCL, #GATE] tmp$clear_wait_inhibited (VAR wait_inhibited: boolean);

*copyc TMH$CLEAR_WAIT_INHIBITED

    VAR
      xcb: ^ost$execution_control_block;

    pmp$find_executing_task_xcb (xcb);
    wait_inhibited := xcb^.wait_inhibited;
    xcb^.wait_inhibited := FALSE;
  PROCEND tmp$clear_wait_inhibited;
?? TITLE := '  [XDCL, #GATE] tmp$enable_preemptive' ??
?? EJECT ??

  PROCEDURE [XDCL, #GATE] tmp$enable_preemptive;

*copyc TMH$ENABLE_PREEMPTIVE

{*callc jmxjthp

    VAR
      traps: 0 .. 3,
      xcb: ^ost$execution_control_block;

    i#enable_traps (traps);
  PROCEND tmp$enable_preemptive;

MODEND tmm$manage_preemptive_buffers;
