.TITLE CKP .IDENT /1.5/ ;+ ; ; ; CKP... is designed to keep GEN clear of 'deadwood', ie stopped tasks. ; 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, WE'RE ALL DONE SEARCHING TST T.STAT(R1) ;; IS TASK ALREADY BLOCKED? BNE LOOP ;; IF NE, YES, SKIP IT .IFDF BL27 ;; IF V3.X TSTB T.CKR(R1) ;; TASK ALREADY BEING CHECKPOINTED OUT? .IFF ;; IF V3.2 BIT #TS.CKR,T.STAT(R1);;TASK ALREADY BEING CHECKPOINTED OUT? .ENDC ;; BNE LOOP ;; IF NE, YES, SKIP IT BIT #T2.CHK,T.ST2(R1);; 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,T.ST2(R1) ;; IS TASK STOPPED? BEQ LOOP ;; IF NE, NO, SKIP IT TSTB T.IOC(R1) ;; IS THERE ANY OUTSTANDING I/O? BNE LOOP ;; IF NE, YES, SKIP THIS TASK ALSO .IFDF BL27 ;; IF V3.X TSTB T.TIO(R1) ;; IS THERE ANY BUFFERED I/O? .IFF ;; IF V3.2 BIT #T2.TIO,T.ST2(R1);; ANY BUFFERED I/O .ENDC ;; 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