*DECK NEIB
USETEXT NIPDEF
USETEXT BPIPBUF 
USETEXT DBGBUF
USETEXT DRHDR 
USETEXT LLCB
USETEXT NBT 
USETEXT PT
USETEXT STATTAB 
USETEXT SUPMSG
USETEXT SYSTIME 
USETEXT TNT 
USETEXT INPARUT 
USETEXT KDIS
 PROC NEIB;                  # EMPTY INPUT BUFFER                      #
  
 STARTIMS;
 #
*1DC  NEIB
* 
*     1. PROC NAME           AUTHOR              DATE 
*        BUFFER AND THE INTRA-HOST A-A MESSAGE QUEUE. 
* 
*     2. FUNCTIONAL DESCRIPTION.
*        THIS ROUTINE IS RESPONSIBLE FOR EMPTYING A NETWORK INPUT 
*        BUFFER.
* 
*     3. METHOD USED. 
*        FOR EACH HOSTNODE - PICK UP MESSAGE FROM PIP 
*        INBOUND BUFFER AND CALL NEIB1 TO PROCESS IT- 
*        CONTINUE UNTIL BUFFER IS EMTPY.  PICK UP 
*        MESSAGES FROM INTRA-HOST A-A MESSAGE 
*        QUEUE AND CALL NEIB1 TO PROCESS THEM.
* 
*     4. INPUT PARAMETERS.
*          NONE 
* 
*     5. EXIT PARAMETERS.  NONE 
* 
*     6. COMDECKS CALLED AND SYMPL TEXTS USED.
*        BPIPBUF     DBGBUF     DRHDR     NIPDEF
*        STATTAB     SYSTIME    SUPMSG    LLCB
*        INPARUT     KDIS       NBT       TNT 
*        PT                  GLOBAL VARIABLES AND POINTERS
* 
*     7. ROUTINES AND OVERLAYS CALLED.
*          MGETS             GET BUFFER SPACE 
*          MRELS             RELEASE BUFFER SPACE 
*          NEIB1             PROCESS UPLINE MESSAGES
*          OPITRCE           INITIALIZE NIP DEBUG LOG FILE
*          OPRETN            RETURN FILE
*          OTIME             GET SYSTEM RTIME 
*          TWRITE            RECORD MESSAGE IN ZZZZZDN FILE 
*          XTRACE            TRACES CALLS 
* 
*     8. DAYFILE MESSAGES AND OTHER IMPORTANT INFORMATION 
*        THIS PROCEDURE IS CALLED BY XEXEC. 
* 
 #
 STOPIMS; 
# INPUT PARAMETERS.  NONE    #
# OUTPUT PARAMETERS.  NONE
  
                    EXTERNAL VARIABLES
# 
 XREF BEGIN 
   PROC MGETS;               # GET BUFFER SPACE                        #
   PROC MRELS;               # RELEASE BUFFER SPACE                    #
   PROC NEIB1;               # PROCESS MESSAGE                         #
   PROC OPITRCE;             # INITIALIZE NIP DEBUG LOG FILE           #
   PROC OPRETN;              # RETURN FILE                             #
   PROC OTIME;               # GET SYSTEM RTIME                        #
   PROC OVLCALL;             # LOAD AND EXECUTE OVERLAY                #
   PROC PURGREG;             # INVALIDATE REGISTERS TO FORCE CM READ   #
   PROC TWRITE;              # RECORD MESSAGE IN ZZZZZDN FILE          #
   PROC XTRACE;              # RECORD TRACE                            #
   END
# 
                    INTERNAL VARIABLES
# 
 CONTROL PRESET;
 ITEM ACTIVENPU B = FALSE,   # NPU ACTIVITY INDICATOR                  #
      JALLOC B = TRUE,       # NIP JUST ALLOCATE AN INBOUND BUFFER     #
      I,                     # TEMPIRARY LOOP VARIABLE                 #
      IND,                   # FRONT END INDEX NUMBER                  #
      IND2,                  # TEMP VARIABLE                           #
      CURIND,                # TEMP VARIABLE                           #
      NXTIND,                # TEMP VARIABLE                           #
      BUFSIZ,                # BUFFER SIZE                             #
      BUF;                   # BUFFER FOR INTRA-HOST A-A QUEUE         #
  
      CONTROL IFEQ STAT,1;
        ARRAY STIME P(1);    # RTIME BUFFER FOR STARTING TIME          #
          BEGIN 
          ITEM SMILS U(0,24,36); # STARTING TIME IN MILLESECONDS       #
          END 
        ARRAY ETIME P(1);    # RTIME BUFFER FOR ENDING TIME            #
          BEGIN 
          ITEM EMILS U(0,24,36); # ENDING TIME IN MILLESECONDS         #
          END 
  
        ITEM STTEMP;         # TEMPORARY STATISTICS VARIABLE           #
        ITEM WORK B;         # FLAG TO INDICATE IF UPLINE MSGS PROCESSD#
      CONTROL FI; 
  
  
#**********************************************************************#
      BEGIN 
      CONTROL IFEQ DEBUG,1 ;
        XTRACE("NEIB ") ; 
      CONTROL FI; 
  
      CONTROL IFEQ STAT,1;
        WORK = FALSE; 
      CONTROL FI; 
  
# 
      LOOP ON ALL NPU-S 
# 
      ACTIVENPU = FALSE;     # PRESET TO NO NPU ACTIVITY               #
      FOR IND = 0 STEP NBTFETNO UNTIL NBTMAXID
      DO
        BEGIN 
        NBTIDX = IND;                  # NBT ENTRY INDEX               #
  
 NEIB2LOOP: 
  
        IF NBTIUF[IND] # NBT ACTIVE                                    #
        THEN
          BEGIN 
          IND2 = IND + 1 ;
            IF NBTCII[IND2] EQ IND # SET CURRENT INPUT INDEX           #
            THEN
              BEGIN 
              CURIND = IND; 
              NXTIND = IND2;
              END 
            ELSE
              BEGIN 
              CURIND = IND2;
              NXTIND = IND; 
              END 
            IF (NBTBRF[CURIND])      # RELEASE CURRENT BUFFER          #
               OR (NBTIN[CURIND] GQ NBTTA[CURIND])
            THEN             # RELEASE SET OR BUFFER HALF USED         #
              BEGIN 
              IF (NBTBRF[CURIND]) OR
                 (NBTLIMIT[CURIND] EQ NBTOUT[CURIND]) 
              THEN           # RELEASING CURRENT BUFFER                #
                BEGIN 
                NBTCII[IND2] = NXTIND; # MOVE CUR BUF INDX TO OTHER FET#
                END 
              IF NOT NBTBFS[NXTIND] 
              THEN           # BUFFER NOT ALLOCATED YET                #
                BEGIN 
# 
                ALLOCATE NEW INBOUND BUFFER 
# 
                IF NBTPIREJ[IND+5] NQ NBTRJCNT[IND2]
                THEN         # PIP HAS REJECTED IVT DATA SINCE LAST BUF#
                  BEGIN 
                  NBTRJCNT[IND2] = NBTPIREJ[IND+5];  # UPDATE REJ CNT  #
                  NBTRTIME[IND2] = RTSECS[0] + NINBRJTO; # UPDT TIMEOUT#
                  IF NBTCOFF[IND2] EQ 0 
                  THEN       # THRESHOLD ADR IS ALREADY AT BEGIN OF BUF#
                    BEGIN    # INCREASE SIZE OF INBOUND BUFFER         #
                    NBTCSIZE[IND2] = NBTCSIZE[IND2] + NINBINC;
                    END 
                  ELSE       # REDUCE OFFSET FOR THRESHOLD ADDR        #
                    BEGIN 
                    NBTCOFF[IND2] = NBTCOFF[IND2] - NINBINC;
                    END 
                  IF NBTCSIZE[IND2] GQ MAXIBSZ   # IF THE ATTEMPTTED   #
                  THEN                           # BUFFER SIZE IS TOO  #
                    BEGIN                        # BIG, THEN           #
                    NBTCSIZE[IND2] = MAXIBSZ;  #REDUCE IT TO THE LIMIT.#
                    CONTROL IFEQ STAT,1;
                    ST$MXIB = ST$MXIB + 1;
                    CONTROL FI; 
                    END 
                  END 
                ELSE         # PIP HAS NOT REJECTED IVT DATA           #
                  BEGIN 
                  IF RTSECS[0] GQ NBTRTIME[IND2]
                  THEN       # ONE MINUTE HAS ELAPSED WITH NO REJECTS  #
                    BEGIN 
                    NBTRTIME[IND2] = RTSECS[0] + NINBRJTO; #RESET TIMEO#
                    IF NBTCSIZE[IND2] GR NINBMIN
                    THEN     # CUR INBOUND BUF SIZE GREATER THAN MIN   #
                      BEGIN 
                      NBTCSIZE[IND2] = NBTCSIZE[IND2] - NINBINC;
                      END 
                    ELSE     # INBOUND BUFFER SIZE IS ALREADY AT MIN   #
                      BEGIN 
                      IF NBTCOFF[IND2] LS NINBMIN 
                      THEN   # OFFSET FOR THRESHOLD ADR NOT AT MAX     #
                        BEGIN  # INCREASE OFFSET FOR THRESHOLD ADDR    #
                        NBTCOFF[IND2] = NBTCOFF[IND2] + NINBINC;
                        END 
                      END 
                    END 
                  END 
                MGETS(NBTCSIZE[IND2],P<DRHDRWD>,FALSE); 
                NBTFIRST[NXTIND] = P<DRHDRWD>;# SET FIRST POINTER      #
                NBTIN[NXTIND] = P<DRHDRWD>;   # SET IN POINTER         #
                NBTOUT[NXTIND] = P<DRHDRWD>;  # SET OUT POINTER        #
                NBTTA[NXTIND] = P<DRHDRWD> + NBTCOFF[IND2]; 
                NBTLIMIT[NXTIND] = P<DRHDRWD> + NBTCSIZE[IND2]; 
                NBTBAF[NXTIND] = TRUE;        # SET BUFFER AVAILABLE   #
                BLKID[0] = PIBIDVALUE;
  
                CONTROL IFEQ STAT,1;
                ST$NIB = ST$NIB + 1;
                CONTROL FI; 
  
                END 
              END 
# 
              PROCESS INPUT BUFFER
# 
  
            CONTROL IFEQ STAT,1;
              IF NBTIN[CURIND] NQ NBTOUT[CURIND]
              THEN           # UPLINE NETWORK MESSAGES TO PROCESS      #
                BEGIN 
                OTIME(STIME);    # GET SYSTEM TIME BEFORE NEIB CALL    #
                WORK = TRUE;
            CONTROL FI; 
  
              FOR CURIND = CURIND WHILE NBTIN[CURIND] NQ
                                        NBTOUT[CURIND]
              DO
                BEGIN        # FOR EACH BLOCK IN INPUT BUFFER          #
                ACTIVENPU = TRUE; 
                P<DRHDRWD> = NBTOUT[CURIND];
                BUFSIZ = BLKBS[0];  # SAVE BUFFER SIZE                 #
  
                CONTROL IFEQ DEBUG,1; 
                TIMESECS[0] = RTSECS[0];# REAL TIME NETWK HAS UP       #
                BPIPINW[BPIPINP] = TIMEWORD[0];# WRITE TIME IN BUFF    #
                BPIPINP = BPIPINP + 1;# INCR BUFFER OFFSET PTR         #
                IF BPIPINP GR 999 
                THEN
                  BPIPINP = 0;# INITIALIZE OFFSET PTR TO BEGINNING     #
# 
                COPY INBOUND BLOCKS TO DEBUG BUFFER 
# 
                P<TRAP> = 0;
                FOR TRAPINDEX = 0 STEP 1 UNTIL BUFSIZ - 1 
                DO
                  BEGIN 
                  BPIPINW[BPIPINP] = WORD[P<DRHDRWD>+TRAPINDEX];
                  BPIPINP = BPIPINP + 1;# INCR BUFFER OFFSET PTR       #
                  IF BPIPINP GR 999 
                  THEN
                    BPIPINP = 0;# INITIALIZE OFFSET PTR TO BEGINNING   #
                  END 
                CONTROL FI; 
  
                CONTROL IFEQ ZZDN,1;
                P<SUPMSG> = P<DRHDRWD> + BLKHSIZE + ABHSIZE;
                IF PFC[0] NQ NPU  OR PFCSFC[0] EQ NPUIN 
                THEN
                  BEGIN 
                    IF KNAMLB[0]
                    THEN      # FLAG SET TO LOG NETWORK TRAFFIC        #
                      BEGIN 
                      TWRITE(BPFET,P<DRHDRWD>,BUFSIZ) ; 
                      MSGCNT = MSGCNT + 1;  # INCREMENT COUNT OF MSGS  #
                      IF BPAT[0] NQ 0 
                      THEN   # I/O ERROR HAS OCCURRED ON DEBUG LOG FILE#
                        BEGIN 
                        OPRETN(BPFET);  # RETURN BAD FILE              #
                        OPITRCE(ZNRF1,0);  # REINITIALIZE DEBUG LOG FIL#
                        END 
                      END 
                  END 
                CONTROL FI; 
  
                NEIB1(P<DRHDRWD>,NBTHN[IND]) ;
                NBTOUT[CURIND] = NBTOUT[CURIND] + BUFSIZ; 
                END 
  
                CONTROL IFEQ STAT,1;
                  OTIME(ETIME);# GET SYSTEM TIME AFTER PROCESSING BUF  #
                  STTEMP = EMILS[0] - SMILS[0]; 
                  IF STTEMP GR ST$LNI 
                  THEN       # FOUND LARGER TIME INTERVAL              #
                    BEGIN 
                    ST$LNI = STTEMP; # LARGEST TIME INTERVAL           #
                    END 
                  IF STTEMP GR 200
                  THEN       # SPENT MORE THAN .2 SECONDS IN INTERVAL  #
                    BEGIN 
                    ST$MNI = ST$MNI + 1; # INCR NO OF TIMES > .2 SEC   #
                    END 
                  ST$TNI = ST$TNI + STTEMP;  # INCR TOTAL TIME PROCESS #
                  END 
                CONTROL FI; 
  
# 
            RELEASE REMAINING BUFFER IF NECESSARY 
# 
            IF NBTBRF[CURIND] 
            THEN
              BEGIN 
NEIB2END: 
              PURGREG;        # PIP MAY HAVE UPDATED IN - FORCE CM READ#
              IF NBTIN[CURIND] EQ NBTOUT[CURIND]  # IF BUFFER EMPTY    #
              THEN
                BEGIN 
                P<DRHDRWD> = NBTOUT[CURIND];
                BLKBS[0] = NBTLIMIT[CURIND] - NBTOUT[CURIND]; 
                MRELS(P<DRHDRWD>);
                NBTBRF[CURIND] = FALSE; 
                NBTIN[CURIND] = NBTLIMIT[CURIND]; 
                NBTOUT[CURIND] = NBTLIMIT[CURIND];
                JALLOC = TRUE;
                GOTO NEIB2LOOP;  # PROCESS OTHER INBOUND BUFFER#
                GOTO NEIB2END;   # FORCE WORD ALIGNMENT OF LABEL# 
                END 
  
              END 
          END 
        END 
# 
      PROCESS MESSAGES IN INTRA-HOST A-A MESSAGE QUEUE
# 
  
      CONTROL IFEQ STAT,1;
        IF NOT WORK 
        THEN                 # NIP PROCESSED UPLINE MESSAGE            #
          BEGIN 
          ST$ENB = ST$ENB + 1;  # INCREMENT NO OF TIMES FOUND NO WORK  #
          END 
      CONTROL FI; 
  
  
      P<LLCB> = TNTLLAD[0]; 
      IF P<LLCB> NQ 0 
      THEN
        BEGIN 
        P<DRHDRWD> = 0; 
        BUF = LLCBSHFP[0];  # FIRST MSG IN LIST                        #
        FOR I=I WHILE BUF NQ 0
        DO
          BEGIN 
          LLCBSHFP[0] = NEXTPTR[BUF];  # UPDATE FORWARD PTR            #
          NBTIDX = NBTMAXID + 1;       # NBT INDEX FOR INTRAHOST MSG   #
          NEIB1(BUF,0)  ;  # PROCESS MESSAGE                           #
          BUF = LLCBSHFP[0];
          END 
        END 
      END 
TERM
