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.SPN-1>] ;ASSUME NOT FRAGD SKIPL T3,SWPLST##(P1) ;FRAGMENTED? SKIPA T2,PAGTAB(T2) LDB T1,[POINT SL.SPN,1(T3),<^L+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,(B2+PM.WRT+PM.PUB+IFE FTMP,) MOVE T2,JBTSWP##(J) ;PAGE WE LEFT OFF AT TLO T2,(B2+PM.WRT+PM.PUB+IFE FTMP,) 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: 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