         PCC      0
*
*M*      LMMON    LOAD MODULE MONITOR
*
*T*      COPYRIGHT, (C) HONEYWELL INFORMATION SYSTEMS INC., 1979.
*
*P*      NAME:    LMMON
*
*P*      PURPOSE:
*,*         THIS PROGRAM PERFORMS THE DATA-COLLECTION FUNCTIONS FOR
*,*         LOAD MODULE USE MONITORING.
*P*      DESCRIPTION:
*P*         THIS PROGRAM PERFORMS THE DATA-COLLECTION FUNCTIONS FOR
*P*         LOAD MODULE USE MONITORING.  THE FOLLOWING POINTS SHOULD
*P*         BE NOTED:
*P*
*P*         1)  THE PROGRAM MUST BE RUN AS A GHOST JOB IN THE :SYS
*P*             ACCOUNT;
*P*
*P*         2)  THE 'LMMON' PATCHES TO CP-V MUST HAVE BEEN INSTALLED
*P*             AT BOOT TIME;
*P*
*P*         3)  THE PROGRAM MUST HAVE BEEN LOADED WITH THE PROPER
*P*             VERSION OF MONSTK (:J1);
*P*
*P*         4)  THE PROGRAM RUNS AT A PRIORITY OF X'E0', ON THE
*P*             MASTER CPU ONLY (IF ON A MULTIPROCESSOR SYSTEM),
*P*             WITH A HARD SWAPPING-INHIBIT (M:HOLD) IN EFFECT;
*P*
*P*         5)  THE PROGRAM MUST BE RUN WITH THE NAME 'LMMON';
*P*
*P*         6)  THE PROGRAM SHOULD BE TERMINATED BY AN 'INT,LMMON.'
*P*             OPERATOR KEYIN.
*
         TITLE    'LMMON - LOAD MODULE MONITOR'
         SYSTEM   BPM
         SYSTEM   SIG9P
*
*
SIZE     EQU      11                ** SIZE OF DATA AREA **
*
*
R0       EQU      0                 REGISTER EQUATE
R1       EQU      1                 REGISTER EQUATE
R2       EQU      2                 REGISTER EQUATE
R3       EQU      3                 REGISTER EQUATE
R4       EQU      4                 REGISTER EQUATE
R5       EQU      5                 REGISTER EQUATE
R7       EQU      7                 REGISTER EQUATE
R8       EQU      8                 REGISTER EQUATE
R9       EQU      9                 REGISTER EQUATE
R10      EQU      10                REGISTER EQUATE
R11      EQU      11                REGISTER EQUATE
R12      EQU      12                REGISTER EQUATE
R13      EQU      13                REGISTER EQUATE
R14      EQU      14                REGISTER EQUATE
R15      EQU      15                REGISTER EQUATE
X1       EQU      R1                REGISTER EQUATE
X2       EQU      R2                REGISTER EQUATE
X3       EQU      R3                REGISTER EQUATE
X4       EQU      R4                REGISTER EQUATE
X5       EQU      R5                REGISTER EQUATE
X6       EQU      R6                REGISTER EQUATE
X7       EQU      R7                REGISTER EQUATE
SR1      EQU      R8                REGISTER EQUATE
SR2      EQU      R9                REGISTER EQUATE
SR3      EQU      R10               REGISTER EQUATE
SR4      EQU      R11               REGISTER EQUATE
DECA     EQU      R12               REGISTER EQUATE
D1       EQU      R12               REGISTER EQUATE
D2       EQU      R13               REGISTER EQUATE
D3       EQU      R14               REGISTER EQUATE
D4       EQU      R15               REGISTER EQUATE
DISABLE  CNAME    X'37'             SET INTERRUPT INHIBITS
ENABLE   CNAME    X'27'             CLEAR INTERRUPT INHIBITS
         PROC
LF       WD,0     NAME
         PEND
         REF      J:JIT             TO SEE IF RUN AS A GHOST
         REF      J:ACCN            TO ENSURE THAT WE'RE :SYS
         REF      SYSACCT           DOUBLEWORD TEXT ':SYS'
         REF      MPATCH            MONITOR PATCH AREA
         REF      S:CUN             CURRENT USER #
         REF      UB:PRIO           USER'S PRIORITY
         REF      UB:PRIOB          USER'S BASE PRIORITY
         REF      X80               'MASTER CPU ONLY' BIT
         REF      S:CUP             CURRENT USER'S PRIORITY
         SREF     UB:MPFLG          MULTIPROCESSOR FLAGS
         REF      NEWQ              FOR VERIFYING MONSTK
         REF      J:PTIME           PROCESSOR TIME
         REF      J:UTIME           USER TIME
         REF      J:CALCNT          CAL COUNT
         REF      TPACCESS          TAPE ACCESSES
         REF      DPACCESS          PACK ACCESSES
         REF      DCACCESS          RAD ACCESSES
         REF      C:TIC             TIME SINCE BOOT
         REF      J:DELTAT          QUANTUM TIME LEFT
         REF      J:IDELTAT         LENGTH OF QUANTUM
         REF      UH:FLG2           USER FLAGS (FOR M:HOLD)
         REF      Y2                X'20000000' IN LITERALS
         REF      M16               X'0000FFFF' IN LITERALS
         REF      BT31TO0           BITS IN LITERALS MODULE
         REF      NB31TO0           BITS IN LITERALS MODULE
X800     EQU      BT31TO0+12        X800 ISN'T DEF'ED (SNAFU)
NX800    EQU      NB31TO0+12
DEBUG    EQU      0
*
*   LMMON normally runs with the 'DON'T SWAP' bit set(M:HOLD).  This
*   however may not be desired for smaller systems and/or systems
*   which tend not to invoke many Load Modules(IE. once a Load Module
*   is called, it is used a long time).  The following switch(NOTSWAP)
*   is used to control the SWAP bit.  When it is 1(default) LMMON
*   won't be swapped.  When 0 it will be.
NOTSWAP  EQU      1                 1 MEANS DON'T SWAP; 0 MEANS SWAP
*
*   Copyright text
*
COPYRITE DSECT   0
         TEXT 'COPYRIGHT, (C) HONEYWELL INFORMATION SYSTEMS INC., 1979.'
         CSECT
         PAGE
BEGIN    M:SYS                      GET MASTER MODE
         BCS,8    NOSYS             QUIT IF FAILED
         CI,SR3   NEWQ              VERIFY MONSTK
         BNE      BADMONSTK         QUIT IF WE HAVE THE WRONG ONE
         LC       J:JIT             TEST IF GHOST JOB
         BCR,4    NOTGHOST          QUIT IF NOT
         LCI      2                 2 WORDS IN ACCOUNT #
         LM,R8    J:ACCN            GET ACCOUNT NUMBER
         CD,R8    SYSACCT           ARE WE IN :SYS?
         BNE      NOT:SYS           CRY IF NOT
         LI,R7    X'FFFF'           GET ADDRESS OF FIRST FREE
         AND,R7   MPATCH              WORD IN THE PATCH AREA
FINDPOOL AI,R7    -1                LOOK BACK THRU PATCH AREA
         CI,R7    MPATCH            HAVE WE RUN OFF
         BL       NOPOOL              THE BEGINNING? QUIT IF SO
         LW,R2    0,R7              GET WORD FROM THE PATCH AREA
         CW,R2    L('HOOK')         IS IT THE HOOK-AREA INDICATOR?
         BNE      FINDPOOL          IF NOT TRY THE NEXT WORD
         LW,R1    S:CUN             GET MY USER NUMBER
         LI,R2    X'E0'             SET UP A NICE HIGH PRIORITY
         STB,R2   UB:PRIOB,R1       BASE PRIO,
         STB,R2   UB:PRIO,R1        CURRENT PRIO,
         STW,R2   S:CUP             CURRENT PRIO FOR OTHERS TO SEE
         LI,R2    UB:MPFLG          USER MULTI-CPU TABLE IF THERE
         BEZ      $+4               IF NOT, MONO-PROCESSOR SYSTEM
         LB,R3    UB:MPFLG,R1       IF THERE, GET OUR FLAGS
         OR,R3    X80                 AND SET PERMANENT
         STB,R3   UB:MPFLG,R1           'MASTER CPU ONLY' FLAG
UPDATE   M:OPEN   F:LOGFILE,(INOUT),(ABN,NOFILE)
         M:PFIL   F:LOGFILE,(EOF)
         B        SAYHELLO
NOFILE   CW,SR3   L(X'03000000'+F:LOGFILE)
         BE       MAKENEW           IF NOT THERE, MAKE A NEW FILE
         M:SNAP   'FILE ERR',(1,0)  SNAPSHOT REASON
         M:TYPE   (MESS,IOERR)
         M:EXIT
MAKENEW  M:OPEN   F:LOGFILE,(OUT),(CONSEC),(SAVE)
         M:CLOSE  F:LOGFILE,(SAVE)
         B        UPDATE            GO OPEN JOURNAL IN UPDATE
SAYHELLO LI,R2    999               CODE FOR 'LMMON STARTED'
         STW,R2   TIMEBUF           STORE AS FIRST WORD
         M:TIME   TIMEBUF+1         GET THE CURRENT TIME
         M:WRITE  F:LOGFILE,(BUF,TIMEBUF),(SIZE,20),(WAIT)
         M:XCON   DIE               SET UP ZONK-OUT ROUTINE
         M:INT    BREAK             SET UP FOR '!INT LMMON.'
         DISABLE                    ** DISABLE **
         DO       NOTSWAP
           LH,R2    UH:FLG2,R1        GET FLAGS
           OR,R2    X800              SET "DON'T SWAP" FLAG
           STH,R2   UH:FLG2,R1        RESTORE FLAGS
         FIN
         STW,R1   2,R7              STORE MY USER # IN BUFFER
         LW,R5    R7                GET POINTER
         AI,R5    3
         SLS,R5   2                 MAKE IT A BYTE ADDRESS
         OR,R5    Y2                SET BYTE COUNT TO 20
         LI,R4    BA(MYID)          POINT TO MY LMN INFO
         MBS,R4   0                 MOVE LMN/ACCT TO BUFFER
         BAL,R3   PUTTIME           PUT ACCTNG INFO INTO BUFFER
         STW,R1   1,R7              IDENTIFY MYSELF AS THE BIG MAN
         B        PROCESS           GO STORE THE DATA
PAUSE    ENABLE                     ** ENABLE **
TEST     DISABLE                    ** DISABLE **
         LI,R2    0
         MTW,0    2,R7              DID SOMEBODY CALL?
         BNEZ     PROCESS           IF SO GO RECORD THE DATA
         MTW,0    BROKEN            WERE WE INTERRUPTED?
         BNEZ     DONE              IF SO GO CLOSE UP SHOP
         B        PAUSE             GO SLEEP AWHILE
PROCESS  LW,R6    R7                COPY POINTER
         LI,R5    SIZE              # OF WORDS TO COPY
COPYER   LW,R4    SIZE+1,R6         GET WORD FROM TABLE
         STW,R4   BUFFER-1,R5       SAVE IN BUFFER
         AI,R6    -1                MOVE BACK TO PREVIOUS WORD
         BDR,R5   COPYER            GET THE NEXT WORD FROM MPATCH
         LI,R4    0
         STW,R4   2,R7              CLEAR USER #
         DO       DEBUG             IF DEBUGGING FLASH ALARM LITE
         LI,R3    5000
         WD,0     X'41'             TURN ON ALARM
         BDR,R3   $                 SPIN FOR A BIT
         WD,0     X'40'             TURN OFF ALARM
         FIN
         ENABLE                     ** ENABLE **
         M:WRITE  F:LOGFILE,(BUF,BUFFER),(SIZE,SIZE*4),(WAIT)
         B        TEST              GO LOOK FOR FURTHER INFO
BREAK    MTW,1    BROKEN            SET 'BREAK HIT' FLAG
         M:TRTN                     RETURN & WAKE UP
DONE     MTW,1    WRAPUP            BEEN THROUGH HERE BEFORE?
         BGZ      FINISH            IF SO GO CLOSE FILE
         LCW,R4   S:CUN             NEGATE MY USER #
         STW,R4   2,R7              PUT IT IN THE BUFFER
         BAL,R3   PUTTIME           GET ACCTNG INFO INTO BUFFER
         B        PROCESS           GO SAVE FINAL DATA
DIE      M:SNAP   'XCON REG',(1,0)  CORONER'S REPORT
         M:SYS                      'CAUSE XCON RETURNS IN SLAVE MODE
FINISH   LI,R1    0
         STW,R1   1,R7              ERASE MY ID NUMBER
         DISABLE                    ** DISABLE **
         LW,R1    S:CUN             CLEAR MY "DON'T SWAP" FLAG
         LH,R2    UH:FLG2,R1          SO THAT I CAN M:CLOSE THE
         AND,R2   NX800                 JOURNAL FILE SAVELY WITHOUT
         STH,R2   UH:FLG2,R1              GETTING A "B803" ERROR.
         ENABLE                     ** ENABLE **
         M:XCON   0                 CLEAR EXIT CONTROL
         M:TIME   TIMEBUF+1         GET MONITORING-DONE TIME
         LI,R2    -999              CODE FOR "LMMON OFF"
         STW,R2   TIMEBUF
         M:WRITE  F:LOGFILE,(BUF,TIMEBUF),(SIZE,20),(WAIT)
         M:CLOSE  F:LOGFILE,(SAVE)  CLOSE JOURNAL
         M:TYPE   (MESS,KAPOOF)     TELL THE OPERATOR
         M:EXIT                     VANISH IN A PUFF OF SMOKE
         SPACE    2
*
*        THIS CODE ESSENTIALLY DUPLICATES THE CODE ADDED TO THE
*        PATCH AREA IN ROUTINE 'RECORD', CALLED FROM STEPOVR
*        AND LDLNK - IT IS USED ONLY TO RECORD THE TIME AND
*        I/O USAGE FOR THE LMMON GHOST ITSELF, SINCE THE
*        RECORD LOGIC WON'T SEE LMMON COMING OR GOING.
*
         SPACE    1
PUTTIME  LW,R5    J:PTIME
         AW,R5    J:PTIME+1         FOR SHARED PROCESSORS
         AW,R5    J:UTIME
         AW,R5    J:UTIME+1         FOR UNSHARED PROGRAMS
         AW,R5    J:DELTAT          -(TIME LEFT IN QUANTUM)
         SW,R5    J:IDELTAT         -(QUANTUM LENGTH)
         STW,R5   8,R7              STORE CPU TIME
         LW,R5    J:CALCNT          GET CAL COUNT
         STW,R5   9,R7              SAVE IT
         LW,R5    M16               GET A 16-BIT MASK
         AND,R5   J:JIT+TPACCESS    GET TAPE ACCESSES
         AW,R5    J:JIT+DPACCESS    ADD PRIV. PACK ACCESSES
         AW,R5    J:JIT+DCACCESS    ADD RAD/PUBL. PACK ACCESSES
         STW,R5   10,R7             SAVE IT
         LW,R5    C:TIC             TMS SINCE BOOT
         STW,R5   11,R7             SAVE IT
         LI,R5    0                 LINKAGE COUNT = 0
         STW,R5   12,R7             SAVE IT
         B        0,R3              GO HOME
         PAGE
NOSYS    M:TYPE   (MESS,NOM:SYS)
         M:EXIT
NOT:SYS  M:TYPE   (MESS,BADACCT)
         M:EXIT
NOPOOL   M:PRINT  (MESS,NOHOOKS)
         M:EXIT
NOTGHOST M:TYPE   (MESS,NOGHOST)
         M:EXIT
BADMONSTK M:TYPE  (MESS,BADJ1)
         M:EXIT
         PAGE
MONHERE  TEXTC    'LMMON HERE'
ABORT    TEXTC    'LMMON HAS ABORTED'
KAPOOF   TEXTC    'LMMON OFF'
NOM:SYS  TEXTC    'COULDN''T GET MASTER MODE'
BADACCT  TEXTC    'LMMON MUST BE RUN IN THE :SYS ACCOUNT!'
BADJ1    TEXTC    'LMMON''S :MONSTK HAS GONE SOUR - RELOAD!'
NOGHOST  TEXTC    'LMMON MUST BE RUN AS A GHOST JOB!'
NOHOOKS  TEXTC    'LMMON NEEDS LMMONAID PATCHES IN THE MONITOR!'
IOERR    TEXTC    'I/O ERROR OPENING FILE'
BUFFER   RES      SIZE
TIMEBUF  DATA     0
         RES      4
BROKEN   DATA     0
WRAPUP   DATA     -1                'FINISHED' FLAG
MYID     TEXTC    'LMMON'           THIS IS WHO I AM
         TEXT     '    '            MAKE IT 3 WORDS
         TEXT     ':SYS    '        WHIS IS WHERE I'M AT
F:LOGFILE DSECT   1
F:LOGFILE M:DCB   (FILE,':LMMON'),OUT,SAVE,CONSEC
         USECT    BEGIN
         END      BEGIN
