*DECK DB$MTR
USETEXT CDCSCTX 
      PROC DB$MTR;
      BEGIN 
 #
* *   DB$MTR -- CDCS MONITOR                     PAGE  1
* *   C O GIMBER                                 10/30/75 
* *   BOB MCALLESTER                             05/31/84 
* 
* DC  PURPOSE 
* 
*     CDCS MONITOR
*         CHECKS FOR ANY OPERATOR COMMANDS. 
*         ROLLS OUT CDCS WHEN THERE ARE NO OUTSTANDING REQUESTS AND 
*         THE OPERATOR IS NOT VIEWING THE CDCS CONSOLE DISPLAY. 
*         TERMINATES CDCS IF THE TERMINATION FLAG, DB$TRMF, IS SET AND
*         THERE ARE NO ACTIVE USERS.
* 
* DC  CALLING ROUTINES
*     CDCS INITIALIZATION PUTS MONITOR INTO THE TQT AND RCB. IT IS
*     CALLED BY THE SCHEDULER ONCE FOR EVERY LOOP THRU THE RCB. 
* 
* DC  CALLED ROUTINES 
# 
      XREF PROC DB$CMOH;     #CLEANUP MANAGED MEMORY# 
      XREF PROC DB$DDFE;           # DISPLAY MANAGER FRONT END  # 
      XREF PROC DB$DROT;           # DISPLAY MANAGER - ROLL OUT TASKS  #
      XREF PROC DB$FLOP;     #GENERATE A FLOW POINT#
      XREF FUNC DB$FTBZ B;   #TRUE IF CDCS HAS A BUSY FET#
      XREF PROC DB$RSDC;     #RESET DELAY COUNTS# 
      XREF PROC DB$RCLL;     #RECALL CONTROL POINT PROC#
      XREF PROC DB$SCHD;     #CDCS SCHEDULER# 
      XREF PROC DB$ROLL;     #ROUTINE TO ROLL OUT CDCS# 
      XREF PROC DB$MSG;      #SEND MESSAGE TO DAYFILE#
      XREF PROC DB$MSGB;     #SEND MESSAGE TO B DISPLAY#
      XREF PROC DB$MSG2;     #CLEAR LINE 2 OF B DISPLAY#
      XREF PROC DB$ODLC;     #DECREMENT OVCAP LOCK COUNTS # 
      XREF PROC DB$TERM;     #CDCS TERMINATE PROCESSOR# 
# 
* DC  ENTRY CONDITIONS
* 
*     SCHEDULER HAS SCANNED ALL OTHER ENTRIES IN THE RCB. 
 #
  
# 
*     CDCS COMMON.
* 
*     XDEF VARIABLES
# 
      XDEF ITEM CRMRC   I = 0;     # COUNT DB$CRMC CALLS SINCE DB$MTR  #
      XDEF ITEM DB$BTF  B = FALSE; # TRUE IF IN CDCSBTF                #
      XDEF ITEM DB$DCWE B = FALSE; # TRUE IF AN OPERATOR CONSOLE       #
                                   # WATCHER EXISTS (THE K/L DISPLAY   #
                                   # HAS BEEN ASSIGNED TO CDCS).       #
      XDEF ITEM DB$DNAA I = 0;     # NUMBER OF ACTIVE AREAS            #
      XDEF ITEM DB$DNAS I = 0;     # NUMBER OF ACTIVE SCHEMAS          #
      XDEF ITEM DB$DNAU I;         # NUMBER OF ACTIVE CDCS USERS       #
      XDEF ITEM DB$DNTU I;         # TOTAL USERS SINCE INITIALIZATION  #
      XDEF ITEM DB$DSST S:SACSTAT = S"UP";  # CDCS SYSTEM STATUS       #
      XDEF ITEM DB$DWSC B = FALSE; # TRUE IF WATCHER STATUS CHANGED    #
                                   # (E.G. A WATCHER APPEARED).        #
      XDEF ITEM DB$RCBW B= FALSE;  # TRUE IF A NEW REQUEST IS WAITING  #
      XDEF ITEM DB$TMST I = 0;     # 18 BIT TIMESTAMP. COUNTS NUMBER OF#
                                   # TIMES MTR LOOP HAS BEEN EXECUTED. #
      XDEF ITEM DB$TRMF B = FALSE; # TRUE IF CDCS SHOULD END WHEN      #
                                   # NO ACTIVE USERS EXIST             #
      XDEF ITEM RJRSW   B = FALSE; # TRUE IF CDCS SHOULD               #
                                   # RESTRICT JOURNAL RECORDS          #
      XDEF ITEM ROFSW   B = FALSE; # TRUE IF CDCS SHOULD               #
                                   # REDUCE OUTPUT FILE                #
      XDEF ITEM REQSCHD I = 0;     # NUMBER OF REQUESTS SCHEDULED      #
                                   # SINCE THE LAST RECALL.            #
      XDEF ITEM ROLLABLE B = TRUE; # TRUE IF CDCS CAN BE ROLLED OUT    #
# 
*     XREF VARIABLES
# 
      XREF ITEM AAM$PBC;     # PRIORITY BLOCK COUNT                    #
      XREF ITEM DB$RLLA;     #POINTS TO THE LAST ID ENTERED            #
      XREF ITEM DB$RLLE;     #LAST WORD IN THE LIST                    #
      XREF ARRAY DB$RA0;
        BEGIN 
        ITEM SWAPLIST (00,00,60); 
        END 
      XREF ITEM DB$ROAF I;   #ROLL OUT ATTACH FLAG                     #
# 
*     LOCAL VARIABLES 
# 
      ITEM ACTIVEMSG C(14) = "  CDCS ACTIVE:";
      ITEM IDLEMSG C(12) = "  CDCS IDLE:";
      ITEM IDLEMSG2 C(25) = "  CDCS IDLE - NO ROLLOUT:";
  
      ITEM I;                #DUMMY LOOP INDEX# 
      ITEM INACTCOUNT = DFSWAPDELAY;   #IDLE COUNTER FOR SCP SWAPOUT# 
      BASED ARRAY JLFIT;     #DUMMY LOG FILE FIT# 
        ITEM JLCOMP B(0,59,1); #COMPLETE BIT# 
      ITEM RCBSAVED;         #SAVED RCB ADDRESS - MONITOR"S RCB#
      ITEM SWAP B;           #SWAP OUT  IS OK FLAG                     #
      ITEM WASIDLE B = TRUE; # LAST IDLE STATUS                        #
  
  
  
#     B E G I N   D B $ M T R   E X E C U T A B L E   C O D E .        #
  
  
 #
* 
* DC  DESCRIPTION 
* 
*     CALL SCHEDULER. 
 #
LOOP: 
      DB$RCBW = FALSE;
      DB$SCHD(LOC(STATCOMP),0); 
 #
*     PROCESS ANY OPERATOR COMMANDS.
 #
      DB$DDFE;                         # DISPLAY MANAGER FRONT END #
 #
*     IF NO ACTIVE USERS AND TERM FLAG SET THEN 
*         CALL DB$TERM TO TERMINATE CDCS. 
*         WHEN RCPRIOR IS EQUAL TO RCNEXT, THERE IS AT MOST ONE OTHER 
*         RCB.  THAT IS NECESSARILY AN RCB WAITING FOR INPUT. 
*         THEN THERE ARE NO OUTSTANDING INTERNAL TASKS. 
 #
      IF DB$TRMF                   # IF CDCS SHOULD END WHEN INACTIVE  #
        AND DB$DNAU EQ 0           # AND NO ACTIVE USERS EXIST         #
        AND RCNEXT[0] EQ RCPRIOR[0]  # AND ONLY A WAITING INPUT RCB    #
      THEN
        DB$TERM;
  
      CRMRC = 0;
 #
*     INCREMENT INTERNAL TIMER. 
*     PERIODICALLY CALL DB$CMOH TO RELEASE UNUSED CODE CAPSULES.
 #
      TIMESTAMP = TIMESTAMP + 1;   # COUNT OF DB$MTR EXECUTIONS        #
                                   # USED FOR AGING EVENTS             #
      DB$TMST = B<42,18>TIMESTAMP; # TIMESTAMP AVAILABLE BY XREF       #
      IF TIMESTAMP LAN O"37" EQ 0 
      THEN
        BEGIN 
  
        CONTROL IFGR DFFLOP,0;
          DB$FLOP("* MTR32");      # FLOW POINT EVERY 32 EXECUTIONS    #
                                   # REQUIRED FOR LOOP DETECTION       #
        CONTROL ENDIF;
  
        AAM$PBC = PBCOUNT;
        IF TIMESTAMP LAN DFRETIRE - 1 EQ 0
        THEN
          BEGIN 
          DB$CMOH(1); 
          END 
        END 
 #
*     IF THERE HAS BEEN NO SIGNIFICANT PROCESSING SINCE THE LAST CALL 
*     TO DB$MTR AND THERE IS NOT MORE THAN ONE PF ATTACH PENDING THEN 
*       IF NO ACTIVITY FOR A DEFINED NUMBER OF CALLS,THEN 
*         CHECK ALL COMPLETE BITS.
*           (CHECK RCB CONSTRAINT FIELD AND JOURNAL LOG COMPLETE BITS)
*         IF THERE ARE NO OUTSTANDING SYSTEM REQUESTS THEN
*           SWAP OUT CDCS.
*       ELSE, ENTER RECALL. 
*     ZERO COUNT OF SCHEDULED JOBS. 
 #
      IF SCHDCOUNT EQ 1 
        AND DB$ROAF GQ 0
      THEN
        BEGIN 
        INACTCOUNT = INACTCOUNT - 1;
        IF INACTCOUNT EQ 0 THEN 
          BEGIN 
          INACTCOUNT = DFSWAPDELAY; 
          SWAP = TRUE;
          P<RCB> = RCNEXT[0]; 
 #
*     LOOP THROUGH ALL RCB"S, EXCEPT MONITOR"S, TO MAKE A LIST OF 
*     RUN UNIT IDS, MAXIMUM OF 5 MEMBERS, FOR ALL THE OS SWAPPED
*     OUT UCPS. 
 #
          DB$RLLA = LOC(DB$RLLA);      #LOAD THE ADDRESS AS THE CONTENT#
          FOR I = I WHILE LOC(RCB) NQ LOC(RCBMTR) 
          DO
            BEGIN                  #CHECK ALL RCB EXCEPT MONITOR# 
            IF RCCONSTRA[0] EQ LOC(STATBUSY)
              OR RCCONSTRA[0] EQ LOC(STATCOMP)
              OR RCCT[0] EQ DFWAITLOCK
            THEN
              BEGIN 
              IF RCOSSWP[0] 
              THEN           # USER JOB IS SWAPPED OUT BY THE OS       #
                BEGIN        # MAKE A LIST OF SWAPPED JOBS             #
                IF DB$RLLA EQ LOC(DB$RLLE)   #TEST IF LIMIT IS REACHED #
                THEN
                  BEGIN 
                  SWAP = FALSE;    #SWAP OUT CDCS IS PROHIBITED        #
                  P<RCB> = LOC(RCBMTR);    #TERMINATE LOOP AT MTR. RCB #
                  TEST I; 
                  END 
                DB$RLLA = DB$RLLA + 1;   #INCREASE THE LOCATION COUNTER#
                SWAPLIST[DB$RLLA] = RCIRRUID[0];  # STORE RUN UNIT ID  #
                END 
              END 
            ELSE
              BEGIN 
              SWAP = FALSE; 
              P<RCB> = LOC(RCBMTR); 
              TEST I; 
              END 
            P<RCB> = RCNEXT[0]; 
            END 
          IF NOT DB$DCWE           # IF NO CONSOLE WATCHER EXISTS      #
            AND SWAP               # AND OK TO SWAP CDCS OUT           #
            AND NOT DB$FTBZ        # AND NO FET IS BUSY                #
            AND ROLLABLE           # AND ROLL IS NOT INHIBITED         #
          THEN
            BEGIN            #ROLLOUT CDCS# 
  
            CONTROL IFGR DFFLOP,0;
              DB$FLOP("MTR-RO1");  # GENERATE FLOW POINT - ROLL OUT 1  #
            CONTROL ENDIF;
  
            DB$DROT;               # PERFORM DISPLAY ROLL OUT TASKS    #
            DB$MSG2;               # CLEAR LINE 2 OF THE B DISPLAY     #
            DB$MSGB(ACTIVEMSG);    # CDCS ROLLED OUT WHILE ACTIVE      #
            DB$ROLL;
            DB$RSDC;               # RESET DELAY COUNTS OF WAITNG TASKS#
            SCHDCOUNT = 0;
            GOTO LOOP;
            END 
          END 
        END 
      ELSE
        BEGIN 
        INACTCOUNT = DFSWAPDELAY; 
        END 
      SCHDCOUNT = 0;
 #
*     UNLOCK THE DISPLAY DRIVER OVCAP IF IT IS LOCKED IN BUT THE
*     K DISPLAY IS NOT IN USE.
 #
      IF RCOVCAPS[0]
        AND NOT DB$DCWE 
      THEN
        BEGIN 
        DB$ODLC;                   # UNLOCK THE OVCAP                  #
        END 
 #
*     ROLL OUT CDCS FL IF THERE ARE NO ACTIVE USERS 
*     AND THERE ARE NO NEW REQUESTS WAITING 
*     AND THERE IS NO CONSOLE DISPLAY WATCHER.
* 
*     OTHERWISE, GO INTO CPU RECALL.
*     RECALL RELINQUISHES THE CPU FOR APPROXIMATELY 25 MILLISECONDS.
 #
      IF TQTCHAIN EQ LOC(TQT) 
        AND RCNEXT[0] EQ RCPRIOR[0] 
        AND NOT DB$RCBW 
        AND NOT DB$DCWE 
        AND ROLLABLE
      THEN
        BEGIN 
  
        CONTROL IFGR DFFLOP,0;
          DB$FLOP("MTR-RO2");      # GENERATE FLOW POINT - ROLL OUT 2  #
        CONTROL ENDIF;
  
        DB$ROAF = 0;               # CLEAR ROLL OUT ATTACH FLAG        #
        DB$RLLA = LOC(DB$RLLA);    # SET SWAPPED OUT JOB LIST TO EMPTY #
        DB$DROT;                   # PERFORM DISPLAY ROLL OUT TASKS    #
        DB$CMOH(1);                # CLEAN UP MEMORY BEFORE ROLLING OUT#
        DB$CMOH(2); 
        DB$MSG2;                   # CLEAR LINE 2 OF THE B DISPLAY     #
        DB$MSGB(IDLEMSG);          # CDCS IDLE                         #
        DB$ROLL;                   # ROLLOUT FL (ROLLED IN WHEN RETURN)#
        END 
  
      IF TQTCHAIN EQ LOC(TQT) 
      THEN
        BEGIN 
        IF NOT WASIDLE
        THEN
          BEGIN 
          DB$MSG2;                 # CLEAR LINE 2 OF THE B DISPLAY     #
          IF ROLLABLE 
          THEN
            BEGIN 
            DB$MSGB(IDLEMSG);      # CDCS IDLE                         #
            END 
          ELSE
            BEGIN 
            DB$MSGB(IDLEMSG2);     # CDCS IDLE - NO ROLLOUT            #
            END 
          END 
        WASIDLE = TRUE; 
        END 
      ELSE
        BEGIN 
        WASIDLE = FALSE;
        END 
  
      IF NOT DB$RCBW               # IF THERE ARE NO NEW REQUESTS      #
        OR REQSCHD GQ 8            # OR SEVERAL REQUESTS HAVE BEEN     #
                                   # SCHEDULED SINCE LAST RECALL       #
      THEN
        BEGIN 
        REQSCHD = 0;
        DB$RCLL(0);                # GO INTO RECALL                    #
        END 
      GOTO LOOP;
      END 
      TERM; 
