Trailing-Edge
-
PDP-10 Archives
-
tops10_703a_sys_atpch16_bb-fr67f-bb
-
swpser.x16
There are 2 other files named swpser.x16 in the archive. Click here to see a list.
TITLE SWPSER - HANDLES I/O FOR SWAPPER - V1174
SUBTTL SWPSER R.KRASIN/AW/CMF/AF/DJB/DAL 26 NOV 85
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.
;
.CPYRT<1973,1986>
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
;
XP VSWPSR,1174
ENTRY SWPSER
SWPSER::
EXTERN JBYSUN,JBYLKN
;THIS CODE SERVES AS AN INTERFACE BETWEEN THE SWAPPER (SCHED1) AND
;I/O CODE FOR SWAPPING DEVICES (FILSER)
IDLEUN==1 ;LOOKING FOR AN IDLE UNIT IF 0
;HERE TO START PAGING/SWAPPING I/O IN A MONITOR WHICH INCLUDES VM
SQIN::
SQOUT:: MOVEI F,SWPDDB## ;SWAPPING DDB
AOS DEVDMP##(F) ;INSURE DEVDMP NON-ZERO SO ERROR RECOVERY WILL HAPPEN
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
PJRST DOPOPJ## ;I/O IN PROGRESS, GO AWAY
;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
TLC P2,(SL.SIO+SL.IPC) ;JUST SWAP OUT THE "IN" QUEUE?
TLCN P2,(SL.SIO+SL.IPC)
JRST SWPI4A ;YES, JUST GO FINISH UP
HRRZ J,SW3LST##(P1) ;SEGMENT NUMBER SWAPPING/PAGING IS DONE FOR
TLNE P2,(SL.SIO) ;SWAPPING I/O?
JRST SWPIN2 ;YES
TLNN P2,(SL.DIO) ;PAGE OUT?
JRST [PUSHJ P,ZERSLE## ;NO, RETURN THE DISK SPACE
JRST SWPIN1] ;PROCEED
PUSHJ P,SVEUB## ;MAKE THE UPMP ADDRESSABLE
MOVSI T1,(UP.PGB) ;INDICATE PAGES OUT BUT NOT GIVEN BACK TO
IORM T1,.USBTS ; FREE CORE YET
SWPIN1: MOVE T1,J ;PAGING I/O, JOB NUMBER TO T1 STPIOD
PUSHJ P,STPIOD## ;PUT JOB INTO PAGE I/O SATISFIED STATE
JRST SWPIN6 ;PROCEED
SWPIN2: TLNN P2,(SL.DIO) ;SWAP OUT?
CAILE J,JOBMAX## ;NO, HIGH SEGMENT SWAP IN?
JRST SWPIN3 ;YES, PROCEED
HRRZ T2,JBTUPM##(J) ;ADDRESS OF THE PAGE ALLOCATED TO THE UPMP
SE1ENT ;MUST BE IN SECTION 1 TO REFERENCE PAGTAB
SSX T2,MS.MEM ;PAGTAB SECTION
LDB T1,[POINT SL.SPN,SWPLST##(P1),<^L<SL.PPN>+SL.SPN-1>] ;ASSUME NOT FRAGD
SKIPL T3,SWPLST##(P1) ;FRAGMENTED?
SKIPA T2,PAGTAB(T2)
LDB T1,[POINT SL.SPN,1(T3),<^L<SL.PPN>+SL.SPN-1>] ;UPT IS SECOND ENTRY OF FRAGMENT IF IT IS
CAIE T1,(T2) ;SWAPPING IN THE UPMP?
JRST SWPIN3 ;NO
MOVE T3,.CPMAP##
HRRZ T1,JBTUPM##(J)
TLO T1,(<PM.DCD>B2+PM.WRT+PM.PUB+IFE FTMP,<PM.CSH>)
MOVE T2,JBTSWP##(J) ;PAGE WE LEFT OFF AT
TLO T2,(<PM.DCD>B2+PM.WRT+PM.PUB+IFE FTMP,<PM.CSH>)
MOVEM T1,.ECKSM/PAGSIZ##(T3)
CLRPGT (0) ;FLUSH THE HARDWARE P.T.
IFN FTKL10&FTMP,<
SKIPN [M.CPU##-1] ;SINGLE KL-10 MONITOR
TDO T1,[PM.CSH] ;YES, CACHE THE UPMP
>
TLO T1,(PM.COR)
MOVEM T1,.ECKSM+.UMUPT
MOVEM T2,.ECKSM+.UMJDT
MOVE T2,T1 ;SAVE STATE OF THE CACHE BIT
TLO T1,(PM.CSH)
MOVEM T1,.ECKSM+.UMUUP
SSX T1,MS.MEM ;PAGTAB SECTION
HRR T2,PAGTAB(T1)
TLO T2,(PM.COR)
MOVEM T2,.ECKSM+.UMUPM
TLO T2,(PM.PUB+PM.CSH) ;USER MAP WILL DECIDE PUBLIC/CONCEALED
MOVEM T2,.ECKSM+SECTAB
JRST SWPIN7
SWPIN3: SKIPGE JBTSWP##(J) ;RUN OUT OF CORE BLOCKS DURING FRAGMENTED SWAP IN?
TLNE P2,(SL.DIO) ;(ONLY IF SWAPIN)
JRST SWPI3A ;NO, GET ADDRESS OF SEGMENT
CAIG J,JOBMAX## ;THIS CASE CAN ONLY COME UP FOR A LOW SEG
JRST SWPIN7 ;YES, SWAP IN NEXT FRAGMENT
SWPI3A: MOVE T1,JBTADR##(J)
SWPIN4: TLNN P2,(SL.DIO) ;IF INPUT
SOSL SINCNT## ;DECREMENT SWAPPING INPUTS IN PROGRESS
SWPI4A: SOSGE SPRCNT## ;DECREMENT SWAP IN PROGRESS COUNT
STOPCD CPOPJ##,DEBUG,SNI, ;++SWAPPING NOT IN PROGRESS
TLNE P2,(SL.ERR+SL.CHN+SL.CHK+SL.IPC) ;I/O ERROR OR "IN" QUEUE SWAP OUT?
JRST SWPIN5 ;YES
PUSHJ P,GETCHK## ;MAKE THE CHECKSUM ADDRESSABLE
HRRZS T1 ;CLEAR POSSIBLE JUNK
MOVE T1,(T1) ;GET THE CHECKSUM WORD
TLNE P2,(SL.DIO) ;SWAPPING OUT?
JRST [MOVEM T1,JBTCHK##(J) ;YES, STORE THE CHECKSUM WORD
JRST SWPIN5] ;AND PROCEED
MOVSI T2,(SL.CHK) ;ASSUME AN ERROR OCCURED
CAME T1,JBTCHK##(J) ;CHECKSUM THE SAME AS ON THE WAY OUT?
JRST [IORM T2,SWPLST##(P1) ;NO, INDICATE AN ERROR
JRST SWPIN5] ;CONTINUE
LDB T1,NZSSCN## ;# OF NZS MAPS
JUMPE T1,SWPIN5
PUSHJ P,SVEUB## ;MAP JOB
SKIPGE T1,.USBTS ;REALLY BIG YET?
TLNN T1,(UP.NZS) ;AND NEED TO CALL BISLST?
JRST SWPIN5 ;NO
AOS SINCNT
AOS SPRCNT ;READJUST COUNTS
JRST SWPN7A ;CALL BISLST YET AGAIN
SWPIN5: MOVSI T1,(SL.DFM) ;ALLOW FNDSLE TO FIND THIS ENTRY
ANDCAB T1,SWPLST##(P1) ;SWPCNT AND SWPLST AGREE
TLC T1,(SL.FRG!SL.DIO)
TLCN T1,(SL.FRG!SL.DIO) ;WAS THIS FRAGMENTED OUTPUT?
TLNE T1,(SL.IPC) ;AND NOT THE PAGING QUEUE OR IPCF?
JRST SWPINA ;NO
PUSHJ P,SVEUB## ;POINT TO JOB
SKIPE T2,.USLPS ;RETURN VIRTUAL POINTER IF IT EXISTS
PUSHJ P,RTNVPN## ;(CAN'T ZERO SLOT AS IT'S NON-ZERO ON DISK)
SWPINA::
AOS SWPCNT## ;FLAG FOR CLOCK-LEVEL
SWPIN6: 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
SWPIN7: PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE
SWPN7A: CAMN J,.USJOB ;RIGHT JOB?
TDZA P2,P2 ;YES
MOVSI P2,(SL.CHK) ;NO, SWAP READ ERROR
IOR P2,SWPLST##(P1) ;RESTORE P2 WITH POSSIBLE ERROR BIT
TLNN P2,(SL.ERR+SL.CHN+SL.CHK) ;DON'T CLEAR SL.SIO IF ERROR
TLZ P2,(SL.SIO) ;CLEAR A BIT SO DLTSLE
MOVEM P2,SWPLST##(P1) ; WON'T SOS SWPCNT
TLNE P2,(SL.ERR+SL.CHN+SL.CHK) ;I/O ERRORS?
JRST SWPIN4 ;SET I/O DONE SO ERROR WILL BE NOTICED
PUSHJ P,ZERSLE## ;RETURN THE DISK SPACE
S0PSHJ 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
RELABP==40000
;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
; DEV ADDR WILL NOT BE STORED IN JBTSWP(J) IF J=0
SWPSPC::PUSHJ P,SAVE4## ;SAVE GLOBAL ACS
IFN FTXMON,<
PUSHJ P,SSEC1## ;MUST BE IN A NON-ZERO SECTION TO ADDRESS SATS
PUSH P,R ;RELOCATION (SECTION NUMBER)
HRRZS J ;MAKE SURE NO BITS
>
MOVE P2,U ;P2=NUMBER 1K BLOCKS NEEDED
HLRZ U,NXTSUN## ;GET ADDR OF NEXT UNIT FOR SWAPPING
HRRZ P4,SWPUN2## ;CLASS WHICH "SLOW" SWAPPING UNITS BELONG TO
SKIPN P4 ;IF "SLOW" UNITS ARE IN CLASS 0
TLZ P2,(PG.SLO) ; IGNORE REQUEST FOR "SLOW" SPACE
HLLZ P4,P2 ;REMEMBER PG.SLO
TLZE P2,(PG.SLO) ;SLOW (DISK) SWAP SPACE WANTED?
HLRZ U,SWPUN2## ;YES, GET UNIT OF FIRST SLOW DISK IN ASL
;LOOP TO SCAN NEXT CLASS OF SWAPPING UNIT
GT1: SETZB P3,T3
LDB P1,UNYCFS## ;GET CLASS FOR SWAPPING
HRL P1,U ;SAVE ADDR WHERE WE STARTED
;LOOP TO SCAN NEXT UNIT IN ACTIVE SWAPPING LIST IN THIS CLASS
GT2:
IFN FTMP,<
PUSHJ P,GETCAM## ;GET THE CPU ACCESSABILITY MASK FOR THIS UNIT
SKIPN MOFLPG## ;IF SETTING MONITOR MEMORY OFF LINE, ONLY
JRST GT2A ; ALLOCATE ON A UNIT ACCESSIBLE ON THE BOOT CPU
MOVN T2,BOOTCP## ;NEGATIVE OF BOOT CPU'S CPU NUMBER
TDNE T1,BITTBL##+^D35(T2) ;IS THE UNIT ACCESSIBLE ON THE BOOT?
GT2A: PUSHJ P,[PUSH P,T3 ;CPUOK CLOBBERS T3
PUSHJ P,CPUOK## ;IS UNIT ACCESSIBLE ON A RUNNING CPU?
JRST T3POPJ##;NO, NEXT UNIT
AOS -1(P) ;YES, SEE IF IT HAS SPACE
JRST T3POPJ##] ; " " "
JRST GT4 ;NEXT UNIT
>; END IFN FTMP
LDB T2,UNYCFS## ;GET CLASS FOR SWAPPING OF THIS UNIT
CAIE T2,(P1) ;SKIP IF STILL SAME CLASS
JRST GT5 ;NO
TLNN T3,IDLEUN ;IF 1ST TIME
SKIPN UNISTS##(U) ; USE UNIT IF IDLE
CAMLE P2,UNIFKS##(U) ;SKIP IF ENOUGH ROOM ON THIS UNIT
JRST GT4 ;FORGET IT FOR NOW
MOVE T1,P2 ;T1 = NUMBER 1K BLOCKS NEEDED
PUSHJ P,GXSAT ;SEE IF CONTIGUOUS SPACE AVAILABLE
JRST GT3 ;NO
JRST FOUND ;YES
;HERE IF ENOUGH ROOM ON THIS UNIT, BUT NOT CONTIGUOUS
GT3: TLNE T3,IDLEUN
CAML P3,UNIFKS##(U) ;SKIP IF THIS UNIT HAS MOST ROOM
JRST GT4 ;SOMEBODY BETTER IN THIS CLASS
MOVE P3,UNIFKS##(U) ;REMEMBER SPACE ON BEST UNIT
HRR T3,U ;AND ITS ADDR
;HERE TO CHECK NEXT UNIT IN THIS CLASS
GT4: HLRZ U,UNISWP##(U) ;NEXT UNIT FOR SWAPPING
MOVSS P1 ;UNIT SCAN WAS STARTED AT
TLNE T3,IDLEUN ;IF NOT FIRST PASS,
CAIE U,(P1) ;DON'T LOOK FUTHER IF ALL UNITS IN THIS CLASS SCANNED
JUMPN U,[MOVSS P1 ;PUT CURRENT CLASS BACK IN THE RH
JRST GT2] ;LOOK AT NEXT UNIT FOR SWAPPING
MOVSS P1 ;CURRENT CLASS
GT5: TLOE T3,IDLEUN ;1ST PASS?
JRST GT6 ;NO. NO CONTIGUOUS SPACE
PUSHJ P,FNDFUC ;YES, RESET U
JRST GT2 ; AND SETTLE FOR ANY UNIT
;HERE IF END OF THIS CLASS AND NO UNIT HAD CONTIGUOUS SPACE
GT6: HRRZ 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
PUSHJ P,FNDFUC ;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
GT7: LDB T1,UNYCFS## ;GET CLASS FOR SWAPPING OF THIS UNIT
CAIE T1,(P1) ;SEE IF STILL SAME CLASS
JRST GT1 ;NO
PUSHJ P,IFDELE## ;FIND OUT IF BY DELETING DORMANT SEGS CAN DO IT
JRST GT8 ;NO
PUSHJ P,DODELE## ;RIGHT ON!
JRST GT8 ;THERE WAS JUST ROOM!
;HERE IF HAD TO DELETE DORMANT SEGMENTS - MAY NOW HAVE CONTIGUOUS SPACE
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
GT8: HLRZ U,UNISWP##(U) ;TRY NEXT
JUMPN U,GT7
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
;SUBROUTINE TO RESET U TO THE FIRST UNIT IN CLASS (P1)
FNDFUC: MOVEI U,SWPUNI##-UNISWP##
FNDFU1: HLRZ U,UNISWP##(U) ;NEXT UNIT IN ASL
LDB T2,UNYCFS## ;SWAPPING CLASS
CAIE T2,(P1) ;FIRST UNIT IN THIS CLASS?
JRST FNDFU1 ;NO, LOOK AT THE NEXT UNIT
POPJ P, ;YES, RETURN U
;HERE IF CONTIGUOUS SPACE AVAILABLE ON UNIT WHOSE ADDR IS IN U
;T2 = FIRST LOGICAL PAGE NUMBER, P2=T1=NUMBER NEEDED
FOUND: CAILE P2,777 ;ONLY 9 BITS TO STORE # BLOCKS IN SWPLST
JRST FOUND1 ;SO FRAGMENT REQUEST IF MORE NEEDED
PUSH P,T2
PUSHJ P,FNDU ;FIND U IN SWPTAB
.CREF JBTSWP
DPB T2,[POINT 3,(P),17] ;STORE IT
.CREF JBYSUN
LDB T2,[POINT 18,(P),35] ;K NUMBER
.CREF JBYLKN
PUSHJ P,MRKALC ;MARK AS ALLOCATED
JRST SPCEX ;SET T1 AND OK RETURN FROM SWPSER
;HERE IF ROOM BUT HAVE TO FRAGMENT
FOUND1: MOVEI T2,1
CAIE P2,1 ;CAN'T FRAGMENT 1 PAGE
PUSHJ P,GET4WD## ;GET 4 FREE LOCS
IFE FTXMON,<
POPJ P, ;CANT - ABORT
>
IFN FTXMON,<
JRST RPOPJ## ;ABORT
>
SETZM 3(T1) ;ENSURE THAT THE LINK-WORD IS 0
MOVE P3,T1 ;P3=ADDR OF CORE BLOCKS
TLO T1,FRGSEG ;MARK AS FRAGMENTED
PUSH P,T1 ;SAVE ADDR
HRLI P3,-4 ;KEEP POINTER TO FREE CORE
FND11: MOVE T3,P2 ;T3=SPACE STILL NEEDED
MOVE T1,T3
PUSHJ P,FNDU ;FIND U IN SWPTAB
HRR P4,T2 ;SAVE INDEX IN P4, DON'T WIPE OUT LH BITS
FND12: CAILE T1,777 ;ONLY GET 777 PAGES IN 1 REQUEST
MOVEI T1,777 ; SINCE ONLY 9 BITS IN SWPLST
PUSHJ P,GXSAT
JRST FND14 ;DIDN'T MAKE IT, T1=SPACE AVAILABLE
FND13: SETZM (P3) ;CLEAR JUNK
DPB T1,FRGCP3## ;AMOUNT ALLOCATED
DPB T2,FRGAP3## ;FIRST LOGICAL PAGE NUM
PUSHJ P,MRKALC ;MARK AS ALLOCATED
DPB P4,FRGUP3## ;SET UNIT
PUSHJ P,BMPAC3
SUBB T3,T1 ;DECREMENT AMOUNT NEEDED, PUT IN T1
JUMPG T1,FND12 ;STILL NEED MORE
SETZM (P3) ;END UP WITH A ZERO
SPCEX: HLRZ U,UNISWP##(U) ;NEXT UNIT IN LIST
TLNE P4,(PG.SLO) ;SLOW SWAPPING ALLOCATION?
JRST SPCEX1 ;YES, LEAVE JXTSUN AS IS
LDB T1,UNYCFS## ;CLASS TO WHICH THE UNIT BELONGS
SKIPE U ;END OF THE CHAIN?
CAILE T1,(P1) ;NO, IF NEXT UNIT IS IN A HIGHER CLASS, OR
HLRZ U,SWPUNI## ; OR END OF CHAIN, START OVER NEXT TIME
HRLM U,NXTSUN## ;STORE FOR NEXT ALLOCATOR
SPCEX1: POP P,T1 ;RESET T1 FOR EXIT
SKIPLE J ;STORE IN JBTSWP TOO?
MOVEM T1,JBTSWP##(J)
IFN FTXMON,<
POP P,R ;RESTORE R
>
JRST CPOPJ1##
FND14: JUMPE T1,NXUN ;JUMP IF NO MORE ROOM THIS UNIT
FND15:
PUSHJ P,GXSAT ;GET THAT MUCH SPACE
STOPCD .,STOP,SSD, ;++SWAP SPACE DISAPPEARED
JRST FND13
;HERE IF FILLED CURRENT UNIT AND NEED MORE SPACE
; (ONLY IF FORCED TO FRAGMENT OVER UNITS)
NXUN: HLRZ U,UNISWP##(U) ;NEXT SWAPPING UNIT
SKIPN U
STOPCD .,STOP,SRO, ;STOP IF NO MORE UNITS - SPACE RAN OUT
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 FND11 ;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,
;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
IFN FTXMON,<
LDB R,UNYSNS## ;SECTION NUMBER CONTAINING THE SATS
MOVSS R ;MAKE AN ADDRESS
TLO T3,RELABP ;ADDRESS IS RELATIVE TO THE SAT
>
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
SOJA P3,UNDD ;ABORT
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: LDB T1,FRGAP3## ;RETURN LAST CHUNK OF SWAP SPACE
LDB U,FRGCP3##
SETZM (P3) ;AND CLEAR
PUSHJ P,FXSAT1 ; END OF LIST MARKER
MOVE T1,-3(P) ;JBTSWP WORD
PUSHJ P,FXSAT ;RETURN SWAPPING SPACE
POP P,T1 ;***THROW AWAY SO THAT EXIT EXITS SWAPPER
POP P,(P) ;MORE JUNK
IFN FTXMON,<
MOVE R,-2(P) ;RESTORE R IN CASE SOMEONE CARES
POP P,(P) ;MORE JUNK
>
BMPACX: POP P,T3
JRST TPOPJ## ;EXIT
;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 PAGE 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,
MOVE T4,UNIUST##(U) ;IF NO NEW ACCESSES FOR THIS UNIT,
TLNE T4,UNPNNA##+UNPRSS##
JRST GXSAT1 ;CANT GET ANY SPACE ON IT
IFN FTXMON,<
LDB R,UNYSNS## ;GET SECTION NUMBER FOR SATS
MOVSS R ;MAKE INTO A RELOCATION ADDRESS
TLO T3,RELABP ;SAT POINTER IS RELATIVE TO THE SECTION
>
PUSHJ P,CLGETZ## ;CALL ROUTINE IN FILSER TO SEARCH FOR 0 BITS
JRST GXSAT1 ;NOT ENOUGH
AOS -1(P) ;OK, SKIP RETURN
IFN FTXMON,<
HRRZS T3 ;CLEAR RELABP
>
HRRZ T1,UNIPTR##(U) ;COMPUTE LOGICAL PAGE 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
JRST T3POPJ## ;RESTORE T3
;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.
FXSAT:: TLZN T1,FRGSEG ;FRAGMENTED ?
JRST FXSAT1 ;NO, NO HASSLE HERE
PUSHJ P,SAVE2## ;SAVE P1
FRAGBK: HRRZ P2,T1 ;YES, LOC OF TABLE IN P1
FRGBK1: HRRZ P1,P2
SKIPG (P1) ;NEXT POINTER?
JRST FRGBK2 ;OR DONE?
LDB T1,FRGAP1## ;GET ADDRESS
LDB U,FRGCP1## ;AND SIZE
PUSHJ P,FXSAT1 ;GIVE UP THE DISK SPACE FOR THIS PART
AOBJP P2,FRGBK1 ;COUNT WORD OF TABLE, GET NEXT
FRGBK2: HRRZ T2,P2 ;LOC OF TABLE
HLRZ T1,P2 ;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 P2,(P1)
PUSHJ P,GIV4WD## ;GIVE UP FREE CORE
SKIPE T1,P2 ;END OF TABLE ?
JRST FRAGBK ;NO, GO CHASE NEXT PART
POPJ P, ;YES, DONE
FXSAT1::SKIPN T2,U ;T2=NUMBER 1K BLOCKS TO RETURN
POPJ P, ;THERE AREN'T REALLY ANY (DUMMY SWPLST ENTRY
;FOR NZS)
LDB U,SSUNT1## ;GET INDEX OF UNIT IN SWPTAB
SKIPG U,SWPTAB##(U) ;GET ADDR OF UNIT DATA BLOCK
POPJ P, ;UNIT WAS REMOVED
EXCH T1,T2 ;T1=HOW MANY, T2=START LOC
HRRZS T2 ;CLEAR OUT UNIT INDEX
.CREF SSUNT1 ;(REFERENCE UNIT VALUE)
; PJRST CSETZS ;CLEAR BITS AND INCREMENT UNIFKS
;SUBROUTINE TO MARK 0'S IN SWAPPING SAT TABLE
;ARGS T1=HOW MANY
; T2=1ST LOGICAL PAGE NUMBER
;CLOBBERS T3,T4
CSETZS:
MOVE T3,UNIUST##(U) ;IF NO NEW ACCESSES FOR THIS UNIT (GOING DOWN SOON),
TLNN T3,UNPNNA##+UNPRSS## ; DONT CHANGE UNIFKS (=0)
ADDM T1,UNIFKS##(U) ;INCREMENT COUNT OF FREE PAGES FOR SWAPPING
IDIVI T2,^D36 ;GET FULL WORDS IN TABLE
HRLS T2 ;BOTH HALVES
ADD T2,UNIPTR##(U) ;POINTER TO FIRST WORD TO MODIFY
IFE FTXMON,<
PJRST SETZRS##
>
IFN FTXMON,<
PUSHJ P,SSEC1## ;CAN'T ADDRESS SWAPPING SATS IN SECTION 0
PUSH P,R ;SOMEONE MAY CARE
PUSH P,P3 ;TO INDICATE AOBJN POINTER RELATIVE TO TABLE
MOVSI P3,RELABP ;(R) + (T2)
LDB R,UNYSNS## ;SECTION NUMBER FOR SWAPPING SATS
MOVSS R ;RELOCATION BY ADDRESS WITHIN SECTION
PUSHJ P,SETZRP## ;ZERO THE BITS TABLE RELATIVE
POP P,P3 ;RESTORE P3
POP P,R ;AND R
POPJ P, ;RETURN
>
;DATA ASSOCIATED WITH THE SWPSER LOGIC ---
$LOW
SQREQ:: Z ;C(LH)=NEGATIVE OF SIZE OF READ/WRITE
; C(RH)=LOCATION OF FIRST WORD TO READ/WRITE
$HIGH
$LIT
SWPEND: END