Trailing-Edge
-
PDP-10 Archives
-
AP-D543V_SB
-
swpser.mac
There are 6 other files named swpser.mac in the archive. Click here to see a list.
TITLE SWPSER - HANDLES I/O FOR SWAPPER - V11113
SUBTTL SWPSER R.KRASIN/AW/CMF/AF/DJB/DAL 08 NOV 77
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VSWPSR,11113
ENTRY SWPSER
SWPSER:
INTERN FT2REL,SQIN,SQOUT,ESQREQ
EXTERN CPOPJ,CPOPJ1,JBTCHK,TPOPJ,P2WLSH
;INTERNALS REQUIRED IN SWAP
INTERN SQREQ,SERA,SWPSPC,SQIN,SQOUT
EXTERN FINISH,GET4WD,GIV4WD,JBTSWP,JBYSUN,JBYLKN,SWPUNI,SWAPIO
EXTERN DODELE
EXTERN UNISLB,UNIFKS,UNISWP,UNIPTR,UNYCFS,UNYK4S
;THIS CODE SERVES AS AN INTERFACE BETWEEN THE SWAPPER (SCHED1) AND
;I/O CODE FOR SWAPPING DEVICES (FILSER)
IFE FTVM,<
;HERE TO PUT A REQUEST IN THE SWAPPING QUEUE. ENTER AT SQIN FOR
; INPUT, SQOUT FOR OUTPUT
;CALL: MOVE T2,XWD -NUMBER OF WORDS,FIRST CORE LOCATION (IE IOWD+1)
; HRRZ T1,DISK BLOCK NUMBER
; PUSHJ P,SQIN/SQOUT
; RETURN HERE ALWAYS
; CONTENTS OF T1,T2,T3,T4,F,U,S LOST
SQIN: TDZA S,S ;CLEAR S, INCLUDING IO
SQOUT: MOVSI S,IO ;CLEAR S, SET IO
MOVEM T1,SERA ;STORE THE BLOCK NUMBER
MOVEM T2,SQREQ ;STORE THE IOWD
MOVEM T2,ESQREQ ;SAVE IN CASE OF DISK ERROR ON FRAGMENTED JOB
HRRZ T1,T2 ;T1 = ADDRESS OF FIRST WORD SWAPPED
CAMGE T1,SYSSIZ## ;IS IT ABOVE MONITOR?
STOPCD .,STOP,S2L, ;SWAP TOO LOW
;NO--WE ARE ABOUT TO SWAP THE MONITOR
; STOP HERE TO PRESERVE STATE.
IFN FTPDBS,< ;IF WE SWAP PDB'S
SKIPGE SCREQ## ;IS THE SWAPPING CHANNEL FREE?
JRST SCGRAB ;YES--GO GET IT
SKIPN SCUSER## ;NO--DOES THE MOINTOR OWN IT?
JRST SQGO ;YES--FINE. KEEP GOING
SCGRAB: SETZM SCUSER## ;FLAG THAT MONITOR HAS THE RESOURCE
AOSE SCREQ## ;GO GET THE RESOURCE
STOPCD .,STOP,SIB, ;++SWAPPER IS BUSY
> ;END FTPDBS
ERATRY==3 ;NUMBER OF TIMES TO READ AND WRITE ON ERRORS
;HERE TO START UP DEVICE WITH SWAPPING REQUEST. THIS ROUTINE
;IS CALLED FROM DISK INTERRUPT SERVICE, AS WELL AS FROM ABOVE.
;IF A SWAPPER REQUEST IS WAITING (SQREQ WILL BE NON-ZERO)
SQGO: MOVEI T2,ERATRY
MOVEM T2,SERACT
SQGO1: SETZM SQLEN ;ZERO AMOUNT TRANSFERRED SO FAR
MOVE T2,SQREQ ;*PUT IOWD INTO T2
MOVSI T1,200000 ;*SET "SWAPPER I/O GOING" FLAG ON
ORB T1,SERA ;*
TRZN T1,FRGSEG ;*FRAGMENTED ?
JRST SQGO2 ;*NO, READ IN ENTIRE (OR PART) OF SEG
FRAGIO: MOVN T3,SQLEN ;AMOUNT PREVIOUSLY TRANSFERRED
SUB T2,T3 ;INCREASE CORE ADDRESS BY PREVIOUS WORD COUNT
FRGIO1: HLRE T3,(T1) ;NUMBER OF K IN THIS DISK CHUNK
HRR T1,(T1) ;SWAPPING ADDRESS FOR THIS DISK CHUNK
JUMPGE T3,FRGIO2 ;POINTER TO NEW CORE LIST IF NEGATIVE
MOVEI T3,377777 ;CLEAR OUT ADR (17 BITS)
ANDCAM T3,SERA ;
ORM T1,SERA ;INSERT NEW ADDRESS
JRST FRGIO1 ;NOW RETRIEVE ADDRESS
FRGIO2: LSH T3,P2WLSH ;CONVERT FROM K TO WORDS
ADDM T3,SQLEN ;ADD TO PREVIOUSLY TRANSFERRED AMOUNT
MOVNS T3 ;-N WORDS
HLRO T4,SQREQ
CAMG T3,T4 ;COMPARE WITH - NUMBER WORDS FOR REST OF SEG
HRL T2,T4 ;SWAPPER ONLY WANTS TO READ A PORTION OF SEG
; NOT ALL OF IT (R,RUN,GET,KJOB COMMAND)
HRLM T3,T2 ;IOWD IN T2
MOVNS T3 ;+NUMBER OF WORDS FOR THIS NEXT TRANSFER
HRLZS T3
ADDM T3,SQREQ ;UPDATE LH OF IOWD FOR ENTIRE SEG, SO IT HAS
; -NUMBER OF WORDS LEFT AFTER THIS TRANSFER IS DONE
PUSHJ P,SAVE1## ;P1 AND J MUST BE PRESERVED IN CALLS TO SWPINT
PUSH P,J
PUSHJ P,SQGO2 ;REQUEST NEXT FRAGMENT TO BE TRANSFERRED
PJRST JPOPJ##
SQGO2: MOVEI F,SWPDDB## ;ADDR OF SWAPPING DDB
IFE FT2SWP,<
HLRZ U,SWPUNI
>
IFN FT2SWP,<
LDB U,UNZCFS## ;GET INDEX OF THIS UNIT
MOVE U,SWPTAB##(U) ;GET ADDR OF THIS UNIT
>
LDB T1,UNZFKS## ;GET 1ST LOGICAL K IN SWAPPING AREA
ROT T1,BLKSPP## ;CONVERT TO BLOCKS
ADD T1,UNISLB(U) ;AND TO LOGICAL BLOCK NUMBER
TRZ S,IODTER!IODERR!IOIMPM!IOBKTL!IOCHMP!IOCHNX ;MAKE SURE NO ERROR BITS.
SOJA T2,SWAPIO ;MAKE T2 AN IOWD AND PUT IN IO QUEUE
;HERE TO SERVICE A SWAPPING INTERRUPT
; S WILL HAVE IO+IOSMON+ERROR BITS SET UP
; U WILL CONTAIN THE ADDRESS OF THE UNIT
; P4 WILL CONTAIN THE NUMBER OF BLOCKS TRANSFERRED
EXTERNAL MBKLSH,UNIICT,UNIOCT
INTERNAL SWPINT
SWPINT: TLNE S,IO ;READING
ADDM P4,UNIOCT(U) ;NO, COUNT BLOCKS WRITTEN
TLNN S,IO ;READING
ADDM P4,UNIICT(U) ;YES, COUNT BLOCKS READ
TRNE S,IODTER!IODERR!IOIMPM ;ANY ERRORS?
JRST SWPDON ;YES, (MAY INCLUDE IOCHNX AND IOCHMP)
MOVE T2,P4 ;NUMBER OF BLOCKS TRANSFERRED
HRLS T2
LSH T2,BLKLSH## ;CONVERT TO WORDS
ADD T2,SWPDMP## ;UPDATE IOWD
JUMPGE T2,SWPIN1 ;FINISHED IF POSITIVE
MOVE T1,P4 ;NOT THROUGH - STOPPED AT END OF CYLINDER
ADDB T1,SWPBLK## ;UPDATE BLOCK NUMBER (T2 HAS NEW IOWD)
PJRST SWAPIO ;GO QUEUE THE NEXT CHUNK
SWPIN1: MOVE T1,SERA ;* GET BITS+FRAGMENT POINTER
TRZE T1,FRGSEG ;*FRAGMENTED ?
SKIPL T2,SQREQ ;*YES, MORE IOWD TO GO ?
JRST SWPDON ;NO, ALL DONE SWAP IN OR OUT
AOS SERA ;YES, FRAGMENTED AND MORE TO GO
SKIPE 1(T1) ;IS THIS THE END OF SWAP COMMAND LIST ?
AOJA T1,FRAGIO ;NO, BO DO NEXT PIECE OF FRAGMENTED SEG
SWPDON:
IFN FTPDBS,< ;IF WE SWAP PDB'S
SKIPE SCUSER## ;MONITOR I/O
JRST [SETZM SQREQ ;NO--UUO CAUSED THIS SWAP
POPJ P,] ;DISMISS INTERUPT
MOVE J,FINISH
> ; END FTPDBS
IFE FTPDBS,<
MOVM J,FINISH
>
MOVE T1,ESQREQ ;FIRST ADR SWAPPED IN OR OUT
IFN FTKI10!FTKL10,<
PUSHJ P,GETCHK## ;MAKE FIRST WORD OF THE SEGMENT ADDRESSABLE
; ADDRESS RETURNED IN T1
>;END IFN FTKI10!FTKL10
MOVE T1,(T1) ;GET CONTENTS
HLRE T2,ESQREQ
MOVNS T2
LSH T2,MBKLSH ;CONVERT TO # OF BLOCKS
TLNE S,IO ;READING?
JRST [
MOVEM T1,JBTCHK(J) ;NO, SAVE CHECKSUM (WRITING)
JRST SWPCHK] ;FINISH, DO NOT RETRY ON SWAP OUT ERRS
; (FILSER ALREADY HAS RETRIED ALL ERRS
; SWAPPER WILL TRY IN NEW PLACE UNLESS
; CHANNEL ERROR (IOCHNX!IOCHMP)
CAMN T1,JBTCHK(J) ;YES, CORRECT CHECKSUM ?
JRST SWPCHK ;YES. EXIT
TRO S,IOIMPM ;SET SOFTWARE CHECKSUM ERROR FLAG
HLRZ T1,JBTSWP(J) ;*SWAP LOC (DISK ADR OR TABLE ADR)
HRRM T1,SERA ;*RESTORE SERA
MOVE T1,ESQREQ ;*RESTORE FROM ESQREQ IN CASE OF FRAGMENTED JOB
MOVEM T1,SQREQ
;HERE TO CHECK FOR ERRORS BEFORE EXIT FROM INTERFACE
SWPCHK: TRNE S,IODTER!IODERR!IOIMPM ;ANY ERRORS?
TRNE S,IOCHNX!IOCHMP ;YES, DO NOT RETRY IF CHANNEL NXM OR
; MEM PARITY (SINCE FILSER HAS ALREADY TRIED
; AND APR SWEEP WILL CLEAR PARITY)
JRST SWPFIN ;NO, DO NOT RETRY
SOSG SERACT ;*TRIED ENOUGH ?
JRST SWPFIN ;*YES, ERROR
MOVE T1,ESQREQ ;*NO, RESET POINTERS (NEEDED IF FRAGMENTED)
MOVEM T1,SQREQ
MOVE T1,JBTSWP##(J)
HLRZM T1,SERA
JRST SQGO1 ;*TRY AGAIN
SWPFIN: HRRZM S,SERA ;CLEAR I/O FLAG,SAVE ERROR BITS
SETZM SQREQ ;NO SWAP REQUEST
PUSHJ P,STOIOS## ;EXIT INTERRUPT
PJRST NJBTST## ;SEE IF THE NULL JOB IS RUNNING AND IF SO
; CAUSE A CLOCK INTERRUPT
> ;END IFE FTVM
;HERE TO START PAGING/SWAPPING I/O IN A MONITOR WHICH INCLUDES VM
IFN FTVM,<
SQIN::SQOUT::
MOVEI F,SWPDDB## ;SWAPPING DDB
AOS DEVDMP##(F) ;INSURE DEVDMP NON-ZERO SO ERROR RECOVERY WILL HAPPEN
DSKOFF ;NO INTERRUPTS HERE
AOS T1,SQREQ ;COUNT UP THE NUMBER OF PAGING/SWAPPING I/O REQUESTS
SOJE T1,SWAPIO## ;START SWAPPING/PAGING I/O IF NOT ALREADY GOING
DSKON ;I/O IN PROGRESS, GO AWAY
POPJ P,
;HERE WHEN PAGING/SWAPPING I/O IS DONE IN A MONITOR WHICH INCLUDES VM
SWPINT::SOSGE SQREQ ;COUNT DOWN THE NUMBER OF PAGING/SWAPPING I/O
; REQUESTS OUTSTANDING
STOPCD CPOPJ,DEBUG,SWN,;++SQREQ WENT NEGATIVE
PUSHJ P,SAVE2## ;SAVE P1,P2
MOVE P2,(P1) ;P2 = THE SWPLST ENTRY
SUBI P1,SWPLST## ;P1 = RELATIVE ADDRESS INTO SWPLST OF ENTRY
HRRZ J,SW3LST##(P1) ;SEGMENT NUMBER SWAPPING/PAGING IS DONE FOR
TLNE P2,(SL.SIO) ;SWAPPING I/O?
JRST SWPIN1 ;YES
MOVE T1,J ;PAGING I/O, JOB NUMBER TO T1 STPIOD
PUSHJ P,STPIOD## ;PUT JOB INTO PAGE I/O SATISFIED STATE
TLNN P2,(SL.DIO) ;PAGE OUT?
JRST [PUSHJ P,ZERSLE## ;NO, RETURN THE DISK SPACE
JRST SWPIN3] ;PROCEED
PUSHJ P,SVEUB## ;MAKE THE UPMP ADDRESSABLE
SETOM .UPMP+.UPPGB ;INDICATE PAGES OUT BUT NOT GIVEN BACK TO
; FREE CORE YET
JRST SWPIN3 ;PROCEED
SWPIN1:
TLNN P2,(SL.DIO) ;SWAP OUT?
CAILE J,JOBMAX## ;NO, HIGH SEGMENT SWAP IN?
JRST SWPIN2 ;YES, PROCEED
HRRZ T2,JBTUPM##(J) ;ADDRESS OF THE PAGE ALLOCATED TO THE UPMP
SKIPL T1,SWPLST(P1) ;CANT BE THE UPMP IF FRAG'D
LDB T1,[POINT 13,SWPLST(P1),26]
CAIE T1,(T2) ;SWAPPING IN THE UPMP?
JRST SWPIN2 ;NO
TRO T1,PM.ACC+PM.WRT+IFN FTKL10,<PM.CSH> ;YES, ACCESSABLE AND WRITABLE
HLRZ T2,JBTSWP##(J) ;FIRST PAGE OF THE JOB
TRO T2,PM.ACC+PM.WRT+IFN FTKL10,<PM.CSH> ;ALSO ACCESSABLE PLUS WRITABLE
HRRM T1,.EPMP##+.MECKS ;MAKE THE UPMP ADDRESSABLE
CLRPGT (0) ;FLUSH THE HARDWARE P.T.
HRLM T1,.ECKSM+.MUPMP ;MAKE THE UPMP P.T. ADDRESSABLE
HRRM T2,.ECKSM+.MJDAT ;AND PAGE 0
JRST SWPIN4
SWPIN2: SKIPGE JBTSWP##(J) ;RUN OUT OF CORE BLOCKS DURING FRAGMENTED SWAP IN?
SKIPG SWPLST##(P1) ;NOT IF NOT FRAGMENTED
SKIPA T1,JBTADR##(J) ;NO, ADDRESS OF THE SEGMENT
JRST SWPIN4 ;YES, SWAP IN NEXT FRAGMENT
SOSGE SPRCNT## ;DECREMENT SWAP IN PROGRESS COUNT
STOPCD CPOPJ,DEBUG,SNI, ;++SWAPPING NOT IN PROGRESS
TLNE P2,(SL.ERR+SL.CHN) ;I/O ERROR?
JRST SWPIN3 ;YES
PUSHJ P,GETCHK## ;MAKE THE CHECKSUM ADDRESSABLE
MOVE T1,(T1) ;GET THE CHECKSUM WORD
TLNE P2,(SL.DIO) ;SWAPPING OUT?
JRST [MOVEM T1,JBTCHK##(J) ;YES, STORE THE CHECKSUM WORD
JRST SWPIN3] ;AND PROCEED
MOVSI T2,(SL.CHK) ;ASSUME AN ERROR OCCURED
CAME T1,JBTCHK##(J) ;CHECKSUM THE SAME AS ON THE WAY OUT?
IORM T2,SWPLST##(P1) ;NO, INDICATE AN ERROR
SWPIN3: MOVE S,DEVIOS(F) ;SWAPPING DDB STATUS
SKIPN SQREQ ;STILL MORE SWAPPING OR PAGING I/O TO DO?
TRZ S,IOACT ;NO, THE DDB IS NO LONGER I/O ACTIVE
PUSHJ P,STOIOS## ;REMEMBER THAT IN THE DDB
PJRST NJBTST## ;START THE SCHEDULAR IF THE NULL JOB IS RUNNING
SWPIN4: PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE
CAMN J,.UPMP+.UPJOB ;RIGHT JOB?
TDZA P2,P2 ;YES
MOVSI P2,(SL.CHK) ;NO, SWAP READ ERROR
IORB P2,SWPLST##(P1) ;RESTORE P2 WITH POSSIBLE ERROR BIT
TLNE P2,(SL.ERR+SL.CHN+SL.CHK) ;I/O ERRORS?
SOSA SPRCNT## ;YES, DECREMENT SWAPS IN PROGRESS
SKIPA T1,P2 ;T1 = THE SWPLST ENTRY
JRST SWPIN3 ;SET I/O DONE SO ERROR WILL BE NOTICED
PUSHJ P,RTNDSP## ;RETURN UPMP DISK SPACE
PUSHJ P,DLTSLE## ;DELETE THE SWPLST ENTRY
PUSHJ P,BISLST## ;SETUP MEMTAB FOR LOW SEGMENT SWAP IN
AOS SQREQ ;ONE MONE SWAPPING REQUEST TO DO
POPJ P, ;RETURN TO FILIO
> ;END IFN FTVM
;SUBROUTINE TO FIND SPACE ON SWAPPING DEVICE
;ARG U=NUMBER 1K BLOCKS NEEDED
;CALL MOVEI U,1K BLOCKS NEEDED, PG.SLO=1 IF SWAP IN SLOW SWAP SPACE
; PUSHJ P,SWPSPC
; ERROR RETURN - SPACE NOT AVAILABLE
; OK RETURN - DEV ADDR STORED IN LH JBTSWP(J) AND IN T1
SWPSPC: PUSHJ P,SAVE4## ;SAVE GLOBAL ACS
MOVE P2,U ;P2=NUMBER 1K BLOCKS NEEDED
HLRZ U,SWPUNI ;GET ADDR OF FIRST UNIT FOR SWAPPING
IFN FTVM,<
TLZE P2,(PG.SLO) ;SLOW (DISK) SWAP SPACE WANTED?
HLRZ U,SWPUN2## ;YES, GET UNIT OF FIRST SLOW DISK IN ASL
>
IFN FT2SWP,<
;LOOP TO SCAN NEXT CLASS OF SWAPPING UNIT
GT0: SETZB P3,T3
LDB P1,UNYCFS ;GET CLASS FOR SWAPPING
HRL P1,U ;SAVE ADDR OF 1ST UNIT OF THIS CLASS
;LOOP TO SCAN NEXT UNIT IN ACTIVE SWAPPING LIST IN THIS CLASS
GT1: LDB T2,UNYCFS ;GET CLASS FOR SWAPPING OF THIS UNIT
CAIE T2,(P1) ;SKIP IF STILL SAME CLASS
JRST GT4 ;NO
> ;END CONDITIONAL ON FT2SWP
CAMLE P2,UNIFKS(U) ;SKIP IF ENOUGH ROOM ON THIS UNIT
JRST GT3 ;FORGET IT FOR NOW
MOVE T1,P2 ;T1 = NUMBER 1K BLOCKS NEEDED
PUSHJ P,GXSAT ;SEE IF CONTIGUOUS SPACE AVAILABLE
JRST GT2 ;NO
JRST FOUND ;YES
IFN FT2SWP,<
;HERE IF ENOUGH ROOM ON THIS UNIT, BUT NOT CONTIGUOUS
GT2: CAML P3,UNIFKS(U) ;SKIP IF THIS UNIT HAS MOST ROOM
JRST GT3 ;SOMEBODY BETTER IN THIS CLASS
MOVE P3,UNIFKS(U) ;REMEMBER SPACE ON BEST UNIT
MOVE T3,U ;AND ITS ADDR
;HERE TO CHECK NEXT UNIT IN THIS CLASS
GT3: HLRZ U,UNISWP(U) ;NEXT UNIT FOR SWAPPING
JUMPN U,GT1 ;JUMP IF NOT LAST UNIT FOR SWAPPING
;HERE IF END OF THIS CLASS AND NO UNIT HAD CONTIGUOUS SPACE
GT4: MOVE U,T3 ;SET U TO ADDR OF UNIT WITH MOST ROOM
CAMG P2,P3 ;SKIP IF NOT ENOUGH ROOM ON UNIT WITH MOST ROOM
JRST FOUND1 ;WE HAVE A WINNER
> ;END CONDITIONAL ON FT2SWP
IFN FT2REL,<
IFN FT2SWP,<
HLRZ U,P1 ;RESET ADDR OF 1ST UNIT THIS CLASS
;HERE TO SEE IF BY DELETING DORMANT SEGMENTS WE CAN CREATE ENOUGH
;SPACE ON A UNIT IN THE CURRENT CLASS
GT5: LDB T1,UNYCFS ;GET CLASS FOR SWAPPING OF THIS UNIT
CAIE T1,(P1) ;SEE IF STILL SAME CLASS
JRST GT0 ;NO
PUSHJ P,IFDELE## ;FIND OUT IF BY DELETING DORMANT SEGS CAN DO IT
JRST GT6 ;NO
> ;END CONDITIONAL ON FT2SWP
IFE FT2SWP,<
GT3:
GT6==CPOPJ##
>
PUSHJ P,DODELE ;RIGHT ON!
JRST GT6 ;THERE WAS JUST ROOM!
;HERE IF HAD TO DELETE DORMANT SEGMENTS - MAY NOW HAVE CONTIGUOUS SPACE
FOUND2: MOVE T1,P2 ;T1=1K BLOCKS NEEDED
PUSHJ P,GXSAT ;SEE IF CONTIGUOUS SPACE AVAILABLE
JRST FOUND1 ;NO
JRST FOUND ;YES!
;HERE IF DELETING DORMANT SEGMENTS DOESN'T HELP THIS UNIT
IFN FT2SWP,<
GT6: HLRZ U,UNISWP(U) ;TRY NEXT
JUMPN U,GT5
> ;END CONDITIONAL ON FT2SWP
> ;END CONDITIONAL ON FT2REL
IFN FT2SWP,<
HLRZ U,SWPUNI ;NO GOOD, MUST FRAGMENT ACROSS UNITS
PUSHJ P,DODELE ;DELETE ALL DORMANT SEGS ON 1ST UNIT
JFCL ;PROBABLY WONT MAKE IT
JRST FOUND1 ;GET AS MUCH AS POSSIBLE ON THIS UNIT.
;FOUND1 WILL MOVE TO NEXT UNIT IF NECESSARY
> ;END CONDITIONAL ON FT2SWP
;HERE IF CONTIGUOUS SPACE AVAILABLE ON UNIT WHOSE ADDR IS IN U
;T2 = FIRST LOGICAL J NUMBER, P2=T1=NUMBER NEEDED
FOUND:
IFN FTVM,<
CAILE P2,777 ;ONLY 9 BITS TO STORE # BLOCKS IN SWPLST
JRST FOUND1 ;SO FRAGMENT REQUEST IF MORE NEEDED
>
HRLM T2,JBTSWP(J) ;STORE LOGICAL K NUMBER OF SWAPPING SPACE
IFE FT2SWP,<
SETZ T2,
>
IFN FT2SWP,<
PUSHJ P,FNDU ;FIND U IN SWPTAB
> ;END CONDITIONAL ON FT2SWP
DPB T2,JBYSUN ;STORE INDEX IN JBTSWP
LDB T2,JBYLKN ;T2=1ST LOGICAL K
PUSHJ P,MRKALC ;MARK AS ALLOCATED
JRST SPCEX ;SET T1 AND OK RETURN FROM SWPSER
;HERE IF ROOM BUT HAVE TO FRAGMENT
IFE FT2SWP,<
GT2:
>
FOUND1: MOVEI T2,1
CAIE P2,1 ;DON'T FRAGMENT IF 1 PAGE
PUSHJ P,GET4WD ;GET 4 FREE LOCS
POPJ P, ;CANT - ABORT
IFN FTVM,<
SETZM 3(T1) ;ENSURE THAT THE LINK-WORD IS 0
>
MOVE P3,T1 ;P3=ADDR OF CORE BLOCKS
TRO T1,FRGSEG ;LIGHT FRAGMENTED BIT
HRLM T1,JBTSWP(J) ;STORE POINTER IN JBTSWP
HRLI P3,-4 ;KEEP POINTER TO FREE CORE
FND12: MOVE T3,P2 ;T3=SPACE STILL NEEDED
MOVE T1,T3
IFN FTVM,<
CAILE T1,777 ;ONLY GET 777 PAGES IN 1 REQUEST
MOVEI T1,777 ; SINCE ONLY 9 BITS IN SWPLST
>
IFE FT2SWP,<
SETZB T2,P4
>
IFN FT2SWP,<
PUSHJ P,FNDU ;FIND U IN SWPTAB
MOVE P4,T2 ;SAVE INDEX IN P4
> ;END CONDITIONAL ON FT2SWP
FND11: PUSHJ P,GXSAT
JRST FND13 ;DIDN'T MAKE IT, T1=SPACE AVAILABLE
FND14: HRLM T1,(P3) ;AMOUNT ALLOCATED
HRRM T2,(P3) ;FIRST LOGICAL K NUM
PUSHJ P,MRKALC ;MARK AS ALLOCATED
DPB P4,[POINT 3,(P3),22]
PUSHJ P,BMPAC3
SUBB T3,T1 ;DECREMENT AMOUNT NEEDED, PUT IN T1
JUMPG T1,FND11 ;STILL NEED MORE
SETZM (P3) ;END UP WITH A 0
SPCEX: HLRZ T1,JBTSWP(J) ;RESET T1 FOR EXIT
JRST CPOPJ1
FND13: JUMPE T1,NXUN ;JUMP IF NO MORE ROOM THIS UNIT
PUSHJ P,GXSAT ;GET THAT MUCH SPACE
STOPCD .,STOP,SSD, ;++SWAP SPACE DISAPPEARED
JRST FND14
;HERE IF FILLED CURRENT UNIT AND NEED MORE SPACE
; (ONLY IF FORCED TO FRAGMENT OVER UNITS)
NXUN:
IFN FT2SWP,<
HLRZ U,UNISWP(U) ;NEXT SWAPPING UNIT
SKIPN U
> ;END CONDITIONAL ON FT2SWP
STOPCD .,STOP,SRO, ;STOP IF NO MORE UNITS - SPACE RAN OUT
IFN FT2SWP,<
MOVE P2,T3 ;P2=NUMBER 1K BLOCKS STILL NEEDED
PUSHJ P,DODELE ;DELETE AS MUCH AS YOU CAN
JFCL ;MAY NOT BE ENOUGH YET
JRST FND12 ;RIGHT ON
;SUBROUTINE TO FIND ADDR CONTAINED IN U IN SWPTAB
;ARGS U=ADDRESS OF A UNIT DATA BLOCK
;CALL MOVEI U,ADDR
; PUSHJ P,FNDU
; RETURN - T2 SET UP. ADDR MUST BE IN THE TABLE
;VALUE T2=INDEX IN SWPTAB OF UNIT IN U
FNDU: SETZ T2,
CAME U,SWPTAB##(T2)
AOJA T2,.-1
POPJ P,
> ;END CONDITIONAL ON FT2SWP
;SUBROUTINE TO MARK BLOCKS ALLOCATED IN A UNIT'S SWAPPING AREA
;ARGS T1=HOW MANY TO ALLOCATE
; T2=1ST TO ALLOCATE
;PRESERVES T3,T1
MRKALC: PUSH P,T1
PUSH P,T3
SUBM T1,UNIFKS(U) ;DECREMENT FREE J FOR SWAPPING
MOVNS UNIFKS(U) ;COMES OUT NEGATIVE THAT WAY
IDIVI T2,^D36 ;T2=FULL WORDS, T3=BITS IN PARTIAL WORD
HRRZ T4,UNIPTR(U)
ADD T4,T2 ;COMPUTE ADDR OF 1ST BIT
MOVEI T2,^D36
SUB T2,T3 ;36-POSITION IN WORD=DESIRED QUANTITY
HRL T4,T2 ; IN LH OF T4
MOVE T3,T1 ;T3=HOW MANY
PUSHJ P,CSETOS ;MARK ONES
POP P,T3
JRST TPOPJ ;RESTORE T1 AND RETURN
;SUBROUTINE TO STEP P3 TO NEXT LOCATION OF TABLE BEING BUILT
BMPGET: MOVEI T2,1
PUSHJ P,GET4WD ;GET 4 MORE CELLS
JRST UNDD ;ABORT
IFN FTVM,<
SETZM 3(T1) ;CLEAR THE LINK-WORD
>
HRLI P3,-4
CAIN T1,(P3) ;ARE THEY CONTIGUOUS ?
JRST BMPACX ;YES, RETURN.
MOVE T2,-1(P3) ;NO, CONVERT LAST GOOD LOCATION
HRROM T1,-1(P3) ; TO A POINTER TO NEXT PART OF TABLE
MOVEM T2,(T1) ;STORE GOOD DATA IN FIRST WORD OF NEW PART
HRR P3,T1 ;NEW TABLE LOC
JRST BMPACL
BMPAC3: PUSH P,T1
PUSH P,T3
BMPACL: AOBJP P3,BMPGET ;COUNT WORD AND RETURN
JRST BMPACX
UNDD: HRRZ T1,-1(P3) ;RETURN LAST CHUNK OF
HLRE U,-1(P3) ; DISK SPACE AND TURN
SETZM -1(P3) ; THAT POINTER INTO AN
PUSHJ P,FXSAT1 ; END OF LIST MARKER
HLRZ T1,JBTSWP(J) ;CAN'T COMPLETE SWAP OUT
PUSHJ P,FXSAT ;RETURN SWAPPING SPACE
POP P,T1 ;***THROW AWAY SO THAT EXIT EXITS SWAPPER
BMPACX: POP P,T3
JRST TPOPJ ;EXIT
INTERNAL GXSAT,FXSAT
EXTERNAL SETZRS,CSETOS,CLGETZ
;SUBROUTINE "GXSAT" IS CALLED TO FIND A SERIES OF CONSECUTIVE FREE BLOCKS ON
; THE DISK TO SWAP SOME JOB OUT ONTO. IT IS CALLED AT CLOCK LEVEL.
;ARGS U=ADDRESS OF UNIT DATA BLOCK TO CHECK
; T1=NUMBER 1K BLOCK NEEDED
;VALUES T1=NUMBER 1K BLOCKS CAN ALLOCATE (BIGGEST HOLE IF LESS THAN REQUEST)
; T2=1ST LOGICAL K NUM IF REQUEST CAN BE SATISFIED
;CALLING SEQUENCE ---
; MOVEI T1,1K BLOCKS NEEDED
; MOVEI U,ADDR
; PUSHJ P,GXSAT
; ERROR EXIT -- THE DISK IS FULL, NO SWAPPING SPACE AVAILABLE.
; NORMAL EXIT
;ACCUMULATORS T4, T1, T2 ARE DESTROYED BY THIS SUBROUTINE.
GXSAT: PUSH P,T3 ;THIS ROUTINE SAVES AND RESTORES ACCUMULATOR "T3".
MOVE T3,T1
MOVE T1,UNIPTR(U) ;AOBJN POINTER TO SWAPPING SAT TABLES
SETZ T2,
IFN FTDHIA&FT2SWP,<
MOVE T4,UNIUST##(U) ;IF NO NEW ACCESSES FOR THIS UNIT,
TLNE T4,UNPNNA##
JRST GXSAT1 ;CANT GET ANY SPACE ON IT
>
PUSHJ P,CLGETZ ;CALL ROUTINE IN FILSER TO SEARCH FOR 0 BITS
JRST GXSAT1 ;NOT ENOUGH
AOS -1(P) ;OK, SKIP RETURN
HRRZ T1,UNIPTR(U) ;COMPUTE LOGICAL K NUM FROM POSITION IN TABLE
MOVEI T2,1(T4)
SUB T2,T1 ;FULL WORDS FROM BEGINNING OF TABLE+1
IMULI T2,^D36 ;TIMES 36 BITS
HLRZ T1,T4
SUB T2,T1 ;-POSITION IN WORD
SKIPA T1,T3
GXSAT1: MOVE T1,T2
POP P,T3 ;RESTORE T3
POPJ P,
;SUBROUTINE "FXSAT" IS CALLED TO RETURN A SERIES OF CONSECUTIVE DISK BLOCKS TO
; THE FREE STORAGE POOL, THUS MAKING THEM AVAILABLE FOR RE-USE IN HANDLING
; FUTURE SWAPPING REQUESTS. IT IS CALLED AT CLOCK LEVEL.
;CALLING SEQUENCE ---
; PUSHJ P,FXSAT
; NORMAL EXIT
;ENTRY CONDITIONS ---
; C(T1) = LOGICAL BLOCK NUMBER OF THE FIRST DISK BLOCK IN THE
; SERIES WHICH IS TO BE MADE AVAILABLE.
; C(U) = NUMBER OF CONSECUTIVE 1K BLOCKS OF DISK SPACE WHICH
; ARE TO BE MADE AVAILABLE.
;EXIT CONDITIONS ---
; THE REQUESTED BITS IN THE SWAPPING SPACE AVAILABILITY TABLE
; (NAMELY, SWPTAB) HAVE BEEN CLEARED TO ZERO.
;ACCUMULATORS U, T1, T2, ARE DESTROYED BY THIS SUBROUTINE.
EXTERNAL GIV4WD
FXSAT: TRZN T1,FRGSEG ;FRAGMENTED ?
JRST FXSAT1 ;NO, NO HASSLE HERE
PUSHJ P,SAVE1## ;SAVE P1
FRAGBK: HRRZ P1,T1 ;YES, LOC OF TABLE IN P1
FRGBK1: HRRZ T1,(P1) ;LOC OF NEXT DISK ADDRESS
HLRE U,(P1) ;NUMBER OF K
JUMPLE U,FRGBK2 ;GIVE UP FREE CORE IF NOT REAL ADDRESS
PUSHJ P,FXSAT1 ;GIVE UP THE DISK SPACE FOR THIS PART
AOBJP P1,FRGBK1 ;COUNT WORD OF TABLE, GET NEXT
FRGBK2: HRRZ T2,P1 ;LOC OF TABLE
HLRZ T1,P1 ;T1=NUMBER OF WDS IN TABLE
SUB T2,T1 ;T2=1ST WORD OF BLOCK
LSH T1,-2 ;T1=NUMBER WORDS-1
AOS T1 ;CONVERT TO NUMBER OF 4 WORD BLOCKS
MOVE P1,(P1)
PUSHJ P,GIV4WD ;GIVE UP FREE CORE
SKIPE T1,P1 ;END OF TABLE ?
JRST FRAGBK ;NO, GO CHASE NEXT PART
POPJ P, ;YES, DONE
FXSAT1::
MOVE T2,U ;T2=NUMBER 1K BLOCKS TO RETURN
IFE FT2SWP,<
HLRZ U,SWPUNI ;GET ADDR OF UNIT DATA BLOCK
>
IFN FT2SWP,<
LDB U,UNZCFS## ;GET INDEX OF UNIT IN SWPTAB
MOVE U,SWPTAB##(U) ;GET ADDR OF UNIT DATA BLOCK
>
EXCH T1,T2 ;T1=HOW MANY, T2=START LOC
TRZ T2,760000 ;CLEAR OUT UNIT INDEX
; PJRST CSETZS ;CLEAR BITS AND INCREMENT UNIFKS
;SUBROUTINE TO MARK 0'S IN SWAPPING SAT TABLE
;ARGS T1=HOW MANY
; T2=1ST LOGICAL K NUMBER
;CLOBBERS T3,T4
CSETZS:
IFN FTDHIA&FT2SWP,<
MOVE T3,UNIUST##(U) ;IF NO NEW ACCESSES FOR THIS UNIT (GOING DOWN SOON),
TLNN T3,UNPNNA## ; DONT CHANGE UNIFKS (=0)
>
ADDM T1,UNIFKS(U) ;INCREMENT COUNT OF FREE K FOR SWAPPING
IDIVI T2,^D36 ;GET FULL WORDS IN TABLE
HRLS T2 ;BOTH HALVES
ADD T2,UNIPTR(U) ;POINTER TO FIRST WORD TO MODIFY
PJRST SETZRS
IFN FTCHECK+FTMONP, <
EXTERNAL SQREQ,SERA,SERACT
EXTERNAL BLKSPK
>
IFE FTCHECK+FTMONP, <
;DATA ASSOCIATED WITH THE SWPSER LOGIC ---
INTERNAL SQREQ,SERA,SERACT
$LOW
SQREQ: Z ;C(LH)=NEGATIVE OF SIZE OF READ/WRITE
; C(RH)=LOCATION OF FIRST WORD TO READ/WRITE
ESQREQ: Z ;COPY OF SQREQ IN CASE OF SWAP ERROR ON FRAGMENTED JOB.
SERA: Z ;SIGN IS 1 IF A READ
;BIT 1=1 IF SWAP IO IN PROGRESS
;RH(BEFORE IO) BIT 18=1 IF JOB FRAGMENTED
;BIT 19-35 ADDRESS OF FRAGMENT TABLE IF JOB FRAGMENTED
;BIT 21-35 DSK SWAPPING AREA BLOCK# IF NOT FRAGMENTED
;RH(AFTER IO)BITS 18-35 FROM RH OF S
SERACT: 0 ;COUNTER FOR ERRORS
SQLEN: 0 ;AMOUNT TRANSFERRED SO FAR FOR FRAGMENTED JOB
$HIGH
> ;END OF FTMONP CONDITIONAL
$LIT
SWPEND: END