*DECK NS$TNA
USETEXT COM$NS
USETEXT LTSB$NS 
USETEXT NAT$NS
USETEXT NCT$NS
USETEXT NPT$NS
  
PROC NS$TNA;                 # TERMINATE NPU ACTIVITY                  #
  
# TITLE NS$TNA - TERMINATE NPU ACTIVITY.                               #
  
      BEGIN    # NS$TNA # 
# 
**    NS$TNA - TERMINATE NPU ACTIVITY.
* 
*     J.C. LEE    1981
* 
*     THIS ROUTINE TERMINATES NPU ACTIVITY. 
* 
*     PROC NS$TNA 
* 
*     ENTRY:  
*       NONE. 
* 
*     EXIT: 
*       NONE. 
* 
*     METHOD: 
*       UPDATE NODE-CONNECTION-TABLE (NCT). 
*         IF NCT ORDINAL NQ 0:  
*           USE NCT ORDINAL TO INDEX INTO NCT TO GET
*           NCT TABLE ENTRY.
*           CLEAR NEIGHBOR NPU ACTIVE FLAG. 
*           DELINK NCT TABLE ENTRY FORM ACTIVE-NODE-LIST. 
*           LINK NCT TABLE ENTRY TO IDLE-NODE-LIST. 
*           IF PICB EXISTS, RELEASE PICB. 
*       CLEAN UP NPU TABLE (NPT). 
*       DELINK NAT. 
*       RELEASE NAT TSB.
*       IF NAT LIST EMPTY AND GRADUAL SHUTDOWN REQUESTED: 
*         SHUTDOWN NS.
*       DECREMENT LOAD TSB ACTIVITY COUNT.
*       IF LOAD TSB ACTIVITY COUNT LQ 0:  
*         LOCATE LOAD-TSB.
*         RELEASE LOAD-TSB. 
*         CLEAR LOAD-TSB WORD IN TABLE POINTER AREA.
* 
# 
  
      $BEGIN
      XREF
        BEGIN 
        PROC NS$DBG;         # TRACE PROCEDURE CALL                    #
        END 
      $END
  
      XREF
        BEGIN 
        PROC NS$STD;         # SHUTDOWN NS                             #
        PROC RECALL;         # RECALL                                  #
        PROC RETTSB;         # RELEASE TSB                             #
        PROC TSBINFO;        # LOCATE TSB                              #
        END 
  
      ITEM ACOUNT     U;     # LOAD TSB ACTIVITY COUNT                 #
      ITEM BACKPTR    U;     # BACK POINTER                            #
      ITEM NCTORD     U;     # MODE CONNECTION TABLE ORDINAL           #
      ITEM NEXTPTR    U;     # NEXT POINTER                            #
      ITEM TAILPTR    U;     # TAIL POINTER OF NCT LIST IN NCT ORDINAL #
      ITEM TSBN       U;     # TSB NUMBER                              #
      ITEM TSBFWA     U;     # TSB FWA                                 #
      ITEM TSBSIZE    U;     # TSB SIZE                                #
  
CONTROL EJECT;
  
      $BEGIN
      NS$DBG("TNA");         # TRACE CALL                              #
      $END
  
# 
      UPDATE NODE CONNECTION TABLE ENTRY
# 
      NCTORD = NAT$NCTORD[0];          # NODE CONNECTION TABLE ORDINAL #
  
      IF NCTORD NQ 0
      THEN                   # ONGOING NPU DUMPING/LOADING ACTIVITY    #
        BEGIN                # LINK NOT ENTRY TO END OF NCT LIST       #
        NCT$F$ACT[NCTORD] = FALSE;     # CLEAR NEIGHBOR NPU ACTIVE FLAG#
        TAILPTR = NCT$LISTTP[0];       # SAVE TAIL PTR OF NCT LIST     #
  
        IF TAILPTR NQ NCTORD
        THEN                           # NCT ENTRY NOT AT END OF LIST  #
          BEGIN 
          NEXTPTR = NCT$LISTFP[NCTORD];  # SAVE CURRENT NEXT PTR       #
          BACKPTR = NCT$LISTBP[NCTORD];  # SAVE CURRENT BACK PTR       #
          NCT$LISTFP[TAILPTR] = NCTORD; 
          NCT$LISTBP[NCTORD] = TAILPTR; 
          NCT$LISTFP[NCTORD] = 0;        # INDICATE END OF LIST        #
          NCT$LISTTP[0] = NCTORD;        # UPDATE TAIL PTR OF NCT LIST #
          NCT$LISTFP[BACKPTR] = NEXTPTR;
          NCT$LISTBP[NEXTPTR] = BACKPTR;
          END 
  
        TSBN = NAT$PITSBN[0]; 
        IF TSBN NQ 0
        THEN                           # PICB EXISTS                   #
          RETTSB(TSBN);                # RELEASE PICB                  #
  
        END 
# 
      CLEAN UP NPU TABLE
# 
      TSBN = NPT$NATTSB[NTORD];        # TSB NUMBER OF NAT             #
      NPT$NCTORD[NTORD] = 0;
      NPT$NATTSB[NTORD] = 0;
      NATTSBN = 0;
# 
      DELINK NAT FROM NAT LIST
# 
      NEXTPTR = NAT$NLFP[0];           # NAT LIST FORWARD PTR          #
      BACKPTR = NAT$NLBP[0];           # NAT LIST BACKWARD PTR         #
      P<NAT> = 0; 
  
      IF NEXTPTR EQ 0 
      THEN                             # LAST NAT IN LIST              #
        NPT$NLTAIL[0] = BACKPTR;       # UPDATE TAIL PTR               #
  
      ELSE                             # NAT TO FOLLOW                 #
        BEGIN 
        TSBINFO(TSBSIZE,TSBFWA,NEXTPTR); # LOCATE NEXT NAT IN LIST     #
        NAT$NLBP[TSBFWA] = BACKPTR;    # UPDATE BACK PTR OF NEXT NAT   #
        END 
  
      IF BACKPTR EQ 0 
      THEN                             # FIRST NAT IN LIST             #
        NPT$NLHEAD[0] = NEXTPTR;       # UPDATE HEAD PTR               #
  
      ELSE                             # PRECEDING NAT EXISTS          #
        BEGIN 
        TSBINFO(TSBSIZE,TSBFWA,BACKPTR); # LOCATE PRECEDING NAT        #
        NAT$NLFP[TSBFWA] = NEXTPTR;    # UPDATE PRECEDING NAT NEXT PTR #
        END 
  
      RETTSB(TSBN);                    # RELEASE NAT TSB               #
  
      IF NPT$NLHEAD[0] EQ 0            # EMPTY NAT LIST                #
        AND GRADSHUT                   # GRADUAL SHUTDOWN REQUESTED    #
      THEN
        NS$STD;                        # SHUTDOWN NS                   #
# 
      DECREMENT LOAD TSB ACTIVITY COUNT 
# 
      ACOUNT = LTW$ACOUNT[0] - 1; 
      LTW$ACOUNT[0] = ACOUNT; # DECREMENT LOAD TSB ACTIVITY COUNT      #
      IF ACOUNT LQ 0
      THEN                   # NO OTHER LOAD ACTIVITY IN PROGRESS      #
        BEGIN 
        TSBN = LTW$LTSBN[0];           # TSB NUMBER OF LOAD TSB        #
        TSBINFO(TSBSIZE,TSBFWA,TSBN);  # LOCATE LOAD TSB               #
        P<LTSB$FET> = TSBFWA + L$LTSBHDR;  # FWA OF LOAD FET           #
        RECALL(LTSB$FET);              # MAKE SURE I/O COMPLETE        #
        RETTSB(TSBN);                  # RELEASE LOAD TSB              #
        LTW$WORD[0] = 0;               # CLEAR LOAD TSB WORD           #
        END 
  
      RETURN; 
      END   # NS$TNA #
      TERM
