.TITLE CKP .IDENT /3/ ;+ ; ; ; ; This privileged program is intended to run on RSX-11M BL31 or greater only. ; It will checkpoint all checkpointable tasks that are stopped and ; have no outstanding I/O. The purpose of this program is to clear ; out the 'DEADWOOD' that might be sitting around in memory and using up ; needless pool. When this program runs on a periodic schedule (such as ; once per minute) pool fragmentation seems to be minimized. ; ; Three modes of operation are possible. First, LDLIB can request CKP... ; to clear out GEN to make room for a transient resident library. If the ; receive data succeeds, and the task is LDLIB, CKP... tries to checkpoint ; everything it can in GEN. Second, CKP... can be rescheduled to run ; periodically at startup (STARTUP.CMD). If this is done, there is no ; data in the receive queue for reschedule runs, and CKP... has CO: as its ; TI: and no checks as to terminal privilege are made. Third a privileged ; user can run CKP... All other users will get a nasty little message. ; ; TO ASSEMBLE ; ; MAC CKP=[1,1]EXEMC/ML,[11,10]RSXMC/PA:1,[X,X]CKP ; ; TO TASK BUILD ; ; TKB CKP/PR=CKP,[1,54]RSX11M.STB/SS,[1,1]EXELIB/LB ; ;- .MCALL EXIT$S,ALUN$S,DIR$,QIOW$,RCVD$ ; LOCAL MACROS ; .MACRO PRINT STRING MOV #STRING,R0 CALL PNTLIN .ENDM PRINT .ENABL LC M1: .ASCII <15><12>/CKP... Your terminal is not privileged. Please do / .ASCIZ / not fool with system tasks/<7> .EVEN QIODPB: QIOW$ IO.WVB,2,2,,,,<0,0,0> ; WRITE TO TERMINAL RECEIV: RCVD$ LDLIB,BUF ; ONLY TAKE DATA FROM LDLIB BUF: .BLKW 15. ; RECIEVE BUFFER ALLFLG: .WORD 0 ; IF SET CHECKPOINT EVERYTHING START: ALUN$S #2,#"TI,#0 ; ASSIGN LUN 2 TO TI: ; SOMETHING STARTED US, WAS IT LDLIB INC ALLFLG ; ASSUME REQUEST FROM LDLIB DIR$ #RECEIV ; CMP $DSW,#IS.SUC ; DID WE GET DATA BEQ OK ; GOT DATA , GO DO IT 5$: CLR ALLFLG ; DON'T CHECKPOINT EVERYTHING MOV $TKTCB,R0 ; LETS FIND OUT IF TI: IS PRIVILEGED MOV T.UCB(R0),R0 ; CMP #.CO0,R0 ; IS THIS CO? BEQ OK ; IF SO, CKP THE BUGGERS BIT #U2.PRV,U.CW2(R0); IS IT PRIVILEGED BNE OK ; IF NE, USER IS PRIVILEGED PRINT M1 ; ISSUE ERROR MESSAGE JMP XIT ; EXIT OK: CALL $SWSTK,XIT ;; MOV @#$ACTHD,R1 ;; BEGIN WITH THE LOADER + 1 LOOP: MOV T.ACTL(R1),R1 ;; GET THE NEXT ACTIVE TASK BEQ RET ;; If EQ, at NULL task, done. MOV R1,R2 ;; Copy TCB address ADD #T.STAT,R2 ;; Point to task blocking bits BIT #^C,(R2)+;; Is task internally blocked? BNE LOOP ;; If NE, yes, try another ; TST T.STAT(R1) ;; IS TASK ALREADY BLOCKED? ; BNE LOOP ;; IF NE, YES, SKIP IT ; TSTB T.CKR(R1) ;; TASK ALREADY BEING CHECKPOINTED OUT? ; BNE LOOP ;; IF NE, YES, SKIP IT BIT #T2.CHK!T2.CKD,(R2) ;; Is task checkpointable? BNE LOOP ;; IF NE, NO, SKIP IT TST ALLFLG ;; SHOULD WE CHECKPOINT ALL ELIGIBLE TASKS BNE 20$ ;; IF NE, YES BIT #T2.STP,(R2) ;; IS TASK STOPPED? ; BEQ LOOP ;; IF NE, NO, SKIP IT BNE 10$ ;; If NE, yes, check for I/O BIT #TS.STP,-(R2) ;; Is task externally blocked? BEQ LOOP ;; If EQ, no, non-zero effective priority 10$: TSTB T.IOC(R1) ;; IS THERE ANY OUTSTANDING I/O? BNE LOOP ;; IF NE, YES, SKIP THIS TASK ALSO TSTB T.TIO(R1) ;; IS THERE ANY BUFFERED I/O? BNE LOOP ;; IF NE, YES, SKIP 20$: MOV T.PCB(R1),R2 ;; GET PCB FOR TASK CMP P.NAM(R2),#^RGEN;; IS THE PARTITION NAME 'GEN' BNE LOOP ;; IF NE, NO, LOOK AGAIN MOV R1,-(SP) ;; FOUND A VICTEM CALL $ICHKP ;; FLUSH THIS TASK NOW MOV (SP)+,R1 ;; RESTORE TCB ADDRESS BR LOOP ;; WHO ELSE GETS THE AX RET: RETURN ;; EXIT SYSTEM STATE XIT: EXIT$S ; THE END ;+ ; PNTLIN ; ; THIS ROUTINE WILL PRINT AN ASCIZ LINE ;- PNTLIN: MOV #-1,R1 ; GET COUNT INITIALIZED MOV R0,QIODPB+Q.IOPL ; STORE BUFFER ADDRESS 10$: INC R1 ; INCREMENT COUNTER TSTB (R0)+ ; IS THIS THE LAST BYTE? BNE 10$ ; NO. KEEP GOING MOV R1,QIODPB+Q.IOPL+2 ; STORE BYTE COUNT DIR$ #QIODPB RETURN .END START