Trailing-Edge
-
PDP-10 Archives
-
dec-10-omona-u-mc9
-
sched1.mac
There are 13 other files named sched1.mac in the archive. Click here to see a list.
TITLE SCHED1 - SCHEDULING ALGORITHM FOR SWAPPING SYSTEM (10/50) V720
SUBTTL R.KRASIN/TH/CMF/AF/RCC/DAL/EVS 08 MAR 77
SEARCH F,S
$RELOC
$HIGH
;***COPYRIGHT 1973,1974,1975,1976,1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***
XP VSCHED,720
;PUT VERSION NUMBER IN GLOB LISTING AND LOADER STORAGE MAP
ENTRY SCHED,SCHED1 ;THIS UNDEFINED GLOBAL IN COMMON CAUSES THIS
; ROUTINE TO BE LOADED.
SCHED1:: ;MODULE ORIGIN
;THIS SCHEDULER BASED ON WORK DONE AT WMU BY E.SMOLSKY AND N.GRANT
;NXTJOB DECREMENTS CURRENT JOB'S QUANT. RUN
;TIME AND REQUEUES IT IF QUANT. TIME GONE TO 0.
;SERVICES ANY JOB REQUEUING REQUESTED AT OTHER PRIORITY
;LEVELS THEN CALLS SHUFFLER,SWAPPER AND SCHEDULAR.
;RETURNS NEXT JOB TO RUN IN J.
NXTJOB::SETZM PASFLG## ;SET FLAG THAT THIS IS FIRST PASS THROUGH SCHED
SKIPN .C0TMF## ;CLOCK TIC?
JRST NXTJB1 ;NO
IFN FTNSCHED,<
PUSHJ P,SCDTYP ;SET P3 UP TO SCHEDULER TYPE (0,1)
>;END IFN FTNSCHED
MOVE T4,TIME## ;GET TIME IN JIFFIES
TRNN T4,1B35 ;ONLY DECREMENT IN CORE TIME ON ODD TICKS
JRST NXTJBX
MOVE J,HIGHJB## ;ANY JOBS AT ALL?
JUMPLE J,NXTJBX ;NO.
MOVEI T4,JS.SCN ;JOB SCANNED DURING TICK BIT
NXTJBA: MOVE T2,JBTSTS##(J) ;JOB STATUS WORD
TLNN T2,SWP ;SWAPPED IN?
TLNN T2,JNA ;AND JOB NUMBER ASSIGNED?
JRST NXTJBF ;NO. GET NEXT JOB
LDB T1,PJBSTS##
CAIGE T1,SLPQ ;IF STATE .GE. SLP, ALWAYS DECREMENT
; (JOBS IN LONG TERM WAIT STATES, NAP
; ARE THUS CHARGED FOR BEING IN CORE
TDNE T4,JBTST2##(J) ;OR IF JOB WAS ACTUALLY SCANNED
JRST .+2 ;WE WILL DECREMENT
JRST NXTJBF ;DO NOT DECREMENT THIS JOB
ANDCAM T4,JBTST2(J) ;CLEAR SCANNED BIT FOR NEXT TIME
IFN FTPDBS,<
PUSHJ P,FNDPDB## ;GET PDB ADDRESS
JRST NXTJBF ;NO PDB IMPLIES NO ICPT
>
IFE FTPDBS,<
HRRZ W,JBTPDB##(J) ;GET PDB ADDRESS
JUMPE W,NXTJBF ;NO ICPT IF NO PDB
>
.LDB T3,PDYIPT## ;GET ICPT
SOJG T3,NXTJBE ;IF STILL POSITIVE, JUST DEPOSIT
MOVSI T3,PDMSWP ;MARK SWAPPABLE IN PDB
.IORM T3,.PDIPT##(W) ;..
PUSHJ P,SETIPT ;AND RESET ICPT SO WILL CYCLE
; EVEN IF DOESN'T NEED TO SWAP
TLNE T2,CMWB!JRQ ;COMMAND WAIT OR REQUE?
JRST NXTJBD ;YES. GET OUT
PUSHJ P,INRNQ ;IS JOB IN A RUN QUEUE?
JRST NXTJBF ;NO. CAN'T REQUE HIM NOW.
IFN FTPSCD,<
PUSHJ P,CNTICP ;COUNT NUMBER WHO EXPIRED IN-CORE BY QUE
>
IFE FTNSCHED,<
MOVEI U,QTIME0 ;REQUE AROUND RUN QUEUES
>
IFN FTNSCHED,<
MOVE U,[EXP QTIME0
EXP QTIME1](P3)
;GET PROPER TABLE FOR PROPER SCHEDULER
>
PUSHJ P,QXFER ;DO TRANSFER
JRST NXTJBF ;GO TO NEXT JOB
NXTJBD: SETZ T3, ;PUT IN A ZERO FOR COMMAND WAIT, JRQ
NXTJBE: .DPB T3,PDYIPT## ;OR JUST STORE NEW VALUE
NXTJBF: SOJG J,NXTJBA ;LOOP FOR THE REST
NXTJBX:
IFN FTNSCHED,<
PUSHJ P,SCDQTA ;RESET CLASS QUOTA STUFF IF ITS THE
;END OF A SCHEDULING INTERVAL
>;END IFN FTNSCHED
IFN FTRSP,< ;KEEP TRACK OF WANT-TO-RUN TIME
RQTPAT::JRST NXTJ1A ;PATCH TO JFCL TO INCLUDE EXPENSIVE
; WANT-TO-RUN TIME CALCULATION
MOVSI T1,WTMASK ;TO CHECK FOR RUN STATE CODE
HRRE J,JBTQ##-PQ1 ;CHECK PQ1
PUSHJ P,RQT2
HRRE J,JBTQ##-PQ2 ; PQ2
PUSHJ P,RQT2
JRST RQT3
RQT1: TDNN T1,JBTSTS##(J) ;SKIP IF NOT IN RUN STATE
AOS JBTRQT##(J) ;BUMP JBTRQT FOR ALL
HRRE J,JBTQ##(J) ; JOBS IN THIS QUEUE
RQT2: JUMPG J,RQT1
POPJ P,
RQT3:
> ; END OF CONDITIONAL ASSEMBLY ON FTRSP
IFN FTNSCHED,<
JRST NXTJ1A
>
;CPU1 ENTERS HERE FROM CIP6
NXTJB1::
IFN FTNSCHED,<
PUSHJ P,SCDTYP ;SET P3 TO SCHEDULER TYPE (1 = CLASSES)
NXTJ1A:>
SKIPN J,.CPJOB##(P4) ;CURRENT JOB NO., IS IT NULL JOB?
JRST CKJB1 ;YES,GO SEE IF OTHER JOBS NEED RESCHEDULING
MOVEI F,0 ;GET READY IN CASE CURRENT JOB UNRUNABLE
IFN FTHPQ,<
SKIPE .CPHQU##(P4) ;IF THE CURRENT JOB JUST DID AN HPQUUO, IT IS ALWAYS
JRST CKJB0A ; RUNNABLE BUT IT MUST BE REQUED INTO THE NEW HPQ
>
HLRZ T2,JBTSTS##(J) ;GET JOB STATUS BITS AND CODES
TRZ T2,RUNMSK+CMWB ;MASK OUT DO NOT CARE BITS
CAIE T2,RUNABLE ;IS CURRENT JOB RUNABLE?
JRST CKJB0 ;NO, REQUE CURRENT JOB
PUSHJ P,FNDPDB## ;YES. GET PDB ADR FOR CURRENT JOB
JRST CKJB1 ;GO AWAY IF NONE
.LDB T2,PDYIPT## ;GET ICPT
JUMPE T2,NXTJB4 ;ALWAYS REQUE IF ZERO
.LDB T2,PDYQNT## ;GET IN QUE TIME
JUMPN T2,CKJB1 ;EXIT IF STILL POSITIVE
IFN FTRSP,< ;RESPONSE DATA?
MOVEI T1,.CPARR##(P4) ;BASE ADR OF 3 WORDS FOR QUANTUM REQUEING
MOVSI T2,(JR.RRR) ;RECORD THIS TYPE OF RSP FOR THIS JOB
PUSHJ P,RSPRC2## ;RECORD ELAPSED TIME FOR RESPONSE
; AND FOR ANY OF TTY IN, TTY OUT, THIS
> ; END OF CONDITIONAL ASSEMBLY ON FTRSP
IFN FTPSCD,<
PUSHJ P,CNTINQ ;COUNT NUMBER WHO EXPIRED IN QUE BY QUE
JRST NXTJ4A
>
NXTJB4:
IFN FTPSCD,<
PUSHJ P,CNTICP ;COUNT NUMBER WHO EXPIRED IN-CORE BY QUE
>
NXTJ4A: SETZM .CPLJU##(P4) ;IF REQUEING, ZERO THE LAST JOB TO DO A UUO WORD
;SINCE JOBQUE FOR THAT JOB WILL THEN BE WRONG
PUSHJ P,QARNDT ;YES - REQUEUE AND RESET QUANT TIMES.
JRST CKJB1 ;DO ONCE A CLOCK TICK STUFF
CKJB0: TRZ T2,JXPN!SHF!SWP ;JOB NOT RUNNABLE, BUT MAY NOT NEED REQUEUE
CAIN T2,RUNABLE ;DOES IT REALLY NEED TO BE REQUEUED?
JRST [ ;NO, DON'T GIVE HIM EXTRA PRIORITY
IFN FTMS,<
SKPCPU (1) ;JUST SELF ON CPU1
>;END IFN FTMS
SKIPN .CPTMF##(P4) ;CLOCK TICK?
JRST CKJB3A ;NO, DON'T REQUEUE ANYONE
JRST CKJB1 ;YES, DO EVERYONE
]
MOVSI T2,JRQ ;DID SOMEONE SET JRQ FOR CURRENT JOB?
TDNN T2,JBTSTS##(J)
JRST CKJB0A ;NO, OK
SOS QJOB ;YES, DECREMENT QJOB
ANDCAM T2,JBTSTS##(J) ; AND CLEAR JRQ
CKJB0A:
IFN FTMS,<
SKPCPU (1) ;IF SLAVE PROCESSOR, ALWAYS GO TO CKJB3
;THIS MUST BE DONE SINCE REQUE IS NOT REENTRANT
> ; END OF CONDITIONAL ASSEMBLY ON FTMS
SKIPN .CPTMF##(P4) ;HAS CLOCK TICKED?
JRST CKJB3 ;NO, REQUEUE ONLY THE CURRENT JOB
; (THIS HAPPENS OFTEN WHEN CURRENT JOB
; GOES INTO IO WAIT)
CAMG J,HIGHJB## ;DON'T SET JRQ IF NOT A JOB
PUSHJ P,REQUE## ;YES, FLAG CURRENT JOB TO BE REQUEUED
; WITH ALL THE REST OF THE JOBS (IF ANY)
; THUS SWAPPER WILL GET CALLED AT CKJB7
CKJB1: AOSN F,CHKQJB ;TIME FOR ONCE A MINUTE CHECK? (IN CASE QJOB WAS TOO LOW)
SOJA F,CKJB1A ;YES, MAKE F-1 AND START LOOKING
SKIPN F,QJOB ;NO, ANYTHING TO DO?
JRST CKJB5 ;NO, SKIP QJOB STUFF
CKJB1A: ;SCAN ALL JOBS EVERY MINUTE IN CASE QJOB WAS OFF
MOVE J,HIGHJB## ;START WITH HIGHEST JOB NUMBER ASSIGNED
CKJB2: MOVSI T2,JRQ ;JOB NEEDS REQUEUEING BIT
TDNN T2,JBTSTS##(J) ;THIS JOB?
SOJG J,.-1 ;NO,KEEP LOOKING
JUMPLE J,CKJB5 ;YES,LOOKED AT ALL JOBS?
; (MAY NOT FIND A KJOBED JOB IF HIGHEST
; GO DECR. COUNT QJOB ANYWAY)
ANDCAM T2,JBTSTS##(J) ;NO,MARK THIS JOB AS DONE
PUSHJ P,DECHJB## ;DECREMENT HIGHJB, IF THIS JOB NOW GONE.
CKJB3: PUSHJ P,QREQ ;GO REQUE THE JOB
CKJB3A: JUMPE F,SCHED ;IF FROM NXTJOB GO DIRECTLY TO SCHED
; I.E. CURRENT JOB NO LONGER RUNNABLE(IOW)
; BUT JRQ WASN'T SET SO DON'T DECR QJOB
JUMPG F,CKJB4D ;ONCE A MINUTE?
SKIPE QJOB ;YES DECREMENT IF GTR THAN 0
SOS QJOB
JRST CKJB4E ;AND LOOK AT NEXT JOB
CKJB4D: SOSLE F,QJOB ;ANY MORE JOBS TO REQUEUE?
CKJB4E: SOJG J,CKJB2 ;YES,BUT LOOK AT EACH JOB ONLY ONCE PER CLOCK TICK
CKJB5:
IFN FTKI10!FTKL10,<
SKIPN EVAVAL## ;EV AVAILABLE AND SOMEONE WAITING?
JRST CKJB7 ;NO.
SETZM EVAVAL ;YES. CLEAR FLAG
SKIPG J,HIGHJB## ;ANY JOBS?
JRST CKJB7 ;NO. SHOULDN'T HAPPEN
MOVSI T2,WTMASK ;YES. TAKE EVERYBODY OUT OF EV WAIT
CKJB5A: LDB T1,PJBSTS## ;GET JOBS STATE CODE
CAIN T1,EVQ ;EV?
ANDCAM T2,JBTSTS##(J) ;YES. TAKE HIM OUT
SOJG J,CKJB5A ;AND LOOP FOR ALL JOBS
> ;END IFN <FTKI10!FTKL10>
CKJB7:
IFN FTMS,<
SKPCPU (0) ;IF SLAVE, DON'T CALL SWAPPER
JRST SCHED ;IF THIS IS CPU 1, DONT SHUFFLE OR SWAP
> ; END OF CONDITIONAL ASSEMBLY ON FTMS
IFN FTHPQ,<
SKIPG .C0RTF## ;IF AN HPQ JOB ON DISK WOKE UP
>
SKIPN .C0JOB## ;OR IF RUNNING NULL JOB
JRST CKJB6 ;CALL SWAP/SHUFFLE
SKIPN .C0TMF## ;ALWAYS CALL SWAP/SHUFFLE ON TICK
JRST SCHED ;NOT TICK OR OTHERWISE
CKJB6:
IFE FTSWAP,<
PUSHJ P,CHKSHF##
> ; END OF CONDITIONAL ASSEMBLY ON FTSWAP
IFN FTSWAP,<
IFN FTTRPSET,<
SKIPN STOPTS## ;DON'T SWAP IF TIMESHARING TURNED OFF.
>
PUSHJ P,SWAP
> ; END OF CONDITIONAL ASSEMBLY ON FTSWAP
IFN FTLOCK,<
SKIPA ;NOT TRYING TO LOCK A JOB, PROCEED.
PUSHJ P,LOCK0## ;SHUFFLER AND SWAPPER ARE IDLE - SO SEE IF JOB CAN BE LOCKED
JFCL ;IGNORE POSSIBLE SKIP RETURN
> ; END OF CONDITIONAL ASSEMBLY ON FTLOCK
MOVEI P4,.C0CDB## ;SHUFFLER AND SWAPPER CLOBBER P4
; SETUP CPU DATA BLOCK ADR AGAIN
;SCHEDULAR--SEARCH THRU QUEUES ACCORDING TO SSCAN TABLE
;FOR 1ST JOB IN CORE--RETURN ITS NO. IN J
SCHED:: SETZM .CPPLT##(P4) ;CLEAR POTENTIALLY LOST TIME FLAG
PJRST @.CPSCH##(P4) ;GO DO CPU DEPENDENT SCHEDULING
;EACH SCHEDULER CALLS SCHEDJ TO FIND RUNNABLE JOBS
;SCHEDJ IS CALLED TO FIND A RUNNABLE JOB
;IT RETURNS WITH THE HIGHEST PRIORITY RUNNABLE JOB IN J
;CALL: PUSHJ P,SCHEDJ
; RETURN HERE WITH J SET UP
SCHEDJ::
IFN FTTRPSET,<
SKIPE J,.CPSTS##(P4) ;TIMESHARING TURNED OFF? (TRPSET)
JRST [SKIPGE JBTSTS##(J) ;RUNNABLE?
PUSHJ P,INRNQ ;YES, IN A RUN QUEUE?
JRST SCHD1 ;NO TO EITHER QUESTION
MOVEI T2,SCHD1 ;IN CASE HE'S NOT REALLY RUNNABLE
JRST SCHEDB ;GO SEE
]
>;END IFN FTTRPSET
MOVE U,.CPSCN##(P4) ;ADDRESS OF SCAN TABLE
MOVE T1,.CPSFC##(P4) ;GET COUNT OF UNFAIR SCHEDULES
CAMGE T1,MFC##(U) ;HAS IT REACHED MAXIMUM FAIRNESS COUNT?
JRST SCHDJ1 ;NO, DONT USE SECONDARY SCAN TABLE
SETZM .CPSFC##(P4) ;YES, CLEAR SCHEDULER FAIRNESS COUNT
MOVE U,SSCN##(U) ;AND GET ADDRESS OF SECONDARY SCAN TABLE
; (PQ1 AND PQ2 REVERSED)
SCHDJ1: MOVEM U,.CPSUD##(P4) ;RECORD WHICH SCAN WE USED
SETZM UNWIND ;FLAG THAT WE ONLY UNWIND ONCE/SCAN
IFN FTDISK,<
SKIPE J,FORCEF ;FORCING ANYONE WITH SHAR. RESOURCE?
PUSHJ P,INRNQ ;IS JOB IN A RUN QUEUE?
JRST SCHED2 ;NO! DON'T BOTHER CHECKING
MOVEI T2,SCHED2 ;PREPARE TO SCAN NORMALLY
;BUT START WITH JOB IN FORCEF
SKIPGE JBTSTS##(J) ;IF NOT RUNNABLE, SCHED NORMALLY. (POSSIBLE
; IF JOB HAS STOPPED AND GIVEN UP RESOURCE
JRST SCHEDB ; BUT FLAG HAS NOT YET BEEN CLEARED)
> ;END OF FTDISK CONDITIONAL
SCHED2: JSP T1,QSCAN ;BEGIN SCAN
JRST SCHD1 ;NO MORE JOBS--RETURN NULLJOB
SCHEDB:
IFN FTMS,<
PUSHJ P,DXRUN## ;GO CHECK IF JOB IS RUNNABLE ON THIS PROCESSOR
JRST (T2) ;NO, GO CONTINUE SCANNING
; (ALSO SETS .CPPLT IF CAN'T RUN ON CPU1 BECAUSE HI-SEG
; BEING SHUFFLED, SWAPPED, OR EXPANDED ON CPU 0)
> ; END OF CONDITIONAL ASSEMBLY ON FTMS
MOVE T3,JBTSTS(J) ;JOB STATUS
MOVEI F,JS.SCN ;JOB SCANNED BIT
TLNN T3,SWP ;SWAPPED IN?
IORM F,JBTST2(J) ;YES. SET SCANNED BIT
LDB F,PJBSTS## ;GET STATE CODE
JUMPE F,SCHEDC ;IF ZERO, LET HIM THROUGH
IFN FTDISK,<
PUSHJ P,CJFRCX ;IF JOB IS IN FORCEF WITH RESOURCE, IGNORE JXPN
; SO JOB CAN BE RUN + THEN SWAPPED
>
IFN FTKI10!FTKL10,<
CAIE F,EVQ ;EV IS HANDLED SEPARATELY ABOVE.
>
TLNE T3,SWP+JRQ+SHF+JXPN ;IF SWAPPED, SHUFFLING,
JRST (T2) ;REQUEING, OR EXPANDING - GIVE UP
CAIL F,MINQ ;NON-ZERO. IS HE WAITING FOR A
CAILE F,MAXQ ;SHAREABLE RESOURCE?
JRST (T2) ;NO. CAN'T HELP HIM
SKIPE AVTBMQ##(F) ;YES - IS IT FREE?
JRST SCHEDA ;YES. TRY TO GIVE IT TO HIM
SKIPE UNWIND ;SHOULD WE UNWIND?
JRST (T2) ;NO. ALREADY TRIED ONCE THIS SCAN
PUSH P,J ;SAVE J SO WE CAN CONTINUE SCAN LATER
SETOM UNWIND ;SAY WE HAVE UNWOUND ONCE
SETZ T4, ;CLEAR LEVEL COUNTER
UNWND1:
IFN FTDISK,<
CAIN F,MQQ ;MON BUF QUE?
JRST MQUNWD ;YES. #@!%$&
>
HRRZ J,USTBMQ##(F) ;GET USER OF RESOURCE WE WANT
JUMPE J,UNWNDF ;FAIL IF NO ONE.
CAMN J,(P) ;SAME AS US?
JRST UNWNDF ;SHOULD NEVER HAPPEN %&'#@!
LDB F,PJBSTS## ;GET HIS STATE CODE
JUMPE F,UNWNDS ;RUN. TRY TO RUN HIM
CAIL F,MINQ ;NOT RUN. SHAREABLE RESOURCE?
CAILE F,MAXQ
JRST UNWNDF ;NO. FAIL EXIT
IFN FTKI10!FTKL10,<
CAIN F,EVQ ;WAITING FOR EV?
JRST UNWNDF ;YES. CAN'T UNWIND THAT!
>
SKIPE AVTBMQ##(F) ;AVAILABLE?
JRST UNWNDS ;YES. TRY TO SELECT
CAIGE T4,^D10 ;LOOPING?
AOJA T4,UNWND1 ;NOT YET
JRST UNWNDF ;APPEAR TO BE LOOPING
IFN FTDISK,<
MQUNWF: POP P,P2 ;RESTORE ACS
POP P,P1
>
UNWNDF: POP P,J ;RESTORE JOB NUMBER FROM SCAN
JRST (T2) ;AND CONTINUE SCAN
IFN FTDISK,<
MQUNW5: HLRZ J,P2 ;GET NUMBER OF THE DESIRED JOB
POP P,P2 ;RESTORE ACS
POP P,P1
JUMPE J,UNWNDF ;FAIL IF FOUND NO ONE
>
UNWNDS: PUSHJ P,CHKRUN ;MAKE SURE WE CAN RUN HIM
JRST UNWNDF ;CAN'T. #%$&@!
POP P,T3 ;FIX UP PDL
MOVEI T3,JS.OOO ;FLAG FOR CLOCK1 TO STOP WHEN GIVES UP
IORM T3,JBTST2##(J) ;ALL HIS SHAREABLE RESOURCES
AOS UNWNDC## ;COUNT AN UNWIND
LDB F,PJBSTS## ;GET STATE CODE.
JUMPE F,SCHEDC ;RUN HIM IF ZERO
JRST SCHEDE ;GIVE HIM RESOURCE AND RUN
IFN FTDISK,<
MQUNWD: PUSH P,P1 ;SAVE SOME ACS
PUSH P,P2
SETZ P1, ;CLEAR P1 FOR NXTJBB
MOVEI P2,777777 ;PUT LARGE SMALLEST CHAIN SO FAR VALUE AND JOB 0
MQUNW1: SETZ T4, ;INIT LENGTH OF THIS CHAIN
MQUNW2: PUSHJ P,NXTJBB## ;GET OWNER OF NEXT MQ
JRST MQUNW5 ;NO MORE BUFFERS. EXIT
MOVE J,T3 ;PUT NUMBER IN J
MQUNW3: JUMPE J,MQUNWF ;IF ZERO, QUIT. NOT SUPPOSED TO BE
LDB F,PJBSTS## ;GET STATE CODE
JUMPE F,MQUNW4 ;END OF CHAIN IF ZERO
CAIL F,MINQ ;WAITING FOR SHAREABLE RESOURCE TOO?
CAILE F,MAXQ
JRST MQUNW1 ;NO. TRY NEXT BUFFER
CAME J,-2(P) ;SAME AS US?
CAIN F,MQQ ;OR MQ?
JRST MQUNW1 ;YES - TRY NEXT CHAIN
IFN FTKI10!FTKL10,<
CAIN F,EVQ ;WAITING FOR EV?
JRST MQUNW1 ;YES. CAN'T UNWIND THAT!
>
SKIPE AVTBMQ##(F) ;IS IT AVAILABLE?
JRST MQUNW4 ;YES. END OF CHAIN
HRRZ J,USTBMQ##(F) ;NO. TRY NEXT LEVEL
CAIGE T4,^D10 ;LOOPING?
AOJA T4,MQUNW3 ;NO. COUNT DEPTH
JRST MQUNW1 ;YES. TRY NEXT CHAIN
MQUNW4: PUSHJ P,CHKRUN ;IS HE RUNNABLE?
JRST MQUNW1 ;NO. TRY NEXT BUFFER.
CAIL T4,(P2) ;YES. WHOSE CHAIN IS SHORTER?
JRST MQUNW1 ;OLD CHAIN SHORTER
MOVE P2,T4 ;SAVE LENGTH OF NEW CHAIN
HRLI P2,(J) ;AND JOB NUMBER
JRST MQUNW1 ;AND LOOK AT CHAIN FROM NEXT BUFFER
>;END OF IFN FTDISK
; SUBROUTINE TO CHECK THAT JOB FOUND BY UNWIND CAN BE RUN
; CALL IS
; MOVE J,JOB-NUMBER
; PUSHJ P,CHKRUN
; NOT RUNNABLE RETURN
; RUNNABLE RETURN
; SETS T3 TO JBTSTS(J). MAY DESTROY F
CHKRUN: SKIPL T3,JBTSTS##(J) ;RUN BIT ON?
POPJ P, ;NO.
PUSH P,T1 ;SAVE T1
PUSHJ P,INRNQ ;IS JOB IN A RUN QUEUE?
JRST TPOPJ ;NO. CAN'T RUN IT
POP P,T1 ;RESTORE T1
IFN FTDISK,<
PUSHJ P,CJFRCX ;CHECK FOR JOB IN FORCEF WITH RESOURCE
;IF SO, IGNORE JXPN TEMPORARILY SO HE
; CAN GIVE UP THE RESOURCE TO GET SWAPPED
>
IFN FTLOCK,<
TRNN T3,LOK
>
TLNE T3,SWP+JRQ+SHF+JXPN+CMWB ;FLAGS THAT CAN'T USE
POPJ P, ;NOT RUNNABLE
IFE FTMS,<
JRST CPOPJ1## ;RUNNABLE!
>
IFN FTMS,<
PJRST DXRUN## ;CHECK THAT WILL RUN ON THIS CPU
;AND EXIT SKIP/NON-SKIP
>
;ROUTINE TO IGNORE JXPN FOR JOB IN FORCEF WITH SHAREABLE RESOURCE
;ENTER WITH JBTSTS IN T3 (OR MASK INCLUDING JXPN)
;ALWAYS EXITS NONSKIP
IFN FTDISK,<
CJFRCX: CAMN J,FORCEF ;JOB IN FORCEF?
PUSHJ P,FLSDR## ;DOES HE HAVE DISK RESOURCE?
POPJ P, ;NO, OK AS IS
TLZ T3,JXPN ;YES, IGNORE JXPN TEMPORARILY
POPJ P, ;RETURN
;ROUTINE TO ASSURE JOB IN FORCEF DOESN'T RUN IF HAS NO RESOURCE
; BUT IGNORE JXPN IF JOB IS IN FORCEF WITH RESOURCE SO HE CAN GIVE
; IT BACK
;ENTER WITH JOBSTS OR MASK IN F
;RETURN NON-SKIP IF IN FORCEF AND HAS NO RESOURCE, OTHERWISE SKIP
CJFWRX: CAME J,FORCEF ;JOB IN FORCEF?
JRST CPOPJ1## ;NO, SKIP RETURN
PUSHJ P,FLSDR## ;SHAREABLE DISK RESOURCE?
POPJ P, ;NO, DON'T LET HIM RUN
TLZ F,JXPN ;IGNORE JXPN
JRST CPOPJ1## ; AND SKIP
>
SCHEDA:
IFN FTDISK,<
CAME J,FORCEF ;FORCING JOB WITH SHAREABLE RESOURCE?
JRST SCHEDE ;NO. GIVE HIM RESOURCE AND RUN HIM
PUSHJ P,FLSDR## ;DOES HE STILL HAVE THE RESOURCE?
JRST (T2) ;NO - DON'T GIVE HIM ONE
;YES - LET HIM HAVE MORE
> ;END FTDISK
SCHEDE:
IFN FTDISK,<
CAIN F,MQQ ;IS THIS THE MONITOR BUFFER QUEUE?
SOSGE MQFRE1## ;YES. DON'T RESET MQAVAL IF STILL FREE MON BUF
> ;END OF FTDISK CONDITIONAL
SETZM AVTBMQ##(F) ;CLEAR AVAL FLAG
MOVEM J,USTBMQ##(F) ;REMEMBER WHO THE RESOURCE WAS GIVEN
; TO SO IT CAN BE RETURNED IN THE EVENT OF
; A CATASTROPHIC ERROR, E.G., SWAP READ ERROR
MOVSI T3,WTMASK ;CLEAR WAIT STATE
ANDCAM T3,JBTSTS##(J)
SCHEDC: MOVEM J,.CPPLT##(P4) ;SET POTENTIALLY LOST TIME FLAG FOR CLOCK1
MOVE F,JBTSTS##(J) ;IS THIS JOB SWAPPED OUT
IFN FTDISK,<
PUSHJ P,CJFWRX ;CHECK FOR JOB IN FORCEF
JRST (T2) ;IN FORCEF BUT NO RESOURCE, DON'T RUN
;EITHER NOT IN FORCEF, OR IS AND HAS
; RESOURCE, IN WHICH CASE JXPN CLEARED IN F
>
IFN FTLOCK,<
TRNN F,LOK ;DON'T RUN JOB CURRENTLY BEING LOCKED IN CORE
> ; END OF CONDITIONAL ASSEMBLY ON FTLOCK
TLNE F,SWP+SHF+JXPN+JRQ ;MONITOR WAITING FOR I/O TO STOP,
; OR JOB EXPANDING CORE?
; OR JOB NEEDS REQUEING (SWAP READ ERROR)?
JRST (T2) ;YES--CONTINUE SCAN,JOB CANNOT BE RUN
IFN FTKL10&FTMS,<
PUSHJ P,SCDCSH## ;IS THIS JOB RUNNABLE WITH RESPECT TO THE
; CACHE?
JRST (T2) ;NO, GO FIND ANOTHER JOB TO RUN
; NOTE THAT THIS IS DONE AFTER LOST
; TIME FLAG IS SET SO THAT CACHE LOST
; TIME IS INCLUDED IN SYSTEM LOST TIME
>;END IFN FTKL10&FTMS
CAMN J,FORCEF ;FORCING A GUY WITH SHARABLE RESOURCE?
AOS FORCFC## ;YES, COUNT A FORCED SCHEDULE
IFN FTNSCHED,<
SETZM .CPSQF##(P4) ;ASSUME NOT FROM SUBQUE
MOVEI T1,SQFORA
CAIN T1,(T2) ;FROM SUBQUE?
SETOM .CPSQF##(P4) ;YES, TELL CLOCK1
>;END IFN FTNSCHED
HLREM T2,.CPQUE##(P4) ;YES--SAVE ITS Q
IFN FTRSP,< ;RESPONSE DATA?
MOVEI T1,.CPACR##(P4) ;BASE ADR FOR CPU RESPONSE DATA THIS CPU
MOVSI T2,(JR.RCR) ;RECORDED CPU RESPONSE FOR THIS JOB
PUSHJ P,RSPREC## ;RECORD RESPONSE TIME (UNLESS ALREADY REC)
MOVE T1,.CPACR##(P4) ;STORE DATA IN
MOVE T2,.CPACR##+1(P4) ; THE WRONG
MOVEM T1,.CPODA##(P4) ; PLACE FOR
MOVEM T2,.CPODA##+1(P4) ; OLD CUSPS
; (DO NOT RECORD AS ONE OF TI, TO, RN, ALSO)
> ; END OF CONDITIONAL ASSEMBLY ON FTRSP
SETZM .CPPLT##(P4) ;CLEAR POTENTIALLY LOST TIME AS A USER IS TO BE RUN
IFN FTKL10&FTMS,<
SETZM .CPCLF##(P4) ;CLEAR CACHE LOST FLAG ALSO
>;END IFN FTKL10&FTMS
MOVE T2,.CPSUD##(P4) ;GET START OF SCAN TABLE USED
CAME T2,.CPSCN##(P4) ;WAS IT PRIMARY SCAN?
POPJ P, ;NO. IT WAS FAIRNESS SCAN
CAMGE U,FSCN##(T2) ;DID THIS SCAN REACH FAIR TERRITORY
AOSA .CPSFC##(P4) ;NO, COUNT UP UNFAIR SCANS
SETZM .CPSFC##(P4) ;YES, CLEAR SCHED FAIRNESS
POPJ P, ;RETURN
SCHD1: SETZ J, ;RETURN NULL JOB
IFN FTMS,<
SKPCPU (0) ;ONLY REQUE AND RETRY FOR CPU0
POPJ P, ;RETURN NULL JOB
>
SKIPN PASFLG## ;LOOPING?
SKIPG QJOB ;NO. ANY JOBS TO REQUE?
POPJ P, ;LOOPING OR NONE TO REQUE
SETOM PASFLG## ;SAY WE ARE NOW LOOPING
JRST CKJB1 ;AND GO REQUE EVERYBODY
; THIS SUBROUTINE DETERMINES HOW TO REQUE THE JOB
QREQ: MOVE T2,JBTSTS##(J) ;JOB STATUS WORD
TDNE T2,[JDC+JS.DEP+(CMWB)] ;ANY STRANGE BITS ON?
JRST QREQ1 ;YES, GO DO SOME SPECIAL THINGS
QREQ0: LDB U,PJBSTS## ;GET QUEUE CODE
JUMPGE T2,QSTOPT ;IS RUN BIT ON? IF NOT, JOB GOES TO STOP Q.
IFN FTMS,<
PUSHJ P,MSRQT## ;GO CHECK IF JOB COMING OUT OF WS,TS, OR DS
; (SETS UUO COUNTER IN CASE JOB WAS DOING
; I/O UUO THAT STARTED ON SLAVE AND GOT
; SWITCHED TO MASTER.
>
HLRZ T1,QBITS(U) ;GET DISPATCH ADDRESS FOR REQUE METHOD
JRST (T1)
QREQ1: MOVEI U,QCMW ;ASSUME COMMAND WAIT
TLNN T2,CMWB ;IS JOB IN COMMAND WAIT?
JRST QREQ2 ;NO--WAIT STATE CODE DETERMINES NEW QUEUE
TLNE T2,SWP+JXPN ;YES--IS JOB ON DISK, OR TRYING TO EXPAND?
PJRST QXFER ;YES--PUT JOB IN COMMAND WAIT QUEUE
IFN FTDAEM,<
QREQ2: MOVEI U,QJDCW ;ASSUME DAEMON WAIT
TRNN T2,JDC!JS.DEP ;IS IT?
JRST QREQ0 ;NO, JUST REQUE BY STATE CODE
TRNE T2,JS.DEP ;ERROR LOGGING? (JDC IS BY REQUEST ONLY)
PUSHJ P,FLSDR## ;YES. PUT IN DAEMON QUEUE IF JOB HAS NO RESOURCES.
JRST .+2 ;(DOESN'T)
JRST QREQ0 ;HAS A RESOURCE, DON'T PUT HIM IN JDCQ.
PUSHJ P,ZERIPT ;CLEAR IN-CORE PROTECT TIME
PJRST QXFER ;INTO JDCQ
>;END IFN FTDAEM
IFE FTDAEM,<QREQ2==QREQ0>
DEFINE X(A,B,C)
< XLIST
Q'A'T==QREQ6
Q'A'W==-1
LIST
>
RWAITS
QIOWT==QREQ6
QDIOWT==QREQ6
QPIOWT==QREQ6
QNAPT==QREQ6 ;IN CASE OF CONTROL C WHILE IN NAP, ETC.
QARNDT:
IFN FTNSCHED,<
JUMPN P3,QARND2 ;IF RUNNING CLASS SYSTEM SCHEDULER,
; DON'T CLEAR IN CORE PROTECT TIME.
>;END IFN FTNSCHED
LDB T1,PJBST2## ;GET REAL QUEUE
CAIN T1,PQ2 ;IS IT PQ2?
JRST QARND1 ;YES. REQUE CLEARING ICPT
LDB T1,PDYIPT ;NOT PQ2. ANY ICPT LEFT?
JUMPG T1,QARND2 ;IF ANY LEFT, DON'T CHANGE IT
QARND1: PUSHJ P,CLRIPT ;SET BIT FOR NO ICPT
PUSHJ P,SETIPT ;RESET ICPT SO JOB WILL CYCLE
QARND2:
IFE FTNSCHED,<
MOVEI U,QTIME0 ;REQUE AROUND RUN QUEUES
>
IFN FTNSCHED,<
MOVE U,[EXP QTIME0
EXP QTIME1](P3)
;GET PROPER TABLE FOR PROPER SCHEDULER
>
PJRST QXFER ;DO TRANSFER
REPEAT 0,<
QPST:
PUSHJ P,INRNQ ;IS JOB IN A RUN QUEUE?
PUSHJ P,QCHNG ;NO. PUT HIM INTO A RUN QUEUE
CAMN J,VMQJOB## ;HAS JUST THIS JOB EXCEEDED PAGE RATE?
JRST QPST1 ;YES. REQUE TO REAR
SKIPGE VMQJOB ;SYSTEM PAGE RATE EXCEEDED?
SKIPN SLECNT## ;SOMEONE WANT TO USE THE SWAPPING/PAGING CHANNEL?
JRST QPSTN ;NO
QPST1: PUSHJ P,FNDPDB ;NEED PDB
JRST QPSTN ;...
PUSHJ P,TOBACK ;PUT TO REAR OF QUEUES, DON'T RESET Q.R.T.
JRST QPSTN ;AND FALL INTO NORMAL QUEUE TRANSFER
>;END REPEAT 0
QWST:
QDST: PUSHJ P,INRNQ ;IS JOB IN A RUN QUEUE?
PUSHJ P,QCHNG ;NO. PUT HIM IN A RUN QUEUE
QPST:
QPSTN: MOVSI T1,WTMASK ;CLEAR WAIT STATE CODE
ANDCAM T1,JBTSTS##(J)
POPJ P, ;AND EXIT QREQ. (NO QUE TRANSFER)
QTIOWT:
QJDCT: PUSHJ P,ZERIPT ;TI, DAEMON CLEARS IN CORE TIME
JRST QREQ3 ;GO DO THE REQUE
QTST: MOVSI T1,WTMASK ;CLEAR WAIT STATE
ANDCAM T1,JBTSTS##(J)
; JRST QREQ3 ;AND PERFORM QUEUE TRANSFER
QRNT:
QSLPT:
QEWT:
QNULT:
QREQ3: HRRZ U,QBITS(U) ;PICK UP TRANSFER TABLE ADDRESS
PJRST QXFER ;REQUE THE JOB
QSTOPT: CAIN U,NULQ ;IS HE REALLY GOING TO THE NULL Q?
JRST QNULT ;YES. PUT HIM THERE
MOVEI U,QSTOP ;TRANSFER TABLE FOR STOP QUEUE
PUSHJ P,ZERIPT ;CLEAR ICPT
JRST QXFER ;GO REQUE JOB
QREQ6: PUSHJ P,INRNQ ;IS JOB IN RUN QUEUE?
PUSHJ P,QCHNG ;NO. PUT IT IN RUN QUEUE
POPJ P,
; SUBROUTINE TO PUT JOB INTO A RUN QUEUE.
; DESTROYS U,T1,T2,R,W. SAVES J
QCHNG: MOVEI U,QRNW1 ;PUT IN BACK OF PQ1
PJRST QXFER ;WITHOUT ASSIGNING QUANTUM TIME
; SUBROUTINE TO DETERMINE IF JOB IS IN A RUN QUEUE.
; RETURN NON-SKIP IF NOT RUN QUEUE
; RETURN SKIP IF IN RUN QUEUE
; RETURNS PHYSICAL QUEUE NUMBER IN T1
INRNQ:: LDB T1,PJBST2## ;GET PHYSICAL QUEUE NUMBER
CAIL T1,PQ1 ;LESS THAN PROCESSOR QUEUE?
CAIN T1,CMQ ;NO. COMMAND WAIT?
POPJ P, ;YES. NOT RUN QUEUE
JRST CPOPJ1 ;RUN QUEUE. GIVE SKIP RETURN
; ROUTINE TO SET ICPT. J AND W MUST BE SET UP AND PDB MUST EXIST
; PRESERVES ALL ACS
SETIPT::PUSH P,T1
MOVE T1,PROT1## ;MINIMUM
LSH T1,-1 ;IPT IS DECREMENTED EVERY OTHER TICK
.DPB T1,PDYIPT##
JRST TPOPJ##
; ROUTINE TO CLEAR ICPT. SET UP W. NEEDS J
; PRESERVES ALL ACS EXCEPT W
ZERIPT::PUSHJ P,FNDPDB## ;FIND PDB
POPJ P, ;NO PDB. NOTHING TO DO.
; PJRST CLRIPT ;FALL INTO CLRIPT
; ROUTINE TO SET BIT TO EXPIRE ICPT
; PRESERVES ALL ACS
CLRIPT::PUSH P,T1
MOVSI T1,PDMSWP ;SWAPPABLE BIT
.IORM T1,.PDIPT##(W) ;SET IT
PJRST TPOPJ##
; SAME AS CLRIPT BUT EXPECTS PDB ADDRESS IN T1
CLRIP1::PUSH P,T2
MOVSI T2,PDMSWP ;SWAPPABLE BIT
.IORM T2,.PDIPT##(T1) ;SET IT
PJRST T2POPJ##
;SUBROUTINE TO PUT JOB TO BACK OF PQ2
; USES SAME REGISTERS AS QCHNG
TOBACK: MOVEI U,QRNW2 ;TRANSFER TABLE TO BACK OF PQ2, DONT
PJRST QXFER ;CHANGE QUANTUM RUN TIME.
IFN FTNSCHED,<;IF CLASS SYSTEM AND TWO-MODE SCHEDULER
;AS OF THE 603 MONITOR RELEASE, THE SCHEDULER WILL RUN IN TWO
; MODES. ONE MODE IS VERY NEARLY IDENTICAL TO THE ORIGINAL WMU
; SCHEDULER ALGORITHM. THE OTHER MODE IS THE ALGORITHM USED
; IN THE DEC SCHEDULER IN THE 602 MONITOR RELEASE. THE 602
; SCHEDULER MODE IS PROVIDED BOTH FOR THOSE WHO FOUND THE 602
; ALGORITHM SATISFACTORY AND FOR THOSE INSTALLATIONS WHICH RUN
; THE CLASS SYSTEM. THE WMU ALGORITHM CANNOT SUPPORT THE
; CLASS SYSTEM.
;
;THIS ROUTINE IS CALLED AT THE BEGINNING OF THE SCHEDULER. P3 IS
; SET TO 0 IF THE SCHEDULER IS RUNNING IN "WMU" MODE, OR SET
; TO 1 IF THE SCHEDULER IS RUNNING IN "DEC" MODE. THE USE OF P3
; AS A GLOBAL FLAG IS TO REDUCE OVERHEAD.
; WARNING: THE SWAPPER CALLS ROUTINES THAT SMASH P3, SO P3 MUST
; BE SAVED SOMEWHERE.
SCDTYP: EXCH P3,(P) ;SAVE P3 ON STACK, GET CALLING PC
MOVE T1,P3 ;SAVE PC IN T1 FOR CALL BACK
MOVE P3,TYPSCD ;SET P3 TO BE ZERO FOR WMU MODE OR
; ONE FOR CLASS SYSTEM MODE.
PUSHJ P,(T1) ;CALL THE CALLER
JRST .+2 ;NON-SKIP RETURN (ALWAYS GET HERE REALLY)
AOS -1(P) ;SKIP RETURN (NEVER GET HERE)
POP P,P3 ;RESTORE ORIGINAL P3
POPJ P, ;RETURN
>;END IFN FTNSCHED
IFN FTPSCD,<
; ROUTINE TO COUNT NUMBER OF TIMES JOB EXPIRED IN CORE PROTECT BY QUE
CNTICP: PUSH P,T1 ;SAVE T1
LDB T1,PJBST2## ;GET PHYICAL STATE CODE
CAIN T1,PQ1 ;PQ1?
AOS XPICP1 ;YES
CAIN T1,PQ2 ;PQ2?
AOS XPICP2 ;YES
CAILE T1,CMQ ;AN HPQ?
AOS XPICHP ;YES
JRST TPOPJ ;RESTORE T1 AND EXIT
; ROUTINE TO COUNT NUMBER OF TIMES JOB EXPIRED IN QUE TIME BY QUE
CNTINQ: PUSH P,T1 ;SAVE T1
LDB T1,PJBST2## ;GET PHYSICAL STATE CODE
CAIN T1,PQ1 ;PQ1?
AOS XPQRP1 ;YES
CAIN T1,PQ2 ;PQ2?
AOS XPQRP2 ;YES
CAILE T1,CMQ ;AN HPQ?
AOS XPQRHP ;YES
JRST TPOPJ ;RESTORE T1 AND EXIT
$LOW
SCDPER:: ;PERFORMANCE STATS TABLE
%DTASL::BLOCK 1 ;DTA GENERATED SLEEPS
%MTASL::BLOCK 1 ;DTA GENERATED SLEEPS
%EWCNT::BLOCK 1 ;MTA GENERATED SLEEPS
%TISJB::BLOCK 1 ;TTY INPUT SATISFIED
%TOSJB::BLOCK 1 ;TTY OUTPUT SATISFIED
%PISJB::BLOCK 1 ;PTY INPUT SATISFIED
%POSJB::BLOCK 1 ;PTY OUTPUT SATISFIED
REQSS:: BLOCK 1 ;NUMBER OF REQUEUES FROM SS INTO PQ1
REQWK:: BLOCK 1 ;NUMBER OF REQUEUES FROM WAKE INTO PQ1
REQJSD::BLOCK 1 ;NUMBER OF REQUEUES FROM DAEMON SATISFIED INTO PQ1
REQPQ1: BLOCK 1 ;NUMBER OF OTHER REQUEUES INTO PQ1
XPQRP1: BLOCK 1 ;NUMBER OF JOBS IN PQ1 WHICH EXPIRED QUANTUM RUN TIME
XPQRP2: BLOCK 1 ;NUMBER OF JOBS IN PQ2 WHICH EXPIRED QUANTUM RUN TIME
XPQRHP: BLOCK 1 ;NUMBER OF JOBS IN HPQ WHICH EXPIRED QUANTUM RUN TIME
XPICP1: BLOCK 1 ;NUMBER OF JOBS IN PQ1 WHICH EXPIRED INCORE PROTECT
XPICP2: BLOCK 1 ;NUMBER OF JOBS IN PQ2 WHICH EXPIRED INCORE PROTECT
XPICHP: BLOCK 1 ;NUMBER OF JOBS IN HPQ WHICH EXPIRED INCORE PROTECT
SWPKP1: BLOCK 1 ;NUMBER OF K SWAPPED IN FOR PQ1 JOBS
SWPKP2: BLOCK 1 ;NUMBER OF K SWAPPED IN FOR PQ2 JOBS
SWPKHP: BLOCK 1 ;NUMBER OF K SWAPPED IN FOR HPQ JOBS
SWPJP1: BLOCK 1 ;NUMBER OF PQ1 JOBS SWAPPED IN
SWPJP2: BLOCK 1 ;NUMBER OF PQ2 JOBS SWAPPED IN
SWPJHP: BLOCK 1 ;NUMBER OF HPQ JOBS SWAPPED IN
RNTPQ1::BLOCK 1 ;TICKS CHARGED TO PQ1
RNTPQ2::BLOCK 1 ;TICKS CHARGED TO PQ2
RNTHPQ::BLOCK 1 ;TICKS CHARGED TO HPQS
%PERLN==:<.-1-SCDPER>B26
BLOCK 10
$HIGH
CNTSWP: PUSH P,T1 ;SAVE ACS
PUSH P,T2
PUSH P,J
LDB T1,IMGIN ;GET INPUT SIZE
LDB T2,IMGOUT ;AND OUTPUT SIZE IN T2
CAMLE T1,T2 ;GET MINIMUM IN T1
MOVE T1,T2 ;T2 WAS SMALLER
LSH T1,P2KLSH## ;IN K
CAILE J,JOBMAX ;HIGH SEG?
MOVE J,SWPIN ;YES
LDB T2,PJBST2## ;GET PHYSICAL QUE
POP P,J ;RESTORE JOB
CAIN T2,PQ1 ;PQ1?
JRST CNTSP1 ;YES
CAIN T2,PQ2 ;PQ2?
JRST CNTSP2 ;YES
CAIG T2,CMQ ;HPQ?
JRST CNTSXT ;NO. EXIT
ADDM T1,SWPKHP ;STORE K
CAIG J,JOBMAX ;LOWSEG?
AOS SWPJHP ;YES. COUNT A JOB
CNTSXT: POP P,T2
JRST TPOPJ ;RESTORE ACS
CNTSP1: ADDM T1,SWPKP1 ;COUNT K IN PQ1
CAIG J,JOBMAX ;LOWSEG?
AOS SWPJP1 ;YES. COUNT JOB
JRST CNTSXT ;EXIT
CNTSP2: ADDM T1,SWPKP2 ;COUNT K IN PQ2
CAIG J,JOBMAX ;LOWSEG?
AOS SWPJP2 ;YES. COUNT JOB
JRST CNTSXT ;EXIT
> ;IFN FTPSCD
SUBTTL QCSS R. KRASIN
;THIS ROUTINE MUST BE ASSEMBLED WITH THE CONFIGURATION
;TAPE TO DEFINE NUMBER OF JOBS
;THIS SECTION CONTAINS 2 ROUTINES FOR Q MANIPULATION
;AND NECESSARY TABLES FOR SPECIFING OPERATIONS PERFORMED
;BY THEM.
;STORAGE:
;EACH Q IS A RING STRUCTURED, FOWARD AND BACKWARD
;LINKED SRING LIST. THE "FIRST" LINK IN A Q IS
;A Q-HEADER POINTING TO THE FIRST AND LAST MEMBERS OF THE Q.
;A NULL Q HAS ONE LINK--THE Q-HEADER ITSELF. THE LINKS MAKING
;UP THE QS ARE CONTAINED IN A TABLE (JBTQ) WITH NEGATIVE
;INDICIES (ADDRESSES LESS THAN JBTQ) USED FOR Q-HEADERS AND
;POSITIVE INDICIES USED FOR MEMBERS (JOBS). THUS ONLY ONE WORD
;PER LINK IS NECESSARY--ITS ADDRESS RELATIVE TO JBTQ GIVES THE
;JOB NO. (OR Q NO. IF NEGATIVE) WHICH IT REPRESENTS WHILE
;ITS CONTENTS CONTAINS THE LINKING POINTERS. THESE
;POINTERS ARE ALSO INDICIES RELATIVE TO JBTQ RATHER THAN
;ABSOLUTE ADDRESSES--RH(LINK)=FOWARD POINTER;
;LH(LINK)=BACKWARD POINTER.
;A JOB IS ASSUMED TO BE IN NO MORE THAN ONE Q AT A TIME, AND
;THE NULL JOB (JOB 0) DOES NOT APPEAR IN THE QS (I.E. JBTQ
;ITSELF IS THE Q-HEADER FOR Q 0).
;ROUTINES:
;BOTH ROUTINES ARE "TABLE DRIVEN" IN THE SENSE THAT THE
;CALLING ROUTINE PROVIDES THE ADDRESS OF A TABLE WHICH
;DEFINES THE SPECIFIC OPERATIONS TO BE PERFORMED.
EQFIX==QFIX+1B0
EQLNKZ==QLNKZ+1B0
QXFER:
IFN FTHALT,<
SKIPLE J ;TRYING TO REQUE JOB 0?
CAILE J,JOBMAX## ; OR IS THE JOB NUMBER OUT OF RANGE?
STOPCD .,STOP,RJZ, ;++REQUEUE JOB ZERO
; MESSED UP AND SYSTEM WILL HANG IF ALLOWED
> ; END OF CONDITIONAL ASSEMBLY ON FTHALT
MOVE R,1(U) ;GET TRANSFER TABLE ADDRESS
JRST @(U) ;DISPATCH
;DEST-Q AS FUNCTION OF JOB QUE, QUANTUM AS FUNCTION OF JOB SIZE
QLNKZ: PUSHJ P,JOBSIZ## ;GET SIZE OF JOB
PUSHJ P,INRNQ ;IS JOB IN A RUN QUEUE?
STOPCD .,STOP,NTE, ;NOT PROCESSOR QUE. ERROR.
ADD T1,1(U) ;ADD TABLE ADDRESS TO QUE NUMBER
HRRO R,0(T1) ;GET QUE HE GOES TO
HLRZ T1,0(T1) ;GET PARAMETERS FOR QUE HE IS GOING TO
SKIPGE 1(U) ;WANT QUANTUM TIME?
JRST QFIXD ;NO - ALL FIXED
IMUL T2,QMLTBL##(T1) ;SIZE * MULTIPLIER
PUSH P,T3 ;SAVE T3
IDIV T2,QRANGE## ;GET IN PROPER UNITS
POP P,T3 ;GET T3 BACK
ADD T2,QADTBL##(T1) ;ADD IN BASE AMOUNT FOR QUE
CAMLE T2,QMXTBL##(T1) ;LESS THAN MAXIMUM ALLOWED?
MOVE T2,QMXTBL##(T1) ;NO. USE MAXIMUM
MOVEM T2,QNTRUN ;STORE IT FOR QFIX
HRLI R,QNTRUN ;AND TELL QFIX WHERE WE PUT IT
JRST QFIXD ;DO TRANSFER
$LOW
QNTRUN: 0
$HIGH
;FIXED DEST-Q
QFIX:
IFN FTHPQ,<
HRRZ T2,R ;PICK UP QUEUE
CAIL T2,-PQ2 ;IS IT A RUN QUEUE?
CAILE T2,-PQ1
JRST QFIXD ;NO.
LDB T2,HPQPNT## ;YES. SHOULD IT GO TO A HPQ
JUMPE T2,QFIXD ;NO. DON'T DO ANYTHING
HRR R,QTTAB##-1(T2) ;YES. GET HPQ POSITION
SKIPL R ;WAS QUANTUM TIME REQUESTED?
HRLI R,QQSTAB##-1(T2) ;YES. GIVE QUANTUM TIME
> ; END OF CONDITIONAL ASSEMBLY ON FTHPQ
QFIXD: AOS RQCNT## ;COUNT A REQUEUE
IFN FTMETR,<
SKIPL T2,MP1## ;METER QUEUE XFERS?
JRST QFIXA ;NO
HRRI T1,(J) ;YES, GET JOB NR
HRLI T1,(R) ;AND QUEUE#
CAME J,MPDPAR##(T2) ;RIGHT JOB?
SKIPGE MPDPAR##(T2) ;OR WANT ALL JOBS?
PUSHJ P,@MPDPRA##(T2) ;YES, CALL POINT ROUTINE
QFIXA:
> ;END CONDITIONAL ON FTMETR
IFN FTNSCHED,<
JUMPE P3,QFIXB ;DON'T MAINTAIN SUBQUEUES IN NON-CLASS SCHEDULER
LDB T1,PJBST2## ;GET SOURCE QUEUE
CAIE T1,PQ2 ;FROM PQ2?
JRST QFIXB ;NO
MOVE T2,JBTSQ##(J) ;YES, DELETE FROM CURRENT SUBQUEUE (CLASS)
MOVS T1,T2
HRRM T2,JBTSQ##(T1) ;NEW FORWARD LINK
HRLM T1,JBTSQ##(T2) ;AND BACK LINK
>;END IFN FTNSCHED
QFIXB: HRRE T1,R ;PICK UP QUEUE NUMBER
MOVMS T1 ;ABS VALUE
DPB T1,PJBST2## ;STORE HIS REAL QUEUE
IFN FTPSCD,<
CAIN T1,PQ1 ;TO PQ1?
AOS REQPQ1 ;YES. COUNT IT
>
MOVE T2,JBTQ##(J) ;DELETE JOB FROM SOURCE-Q
MOVS T1,T2 ;T2=FORW. LINK, T1=BACK LINK
HRRM T2,JBTQ##(T1) ;FORW. LINK PAST JOB
HRLM T1,JBTQ##(T2) ;BACK LINK PAST JOB
SKIPL (U) ;TRYING TO REQUEUE TO BEGINNING OF QUEUE?
STOPCD (.,STOP,RBQ) ;++REQUEUEING TO BEGINNING OF QUEUE
HLR R,JBTQ##(R) ;END--THIS WILL LEAVE R=IDX OF
; CURRENT LAST LINK;T1=IDX OF Q-HEADER
MOVE T1,JBTQ##(R) ;T1=IDX OF CURRENT 1ST LINK
; R=IDX OF Q-HEADER
HRRM J,JBTQ##(R) ;INSERT JOB IN DEST-Q
HRLM J,JBTQ##(T1)
HRRM T1,JBTQ##(J)
HRLM R,JBTQ##(J)
JUMPL R,QX3
IFE FTPDBS,< ;IF WE DO NOT SWAP PDB'S
HLRZ U,R ;GET QUANTUM TIME ADDRESS FOR DPB
MOVE U,(U) ;GET QUANTUM TIME
SKIPN W,JBTPDB##(J) ;GET PDB ADR
STOPCD .,STOP,NPC, ;++NO PDB IN CORE
.DPB U,PDYQNT## ;STORE QUANTUM RUN TIME
> ;END CONDITIONAL ON FTPDBS
IFN FTPDBS,< ;IF WE SWAP PDB'S
HLRZ T1,R ;SET UP QUANTUM RUN TIME ADDRESS
MOVE T1,(T1) ;GET QUANTUM TIME
PUSHJ P,SETQNT## ;STORE IN PDB
> ;END CONDITIONAL ON FTPDBS
IFN FTNSCHED,<
QX3: JUMPE P3,CPOPJ## ;DON'T MAINTAIN SUBQUEUES IN NON-CLASS SCHEDULER
LDB T1,PJBST2## ;GET DESTINATION QUEUE NUMBER
CAIE T1,PQ2 ;DID WE JUST PUT HIM IN PQ2?
POPJ P, ;NO, JUST RETURN
;HERE IF WE JUST PUT A JOB INTO PQ2. MUST ALSO PUT IT INTO
; A PARALLEL SUBQUEUE.
LDB T1,JBYCLS## ;YES, GET HIS CLASS NUMBER
MOVNI T1,1(T1) ;GET NEGATIVE INDEX TO JBTSQ
HLRZ T2,JBTSQ##(T1) ;GET OLD LAST MEMBER OF QUEUE
HRRM J,JBTSQ##(T2) ;MAKE HIM POINT TO US AS LAST MEMBER
HRLM J,JBTSQ##(T1) ;MAKE BACK POINTER IN HEADER POINT TO US AS LAST MEMBER
HRL T1,T2 ;T1 = OLD LAST MEMBER,,-SQ
MOVEM T1,JBTSQ##(J) ;SAVE AS OUR JBTSQ ENTRY
POPJ P, ;AND RETURN
>;END IFN FTNSCHED
IFE FTNSCHED,<
QX3: POPJ P, ;RETURN
>;END IFE FTNSCHED
;SCANS THE QS RETURNING THE NUMBERS OF THE JOBS IN THE QS.
;THE ORDER AND MANNER IN WHICH THE QS ARE SEARCHED IS
;DETERMINED BY A "SCAN TABLE" ADDRESSED IN THE CALLING SEQ.
;THE SCAN TABLE HAS THE FORM:
;
;SCANTAB: XWD <Q1>,<CODE1> ;SCN Q1 ACCRDING TO CODE1
; ...
; XWD <QN>,<CODEN> ;QN ACCORDING TO CODEN
; Z ;ZERO TERMINATES TABLE
;
;EACH Q MAY BE SCANNED IN ONE OF FOUR WAYS SPECIFIEDBY <CODE>
;THE CODES ARE:
;
;QFOR SCAN WHOLE Q FOWARD
;QFOR1 SCAN FOR ONY THE 1ST MEMBER (IF ANY)
;QBAK SCAN WHOLE Q BACKWARD
;QBAK1 SCAN BACKWARD FOR ALL MEMBERS EXCEPT THE 1ST
;SQFOR SCAN SUBQUEUES FORWARD ACCORDING TO SQSCAN TABLE IF RRFLAG .NE. 0,
; ELSE SCAN PQ2 VIA QFOR ROUTINE.
;
;CALLING SEQ.
;
; MOVEI U,SCAN TABLE ADDRESS
; JSP T1,QSCAN ;SET UP PC FOR REPEATED RETURNS
; ... ;RETURN HERE WHEN NO MORE JOBS
; ... ;RETURN HERE WITH NEXT JOB IN AC J
; ; AND ITS Q IN LH(T2)
;
; PERFORM ANY NECESSARY TESTING OF THIS JOB
; J,U,T1,T2 MUST BE PRESERVED
;
; JRST (T2) ;RETURN TO QSCAN TO GET NEXT JOB
; ; IF THIS ONE NOT ACCEPTABLE
;
QSCAN:: SKIPN T2,(U) ;END OF SCAN TABLE?
JRST (T1) ;YES--RETURN TO CALL+1
HLRE J,T2 ;NO--GET NO. OF Q
JRST (T2) ;DISPATCH
QFOR1:: MOVEI T2,QFOR2 ;ONLY THE FIRST JOB
QFOR:: HRRE J,JBTQ##(J) ;SCAN FOWARD ALL JOBS
IFN FTNSCHED,<
JUMPE P3,QFOR0 ;IF RUNNING NON-CLASS SYSTEM SCHEDULER, JUMP
JUMPL J,QFOR2 ;JUMP IF END OF THIS QUEUE
SKIPL JBTSCD##(J) ;JOB IN A FIXED CLASS?
JRST 1(T1) ;NO, WE CAN RETURN IT
HLRZ T3,(U) ;GET MINUS QUEUE NUMBER WE'RE SCANNING
CAIE T3,-PQ2 ;PQ2?
JRST 1(T1) ;NO, JUST RETURN THE JOB
JRST (T2) ;YES, ONLY RUN HIM IF SQFOR WANTS TO.
>;END IFN FTNSCHED
QFOR0: JUMPG J,1(T1) ;RETURN THIS JOB NUMBER CALL+2 UNLESS--
QFOR2: AOJA U,QSCAN ;END OF THIS Q--GET NEXT Q
QBAK1:: HLRE J,JBTQ##(J) ;SCAN BACKWARD ALL JOBS EXCEPT 1ST
SKIPLE JBTQ##(J) ;IS THIS THE FIRST MEMBER?
JRST 1(T1) ;NO--RETURN CALL+2
AOJA U,QSCAN ;YES--GET NEXT Q
QBAK:: HLRE J,JBTQ##(J) ;SCAN BACKWARD ALL JOBS
JUMPG J,1(T1) ;RETURN CALL+2 WITH JOB NO. UNLESS
AOJA U,QSCAN ;BEG OF THIS Q--GET NEXT Q
IFN FTNSCHED,<
SQFOR:: JUMPE P3,QFOR2 ;NO CLASSES, SO GO AWAY IMMEDIATELY
SKIPG RRFLAG## ;COUNT OF CLASSES WITH NON ZERO QUOTA .LE. ZERO?
JRST SQFR1A ;YES, JUST SCAN PQ2 FORWARD
MOVEI M,SQSCAN## ;SOME CLASSES HAVE QUOTAS LEFT, SCAN THEM
MOVEI T2,SQFORA ;RETURN ADDRESS FOR MORE JOBS, IF ANY
SQFOR1: SKIPN T3,(M) ;ANY ENTRIES LEFT IN SUBQUEUE LIST?
SQFR1A: AOJA U,QSCAN ;NO, STEP TO NEXT MAJOR QUEUE
SQFOR2: SKIPG (T3) ;YES, ANY QUOTA LEFT?
;(RH OF SQSCAN ENTRY IS ADDR OF QUOTA LEFT WORD)
AOJA M,SQFOR1 ;NO,GET NEXT SUBQUEUE
HLRE J,T3 ;YES, GET -SQ NUMBER IN J
SQFORA: HRRE J,JBTSQ##(J) ;GET NEXT JOB IN QUEUE
JUMPG J,1(T1) ;TO TO CALL+1 IF HAVE A JOB
AOJA M,SQFOR1 ;ELSE STEP TO NEXT SUBQUEUE
>;END IFN FTNSCHED
DEFINE X(A,B,C)
<
A'Q==:ZZ
ZZ==ZZ+1>
ZZ==0
QUEUES
XP MINQ,ZZ
DEFINE X(A,B,C)
< A'Q==:ZZ
EXTERNAL A'AVAL
ZZ==ZZ+1>
RWAITS
NQUEUE==ZZ
XP MAXQ,NQUEUE-1
XP AVLNUM,MAXQ-MINQ
DEFINE X(A,B,C)
< A'Q==:ZZ
ZZ==ZZ+1>
CODES
XP MXCODE,ZZ-1
PQ1==:ZZ
ZZ==ZZ+1
PQ2==:ZZ
ZZ==ZZ+1
CMQ==:ZZ
;CORRESPONDENCE TABLE BETWEEN JOB STATUS CODES AND QUEUE TRANSFER TABLES
;USED BY SCHEDULER
;RUNCSS SETS JOB STATUS WORD TO NEW STATE CODE.
;SCHEDULER SETS UP QUEUE TRANSFER TABLE ADDRESS FROM
;FOLLOWING TABLE USING NEW STATE CODE AS INDEX
DEFINE X(A,B,C)
< XWD Q'A'T, Q'A'W
>
QWSW==-1
QIOWW=-1
QDIOWW==-1
QDSW==-1
QPIOWW==-1
QPSW==-1
QNAPW==-1
QBITS:: QUEUES
RWAITS
CODES
;SHARABLE DEVICE REQUEST TABLE(GENERALIZED FOR OTHER QUEUES TOO)
;CONTAINS THE NUMBER OF JOB WAITING TO USE SHARBLE DEVICE
;WSREQ AND RNREQ ARE UNUSED
$LOW
DEFINE X(A,B,C)
<A'REQ:: 0
>
REQTAB::RWAITS ;GENERATE REQ TABLE
XP RQTBMQ,REQTAB-MINQ
$HIGH
$LOW
QJOB:: 0 ;NUMBER OF JOBS NEEDING QUEUE TRANSFERS AT
;OTHER THAN CLOCK LEVEL
XJOB:: 0 ;NUMBER OF JOBS NEEDING EXPANSION BY SWAPOUT-IN
UNWIND: 0 ;FLAG THAT SAYS WE'VE UNWOUND ONCE THIS SCHEDULER CYCLE
$HIGH
DEFINE TTAB(FCTN,QUEUE,QUANT)
< EXP FCTN
XWD QUANT,-QUEUE
>
DEFINE PTTAB(FCTN,QUEUE,QUANT)
< EXP FCTN
XWD QUANT,QUEUE
>
QNULW: TTAB EQFIX,NULQ,-1 ;NULL QUEUE JOB NO. NOT ASSIGNED
QSTOP::QSTOPW: TTAB EQFIX,STOPQ,-1 ;UNRUNABLE JOBS TO END OF STOPQ
IFN FTDAEM,<
QJDCW: TTAB EQFIX,JDCQ,-1
> ; END OF CONDITIONAL ASSEMBLY ON FTDAEM
QCMW:: TTAB EQFIX,CMQ,-1 ;COMMAND WAIT TILL JOB IN CORE
QTSW: ;TTY IO WAIT SATISFIED(ENTER BACK OF PQ1)
QRNW: TTAB EQFIX,PQ1,QADTAB## ;JUST RUNABLE JOBS
;WHICH ARE NOT IN SOME WAIT STATE BELOW
QRNW1: TTAB EQFIX,PQ1,-1 ;PUT IN BACK OF PQ1. NO QUANTUM FOR SPECIAL TRANSFER
QRNW2: TTAB EQFIX,PQ2,-1 ;PUT IN BACK OF PQ2, NO QUANTUM CHANGE
QTIOWW: TTAB EQFIX,TIOWQ,-1 ;TTY IOW HELD IN TIOWQ
QSLPW: TTAB EQFIX,SLPQ,-1 ;SLEEP UUO
QEWW: TTAB EQFIX,EWQ,-1 ;EVENT WAIT
IFN FTNSCHED,<
QTIME1::TTAB EQFIX,PQ2,RNQUNT## ;WHEN QUANT. TIME EXCEEDED.
>
QTIME0::PTTAB EQLNKZ,QRQTBL##,0 ;WHEN QUANT. TIME EXCEEDED.
;WHEN QUANT. TIME EXCEEDED AND RESET QUANT. TIME
SUBTTL SWAP R. KRASIN
;SWAPPER CALLED EVERY CLOCK TIC.
;SINCE MOST OPERATIONS STARTED BY THE SWAPPER REQUIRE SEVERAL
;TICS TO RUN TO COMPLETION, SEVERAL FLAGS(FINISH,FIT,FORCE
;ARE USED TO "REMEMBER" PREVIOUS STATES.
;THE BASIC ALGORITHM:
;IS CORE SHUFFLER WAITING FOR IO TO FINISH FOR SOME JOB?
; YES--TRY AGAIN TO SHUFFLE(WHEN IO STOPS)
;IS CORE SHUFFLER STILL WAITING FOR IO TO FINISH?
; YES--RETURN AND DO NOTHING
;IS SWAPPER STILL BUSY?
; YES--RETURN AND DO NOTHING
;SCAN QS FOR 1ST JOB OUT OF CORE.
; IF NONE--RETURN
;A:
; IF ONE--WILL LOW(HIGH) SEG FIT IN LARGEST HOLE IN CORE?
; YES--START INPUT AND RETURN
; NO--IS TOTAL FREE CORE(CORTAL) ENOUGH TO ACCOMMODATE LOW(HIGH) SEG?
; YES--CALL CORE SHUFFLER
; IS SHUFFLER WAITING FOR IO TO STOP?
; YES--RETURN AND DO NOTHING
; NO--GO TO A:
; NO--"REMEMBER" THIS JOB FOR INPUT AND LOOK FOR OUTPUT:
;ANY JOBS WAITING TO XPAND CORE BY SWAP OUT/IN?
; YES--OUTPUT ONE AND RETURN
; NO--SCAN QS BACKWARD FOR JOB IN CORE WHOSE PROTECT TIME
; (SET ON INPUT) HAS GONE TO 0.
; IF NONE--RETURN
; IF ONE--IS IT SWAPPABLE(NO ACTIVE IO AND NOT CURRENT JOB)?
; YES--OUTPUT HIGH SEG(IF ANY AND NOT ON DISK) THEN LOW SEGMENT
; NO--SET SWP BIT(SO SCHEDULER WILL NOT RUN), IO WILL CONTINUE
; IN LOW SEGMENT AS LONG AS IT CAN
; IO ROUTINES NO LONGER STOP IF SWP SET, JUST SHF)
;ALL DEVICE DEPENDENT CODE MARKED WITH A "*"
SWAP::
IFN FTVM,<
PUSHJ P,SAVE3##
>
IFE FTVM,<
IFN FTSHFL,< ;SHUFFLER PRESENT?
CPUNLK (SCD) ;UNLOCK CALL TO SHUFFLER
SKIPE SHFWAT## ;IS CORE SHUFFLER WAITING FOR IO TO STOP
; FOR SOME JOB?
PUSHJ P,CHKSHF## ;YES, CALL CORE SHUFFLER TO SEE IF
; IO STOPPED YET
CPLOCK (SCD) ;LOCK CP AGAIN
SKIPN SHFWAT## ;IS SHUFFLER STILL WAITING?
> ; END OF CONDITIONAL ASSEMBLY ON FTSHFL
SKIPE SQREQ## ;*NO--IS SWAP SERV. ROUT. STILL BUSY WITH LAST JOB?
POPJ P, ;*YES--RETURN
>
IFN FTPDBS,< ;IF WE SWAP PDB'S
SKIPL SCREQ ;CAN WE GET THE SWAPPER IF WE DECIDE
; THAT WE WANT IT.
SKIPN SCUSER## ; ..
JRST SWAP0 ;YES--TRY TO SWAP
POPJ P, ;NO--RETURN NOW.
SWAP0:> ;END CONDITIONAL ON FTPDBS
IFN FTHPQ,<
SKIPE FIT ;IS FIT SET?
SKIPG J,.CPRTF##(P4) ;AND HPQ JOB ON DISK?
JRST SWAP0A ;NO. CONTINUE
LDB T4,HPQPNT## ;GET ITS HPQ NUMBER
MOVE J,FIT ;GET NUMBER FROM FIT
IFN FT2REL,<
PUSHJ P,FITHPQ ;GET LOW SEG NUMBER OF JOB IN FIT
>
LDB T2,HPQPNT ;GET HPQ NUMBER OF JOB IN FIT
CAIL T2,(T4) ;IS IT LESS THAN JOB IN .CPRTF?
JRST SWAP0A ;NO. PROCEED NORMALLY
IFN FT2REL,<
SKIPLE T1,JBTSGN##(J) ;REAL HIGH SEG?
SKIPE JBTADR(T1) ;YES. IN CORE, IF NOT, COULD BE IN FIT
>
PUSHJ P,ZERFIT ;NO. CAN CLEAR FIT AND RESELECT
SWAP0A:> ; END OF CONDITIONAL ASSEMBLY ON FTHPQ
IFE FTVM,<
MOVEI F,SWPDDB## ;POINT TO SWAP DDB
HRRZ S,DEVIOS(F) ;ERROR FLAGS
;BACK HERE AFTER SWAP OUT OR IN ERROR (ERR BITS (S) CLEARED SO DO NORMAL
; POST PROCESSING)
SWAP1: SKIPN J,FINISH## ;ANY IN/OUTPUT TO FINISH?
JRST SWP2 ;NO-
IFE FTPDBS,< ;IF WE DO NOT SWAP PDB'S
JUMPL J,FINOUT ;YES--INPUT OR OUTPUT?
> ;END CONDITIONAL ON FTPDBS
IFN FTPDBS,< ;IF WE SWAP PDB'S
SKIPN SWAPIN## ;IS THIS A SWAP IN?
JRST FINOUT ;NO--MUST BE SWAP OUT
> ;END CONDITIONAL ON FTPDBS
> ;END CONDITIONAL ON FTVM
IFN FTVM,<
SWAP1:
IFN FTIPCF,<
PUSHJ P,GVIPCP## ;RETURN ANY IPCF PAGES WHICH
; WERE SWAPPED OUT TO THE FREE CORE LIST
>
SKIPN SWPCNT## ;ANY SWAP REQUESTS COMPLETED?
JRST SWP2 ;NO, PROCEED
PUSHJ P,FNDSLE## ;FIND A COMPLETED SWPLST ENTRY
STOPCD CPOPJ,DEBUG,SMU, ;++SWPCNT MESSED UP
FININN: PUSHJ P,GETIOS## ;GET ERROR PLUS DIRECTION OF I/O BITS
TLNE S,IO ;SWAP OUT?
JRST FINOUT ;YES, FINISH UP OUTPUT
> ;END CONDITIONAL ON FTVM
JUMPN S,INERR ;JUMP IF SWAP READ ERROR
FININ0: ;HERE IF NOTHING TO SWAP IN(HIGH OR LOW SEG EXPANDING FROM 0)
IFN FTPDBS,< ;IF WE SWAP PDB'S
JUMPL J,PDBIN ;JUMP IF PDB
> ;END CONDITIONAL ON FTPDBS
IFN FT2REL,<
CAILE J,JOBMAX## ;WAS SEG JUST SWAPPED IN, A LOW SEG?
IFE FTDHIA&FT2SWP,<
JRST FININ1 ;NO, GO FINISH HIGH SEG SWAP IN
>
IFN FTDHIA&FT2SWP,<
JRST FININH
>
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
IFN FTVM,<
PUSHJ P,GIVBAK ;RETURN DISK SPACE, 4-WORD BLOCKS
FININ5:
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
IFN FTKA10,<
MOVE R,JBTDAT##(J) ;SETUP LOW SEG PROTECTION,RELOCATION
MOVE F,JOBPC##(R) ;JOB STOPPED IN EXEC MODE?
TLNE F,USRMOD ;TEST PD FLAG
JRST FININ1 ;NO
HRRZ F,JOBDPG##(R) ;YES, ADJUST R AND P IN DUMP AC AREA
SUBI F,(R) ;OLD RELOC-NEW RELOC
MOVNS F ;NEW RELOC-OLD RELOC
HRRZ T2,JOBDPD##(R) ;OLD PD LIST POINTER
CAMLE T2,SYSSIZ## ;IS IT IN THE MONITOR(EXTENDED PD LIST,NULL PD LIST)
ADDM F,JOBDPD##(R) ;NO, ADJUST DUMP PUSH DOWN POINTER
MOVEM R,JOBDPG##(R) ;STORE NEW AC R
> ; END OF IFE FTKI10
IFN FTDHIA&FT2SWP,<
JRST FININ1 ;CONTINUE
FININH: MOVE T1,SWPIN ;LOW-SEG NUMBER
CAMN T1,MIGRAT## ;SWAP IN CAUSE MIGRATING FROM BAD UNIT?
PUSHJ P,ZERSWP ;YES, GIVE UP HI-SEG SWAPPING SPACE
>
FININ1:
IFN FT2REL,<
CPUNLK (SCD) ;UNLOCK CALL TO SHUFFLER
PUSHJ P,FININ## ;IS THERE A HIGH SEG WHICH MUST BE SWAPPED IN?
IFN FTVM,<
JRST [CPLOCK (SCD) ;SWAPPING I/O IN PROGRESS FOR HI SEG
PUSHJ P,NXTSLE##
POPJ P,
JRST FININN]
>
JRST FININ2 ;YES, GO SWAP IT IN(J SET TO HIGH SEG NO,JOB # IN INPJOB)
CPLOCK (SCD) ; NO, EITHER HIGH SEG ALREADY IN FOR ANOTHER USER
; OR THERE IS NONE, J STILL JOB NO. (IE LOW SEG)
JRST FININ3 ;
FININ2: CPLOCK (SCD) ;LOCK SCHEDULER AGAIN
JRST FIT1 ;GO SWAP IN HIGH SEG
FININ3:
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
;HERE WHEN PDB IS IN CORE
PDBIN: HRRE J,J ;CLEAR BITS IN LH(J)
PUSHJ P,SEGSIZ## ;T2 = SIZE OF PDB IN PAGES
PUSHJ P,ZERSWP ;GIVE UP DISK SPACE
; ALSO FIX VIRTAL
MOVM J,J ;MAKE J POSITIVE
MOVEI T2,JS.RQR ;IF THE QUANTUM RUN TIME WAS RESET
MOVE T1,RNQUNT## ; WHILE PDB WAS ON THE DISK WE MUST
TDNE T2,JBTSTS##(J) ; DO THE ACTUAL DPB NOW.
PUSHJ P,SETQNT## ;GO STORE IN PDB
ANDCAM T2,JBTSTS##(J) ;AND CLEAR THE FLAG BIT
LDB T2,IMGIN## ;GET SIZE OF LOWSEG
JUMPE T2,SWP1 ;IF ZERO GO SCAN SWAP IN QUEUE.
MOVEM J,FIT## ;ELSE GO SWAP IN LOWSEG
CAMG T2,BIGHOL## ;IS THERE STILL ROOM IN CORE?
JRST SWAPI ;YES--GO SWAP IN LOW SEGMENT
JRST FIT1A ;NO--SWAP SOMEONE OUT. THIS HAPPENS
; ONLY IF SOME JOB DID A CORE UUO
; WHILE THE SWAPPER WAS BUSY AND GOT
; THE SPACE IN CORE.
> ;END FTPDBS
IFN FTKI10!FTKL10,<
PUSHJ P,MAPUSR## ;SETUP THE MAP INCLUDING THE TRAP LOCATIONS
; FOR THE JOB JUST SWAPPED IN
IFN FTVM,<
PUSHJ P,SXOPFH## ;MAKE PFH CONCEALED IF IT SHOULD BE
>
> ; END OF CONDITIONAL ASSEMBLY ON FTKI10
LDB F,IMGIN## ;NEW CORE SIZE
LDB T2,IMGOUT## ;OLD SIZE WHEN ON DISK
SUB T2,F ;OLD-NEW=DECREASE
; HAS USER DECREASED VIRTUAL MEMORY FROM M TO N(N GR 0)
; WHILE OUT ON DISK(R,RUN,GET,KJOB) TO 140 WORDS?
; CORE COMMAND ALWAYS FORCES SWAP IN BEFORE
; CORE REASSIGNMENT SO NOT IN THIS CATEGORY
; FRAGMENTED USER TOO HARD TO PARTIALLY
; RECLAIM DISK SPACE
; ON REDUCTION WHICH DOES NOT GO TO 0
SKIPLE T2 ;DECREASED?
ADDM T2,VIRTAL## ;YES, NOW INCREASE VIRTUAL MEMORY AVAILABLE BY
; AMOUNT OF DECREASE IN HIGH OR LOW SEG
IFE FTVM,<
PUSHJ P,ZERSWP ;RETURN LOW SEG DISK SPACE, SET IMGOUT,IMGIN
; AND SWP!SHF(JBTSTS) TO 0
>; ; END OF CONDITIONAL ON FTVM
IFN FTVM,<
PUSHJ P,UNSWAP ;MARK JOB IN CORE AGAIN
>
PUSHJ P,SEGSIZ## ;COMPUTE AND SET IN CORE PROTECT TIME FROM
MOVEI F,-1(T2) ; SIZE OF JOB(1K BLOCKS-1)
IMUL F,PROT## ;ADD VARIABLE AMOUNT DEPENDING ON CORE SIZE
ADD F,PROT0## ;ADD FIXED AMOUNT INDEPENDENT OF CORE SIZE
ADDI F,^D8333 ;CONVERT TO TICKS FROM US
IDIVI F,^D16667*2 ;AND ACCOUNT FOR THE FACT THAT WE DECREMENT EVERY OTHER TICK
PUSHJ P,FNPDBS## ;FIND THE PDB OR STOP
.DPB F,PDYIPT## ;SET IN-CORE PROTECT TIME.
MOVSI F,PDMSWP
IFN FTDHIA&FT2SWP,<
CAME J,MIGRAT## ;IF JUST SWAPPING IN TO GET OFF A UNIT GOING
; DOWN DONT CLEAR SWAPPABLE BIT
>
ANDCAM F,.PDIPT##(W) ;CLEAR SWAPPABLE BIT
MOVE F,[JS.HNG,,JS.SCN!JS.TFO] ;CLEAR SCANNED, FORCED BY TIMER, AND HUNG
ANDCAM F,JBTST2##(J) ;IN SECOND STATUS TABLE
SETZM INFLG ;CLEAR FRUSTRATION FLAGS
SETZM INFLGJ
SETZM INFLGC
IFN FTHPQ,<
CAMN J,FITJBZ ;WAS THIS GUY IN THE TIMER?
SETZM FITJBZ ;YES. REMOVE HIM
>
JRST SWP1
;HERE ON SWAP INPUT ERROR IN LOW OR HIGH SEG
INERR: MOVE R,JBTADR##(J) ;SETUP RELOC,PROTECTION FOR HIGH OR LOW SEG
IFN FTSWPERR,< ;SWAP READ ERROR RECOVERY CODE
IFN FT2REL,<
CAILE J,JOBMAX## ;IS THIS A HIGH SEGMENT JUST SWAPPED IN?
JRST INERR2 ;YES
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
PUSHJ P,SWPREC ;RECORD ERRORS AND DECREASE AMOUNT OF
;VIRTUAL CORE LEFT BY SIZE OF DISK SPACE LOST (IMGOUT)
MOVSI T1,JACCT ;CLEAR JACCT SO THAT A START COMMAND
ANDCAM T1,JBTSTS##(J) ; WILL NOT START A DAMAGED PROGRAM
; WITH PRIVILEDGES AND SO DAEMON WON'T
; GET RESTARTED
IFE FTVM,<
MOVEI T1,0 ;NO, PRETEND DISK SPACE WITH ERROR IN IT
DPB T1,IMGOUT## ; IS NO LONGER ON DISK (ZERSWP WILL NOT
; FREE IT UP)
>
PUSHJ P,ZAPUSR## ;CLEAR ALL DDB'S, IO CHANS
PUSHJ P,CLRJOB## ;CLEAR PROTECTED PART OF JOB DATA AREA
INERR2:
IFN FTVM,<
PUSH P,J ;SAVE SEGMENT NUMBER
>
IFN FT2REL, <
PUSHJ P,SEGERR## ;GO CHECK IF HIGH SEG WHICH HAD ERROR
; IF YES, CLEAR HIGH SEG NAME SO NO NEW
; USERS WILL USE. ALWAYS RETURN JOB NO.
;RECORD ERROR AND DECREASE VIRTUAL CORE LEFT (SWPREC) IF THIS IS
; FIRST READ ERROR ONLY.
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
PUSHJ P,ERRSWP## ;PRINT "SWAP READ ERROR"
IFN FTVM,<
POP P,J ;RESTORE SEGMENT NUMBER
LDB T1,[POINT 9,SWPLST##(P1),26] ;FIRST PAGE IN
CAILE J,JOBMAX## ;A HIGH SEGMENT?
JRST FININ0 ;NO
HLL T1,JBTUPM##(J) ;PICK UP LH FOR COMPARE
CAME T1,JBTUPM##(J) ;UPMP?
JRST FININ0 ;NO, WE'RE NOT TOO BAD OFF
PUSHJ P,GVPAGS## ;YES, WE'RE IN BAD TROUBLE
HLRZ T1,JBTSWP##(J) ;GIVE BACK ALL CORE FOR THE JOB
PUSHJ P,GVPAGS
PUSHJ P,DLTSLE## ;CLEAR THE SWPLST ENTRY
SETZM JBTADR##(J) ;THE JOB HAS NO CORE IN CORE
SETZM JBTUPM##(J)
SETZM JBTSWP##(J) ;NO CORE ON DSK EITHER
IFN FT2REL,<
SKIPLE T1,JBTSGN##(J) ;SKIP IF SPY OR NO HI SEG
TLNE T1,SHRSEG ;SHARABLE?
CAIA ;YES, LET SEGCON REMOVE IT
SETZM JBTSGN##(J) ;NO, JUST ZAP IT
PUSHJ P,KILHGH## ;ALSO REMOVE HI SEG FROM ADR SPACE
>
PJRST UNSWAP ;CLEAR SWP AND RETURN
> ;END FTVM
IFE FTVM,<
MOVEI S,0 ;CLEAR ERROR FLAGS SO CAN
; REENTER SWAPPER
JRST SWAP1 ;GO BACK AND START OVER AFTER HAVING
> ;END FTVM
> ; END OF CONDITIONAL ASSEMBLY ON FTSWPERR
; CLEARED S SO LOOK LIKE NO ERROR
IFE FTSWPERR,<
SETZM FINISH## ;CLEAR FINISH FLAG SO SWAPPING CAN CONTINUE
IFN FTPDBS,< ;IF THE SC RESOURCE EXISTS
SKIPL SCREQ ; AND IF WE OWN IT
PUSHJ P,SCFREE## ;RETURN IT.
> ;END FTPDBS
PUSHJ P,KCORE1## ;RETURN CORE
PJRST ERRSWP## ;TYPE SWAP READ ERROR MESSAGE AND STOP JOB
> ; END OF CONDITIONAL ASSEMBLY ON FTSWPERR
FINOUT:
IFE FTVM,<
IFE FTPDBS,< ;ONLY NEEDED IF WE DO NOT SWAP PDB'S
MOVNS J ;ON OUTPUT FINISH IS NEGATIVE THIS
; CONVERTS IT BACK TO POSITIVE.
> ;END FTPDBS
JUMPN S,OUTERR ;JUMP IF SWAP OUT ERROR
> ; END OF CONDITIONAL ASSEMBLY OF FTVM
IFN FTVM,<
TRNE S,-1 ;ANY ERRORS?
JRST OUTERR ;YES, PROCESS SWAP OUT ERRORS
PUSHJ P,DLTSLE## ;DELETE THE SWPLST ENTRY
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
IFN FTDHIA&FT2SWP,<
CAILE J,JOBMAX## ;HI-SEG?
JRST FINOU2 ;YES, WE'LL GET IT LATER
;****************
;WHAT ABOUT HI SEGS, WILL DODELE WORK FOR ALL SHARABLE HI SEGS,
;WHAT ABOUT NON-VM NON-SHARABLE HI SEGS?
;**********************
IFE FTVM,<
MOVEI T1,JS.MIG ;LIGHT A BIT INDICATING THIS JOB
SKIPE MIGRAT## ; HAS BEEN MIGRATED TO ANOTHER UNIT
IORM T1,JBTST2##(J) ; IF WE ARE TURNING OFF A SWAPPING UNIT
> ;END IFE FTVM
IFN FTVM,<
SKIPN MIGRAT##
JRST FINOU2
PUSHJ P,PGOFF## ;INSURE ALL PAGES OF JOB ARENT ON BAD UNIT(S)
TDZA T1,T1 ;NOT COMPLETELY MIGRATED YET
MOVEI T1,JS.MIG ;COMPLETELY OFF THE BAD UNIT
IORM T1,JBTST2##(J) ;LIGHT BIT IF ALL OFF
> ;END IFN FTVM
> ;END FTDHIA&FT2SWP
FINOU2: MOVE R,JBTADR##(J) ;XWD PROTECT,,RELOC. FOR LOW SEG
CPUNLK (SCD) ;UNLOCK CALLS TO SHUFFLER
PUSHJ P,KCORE1## ;RETURN CORE FOR LOW OR HIGH SEG JUST SWAPPED OUT
; EVEN IF
; ANOTHER JOB STARTED TO SHARE HIGH SEG DURING
; SWAP OUT (GET) SINCE JOB IS MARKED WITH
; SWP BIT ON AND CANNOT RUN UNTIL HIGH SEG
; IS SWAPPED BACK IN
CPLOCK (SCD) ;LOCK SCHEDULER AGAIN
FINOU0:
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
CAILE J,JOBMAX## ;IS THIS A HISEG?
JRST FINOU1 ;YES--SEE ABT LOW SEG
JUMPL J,SWP1 ;IF THIS WAS THE PDB WE ARE DONE
MOVN J,J ;CONVERT TO PDB
MOVEM J,FORCE## ;SAVE SEG #
JRST SWAPO ;GO SWAP OUT
FINOU1:> ;END FTPDBS
IFN FT2REL,<
PUSHJ P,FINOT## ;IS THIS A HIGH SEG WHICH WAS JUST SWAPPED OUT?
JRST FORCEL ;YES, J SET TO LOW SEG NO, GO TRY SWAP IT OUT
; NO, THIS WAS A LOW SEG, ALL SWAPPING FOR THIS USER
; IS FINISHED.
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
SWP1: SETZM FINISH## ;CLEAR FINISH FLAG
IFN FTPDBS,< ;IF THE SC RESOURCE EXISTS
SKIPL SCREQ ; AND IF WE OWN IT
PUSHJ P,SCFREE## ;GIVE IT UP
> ;END FTPDBS
SWP2: SKIPE J,FORCE## ;WAITING FOR JOB TO BECOME SWAPPABLE?
JRST FORCE1 ;YES, TRY TO SWAP OUT
FIT0:
IFN FTVM,<
SKIPE SPRCNT## ;ARE THERE ALREADY SWAPS IN PROGRESS?
JRST CHKXPN ;YES, LOOK ONLY FOR EXPANDING JOBS
SKIPE SWPCNT## ;ANY SWAPPING I/O DONE (PROBABLY ONLY IF
; ONE PASS HAS ALREADY BEEN MADE THROUGH THE
; MAJOR LOOP OF THE SWAPPER)
JRST SWAP1 ;YES, GO PROCESS THAT FIRST
>
SKIPE J,FIT## ;NO-- WAITING TO FIT JOB IN CORE?
JRST FIT1 ;YES, TRY TO SWAP IN
IFN FTLOCK,<
SKIPE J,LOCK## ;WAITING TO LOCK A JOB IN CORE?
JRST CPOPJ1## ;YES, TRY TO POSITION JOB FOR LOCKING
> ; END OF CONDITIONAL ASSEMBLY ON FTLOCK
;SCAN FOR INPUT
MOVEI U,ISCAN##
MOVE T1,SWPIFC ;NUMBER OF UNFAIR INPUT SCANS
CAMGE T1,MAXIFC ;REACH MAXIMUM?
JRST FITPRM ;NO
SETZM SWPIFC ;YES
MOVEI U,ISCAN1## ;USE SECONDARY
FITPRM: JSP T1,QSCAN
JRST ZCKXPN ;NO INPUT TO DO--CK FOR EXPANDING JOBS
MOVE F,JBTSTS##(J) ;JOB STATUS WORD
IFN FT2REL,< TLNE F,SWP ;ARE ALL OF THIS JOB'S SEGS IN CORE?
PUSHJ P,CKXPN## ;NO, IS HIGH SEG EXPANDING?
JRST (T2) ;YES, CONTINUE SCAN FOR SOME OTHER JOB
MOVEM J,FIT## ;NO, REMEMBER JOB (OR HI SEG) TRYING TO FIT IN
CAIGE U,FISCAN## ;REACH FAIR TERRITORY
AOSA SWPIFC ;NO. COUNT UP
SETZM SWPIFC ;YES. CLEAR COUNT
JRST FIT1A ; TRY TO FIT JOB INTO CORE
; (BYPASS SECOND CALL TO CKXPN FOR SPEED)
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
IFE FT2REL,<
TLNN F,SWP ;ARE ALL OF THIS JOB'S SEGS IN CORE?
JRST (T2) ;YES, CONTINUE SCAN FOR SOME OTHER JOB
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
;HERE TO TRY TO FIT A SWAPPED JOB (OR HI SEG) INTO CORE (AGAIN)
FIT1::
IFN FTRSP,<
SETOM SWPPLT## ;SET POTENTIALLY LOST TIME FLAG FOR SWAPPER
>
MOVEM J,FIT## ;REMEMBER JOB (OR HI SEG) TRYING TO FIT IN
IFN FT2REL,<
PUSHJ P,CKXPN## ;IS THIS A LOW SEG WHICH IS CONNECTED TO
; AN EXPANDING HIGH SEG? (SHOULD BE RARE)
JRST NOFITZ ;YES. DESELECT IT AND GET OUT.
FIT1A:
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
LDB P1,IMGIN## ;CORE SIZE NEEDED FOR THIS SEG(0 IF LOW SEG
; OR HIGH SEG WITH UWP OFF ALREADY IN CORE
IFN FTKI10!FTKL10,<
CAIG J,JOBMAX## ;ON LOW SEGMENT SWAP-IN, MUST ALSO ALLOCATE
ADDI P1,UPMPSZ## ; A USER PAGE MAP PAGE SO ADD THAT TO
; TOTAL CORE REQUIRED TO SWAP IN JOB OR LOW SEGMENT
> ; END OF CONDITIONAL ASSEMBLY ON FTKI10
SKIPE JBTADR##(J) ;IS LOW OR HIGH SEG ALREADY IN CORE?
MOVEI P1,0 ;YES (RARE) CAN HAPPEN IF JOB IN CORE EXPANDS
; DURING LOW SEG SWAP IN SO HIGH SEG COULD NOT
; FIT AND COUND NOT FIND ENOUGH JOBS TO SWAP OUT
;;(SO CLEARED FIT AT NOFIT).
IFE FT2REL,<
CAMLE P1,CORTAL## ;WILL LOW SEG FIT IN FREE+DORMANT CORE?
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
IFN FT2REL,<
PUSHJ P,FITSIZ## ;COMPUTE AMOUNT OF CORE NEEDED TO BRING IN
; 1. THIS JOBS LOW SEG AND HIGH SEG
; 2. THIS JOBS LOW SEG(HIGH ALREADY IN OR NONE)
; 3. THIS HIGH SEG BECAUSE LOW SEG ALREADY IN
;WILL LOW SEG FIT IN FREE+DORMANT+IDLE CORE?
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
JRST SCNOUT ;NO,WILL NOT FIT EVEN IF ALL DORMANT SEGS DELETED
; P1=TOTAL CORE NEEDED(IN K)
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
CAIG J,JOBMAX## ;SKIP IF HISEG -- NO PDB IN THAT CASE
ADDI P1,PDBPGS## ;P1=TOTAL CORE NEEDED IN PAGES INCLUDING
; THE PDB.
> ;END FTPDBS
FIT1B: CAMG P1,BIGHOL## ;YES, WILL THIS SEG FIT IN BIGGEST HOLE OF FREE CORE
; WITHOUT DELETEING ANY DORMANT OR IDLE SEGS?
; (P1 RESTORED TO SIZE FOR JUST THIS LOW OR HIGH SEG)
; BIGHOL CONTAINS THE NUMBER OF FREE PAGE ON
; THE KI10 RATHER THAN THE LARGEST SET OF
; CONTIGUOUS FREE PAGES
JRST SWAPI ;YES, GO SWAP IN THIS LOW OR HIGH SEG
IFN FT2REL,<
PUSHJ P,FRECR1## ;NO, GO DELETE ONE DORMANT OR IDLE SEG IN CORE
; (THERE MUST BE AT LEAST ONE, OTHERWISE
; CORTAL WOULD EQUAL BIGHOL).
; SKIP RETURN (USUAL) EXCEPT IF AN IDLE SEGMENT
; WAS FOUND WITH NO COPY ON DISK (UWP OFF).
JRST FORIDL ; GO SWAP OUT IDLE HIGH SEG WITH NO DSK COPY.
JRST FIT1B ; ONE DORMANT OR IDLE SEGMENT HAS BEEN DELETED, GO
; TRY TO SWAP IN NOW.
IFN FTSHFL,< ;SHUFFLER?
;TAG TO PATCH OUT SHUFFLER FOR EXPERIMENTS - PATCH TO JFCL
SHFPAT:: SKIPN HOLEF## ;NO, ARE THERE ANY HOLES IN CORE WHICH THE SHUFFLER
; COULD ELIMINATE(NOT COUNTING ONE AT TOP)?
> ; END OF CONDITIONAL ASSEMBLY ON FTSHFL
JRST SCNOUT ;MEMORY IS FRAGMENTED AND THERE ARE NO
;DORMANT HIGH SEGMENTS OR HOLES. SCAN FOR OUTPUT
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
IFN FTSHFL,< ;SHUFFLER?
CPUNLK (SCD) ;UNLOCK ALL CALLS TO SHUFFLER
PUSHJ P,CHKSHF## ;YES, CALL CORE SHUFFLER TO MOVE ONE SEG DOWN
CPLOCK (SCD) ;LOCK AGAIN
SKIPN SHFWAT## ;SHUFFLER WAITING FOR IO TO STOP?
JRST FIT0 ;NO, SEE IF JOB WILL FIT NOW.
POPJ P, ;YES, RETURN AND WAIT TILL IO STOPS
> ; END OF CONDITIONAL ASSEMBLY ON FTSHFL
;HERE ON SWAP OUT ERROR
;CANNOT BE MEMORY PARITY ON CHANNEL READ BECAUSE ARR INTERRUPTS
; OR PROCESSOR STOPS WHEN CONTROLLER ROUTINE TOUCHES BAD PARITY.
OUTERR: TRNN S,IOCHMP ;CHANNEL (READ) MEMORY PAR ERROR?
JRST OUTER1 ;NO, ERROR ON DISK (WRITE)
PUSHJ P,SWPRC1 ;RECORD ERROR FLAGS AND NO. OF SWAP ERRORS
IFN FT2REL,< ;2 RELOC REG SOFTWARE?
PUSHJ P,HGHSWE## ;IF HIGH SEG, PRINT ERROR FOR ALL JOBS USING
JRST OUTER0 ;YES, ALL JOBS USING HIGH SEG GOT ERROR MESSAGE
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
MOVEI T2,JOBPFI##+1 ;NO, TEMP UNTIL GET REL ADR OF PAR AREA?
CAIG T2,JOBPFI## ;IS ERROR IN PROTECTED PART OF JOB DATA
PUSHJ P,[PUSHJ P,CHGSWP ;YES, RETURN DISK SPACE
; CANNOT TRUST JOB DATA AREA
; INCREASE FREE VIRTUAL CORE
PJRST ZAPUSR##];CLEAR ALL HIS DDB'S, IO CHANS
PUSHJ P,SWOMES## ;PRINT ERROR MESSAGE AND STOP JOB
; "SWAP OUT CHN MEM PAR ERR"
OUTER0:
IFE FTVM,<
MOVEI S,0 ;CLEAR ERROR FLAGS
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
IFN FTVM,<
MOVSI T1,(SL.CHN+SL.ERR)
ANDCAM T1,SWPLST##(P1)
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
JRST SWAP1 ;REENTER SWAPPER AS IF NO ERROR
; AND FINISH SWAP OUT PROCESSING
;HERE IF SWAP OUT ERROR IS ON THE DEVICE (NOT CORE MEMORY)
OUTER1: PUSHJ P,SWPREC ;RECORD ERRORS
IFE FTVM,<
SETZ T1,
DPB T1,IMGOUT##
> ;END IFE FTVM
IFN FTVM,<
PUSHJ P,MAPBAK## ;RESET THE MAP (SETOMT WIPED IT OUT)
>
JRST SWAPO ;TRY AGAIN IN A DIFFERENT PLACE
;SUBROUTINE TO RECORD SWAP IN/OUT ERRORS - REDUCE AMOUNT OF VIRTUAL CORE
; CALLED FROM SEGERR ON FIRST HIGH SEG ERROR
SWPREC::LDB T1,IMGOUT## ;KEEP COUNT OF NO. OF OCCURANCES
ADDM T1,SWPERC## ;AND TOTAL VIRTUAL CORE LOST IN TH
IFN FTVM,<
CAIG J,JOBMAX## ;HIGH SEGMENT?
ADDI T1,UPMPSZ## ;NO, THE SPACE OCCUPIED BY THE UPMP IS LOST TOO
> ;END IFN FTVM
MOVNI T1,(T1) ;DECREASE TOTAL AMOUNT OF VIRTUAL CORE
;IF THIS IS HIGH SEG
ADDM T1,VIRTAL## ;BY THE AMOUNT BEING GIVEN UP
;FALL INTO SWPRC1
;SUBROUTINE TO RECORD SWAP OUT ERROR FROM MEMORY
SWPRC1: IORM S,SWPERC## ;OR IN FLAGS FOR ERROR REPORTING (18-23)
MOVSI T1,1 ;INCREASE COUNT OF NO OF SWAP ERRORS
ADDM T1,SWPERC##
POPJ P,
;NO INPUT TO DO, CHECK FOR EXPANDING JOBS
ZCKXPN:
SETZM SWPIFC ;CLEAR SWAPPER FAIRNESS SCAN
CHKXPN: SKIPG XJOB ;ANY JOBS TO EXPAND?
JRST CHKMIG ;NO, NO REGULAR WORK FOR SWAPPER TO DO
; YES, FALL INTO SCNOUT WHICH WILL SWAP OUT EXPANDING
; JOB SINCE THERE IS ONE
;INPUT TO DO, CHECK TO SEF IF ANY JOBS JUST HAPPEN TO WANT TO EXPAND
SCNOUT: SKIPE J,FORCE## ;ALREADY SCANNED FOR OUTPUT, AND FOUND A JOB
; (BUT HAS ACTIVE IO, SO FINISH NOT SET YET)
JRST SCNOU1 ;YES, TRY TO FORCE IT OUT AGAIN INSTEAD OF
; SCANNING AGAIN AND POSSIBLY FINDING A DIFFERENT JOB
; AND LEAVE THIS JOB IN CORE WITH SWP BIT ON SO CAN NOT
; RUN (CAN HAPPEN ONLY IF JOBS IN CORE EXPAND
; WHILE SWAPPING LOW SEG, SO HIGH SEG NO LONGER FITS)
; BUT DO SOME CHECKING FIRST.
SKIPG XJOB ;NO, ANY JOBS WAITING TO EXPAND?
JRST SCNJOB ;NO, SCAN ALL JOBS IN PRIORITY ORDER LOOKING
; FOR ONE TO SWAP OUT
MOVE J,HIGHJB## ;YES, START WITH HIGHEST JOB NUMBER ASSIGNED
MOVSI F,JXPN ;SETUP JOB EXPANDED BIT
TDNN F,JBTSTS##(J) ;IS THIS JOB EXPANDING?
SOJG J,.-1 ;NO, KEEP LOOKING
IFN FTRCHK,<
JUMPG J,SCNOK
STOPCD .+1,DEBUG,XTH, ;++XJOB TOO HIGH
SETZM XJOB ;CLEAR XJOB SO MESSAGE WILL PRINT
JRST SCNJOB ;SCAN FOR OUTPUT
> ; END OF CONDITIONAL ASSEMBLY ON FTRCHK
SCNOK:
IFN FTVM,<
SKIPE JBTADR##(J) ;DOES THIS JOB HAVE CORE IN CORE?
JRST FORCE0 ;YES, DON'T CLEAR JXPN UNTIL THE JOB IS ON WAY OUT
> ;END IFN FTVM
SOS XJOB ;DECREMENT COUNT OF EXPANDING JOBS
ANDCAM F,JBTSTS##(J) ;CLEAR EXPAND BIT IN JOB STATUS WORD
JRST FORCE0 ;GO TRY TO SWAP JOB OUT
CHKMIG:
IFN FTDHIA&FT2SWP,<
IFN FTVM,<
SKIPN SPRCNT## ;IF THE SWAPPER IS BUSY,
SKIPE SWPCNT## ; DONT TRY TO START ANYTHING
JRST FLGNUL
>
SKIPN J,MIGRAT## ;TRYING TO FORCE JOBS OFF A SWAPPING UNIT?
JRST FLGNUL ;NO, EXIT SWAPPER
CHKMI1: CAMLE J,HIGHJB## ;YES, DONE ALL JOBS?
JRST MIGDON ;YES, THROUGH
MOVE T1,JBTSTS##(J) ;NO, GET SOME INFO ON JOB
HRR T1,JBTST2##(J)
IFN FTVM,<
TLNE T1,SWP
JRST CHKMI2 ;IF JOB IS NOT SWAPPED,
PUSHJ P,PGOFF## ; DOES IT HAVE ANY PAGES ON UNIT GOING DOWN?
JRST [MOVEM J,MIGRAT## ;YES, SWAP IT OUT AND BACK IN TO GET
JRST FORCE0] ; PAGES OFF THE BAD UNIT
AOJA J,CHKMI1 ;NO, GO CHECK NEXT JOB
CHKMI2:> ;END FTVM
IFE FTVM,<
TLNE T1,SWP ;IF JOB IS SWAPPED,
>
TRNE T1,JS.MIG ; AND WE'RE NOT SURE IT MIGRATED FROM BAD UNIT,
AOJA J,CHKMI1
CAMN J,FINISH ; IF IT ISNT BEING SWAPPED NOW,
JRST FLGNUL
MOVEM J,MIGRAT## ; SWAP IT IN, SO IT WILL SWAP OUT ONTO
JRST FIT1 ; ANOTHER SWAPPING UNIT
MIGDON: SETZM MIGRAT## ;DONE - CLEAR FLAG
;FALL INTO FLGNUL
> ;END FTDHIA&FT2SWP
IFN FTRSP,<
FLGNUL: SETOM SWPNUF## ;TELL CLOCK1 THAT SWAPPER WILL BE
;IDLE THIS TICK
POPJ P, ;RETURN
>;END IFN FTRSP
;EXIT SWAPPER IF NO RESPONSE DATA
IFE FTRSP,<
FLGNUL: POPJ P, ;IF NO RESPONSE DATA
>
;HERE IF WE ARE TRYING TO FORCE OUT A JOB LEFT OVER FROM LAST TICK.
IFN FTDISK,<
SCNOU1: CAME J,FORCEF ;IS THIS A JOB WE MUST RUN TO FREE A SHAR. RESOURCE?
JRST FORIDL ;NO, INSURE SWAP GETS SET
JRST FORCE1 ;YES, SEE IF WE CAN GET IT BEFORE TURNING ON SWAP, WHICH
; WOULD PREVENT US FROM GETTING IT BACK
; IF THE JOB DID HAVE IT
>
IFE FTDISK,<
SCNOU1==FORIDL
>
;SCAN FOR JOB TO OUTPUT IN ORDER TO MAKE ROOM FOR JOB TO COME IN
;SIZE(IN K) NEEDED TO GET THIS USER IN CORE IS IN P1(FITSIZ)
;JUST LOW SEG SIZE IF NO HIGH OR HIGH ALREADY IN, JUST HIGH IF LOW ALREADY IN,
;OR SUM IF BOTH MUST BE SWAPPED IN
SCNJOB: MOVE F,CORTAL## ;INITIALIZE FREE CORE COUNTER
MOVEM F,SUMCOR##
SETZM MAXJBN## ;CLEAR SWAP OUT JOB NUMBER
IFN FTHPQ,< ;HIGH PRIORITY QUEUES?
MOVE J,FIT## ;JOB (OR HI SEG) BEING FIT IN
IFN FT2REL,< ;2 RELOC REG SOFTWARE?
PUSHJ P,FITHPQ## ;GET JOB NO. IF TRYING TO FIT A HIGH SEG
; (IN CASE HIGH PRIORITY JOB HAMPERED BY
; USER IN CORE EXPANDING DURING HIS SWAP IN
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
MOVEM J,FITLOW## ;REMEMBER JOB WE ARE FITTING
LDB T4,HPQPNT## ;GET CURRENT HIGH PRIORITY Q NO, 0 IF NONE
MOVEI T1,JS.TFO ;FORCED OUT BY TIMER?
TDNE T1,JBTST2##(J) ;...
SETZ T4, ;YES. DON'T IGNORE ICPT
> ; END OF CONDITIONAL ASSEMBLY ON FTHPQ
IFN FTNSCHED,<
SETZM SCNSTP ;ASSUME WE CAN STOP AT JOB IN FIT
SKIPN TYPSCD ;IS THIS THE CLASS SCHEDULER?
JRST NOTCLS ;NO
LDB T3,PJBST2 ;GET JOB'S QUEUE
MOVEI T1,LOSCAN## ;ASSUME FIT JOB IS IN PQ2
CAIN T3,PQ2 ;IS IT IN PQ2?
MOVEM T1,SCNSTP ;YES
NOTCLS:>;END IFN FTNSCHED
MOVEI U,OSCAN## ;SCAN ALL JOBS RANKED IN PRIORITY TO BE SWAPPED OUT
JSP T1,QSCAN
JRST NOFIT ;NO MORE JOBS LEFT, CANNOT FIT JOB IN CORE
IFN FTNSCHED,<
SKIPN SCNSTP ;SCANNING ALL OF PQ2?
JRST USEFIT ;NO, COMPARE AGAINST FIT
CAMLE U,SCNSTP ;YES. HAVE WE REACHED END OF PQ2?
SKIPE INFLG ;YES. IGNORE IF IMPATIENT
JRST .+2 ;NOT END OF PQ2 OR TIMER WENT OFF
JRST NOFIT ;CAN'T FIT JOB IN, GO TELL TIMER
CAMN J,FITLOW## ;DON'T SWAP OUT SWAP-IN JOB
JRST (T2) ;IT'S US
JRST SCNJB0 ;IT'S NOT, TRY TO SWAP THIS JOB OUT
USEFIT:>;END IFN FTNSCHED
CAMN J,FITLOW## ;IS THIS JOB WE ARE TRYING TO FIT IN?
JRST [ SKIPE INFLG ;IGNORE POSITION IF IMPATIENT
JRST (T2) ;TIMER HAS GONE OFF
JRST NOFIT ;TIMER HASN'T GONE OFF
]
SCNJB0: SKIPN JBTADR##(J) ;DOES JOB HAVE LOW SEG PHYSICAL CORE?
JRST (T2) ;NO, CONTINUE SCAN TO FIND ANOTHER JOB
; (HIGH SEG ALREADY SWAPPED OUT IF NO LOW
; SEG IN CORE)
IFE FTPDBS,< ;IF WE DO NOT SWAP PDB'S
MOVE F,JBTSTS##(J) ;NO, PICK UP JOB STATUS WORD.
HRRZ W,JBTPDB##(J) ;GET PDB ADR
JUMPE W,SCNJB1 ;NO PDB, FORGET PROTECT TIME
IFN FTLOCK,<
TLZE F,NSWP ;IS THIS SEGMENT LOCKED?
TLNN F,SWP ;YES, IS IT ALREADY SWAPPED? (OTHER SEGMENT LOCKED)
PUSHJ P,LOKCHK## ;NO, IT CAN BE SWAPPED (BOTH SEGMENTS NOT LOCKED)?
JRST (T2) ;YES, CONTINUE SCAN
> ;END IFN FTLOCK
> ;END FTPDBS
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
MOVE F,JBTSTS##(J) ;NO, PICK UP JOB STATUS WORD.
PUSHJ P,FNDPDB## ;GET PDB ADDRESS
JRST SCNJB1 ;NO PDB -- NO PROTECT TIME
> ;END FTPDBS
TLNN F,SWP ;NO ICPT IF SWP BIT SET
.SKPGE .PDIPT##(W) ;PROTECTED TIME PAST?
SCNJB1: TLNE F,NSWP ;YES, IS THIS JOB NOT TO BE SWAPPED?
; (DISPLAY, REAL TIME)?
IFN FTHPQ,< ;HIGH PRIORITY QUEUE
JUMPE T4,(T2) ;IF JOB BEING FIT IN IS NOT HIGH PRIORITY
; CONTINUE SCAN
TLNE F,NSWP ;IS THIS JOB NOT TO BE SWAPPED?
; (DISPLAY, LOCKED IN CORE)?
> ; END OF CONDITIONAL ASSEMBLY ON FTHPQ
JRST (T2) ;YES,CONTINUE SCAN TO FIND ANOTHER
IFN FT2REL,<
SKIPLE T3,JBTSGN##(J) ;DOES THIS JOB HAVE A HIGH SEGMENT?
CAME T3,FIT## ;YES, IS IT THE ONE WE ARE TRYING TO FIT IN?
JRST SCNJB2 ;NO. CONTINUE
CAMN J,SWPIN## ;YES. IS THIS THE LOW SEG WE ARE GETTING IT FOR?
JRST (T2) ;YES. DON'T TRY TO SWAP HIM OUT
SCNJB2:
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
IFN FTVM,<
LDB F,IMGOUT## ;OUTPUT SIZE
JUMPN F,[SKIPN INFLG ;STILL HAVE A DISK COPY?
JRST (T2) ;IF TIMER HASN'T GONE OFF, IGNORE THIS JOB
SKIPN SPRCNT## ; OTHERWISE, WE MAY WANT TO SWAP THIS JOB ANYWAY
SKIPE SWPCNT## ;IF THE SWAPPER IS IDLE, WE CAN'T
; FINISH SWAPPING IT IN
JRST (T2)
JRST .+1] ;SO WE'D BETTER SWAP IT OUT (OR SYS WILL HANG)
;THIS COULD HAPPEN IF A JOB EXPANDED IN CORE
; BEFORE THE HIGH SEGMENT COULD SWAP IN AND
; FIT GOT CLEARED BECAUSE THERE WAS NO MORE ROOM
LDB F,IMGIN##
ADDI F,UPMPSZ##
> ;END IFN FTVM
IFE FTVM,<
HLRZ F,JBTADR##(J) ;PICK UP SIZE OF JOB
ASH F,W2PLSH## ;CONVERT TO 1K BLOCKS
ADDI F,1+UPMPSZ##
> ;END IFE FTVM
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
ADDI F,PDBPGS## ;ACCOUNT FOR CORE FREED UP BY SWAPPING
; OUT THE PDB.
> ;END FTPDBS
IFN FT2REL,<
PUSHJ P,FORSIZ## ;INCREASE SIZE(F) BY HIGH SEG SIZE/# IN CORE LO SEGS +1
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
SKIPE MAXJBN## ;PICKED ONE YET?
JRST FORCE2 ;NO
IFN FTMS,<
PUSHJ P,ANYRUN## ;JOB CURRENTLY RUNNING ON CPU1?
JRST [MOVEM J,SW0JOB ;YES, DON'T SELECT THIS JOB
JRST (T2)] ; SINCE IT MAY HAVE A HI SEG WITH
; AN IN-CORE COUNT OF 1 WHICH COULD
; GET DELETED BY FORHGH
>
PUSH P,J ;SAVE J
SKIPG J,JBTSGN##(J) ;A REAL HIGH SEGMENT?
JRST FORCE3 ;NO
PUSH P,F ;SAVE F
PUSHJ P,ANYSAV## ;MAKE SURE THIS CAN SWAP
JRST [POP P,F ;RESTORE SIZE
POP P,J ;AND JOB
JRST (T2)] ;AND REJECT JOB
POP P,F ;RESTORE SIZE
FORCE3: POP P,J
MOVEM J,MAXJBN## ;SAVE JOB NUMBER
FORCE2: ADDM F,SUMCOR## ;ADD TO TOTAL
CAMLE P1,SUMCOR## ;FOUND ENOUGH CORE FOR JOB TO BE FIT IN?
JRST (T2) ;NO. LOOK FOR MORE
EXCH J,MAXJBN## ;YES, SWAP OUT FIRST
MOVEI F,JS.TFO
PUSH P,T1 ;SAVE T1
PUSHJ P,INRNQ ;DON'T SET IF NOT IN RUN Q
SETZ F, ;NOT IN RUN Q
POP P,T1 ;RESTORE T1
SKIPE INFLG ;BECAUSE OF TIMER?
IORM F,JBTST2##(J) ;YES. MARK IT
JRST FORC00 ;AND DO PROPER ENTER
;HERE FROM SCNOUT OR LOCK
FORCE0::MOVEI T2,FLGNUL ;GET READY TO FLAG SWAPPER NULL TIME IF ACTIVE DEVICES
FORC00:
IFN FTKL10&FTMS,<
PUSHJ P,SWPCSH## ;JOB MUST BE RUNNABLE W.R.T. CACHE IN ORDER
; TO SWAP IT OUT, SINCE SOME OF IT MAY
; ONLY EXIST ON ANOTHER CPU'S CACHE
JRST (T2) ;NO GOOD, DO NOTHING THIS TICK, WAIT
; FOR OTHER CPU TO SWEEP ITS CACHE
; (HOPE THIS DOESNT HAPPEN TOO OFTEN)
>;END IFN FTKL10&FTMS
IFN FT2REL,<
PUSHJ P,ANYSAV## ;NO CAN THIS JOB BE STOPPED IN ORDER TO DO SWAP?
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
JRST (T2) ;NO, NSWP OR NSHF SET(DISPLAY,REAL TIME) OR
; SAVE OR GET IN PROGRESS WITH DEVICE STILL ACTIVE
; LOOK FOR AN OTHER JOB TO SWAP
CAILE J,JOBMAX## ;HIGH OR LOW?
JRST FORCEA ;HIGH
MOVSI F,JS.HNG ;SET TO TEST FOR JOB HUNG
SKIPE R,JBTADR##(J) ;CORE IN CORE?
TDNN F,JBTST2##(J) ;AND WAS JOB HUNG?
JRST FORC0A ;NO. CONTINUE CHECKING
PUSHJ P,ANYDEV## ;IS JOB STILL HUNG?
SKIPA J,MAXJBN## ;YES. LOOK FOR ANOTHER
JRST SWAPO ;NO LONGER HUNG. SWAP IT OUT
JRST 0(T2)
FORC0A:
IFN FTDISK,<
PUSHJ P,FLSDR## ;LOW. ANY SHAREABLE DISK RESOURCES?
JRST FORCEA ;HIGH SEG OR NO RESOURCES - SO OK
MOVEM J,FORCE## ;SET FOR LATER RETRIES
MOVEM J,FORCEF ;AND FLAG THE PROBLEM
JRST FLGNUL ;QUIT FOR NOW SINCE CAN'T SWAP HIM
> ;END OF FTDISK CONDITIONAL
FORCEA:
IFN FT2REL,<
PUSHJ P,FORHGH## ;IS THERE A HIGH SEG TO BE WRITTEN BEFORE
; TRYING TO SWAP OUT LOW SEGMENT?
; WRITE HIGH SEG IF ALL OF THE FOLLOWING ARE TRUE:
; 1. JOB HAS A HIGH SEG AND
; 2. IT HAS NOT BEEN SWAPPED FOR THIS USER
; (SWP=0 FOR JOB)
; 3. IT IS IN CORE(NOT XPANDH)
; 4. IF IN-CORE COUNT IS EXACTLY 1 MEANING
; THIS ONLY USER USING IN CORE
; 5. HIGH SEG NOT ON DISK YET
; 6. THIS HIGH SEG IS NOT THE SAME ONE AS JOB
; BEING FITTED IN IS GOING TO WANT
; RETURN HIGH SEG NO. IN J IF YES, OTHERWISE
; RETURN LOW SEG NO.
; IF JOB JUST HAS LOW SEG, SHF BIT IS SET IN JBTSTS
; FOR JOB SO IO WILL STOP NEXT BUFFER
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
;HERE FROM LOKCON TOO TO FORCE OUT IDLE HIGH SEG
FORIDL::MOVSI F,SWP!IFE FT2REL,<SHF> ;SET SWAPPED OUT BIT FOR LOW OR HIGH SEG
IORM F,JBTSTS##(J) ;SCHEDULER WILL NO LONGER RUN THIS JOB
; SET SHF BIT IF ONE SEG SOFTWARE, SO IO WILL
; STOP AFTER NEXT BUFFERFUL.
; HERE TO FORCE OUT IDLE HIGH SEG WHEN IT
; HAS NO COPY ON DISK (UWP OFF)
FORCEL: MOVEM J,FORCE## ;ASSUME NOT SWAPPABLE--IS IT?
IFE FTPDBS,< ;IF WE DO NOT SWAP PDB'S
FORCE1:
> ;END FTPDBS
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
FORCE1: JUMPL J,SWAPO ;NO I/O INTO PDB
> ;END FTPDBS
IFN FTDISK,<
SKIPN FORCEF ;TRYING TO SWAP GUY WITH DISK RESOURCE?
JRST FORCEB ;NO. PROCEED NORMALLY
PUSHJ P,FLSDR## ;YES. DOES HE STILL HAVE IT
JRST .+2 ;NO. SWAP HIM
JRST FLGNUL ;YES. TRY LATER
SETZM FORCEF ;CLEAR FLAG
JRST FORCE0 ;COMPLETE THE WORK SKIPPED EARLIER
FORCEB:> ;END OF FTDISK CONDITIONAL
SKIPN R,JBTADR##(J) ;LOC. IN PHYSICAL CORE, IS CORE
; ASSIGNED IN MEMORY?
JRST SWAPO ;NO, CANNOT HAVE ACTIVE DEVICES
CAME J,.C0JOB## ;IF THIS IS CURRENT JOB, WAIT UNTIL
; PROTECTED AREA IS MOVED BACK TO JOB DATA AREA
PUSHJ P,ANYDEV## ;ANY ACTIVE DEVICES?(2ND HALF OF ANYACT ROUT.)
JRST NOFIT ;YES--RETURN AND WAIT FOR I/O TO STOP.
; IF FIT TIMER HAS EXPIRED, CONSIDER THIS JOB
; HUNG AND REMOVE IT FROM FORCE SO ANOTHER
; JOB CAN BE SWAPPED
;SWAP OUT LOW OR HIGH SEGMENT
SWAPO:
IFE FTVM,<
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
CAILE J,JOBMAX## ;HISEG?
JRST SWAPO2 ;YES--JUST SWAP
MOVM J,J ;YES--LOOK AT JOB
SKIPN JBTADR##(J) ;SKIP IF JOB IN CORE
SWAPO1: MOVN J,J ;JOB SWAPPED TRY PDB
SWAPO2:> ;END FTPDBS
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
IFN FTTRACK,< MOVEM J,LASOUT## ;SAVE LAST SWAP OUT FOR DEBUGGING ONLY
> ; END OF CONDITIONAL ASSEMBLY ON FTTRACK
SETZM FORCE## ;CLEAR FORCE FLAG
SETZM SW0JOB
IFN FTLOCK,<
MOVE F,JBTSTS(J) ;GET SEGMENT STATUS
TLNE F,NSWP ;IS THIS SEGMENT LOCKED IN CORE?
IFN FTVM,<
JRST [PUSHJ P,FIXXPN ;YES, RETURN AND PRETEND IT WAS SWAPPED OUT
JRST FINOU0]
>
IFE FTVM,<
JRST FINOU0
>
> ;END IFN FTLOCK
HLRZ F,JBTADR##(J) ;COMPUTE CORE IMAGE
JUMPE F,SWP1 ;DONT OUTPUT IF 0 CORE(IMGOUT ALREADY SET TO 0
; WHEN CORE WAS RETURNED
IFE FTVM,<
LDB T2,IMGOUT## ;ASSUME SWAPING SPACE
JUMPN T2,FINOU2 ; IS NOT ALREADY ALLOCATED
HRRZ T2,JBTADR##(J)
MOVNM F,T1 ;*SAVE COUNT FOR CALL TO SQOUT
ASH F,W2PLSH## ;CONVERT TO 1K BLOCKS
ADDI F,1
DPB F,IMGOUT## ;RECORD AS OUT IMAGE
HRLI T2,-1(T1) ;*BUILD AND SAVE IOWD FOR SQOUT
PUSH P,T2 ;*
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
LDB U,IMGIN## ;HAS SIZE OF CORE NEEDED WHEN NEXT SWAPPED IN
IFN FTVM,<
MOVSI F,SHF ;ASSUME A LOW SEGMENT
CAIG J,JOBMAX ;IS IT?
IORM F,JBTSTS##(J) ;YES, INDICATE SWAPPING OUTPUT IN PROGRESS
LDB F,IMGOUT## ;OUTPUT IMAGE SIZE
SKIPE F ;HAS IT BEEN SET BY XPAND?
SKIPA U,F ;YES, DON'T CHANGE IT
DPB U,IMGOUT## ;NO, SET OUTPUT IMAGE
>
IFE FTVM,<
SKIPN U ;ALREADY BEEN SET(XPAND)
DPB F,IMGIN## ;NO, SO SET TO # 1K BLOCKS OF CORE NEEDED
MOVE U,F ;*CONVERT CORE IMAGE TO 128 WD BLOCKS
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
IFN FTVM,<
CAIG J,JOBMAX## ;A HIGH SEGMENT?
MOVEI U,UPMPSZ##(U) ;NO, ACCOUNT FOR THE UPMP
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
LDB F,IMGOUT## ;GET OUTPUT IMAGE SIZE
MOVEI T2,0 ;ZERO IMGOUT SO IF A HIGH SEGMENT IT WON'T
DPB T2,IMGOUT## ; LOOK LIKE IT ALREADY HAS DISK SPACE TO DODELE
PUSHJ P,SWPSPC## ;*GET DEVICE STORAGE, SAVE DEVICE ADDR IN JBTSWP
JRST SWAPO3 ;DIDN'T MAKE IT
DPB F,IMGOUT## ;NOW, SAFELY STORE OUTPUT SIZE
IFE FTVM,<
IFE FTPDBS,< ;IF WE DO NOT SWAP PDB'S
MOVNM J,FINISH## ;DISK SWAP SPACE ASSIGNED, NOW SET FINISH FLAG
> ;END FTPDBS
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
SETZM SWAPIN## ;FLAG AS SWAP OUT
MOVEM J,FINISH## ;DISK SWAP SPACE ASSIGNED, NOW SET FINISH FLAG
> ;END FTPDBS
; SO THAT SWAPPER WILL KNOW WHICH SEG FINISHED
; WHEN IO COMPLETED(SQREQ BECOMES ZERO)
POP P,T2 ;*GET IOWD
IFN FTRSP,<
SETZM SWPPLT## ;CLEAR LOST TIME FLAG, WE'RE ACTIVE
>;END IFN FTRSP
JRST SQOUT## ;*START OUTPUT AND RETURN
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
IFN FTVM,<
PUSH P,J ;FILSER CLOBBERS J
PUSHJ P,BOSLST## ;BUILD AN OUTPUT SWPLST ENTRY
AOS SPRCNT## ;COUNT UP THE NUMBER OF SWAPS IN PROGRESS
IFN FTRSP,<
SETZM SWPPLT## ;CLEAR LOST TIME FLAG
>;END IFN FTRSP
PUSHJ P,SQOUT## ;START I/O IF NOT ALREADY GOING
POP P,J ;RESTORE SEGMENT NUMBER
PUSHJ P,FIXXPN ;FIX JXPN BIT
JRST CHKXPN
FIXXPN: MOVSI T1,JXPN ;JOB IS EXPANDING BIT
CAIG J,JOBMAX## ;HIGH SEGMENT?
TDNN T1,JBTSTS##(J) ;NO, IS THIS JOB EXPANDING?
POPJ P, ;NO, RETURN
ANDCAM T1,JBTSTS##(J) ;YES, CLEAR JXPN SO JOB WON'T BE SEEN AGAIN
SOS XJOB ;DECREMENT THE COUNT OF EXPANDING JOBS
POPJ P, ;AND RETURN
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
SWAPO3:
IFE FTVM,<
POP P,(P) ;POP OFF JUNK
>
IFN FTVM,<
LDB T1,IMGIN## ;INPUT SIZE SET BY XPAND
CAIN T1,(F) ;INPUT AND OUTPUT SIZES DIFFERENT?
MOVEI F,0 ;NO, NOT SET OUTPUT SIZE TO ZERO
DPB F,IMGOUT## ;STORE AS OUTPUT SIZE
>
MOVEM J,FORCE## ;REMEMBER WHO WE WERE TRYING TO SWAP OUT
JRST FLGNUL ;RETURN, TRY SWAP NEXT TICK
NOFIT: SKIPE J,FIT## ;PICK UP JOB NUMBER WE COULDNT FIT IN NOW
CAILE J,JOBMAX
JRST FLGNUL
IFN FTHPQ,<
CAME J,FITJBZ ;WAS THIS PERSON IN FIT AND TIMING?
JRST NOFIT0 ;NO. JUST NORMAL
MOVEM J,INFLGJ ;YES. PUT HIM BACK WHERE HE WAS BEFORE
MOVE F,UPTIME## ; THE HPQ JOB ZAPPED HIM
SUB F,FITTIM ;CURRENT TIME MINUS TIME HE WAITED
MOVEM F,INFLGC ; LAST TIME IS NEW TIMER
SETZM FITJBZ ;NOW CLEAR REMEMBRANCE OF IT
JRST NOFIT1 ;AND PROCEED
NOFIT0:> ;END IFN FTHPQ
CAMN J,INFLGJ ;SAME JOB WE COULDNT FIT IN LAST TICK?
JRST NOFIT1 ;YES. COUNT HIS FRUSTRATION INDEX
MOVEM J,INFLGJ ;NO. REMEMBER HIM FOR FUTURE REFERENCE
MOVE F,UPTIME## ;AND START TIMER
MOVEM F,INFLGC
JRST FLGNUL ;FINISH UP
NOFIT1: MOVE F,UPTIME## ;CURRENT TIME
SUB F,INFLGC ;COMPUTE TIME WE'VE BEEN WAITING
CAIGE F,^D360 ;FRUSTRATION TIMED OUT? (ABOUT 6 SEC)
JRST FLGNUL ;NO. PATIENCE PLEASE.
SETOM INFLG ;GIVE HIM A QUICKER IN
AOS CINFLG ;COUNT # OF TIMES INFLG WAS SET.
SKIPE J,FORCE## ;IS THERE A JOB IN FORCE?
CAILE J,JOBMAX## ;AND IS IT A LOW SEGMENT?
JRST FLGNUL ;NO, WORK IS DONE
MOVSI F,JS.HNG ;YES, INDICATE THAT THIS JOB SHOULD NO LONGER BE
IORM F,JBTST2##(J) ; FORCED. SWAP IT OUT ONLY WHEN I/O IS INACTIVE
MOVSI F,SHF ;AND IT SHOULD NOT BE ALLOWED TO ADVANCE BUFFERS
IORM F,JBTSTS##(J) ; SINCE THE JOB MAY BE THE ONLY ONE ELIGIBLE FOR SWAP OUT
AOS CJHUNG ;COUNT # OF TIMES A JOB HUNG WITH ACTIVE I/O
SETZM FORCE## ;ALLOW SWAPPER TO PICK ANOTHER JOB IF POSSIBLE
JRST FLGNUL ;RETURN AND TRY TO SWAP NEXT TICK
$LOW
INFLGJ::0 ;FRUSTRATED JOB NUMBER WAITING TO BE SWAPPED IN
INFLGC::0 ;TIME HE STARTED WAITING
INFLG:: 0 ;HE IS FRUSTRATED
CINFLG::0 ;NUMBER OF TIMES WE GOT FRUSTRATED
CHKQJB::0 ;IF SET TO -1, CKJB1 WILL SCAN ALL JOBS FOR JRQ
CJHUNG::0 ;NUMBER OF TIMES FORCE WAS CLEARED TO AVOID
; HANGING THE SYSTEM
SW0JOB::0
IFN FTHPQ,<
FITJBZ::0 ;JOB THAT WAS IN FIT WHEN HPQ ZEROED
FITTIM::0 ;HOW LONG HE WAS THERE
>;END IFN FTHPQ
SWPIFC::0 ;SWAPER FAIRNESS COUNT
MAXIFC::IFC0## ;MAXIMUM FAIRNESS COUNT FOR SWAPPER
IFN FTNSCHED,<
TYPSCD::0 ;PLACE FOR SWAPPER TO CHECK SCHEDULER TYPE
SCNSTP: 0 ;IF SCHEDULER IS IN CLASS MODE AND JOB BEING
; FIT IS IN PQ2,
;CONTAINS ADDRESS IN OSCAN OF FIRST QUEUE AFTER PQ2
; ZERO OTHERWISE.
>;END IFN FTNSCHED
$HIGH
IFN FTDISK,<
$LOW
FORCEF::0
$HIGH
>
NOFITZ: SETZM FIT## ;CLEAR JOB BEING FIT IN
JRST FLGNUL ;EXIT SWAPPER. NEW JOB WILL BE SELECTED NEXT TIME
IFN FTHPQ,<
ZERFIT: SETZM FIT## ;CLEAR FIT SO WE CAN RESELECT
SKIPE FITJBZ ;ARE WE ALREADY REMEMBERING SOMEONE?
POPJ P, ;YES. REMEMBER OLDEST
MOVEM J,FITJBZ ;REMEMBER HIM
MOVE T2,UPTIME## ;NO. SEE HOW LONG THIS GUY WAITED
SUB T2,INFLGC
MOVEM T2,FITTIM ;AND REMEMBER THAT TOO
MOVE J,.C0RTF## ;SELECT HPQ JOB TO SWAP IN
MOVEM J,FIT##
POPJ P,
>
;SWAP IN A JOB OR HIGH SEGMENT
SWAPI:
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
CAILE J,JOBMAX## ;IS THIS A HISEG
JRST SWAPI2 ;YES--NO PDB TO WORRY US
MOVM J,J ;GET THE PDB NUMBER
MOVN J,J ; FOR THIS JOB
SKIPE JBTADR##(J) ;IS THE PDB IN CORE?
MOVM J,J ;YES--BRING IN THE LOWSEG
SWAPI2:> ;END FTPDBS
IFN FTTRACK, < MOVEM J,LASIN## ;SAVE LAST SWAP IN FOR DEBUGGING ONLY
> ; END OF CONDITIONAL ASSEMBLY ON FTTRACK
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
SETOM SWAPIN## ;FLAG AS A SWAP IN.
> ;END FTPDBS
SETZM FIT## ;CLEAR FIT FLAG
LDB T1,IMGIN## ;SIZE OF CORE TO BE ASSIGNED WHEN SWAPPED IN (IN K)
IFE FTPDBS,< ;IF WE DO NOT SWAP PDB'S
LSH T1,P2WLSH## ;CONVERT TO HIGHEST ADR
> ;END FTPDBS
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
JUMPE T1,FININ0 ;ALL DONE IF LOWSEG SIZE IS ZERO.
LSH T1,P2WLSH## ;CONVERT TO HIGHEST ADR
> ;END FTPDBS
MOVEI T1,-1(T1) ;-1 FOR CALL TO CORGET (ALWAYS POSITIVE)
SKIPE R,JBTADR##(J) ;IS (LOW) SEG ALREADY IN CORE ?
IFE FTVM,<
JRST FININ0 ;YES, POSSIBLE IF THIS IS LOW SEG AND ONLY
; HIGH SEG WAS SWAPPED OUT.
>
IFN FTVM,<
JRST FININ5 ;YES, TREAT AS SWAP IN - GO CLEAN UP
>
MOVEM J,FINISH## ;SET FINISH FLAG TO INPUT
CPUNLK (SCD) ;UNLOCK ALL CALLS TO SHUFFLER
PUSHJ P,CORGET## ;NO, GET CORE FOR LOW OR HIGH SEG
STOPCD .,STOP,CNA, ;++CORE NOT AVAILABLE
SKIPN JBTADR##(J) ;IS SPACE IN CORE?
STOPCD .,STOP,SOD, ;++SPACE ON DISK
;SPACE IS ON THE DISK. THIS HAPPENS
; IF PDB FRAGMENTS CORE.
CPLOCK (SCD) ;LOCK AGAIN
IFN FT2REL, < PUSHJ P,FITHGH## ;INCREASE INCORE COUNT FOR THIS JOB'S HIGH SEG.
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
LDB F,IMGOUT## ;GET OUTPUT IMAGE
JUMPE F,FININ0 ;DON'T INPUT IF OUT IMAGE IS 0
IFN FTPSCD,<
PUSHJ P,CNTSWP ;RECORD DATA ON SWAPPING
>
IFE FTVM,<
LDB T2,IMGIN## ;IS SIZE OF CORE SMALLER THAN DISK SPACE ?
CAMGE T2,F ;WELL ?
MOVE F,T2 ;YES, ONLY INPUT SMALLER AMOUNT (X,RUN,GET,KJOB)
LSH F,^D18+P2WLSH## ;*BUILD IOWD FOR SQIN
MOVN T2,F ;*
HRR T2,JBTADR##(J) ;*
HLRZ T1,JBTSWP##(J) ;*GET DEVICE ADDRESS
> ; END OF CONDITIONAL ASSMBLY ON FTVM
IFN FTVM,<
PUSHJ P,BUSLST## ;SETUP TO SWAP IN THE UPMP
AOS SPRCNT## ;COUNT UP NUMBER OF SWAPPING OPERATIONS IN PROGRESS
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
IFN FTRSP,<
SETZM SWPPLT## ;CLEAR POT LOST FLAG, WE'RE DOING
>;END IFN FTRSP
;SOMETHING
JRST SQIN## ;*START INPUT
;ROUTINE TO CHANGE DISK SWAPPING SPACE ALLOCATION (OR SET TO 0)
;DIFFERS FROM ZERSWP IN THAT VIRTUAL TALLY FOR SYSTEM IS ALSO CHANGED
;CALLED FROM CORE0
;CALL: MOVE J,JOB OR HIGH SEG NUMBER
; MOVE T1,#1K BLOCKS TO BE NEW ASSIGNMENT
; PUSHJ P,CHGSWP
; ALWAYS RETURN
;CALLED ONLY FROM VIRTUAL+PHYSICAL CORE ROUTINE CORE0
CHGSWP::LDB T2,IMGIN## ;SIZE WHEN SEG NEXT SWAPPED IN
JUMPE T1,CHG1 ;IS ZERO BEING ASKED FOR ?
LSH T1,W2PLSH## ;NO, CONVERT TO 1K BLOCKS
ADDI T1,1 ;BUT DO NOT ATTEMPT TO RETURN DISK SPACE
; SINCE IT MIGHT BE FRAGMENTED (SWAPPER WILL
; RETURN ALL OF DISK SPACE ON NEXT SWAPIN)
; HAPPENS ONLY ON X,RUN,GET,KJOB
DPB T1,IMGIN## ;STORE NEW SIZE WHEN NEXT SWAPPED IN
PUSH P,J ;SAVE AN AC
IFN FTVM,<
MOVNI J,UPMPSZ## ;UPMP SIZE
SKIPN T2 ;IF GOING FROM 0 TO POSITIVE CORE,
ADDM J,VIRTAL## ; DECREMENT VIRTAL FOR UPMP
>
LDB J,IMGOUT## ;GET OLD DISK SIZE OF THIS USER (USES ITEM)
CAMGE T2,J ;IS OLD IN-CORE SIZE BIGGER ?
MOVE T2,J ;NO, USE DISK SIZE AS USER'S OLD VIRTUAL CORE
CAMGE T1,J ;IS NEW IN-CORE SIZE BIGGER ?
MOVE T1,J ;NO, USE DISK SIZE AS USER NEW
; VIRTUAL CORE
SUB T2,T1 ;DECREASE OF USER VIRTUAL CORE=OLD-NEW
ADDM T2,VIRTAL## ;USER'S DECREASE=SYSTEM'S INCREASE OF VIRTUAL
; CORE
JRST IPOPJ## ;RESTORE J AND RETURN
;ROUTINE TO RETURN ALL OF DISK SPACE FOR A LOW OR HIGH SEG
;THIS IS A PHYSICAL DEALLOCATION ONLY AND HAS NO EFFECT ON A SEGMENTS
;VIRTUAL CORE ASSIGNMENT
;CALL: MOVE J,JOB NUMBER OR HIGH SEG NUMBER
; PUSHJ P,ZERSWP
;CALLED FROM SEGCON IN MANY PLACES (5)
;AND FININ0 HERE IN SWAP
CHG1:
IFN FTVM,<
JUMPE T2,ZERSWP ;HAVE CORE ON DISK?
CAIG J,JOBMAX## ;LOW SEGMENT?
ADDI T2,UPMPSZ## ;YES, ACCOUNT FOR THE UPMP
>
ADDM T2,VIRTAL## ;INCREASE SIZE OF VIRTUAL CORE AVAILABLE IN SYSTEM
; AND THEN RETURN ALL OF DISK SPACE (CHGSWP)
ZERSWP::PUSH P,U ;SAVE TTY OUTPUT BYTE POINTER (COMMAND DECODER)
LDB U,IMGOUT## ;*SIZE ON DISK (1K BLOCKS)
JUMPE U,CHG10 ;DID SEG HAVE ANY DISK SPACE ?
HLRZ T1,JBTSWP##(J) ;*YES, LOGICAL DISK BLOCK+FRGSEG BIT
IFN FT2REL,< PUSHJ P,ZERSWH## ;IS THIS A HIGH SEG WITH AN ERROR?
;T2 SETUP AS ARG
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
IFE FTVM,<
PUSHJ P,FXSAT## ;*NO, FREE THE DISK BLOCKS NO LONGER NEEDED
> ; END OF CONDITIONAL ASSEMBLY ON FTVM
IFN FTVM,<
PUSHJ P,GIVBKH ;GIVE BACK HIGH SEGMENT SWAPPING SPACE
> ; END CONDITIONAL ASSEMBLY OF FTVM
CHG10: POP P,U ;RESTORE U
UNSWAP: MOVSI T2,SWP!SHF ;CLEAR SWAPPED OUT BIT IN JOB OR SEG
ANDCAB T2,JBTSTS##(J) ;STATUS WORD (SHF SET IF I/O WAS TO BE STOPPED
; FOR SWAP OR CORE SHUFFLE
HRRZ T1,J ;GET JOB NUMBER IN T1
CAME T1,FORCE ;SWAPPER REMEMBERING US?
JRST UNSWP1 ;NO, CONTINUE
SETZM FORCE ;YES, CLEAR FLAGS THAT HAVE OUR NUMBER
IFN FTDISK,<
SETZM FORCEF ;FORCEF MAY HAVE OUR JOB NUMBER TOO
>
;(FORCEF SHOULD EITHER BE ZERO OR SAME AS FORCE)
UNSWP1: MOVEI T1,0 ;0 IS NEW DISK ASSIGNMENT
DPB T1,IMGOUT## ;SET DISK ASSIGNMENT TO 0
IFN FTVM,<
CAIG J,JOBMAX## ;A LOW SEGMENT?
HRRZS JBTSWP##(J) ;SO IT WONT LOOK LIKE IT HAS CORE
;WHEN IT DOESNT
>
IFE FTVM,<
DPB T1,IMGIN## ;SET NEW CORE IMAGE BLOCK SIZE WHEN NEXT SWAPPED IN
>
; HERE FROM CHGSWP IF NOT ASKING FOR 0
POPJ P, ;RETURN
IFN FTVM,<
RTNDSP::TLNE T1,(SL.ERR+SL.CHN) ;DONT GIVE BACK SWAPPING SPACE IF BAD
POPJ P, ;RETURN
LDB U,[POINT 9,T1,35] ;NUMBER OF PAGES OF SWAPPING SPACE
LDB T1,[POINT 13,T1,26] ;FIRST PHYSICAL PAGE I/O WAS DONE INTO OR OUT OF
LDB T1,[POINT 17,MEMTAB(T1),35] ;FIRST DISK ADDRESS
PJRST FXSAT1## ;RETURN THE DISK SPACE
;SUBROUTINE TO GIVE BACK DISK SPACE AND CORE BLOCKS
;CALL WITH P1=LOC OF SWPLST ENTRY
GIVBAK: LDB T1,IMGOUT## ;OUTPUT IMAGE SIZE
JUMPE T1,CPOPJ## ;RETURN IF NO OUTPUT IMAGE
PUSHJ P,ZERSLE ;RETURN THE DISK SPACE
PJRST DLTSLE## ;AND DELETE THE SWPLST ENTRY
ZERSLE::SKIPL T1,SWPLST##(P1) ;FRAGMENTED?
PJRST RTNDSP ;NO, JUST RETURN THE DISK SPACE
PUSHJ P,SAVE1## ;SAVE AN AC
HRRZ P1,T1 ;ADDRESS OF THE FRAGMENT TABLE
GIVBK1: MOVE T1,(P1) ;NEXT ENTRY IN THE FRAGMENT TABLE
JUMPLE T1,GIVBK2 ;JUMP IF A LINK WORD
PUSHJ P,RTNDSP ;RETURN THE DISK SPACE REPRESENTED IN THIS ENTRY
AOSA P1 ;STEP ON TO THE NEXT ENTRY IN THE TABLE
GIVBK2: HRRZ P1,T1 ;LINK TO NEXT ENTRY
JUMPN P1,GIVBK1 ;JUMP IF NOT THE LAST ENTRY
POPJ P, ;ALL DONE, RETURN
GIVBKH: PUSHJ P,SAVE1## ;SAVE P1
MOVSI P1,MJBTMX## ;- TOTAL NUMBER OF SEGMENTS ALLOWED
CHG4: SKIPN SWPLST##(P1) ;NON-ZERO ENTRY IN SWPLST?
JRST CHG6 ;NO, LOOK AT THE NEXT ENTRY
HRRZ T1,SW3LST##(P1) ;SEGMENT NUMBER ASSOCIATED WITH THIS ENTRY
CAIN T1,(J) ;SAME AS THE ONE WE ARE LOOKING FOR?
PJRST GIVBAK ;YES, GIVE BACK THE DISK SPACE
CHG6: AOBJN P1,CHG4 ;LOOP FOR THE NEXT ENTRY
HLRZ T1,JBTSWP##(J) ;GET SWAPPING POINTER
PJRST FXSAT## ;GIVE BACK THE DISK SPACE
>
;XPAND SETS CONDITIONS TO GET MORE CORE FOR A JOB BY SWAPPING IN OUT
;THEN BACK IN TO DESIRED AMOUNT.
;JOBS POSITION IN QS NOT AFFECTED.
;CALLED ONLY FROM CORE COMMAND
;ASSUMES CALL FOR CURRENT JOB IF EXPANDING HIGH SEG,IE ASSUME AT UUO LEVEL
;THIS IS TRUE SINCE THERE IS NO CORE COMMAND WHICH CAN EXPAND HIGH SEG
;CALL: MOVE J,[JOB NUMBER]
; MOVE T1,[HIGHEST LEGAL ADDRESS DESIRED]
; PUSHJ P,XPAND
; RETURN, T1 DESTROYED
XPAND::
IFN FTVM,<
CAILE J,JOBMAX## ;IS THIS A LOW SEG?
TLNN J,SHRSEG ;SHAREABLE HIGH SEG?
CAIA ;OK TO CHANGE JBTADR
JRST XPAND2 ;DON'T CHANGE JBTADR FOR SHR SEG
SKIPE R ;DON'T MAKE JBTADR NON-ZERO IF NO CORE IN CORE
HRLM T1,JBTADR##(J) ;MAKE JBTADR RIGHT
XPAND2:>
ADDI T1,1 ;CONVERT HIGHEST DESIRED ADDRESS
LSH T1,W2PLSH## ;TO 1K BLOCKS
IFN FTVM,<
CAILE J,JOBMAX## ;A LOW SEGMENT?
JRST XPANDP ;NO, A SHARABLE HIGH SEGMENT, DON'T CHANGE
; THE WORKING SET
JUMPE R,XPAND1 ;IF NO CORE, NO WORKING SET TO MAKE RIGHT
PUSHJ P,ADJWS## ;TURN ON BITS IN WSBTAB WHICH REPRESENT PAGES
; BEING ADDED TO THE WORKING SET
XPANDP::LDB T2,IMGIN## ;CURRENT PHYSICAL SIZE
DPB T2,IMGOUT## ;STORE AS OUTPUT IMAGE SIZE
XPAND1:>
DPB T1,IMGIN## ;STORE, SO SWAPPER WILL KNOW HOW MUCH CORE
; TO REQUEST WHEN NEXT SWAPPED IN
;ROUTINE TO FLAG JOB TO BE STOPPED AND SWAPPED OUT
;BECAUSE IT HAS JUST BEEN CONNECTED TO A HIGH SHARABLE SEG WHICH IS ON DISK
;OR ON ITW WAY IN OR OUT. THE SIZE OF THE HIGH SEG IS UNCHANGED
;THE JOB MUST BE STOPPED UNTIL HIGH SEG SWAPPED IN JUST AS IF JOB HAS
;EXPANDED HIGH SEG (MUST BE CALLED FROM UUO LEVEL FOR CURRENT JOB IF HIGH SEG)
;ALSO CALLED FROM HIBERNATE UUO IF USER WANTS TO BE SWAPPED OUT
; AND MEMORY PARITY ERROR RECOVERY
; IF JOB (LOW OR HIGH SEG) IS LOCKED OR HIGH SEG LOCKED
; NOTHING IS SWAPPED OUT (INCLUDING OTHER JOBS USING HIGH SEG)
;CALL: MOVE J,HIGH SEG NUMBER
; PUSHJ P,XPANDH
XPANDH::
IFN FTLOCK,< ;LOCK UUO FEATURE?
PUSHJ P,LOKCHK## ;IS THIS JOB (LOW OR HIGH SEG) OR HIGH SEG LOCKED?
POPJ P, ;YES, CANNOT SWAP OUT
> ; END OF CONDITIONAL ASSEMBLY ON FTLOCK
IFN FT2REL,< ;2 RELOC REG SOFTWARE?
PUSH P,J ;SAVE JOB NUMBER
PUSHJ P,XPNHGH## ;CHECK IF THIS IS A HIGH SEG EXPANDING
; IF YES, SCAN OTHER JOBS, CALL XPANDH
; FOR EACH JOB WHICH IS STILL IN CORE
; SET JXPN FOR THIS HIGH SEG. THUS NO JOB
; WILL BE ABLE TO USE THIS HIGH SEG UNTIL
; IT IS SWAPPED BACK IN FOR SOME JOB.
; ALWAYS RETURN JOB NO.
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
MOVSI T2,JXPN ;SET THIS JOB EXPANDING BIT SO IT WILL NOT BE RUN
IFN FTPDBS,< ;THIS IS INCLUDED IF WE SWAP PDB'S
MOVM J,J ;MAKE SURE WE HAVE A JOB NUMBER
CAMLE J,HIGHJB## ;IS THIS NUMBER GREATER THAN THE HIGHEST
; JOB NUMBER IN THE SYSTEM.
MOVEM J,HIGHJB## ;YES--FIX UP HIGHJB. THIS HAPPENS IF
; CREPDB IS CALLED FOR A NEW PROCESS
; AND WE NEED TO PLACE THE PDB ON THE
; DISK FOR A WHILE.
> ;END FTPDBS
TDNN T2,JBTSTS##(J) ;IS IT ALREADY SET FOR THIS JOB?(UNLIKELY)
AOS XJOB ;NO, INCREMENT COUNT ONLY ONCE FOR EACH JOB EXPANDING
IORM T2,JBTSTS##(J) ;AND SET JOB EXPANDING BIT
IFE FT2REL, <
POPJ P, ;RETURN
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
IFN FT2REL, <
JRST IPOPJ## ;RESTORE JOB OR HIGH SEG NUMBER (ITEM) AND RETURN
> ; END OF CONDITIONAL ASSEMBLY ON FT2REL
SUBTTL SCHED. UUO
IFN FTNSCHED,<
;SCHED. UUO USED TO SET SCHEDULER PARAMETERS
; CALL:
; MOVE AC,[XWD N,ADDR]
; SCHED. AC, ;OR CALLI AC,150
; ERROR RETURN
; GOOD RETURN
;
; THE FORMAT OF ADDR THROUGH ADDR+N-1 IS
;
; ADDR: XWD FN CODE,BLOCK
; XWD FN CODE,BLOCK
; .
; .
; .
; WHERE FN CODE IS THE FUNCTION CODE DESIRED. BIT 0 CONTROLLS WHETHER
; THE READ PART OR THE WRITE PART OF THE FUNCTION IS SELECTED, A 1 MEANING
; WRITE.
; THE FORMAT OF BLOCK DIFFERS WITH EACH FUNCTION, AND IS DESCRIBED BEFORE
; EACH FUNCTION'S SUBROUTINE.
SC.WRT==1B0 ;WRITE BIT (MUST BE SIGN BIT)
SCHED.::PUSHJ P,SAVE1## ;SAVE P1
MOVE P1,T1 ;SAVE C(AC) IN P1
PUSHJ P,PRVJ## ;PRIVELEGED?
JRST .+2 ;YES, CONTINUE
JRST SCHNPE ;NO,GIVE ERROR
HLRE T1,P1 ;GET NUMBER OF OPERATIONS
JUMPLE T1,CPOPJ1 ;DONE IF ZERO OR NEG.
MOVNS T1
HRL P1,T1 ;-N,,ADDR IS AOBJN POINTER
SCHDU1: HRR M,P1 ;GET ADDR OF BLOCK
PUSHJ P,SCHGET ;GET A FUNCTION
HRR M,T1 ;GET ADDRESS IN M
HLRZ T2,T1 ;GET FUNCTION, BITS IN T2
TRZ T2,(SC.WRT) ;CLEAR WRITE BIT (MUST BE SIGN BIT)
CAILE T2,SCDFMX ;OVER MAXIMUM FUNCTION?
JRST SCHFNE ;YES, FUNCTION NUMBER ERROR
MOVE T4,LNCSFM ;LEGAL NON-CLASS SCHED. FUNCTION MASK
LSH T4,0(T2) ;POSITION FLAG AS SIGN BIT
SKIPN TYPSCD ;CLASSES ENABLED? ALL FUNCTIONS LEGAL
JUMPGE T4,SCHNSS ;IF CLASS FUNCTION AND CLASSES DISABLED
MOVE T3,SCDDIS(T2) ;ASSUME WRITE OPERATION
JUMPL T1,.+2 ;TEST WRITE BIT
MOVSS T3 ;FUNCTION IS REALLY READ.
PUSHJ P,(T3) ;DISPATCH TO ROUTINE
POPJ P, ;ERROR - CODE IS STORED IN USER AC
AOBJN P1,SCHDU1 ;CONTINUE FOR ALL FUNCTIONS
JRST CPOPJ1 ;FINISHED. RETURN SUCCESSFULLY
;DISPATCH TABLE. LEFT HALF IS ADDRESS OF READ PART OF FUNCTION,
; RIGHT HALF IS ADDRESS OF WRITE PART.
SCDDIS: XWD SCHRSI,SCHWSI ;(0)READ/SET SCHEDULING INTERVAL
XWD SCHRMI,SCHWMI ;(1)READ/SET MCU INTERVAL
XWD SCHRQT,SCHWQT ;(2)READ/SET CLASS QUOTAS AND FLAGS
XWD SCHRTS,SCHWTS ;(3)READ/SET TIME SLICES FOR PQ1 AND PQ2
XWD SCHRDC,SCHWDC ;(4)READ/SET DCUF
XWD SCHRJC,SCHWJC ;(5)READ/SET JOB'S CLASS
XWD SCHRMC,SCHWMC ;(6)READ/SET PROT0 (MCU CONSTANT)
XWD SCHRCT,SCHFNE ;(7)READ QUOTAS USED FOR EACH CLASS SINCE STARTUP
XWD SCHREF,SCHWEF ;(10)READ/SET EXPONENTIAL FACTOR
XWD SCHRPF,SCHWPF ;(11)READ/SET MCU MULTIPLIER (PROT)
XWD SCHRCD,SCHWCD ;(12)READ/SET NEW JOBS' DEFAULT CLASS
XWD SCHRSC,SCHWSC ;(13)READ/SET SWAPPABLE CYCLING TIME
SCDFMX==.-SCDDIS-1 ;MAXIMUM FUNCTION NUMBER
;DEFINE BIT TABLE OF LEGAL FUNCTIONS IN NON CLASS SCHEDULER
LNCSFM: EXP 1B3!1B4!1B6!1B<^O11>!1B<^O13>
;ROUTINES TO PERFORM SCHED. UUO FUNCTIONS. CALLED FROM SCHED. UUO
; WITH M SET TO ADDRESS OF BLOCK. THESE ROUTINES PRESERVE P1-P4, USE
; T1,T2,T3,T4
;FUNCTION 0
;READ/SET SCHEDULING INTERVAL
; READ FUNCTION RETURNS INTERVAL VALUE AT LOCATION BLOCK
; FORMAT OF ARGUMENT BLOCK ON WRITE:
; WARNING: NOT RESPONSIBLE FOR EFFECTS ON QUOTA ENFORCEMENT IF MEDIUM
; TERM SCHEDULING INTERNAL IS CHANGED FROM ONE NON-ZERO VALUE TO ANOTHER
; NON-ZERO VALUE.
;
; BLOCK: <DESIRED VALUE>
SCHRSI: MOVE T1,SCDINT## ;GET INTERVAL
JRST SCHPVL ;
SCHWSI: PUSHJ P,SCHGET ;GET ARGUMENT FROM ADDRESS IN M
MOVEM T1,SCDINT ;USE AS SCHEDULING INTERVAL
MOVEM T1,UTMEAR## ;USE THIS AS START FOR EXPONENTIALLY AVERAGED
;USER TIME (WILL DECREASE, BUT THIS IS
;CLOSER THAN ZERO
JUMPN T1,SCHWS2 ;IF NOT TURNING OFF CLASSES, SKIP THIS NEXT STUFF
MOVEI T2,M.CLSN## ;GET NUMBER OF CLASSES = LENGTH OF CLSSTS
SETZM CLSQTA## ;CLEAR QUOTA WORDS THAT SQ FOR LOOKS AT
MOVE T1,[CLSQTA,,CLSQTA+1]
BLT T1,CLSQTA-1(T2)
SETZM RRFLAG## ;NO MORE CLASSES WITH QUOTA NOW
SETZM CLSEAR## ;CLEAR OUT EXPONENTIAL AVERAGES TOO.
MOVE T1,[CLSEAR,,CLSEAR+1]
BLT T1,CLSEAR-1(T2)
SETZM CLSSTS## ;CLEAR FIRST WORD AS USUAL
MOVE T1,[CLSSTS##,,CLSSTS##+1] ;BLT POINTER TO CLEAR
BLT T1,CLSSTS##-1(T2) ;CLEAR TO LAST WORD
;NOW TURN OFF ALL FIXED QUOTA BITS FOR JOBS IN THEIR JBTSCD ENTRY,
; SINCE THATS WHAT QSCAN LOOKS AT.
MOVE J,HIGHJB ;HIGHEST JOB TO WORRY ABOUT (CLRJBT TAKES CARE OF THE REST)
MOVSI T2,(JS.FXC) ;THE BIT
SCHWS1: ANDCAM T2,JBTSCD##(J) ;CLEAR IT
SOJG J,SCHWS1 ;FOR ALL JOBS
SCHWS2: SETZM SCDTIM## ;FORCE NEW SCHEDULING INTERVAL
JRST CPOPJ1## ;GIVE GOOD RETURN
;FUNCTION 1
;
;HERE TO READ MCU INTERVAL
; FORMAT OF BLOCK SAME AS THAT FOR SCHEDULING INTERVAL FUNCTION
;
SCHRMI: MOVE T1,MCUINT## ;GET MCU INTERVAL
SCHPVL: PUSHJ P,PUTWRD## ;SEND TO USER
JRST SCHAER ;ADDRESS PROBLEM...
JRST CPOPJ1 ;OK
SCHWMI: PUSHJ P,SCHGET ;GET ARG
MOVEM T1,MCUINT## ;STORE
SETZM MCUTIM## ;FORCE NEW MCU CALCULATION RIGHT AWAY
JRST CPOPJ1
;FUNCTION 2
;
;HERE TO READ CLASS QUOTAS
; ARGUMENT BLOCK SETUP FOR READ CLASS QUOTA FUNCTION:
;
; BLOCK: N ;NUMBER OF CLASSES TO READ QUOTAS OF
; BLOCK+1: ;QUOTA AND BITS OF CLASS 0 RETURNED HERE
; BLOCK+2: ;QUOTA AND BITS OF CLASS 1 RETURNED HERE
; .
; BLOCK+N: ;QUOTA AND BITS OF CLASS N-1 RETURNED HERE
;
SCHRQT: PUSHJ P,SCHGET ;GET NUMBER OF CLASSES TO RETURN
SKIPLE T1 ;TOO LOW OR
CAILE T1,M.CLSN## ;TOO HIGH?
JRST SCHCLE ;YES, TELL HIM SO
MOVN T4,T1 ;GET AN AOBJN POINTER
HRLZS T4
SCHRQ1: MOVE T1,CLSSTS##(T4) ;GET QUOTA, BITS FOR CLASS
JSP T2,SCHBLK ;STORE WORD
JRST SCHRQ1 ;LOOP FOR MORE
;HERE TO SET QUOTAS FOR CLASS
;
; FORMAT OF BLOCK:
;
; BLOCK: N ;NUMBER OF WORDS FOLLOWING
; BLOCK+1: XWD <BITS>+CLASS,QUOTA
; BLOCK+2: XWD <BITS>+CLASS,QUOTA
; .
; BLOCK+N: XWD <BITS>+CLASS,QUOTA
;
SCHWQT: PUSHJ P,SCHGET ;GET NUMBER OF ARGS
JUMPLE T1,CPOPJ1 ;DONE IF LE ZERO
MOVE T4,T1 ;SAVE IN T4
SCHWQ1: PUSHJ P,SCHGT1 ;GET ARG
LDB T3,[POINT 5,T1,17] ;GET CLASS
CAIL T3,M.CLSN## ;TOO HIGH?
JRST SCHCLE ;YES, REPORT IT.
TLZ T1,(JS.CLS) ;CLEAR CLASS PART OF ARG
HRRZM T1,CLSEAR##(T3) ;SAVE QUOTA AS START FOR NEW EXP. AUG.
EXCH T1,CLSSTS##(T3) ;AND SAVE QUOTA AND BITS
XOR T1,CLSSTS##(T3) ;SEE IF FIXED QUOTA BIT HAS CHANGED
JUMPGE T1,SCHWQ4 ;NO. (THIS CHECK DEPENDS ON SIGN BITS
; BEING THE FLAGS FOR BOTH WORDS)
MOVSI F,(JS.FXC) ;OH WELL, HAVE TO LOOP THRU ALL JOBS
MOVE W,[ANDCAM F,JBTSCD##(J)] ;ASSUME IT'S NOT FIXED
SKIPGE CLSSTS##(T3) ;IS IT REALLY NOT FIXED?
MOVE W,[IORM F,JBTSCD##(J)] ;IT'S FIXED
MOVE J,HIGHJB ;HIGHEST JOB
SCHWQ2: LDB T2,JBYCLS## ;GET CLASS NUMBER
CAMN T2,T3 ;SAME AS CLASS WE'VE CHANGED FIXED BIT ON?
XCT W ;YES, THEN DO THE INSTRUCTION
SCHWQ3: SOJG J,SCHWQ2 ;AND LOOP FOR ALL JOBS
SCHWQ4: SOJG T4,SCHWQ1 ;AND LOOP UNTIL DONE.
MOVEI T2,M.CLSN##-1 ;COMPUTE END ADDRESS
MOVE T1,[CLSRTM##,,CLSRTM##+1]
CONO PI,PIOFF## ;DON'T INTERRUPT US
SETZM CLSRTM## ;CLEAR CLSRTM
BLT T1,CLSRTM##(T2)
SETZM RTCTOT## ;CLEAR USER TIME SINCE WE LAST DID THIS
CONO PI,PION## ;PI BACK ON
JRST CPOPJ1 ;GOOD RETURN.
;FUNCTION 4
;
;HERE TO READ DESIRED CHANNEL USAGE FRACTIONS (DCUF)
; FORMAT OF BLOCK:
;
; BLOCK: N ;NUMBER OF CHANNELS TO READ DCUF OF, STARTING
;WITH CHANNEL 0
; BLOCK+1: ;CHANNEL 0 DCUF RETURNED HERE
; BLOCK+2: ;CHANNEL 1 DCUF RETURNED HERE
; .
; BLOCK+N: ;CHANNEL N-1 DCUF RETURNED HERE
;
SCHRDC: PUSHJ P,SCHGET ;GET NUMBER OF CHANNELS TO READ
SKIPLE T1 ;NEGATIVE OR
CAILE T1,M.CHN## ;TOO HIGH?
JRST SCHCNE ;YES, ERROR.
MOVN T4,T1
HRLZS T4 ;MAKE AOBJN POINTER
SCHRD1: MOVE T1,.GTDCF##(T4) ;GET FRACTION
JSP T2,SCHBLK
JRST SCHRD1
;HERE TO WRITE SELECTED DCUFS
; FORMAT OF BLOCK:
;
; BLOCK: N ;NUMBER OF WORDS FOLLOWING
; BLOCK+1: XWD CHANNEL,PERCENT
; BLOCK+2: XWD CHANNEL,PERCENT
; .
; BLOCK+N: XWD CHANNEL,PERCENT
;
SCHWDC: PUSHJ P,SCHGET ;GET NUMBER OF WORDS FOLLOWING
JUMPLE T1,CPOPJ1 ;DONE IF LE ZERO
MOVE T4,T1 ;COPY
SCHWD1: PUSHJ P,SCHGT1
HLRZ T2,T1 ;GET CHANNEL NUMBER IN T2
CAIL T2,M.CHN## ;LEGAL?
JRST SCHCNE ;NO
HRRZM T1,.GTDCF##(T2) ;STORE
SOJG T4,SCHWD1 ;AND LOOP.
JRST CPOPJ1 ;DONE.
;FUNCTION 3
;
;HERE TO READ TIME SLICES FOR EITHER PQ1 OR PQ2
; FORMAT OF BLOCK:
;
; BLOCK: N ;NUMBER OF QUEUES TO READ TIME SLICES FOR
; ;(CAN ONLY BE 1 OR 2)
; BLOCK+1: ;TIME SLICE FOR PQ1 RETURNED HERE
; BLOCK+2: ;TIME SLICE FOR PQ2 RETURNED HERE
; ;(IF N WAS BIG ENOUGH)
;
SCHRTS: PUSHJ P,SCHGET ;GET N
SKIPLE T1
CAILE T1,2 ;LEGAL ARG?
JRST SCHQNE ;NO
MOVN T4,T1
HRLZS T4 ;AOBJN POINTER
SCHRT1: MOVE T1,QADTAB##(T4) ;GET SLICE
IMULI T1,^D1000 ;MILLITICKS
IDIV T1,TICSEC## ;CONVERT TO MILLISECS
JSP T2,SCHBLK
JRST SCHRT1
;HERE TO WRITE TIME SLICES FOR PQ1 OR PQ2
; FORMAT OF BLOCK:
;
; BLOCK: N ;NUMBER OF WORDS FOLLOWING
; BLOCK+1: XWD Q#,TIME SLICE(MS)
; BLOCK+2: XWD Q#,TIME SLICE(MS)
; .
; BLOCK+N: XWD Q#,TIME SLICE
;
SCHWTS: PUSHJ P,SCHGET ;GET N
JUMPLE T1,CPOPJ1 ;DONE IF LE ZERO
MOVE T4,T1 ;COPY N
SCHWT1: PUSHJ P,SCHGT1 ;GET ARG
MOVE T2,TICSEC## ;GET JIFSEC
IMULI T2,(T1) ;GET MILLITICS IN T2
IDIVI T2,^D1000 ;CONVERT TO TICKS (ARG WAS IN MS)
HLRZ T3,T1 ;GET Q NUMBER
SKIPE T3 ;ZERO IS NOT LEGAL
CAILE T3,2 ;LEGAL?
JRST SCHQNE ;NO, Q NUMBER ERROR
MOVEM T2,QADTAB##-1(T3);SAVE
SOJG T4,SCHWT1 ;AND LOOP
JRST CPOPJ1 ;FINISHED.
;FUNCTION 5
;
;HERE TO READ CLASS NUMBERS FOR ALL JOBS ON THE SYSTEM UP TO
; THE NUMBER IN ADDRESS
; FORMAT OF BLOCK:
;
; BLOCK: N ;NUMBER OFJOBS TO READ CLASS FOR
; BLOCK+1: ;RETURN CLASS OF JOB 1 HERE
; BLOCK+2: ;RETURN CLASS OF JOB 2 HERE
; .
; BLOCK+N: ;RETURN CLASS OF JOB N HERE
;
SCHRJC: PUSHJ P,SCHGET ;GET NUMBER OF JOBS TO DO
PUSHJ P,LGLPRC## ;IS THIS A LEGAL JOB NUMBER?
JRST SCHBJN ;NO
MOVN T4,T1
HRLZS T4
AOS T4 ;START WITH JOB 1
SCHRJ1: LDB T1,JBYCL4## ;GET CLASS
JSP T2,SCHBLK
JRST SCHRJ1
;HERE TO PUT A JOB INTO A CPU CLASS
; FORMAT OF BLOCK:
;
; BLOCK: N ;NUMBER OF WORDS FOLLOWING
; BLOCK+1: XWD JOB,CLASS
; BLOCK+2: XWD JOB,CLASS
; .
; BLOCK+N: XWD JOB,CLASS
;
SCHWJC: PUSHJ P,SCHGET ;GET N
JUMPLE T1,CPOPJ1 ;RETURN IF NO WORK TO DO
MOVE T4,T1 ;COPY N
SCHWJ1: PUSHJ P,SCHGT1 ;
HRRZ T2,T1 ;SAVE CLASS NUMBER IN T2
HLRZS T1 ;GET JOB NUMBER IN RHOF T1 FOR LGLPRC
CAIN T1,-1 ;US?
MOVE T1,J ;YES, USE OUR JOB NUMBER
PUSHJ P,LGLPRC## ;LEGAL JOB NUMBER?
JRST SCHBJN ;NO
MOVSI T3,JNA
TDNN T3,JBTSTS##(T1)
JRST SCHBJN ;NO GOOD IF JOB NOT ASSIGNED
CAIL T2,M.CLSN## ;BAD CLASS NUMBER?
JRST SCHCLE ;YES.
MOVSI T3,(JS.FXC) ;FIXED CLASS BIT (MUST BE SIGN BIT)
MOVE F,[ANDCAM T3,JBTSCD##(T1)] ;ASSUME NEW CLASS NOT FIXED QUOTA
SKIPGE CLSSTS##(T2) ;IS HIS NEW CLASS FIXED QUOTA?
MOVE F,[IORM T3,JBTSCD##(T1)] ;ITS FIXED
XCT F ;DO THE PROPER THING TO THE BIT
DPB T2,JBYCL1## ;DEPOSIT
LDB T3,PJ2ST1## ;GET Q NUMBER OF JOB IN T1
CAIE T3,PQ2 ;IF IN PQ2, REQUEUE
JRST SCHWJ2 ;NOT IN PQ2
PUSH P,J ;SAVE OUR JOB NUMBER
MOVE J,T1 ;GET TARGET JOB IN J
PUSHJ P,REQUE## ;REQUEUE HIM SO HE WILL WIND UP IN PROPER SUBQUE
POP P,J
SCHWJ2: SOJG T4,SCHWJ1 ;AND LOOP FOR NEXT SPEC.
JRST CPOPJ1
;FUNCTION 6
;
;HERE TO READ MCU CONSTANT (PROT0)
; FORMAT OF BLOCK
;
; BLOCK: ;PROT0 RETURNED HERE
;
SCHRMC: MOVE T1,PROT0##
PJRST SCHPVL ;STORE VALUE IN USERS AREA AND RETURN
;HERE TO WRITE MCU CONSTANT (PROT0)
; FORMAT OF BLOCK:
;
; BLOCK: <DESIRED VALUE OF PROT0>
SCHWMC: PUSHJ P,SCHGET
MOVEM T1,PROT0##
JRST CPOPJ1
;FUNCTION 7
;
;HERE TO READ TIME SINCE SYSTEM STARTUP EACH CLASS HAS USED.
; FORMAT OF BLOCK
;
; BLOCK: N ;NUMBER OF CLASSES TO READ RUNTIMES FOR
; BLOCK+1: ;CLASS 0 RUNTIME RETURNED HERE
; BLOCK+2: ;CLASS 1 RUNTIME RETURNED HERE
; .
; BLOCK+N: ;CLASS N-1 RUNTIME RETURNED HERE
;
SCHRCT: PUSHJ P,SCHGET
SKIPLE T1 ;BOMB IF OUT OF RANGE
CAILE T1,M.CLSN##
JRST SCHCLE
MOVN T4,T1
HRLZS T4
SCHRC1: MOVE T1,CLSRTM##(T4) ;GET TIME
JSP T2,SCHBLK
JRST SCHRC1
;FUNCTION 10
;
;HERE TO READ EXPONENTIAL FACTOR USED IN KEEPING CLSEAR
; FORMAT OF BLOCK:
;
; BLOCK: ;RETURN VALUE HERE
SCHREF: MOVE T1,SCDEXF## ;GET VALUE
PJRST SCHPVL ;PUT INTO USERS AREA AND RETURN
;HERE TO WRITE EXPONENTIAL FACTOR. VALUE MUST BE BETWEEN
; ZERO AND 10000., SINCE THE FACTOR IS A SCALED FRACTION
; WITH THE SCALE FACTOR BEING 10000.
;
; FORMAT OF BLOCK:
;
; BLOCK: <DESIRED VALUE>
SCHWEF: PUSHJ P,SCHGET ;GET DESIRED VALUE
JUMPL T1,SCHBFE
CAILE T1,^D10000
JRST SCHBFE ;BAD VALUE
MOVEM T1,SCDEXF## ;SAVE
JRST CPOPJ1 ;AND GIVE GOOD RETURN
;FUNCTION 11
;
;HERE TO READ VALUE OF PROT (MCU MULTIPLIER) WHICH CAN BE SET EITHER
; BY THE MCU ALGORITHM OR MANUALLY (BUT NOT BOTH).
;
; FORMAT OF BLOCK:
;
; BLOCK: ;RETURN VALUE HERE
;
SCHRPF: MOVE T1,PROT## ;GET DESIRED VALUE
PJRST SCHPVL ;STORE AND RETURN
;HERE TO WRITE PROT "MANUALLY", MEANING WITHOUT THE MCU
; CALCULATOR OPERATING. IF MCUINT IS NONZERO, AN ERROR RETURN IS GIVEN.
;
; FORMAT OF BLOCK:
;
; BLOCK: <DESIRED VALUE OF PROT>
SCHWPF: SKIPE MCUINT## ;IS MCUINT ZERO?
JRST SCHMIS ;NO, PROT WOULD HAVE BEEN OVERWRITTEN ANYWAY
PUSHJ P,SCHGET ;YES, GET DESIRED VALUE
MOVEM T1,PROT## ;SAVE DESIRED VALUE (IN MICROSECS)
PJRST CPOPJ1 ;AND RETURN WELL.
;FUNCTION 12
;
;HERE TO READ VALUE OF DEFAULT CLASS FOR NEW JOBS
;
; FORMAT OF BLOCK:
;
; BLOCK: ;RETURN VALUE HERE
;
SCHRCD: MOVE T1,DEFCLS## ;GET DEFAULT CLASS
ANDI T1,37 ;JUST CLASS BITS, NO OTHER GARBAGE
PJRST SCHPVL ;STORE VALUE AND RETURN
;HERE TO WRITE THE DEFAULT CLASS OF NEW JOBS
;
; FORMAT OF BLOCK:
;
; BLOCK: <DESIRED VALUE OF DEFALT CLASS, BITS 31-35>
;
SCHWCD: PUSHJ P,SCHGET ;GET ARG
CAIL T1,M.CLSN## ;IS IT A LEGAL CLASS?
JRST SCHCLE ;NO, GIVE ILLEGAL CLASS NUMBER ERROR
MOVEM T1,DEFCLS## ;STORE
PJRST CPOPJ1## ;AND GIVE GOOD RETURN
;FUNCTION 13
;
;HERE TO READ SWAPPABLE CYCLING TIME, WHICH CONTROLS THE RATE
; AT WHICH SWAPPABLE JOBS IN CORE GET REQUEUED IF THEY HAVEN'T
; USED UP THEIR QUANTUM RUN TIME.
;
; FORMAT OF BLOCK:
;
; BLOCK: ;RETURN VALUE HERE
SCHRSC: MOVE T1,PROT1## ;GET THE VALUE
PJRST SCHPVL ;STORE AND RETURN
;HERE TO WRITE THE SWAPPABLE CYCLING TIME PARAMETER
;
; FORMAT OF BLOCK:
;
; BLOCK <DESIRED VALUE OF SWAPPABLE CYCLING TIME>
;
SCHWSC: PUSHJ P,SCHGET ;GET THE VALUE
MOVEM T1,PROT1##
PJRST CPOPJ1## ;JUST CHANGE IT.
;GET A WORD FROM USER (ERROR CODE 1 IF BAD ADDRESS)
SCHGT1: HRRI M,1(M)
SCHGET: PUSHJ P,GETWRD## ;GET WORD
JRST [POP P,(P) ;ADDRESS CHECK
JRST SCHAER]
POPJ P,0 ;GOT IT
;SUBROUTINE TO STORE A WORD INTO A BLOCK
;CALL WITH:
; T1 = WORD
; M = ADDRESS
; T4 = AOBJN WORD
; JSP T2,SCHBLK
; RETURN HERE IF MORE
SCHBLK: PUSHJ P,PUTWR1##
JRST SCHAER
AOBJP T4,CPOPJ1##
JRST (T2)
;ERROR RETURNS
ERCODE SCHAER,SCHAC% ;(1) ADDRESS CHECK ERROR
ERCODE SCHFNE,SCHUF% ;(2) BAD FUNCTION NUMBER
ERCODE SCHBJN,SCHUJ% ;(3) BAD JOB NUMBER
ERCODE SCHNPE,SCHNP% ;(4) NO PRIVELEGES
ERCODE SCHCLE,SCHUC% ;(5) BAD CLASS NUMBER
ERCODE SCHQNE,SCHUQ% ;(6) BAD QUEUE NUMBER
ERCODE SCHCNE,SCHNC% ;(7) BAD CHANNEL NUMBER
ERCODE SCHBFE,SCHEB% ;(10) BAD EXPONENTIAL FACTOR VALUE
ERCODE SCHMIS,SCHMI% ;(11) ATTEMPT TO SET PROT WHILE MCUINT NON ZERO.
ERCODE SCHNSS,SCHNS% ;(12) NOT SUBQUE SCHEDULER
>;END IFN FTNSCHED
SUBTTL MEDIUM TERM SCHEDULING INTERVAL ROUTINES
IFN FTNSCHED,<
;HERE EVERY MEDIUM TERM SCHEDULING INTERVAL TO MAINTAIN
; THE EXPONENTIALLY AVERAGED RUNTIMES FOR EACH CLASS
; AND VARIOUS OTHER DATA ABOUT QUOTAS.
;THIS ROUTINE COMPUTES THE EXPONENTIAL AVERAGING FORMULA
; (1-ALPHA)*LAST AVERAGE+(ALPHA)*INCREMENT. THE FORMULA
; ACTUALLY USED IN THE ROUTINE USES SCALED ARITHMETIC,
; WHERE ALPHA IS EXPRESSED IN UNITS OF 1/10000. THS,
; AND FOR EASE OF COMPUTATION USES THE FORMULA
; (SF*CLSEAR+ALPHA(CLSITM-CLSEAR))/SF
; WHERE SF IS THE SCALE FACTOR 10000.
;
;CLSQTA, THE REAL QUOTA WHICH SQFOR USES WHEN SCANNING FOR JOBS,
; IS COMPUTED VIA THE FORMULA
; CLSQTA = CLSSTS + (CLSSTS-CLSEAR)
; = 2* CLSQTA - CLSEAR
;
;
;SCDQTA USES AC'S T1,T2,T4.
SCDQTA::SKIPN T1,SCDINT## ;ANY INTERVAL AT ALL?
POPJ P, ;NO, DON'T DO ANYTHING
MOVE T2,UPTIME## ;GET UPTIME
CAMGE T2,SCDTIM## ;IS IT TIME FOR ANOTHER SCHED INTERVAL?
POPJ P, ;NO, RETURN
ADD T1,T2 ;GET NEXT UPTIME FOR INTERVAL
MOVEM T1,SCDTIM## ;SAVE
SETZM RRFLAG## ;CLEARCOUNT OF SUBQUEUES WITH
;NONZERO QUOTA
;HERE TO COMPUTE THE VALUE OF UTMEAR, THE EXPONENTIALLY AVERAGED
; VALUE OF THE NUMBER OF JIFFIES OF USER TIME WE HAVE GIVEN AWAY
; PER SCHEDULING INTERVAL. THIS VALUE IS AVAILABLE THROUGH GETTAB.
; IT IS COMPUTED USING THE SAME FORMULA
; FOR EXPONENTIAL AVERAGING THAT IS USED FOR CLSEAR VALUES.
; THE EXPONENTIAL FACTOR IS THE MONGEN SYMBOL M.UTEF, WHICH ASSUMES
; A DEFAULT VALUE OF .3333 . THE USE OF THIS NUMBER NOT ONLY MAKES
; QUOTA ENFORCEMENT MORE ACCURATE BY BASING THE QUOTAS ON ACTUAL AVAILABLE
; USER TIME, BUT AUTOMATICALLY COMPENSATES FOR DUAL CPUS AS WELL
;
SETZ T1,
EXCH T1,TOTUTM## ;GET AND CLEAR USER TIME GIVEN THIS INTERVAL
MOVE T2,UTMEAR## ;GET LAST AVERAGE
SUB T1,T2
IMUL T1,SCDEXF## ;
IMULI T2,^D10000 ;SCALE FACTOR 10000.
ADD T1,T2
IDIVI T1,^D10000
MOVEM T1,UTMEAR## ;SAVE
;HERE TO COMPUTE QUOTAS AND AVERAGES FROM THE LAST INTERVAL
MOVEI T4,M.CLSN##-1 ;START WITH HIGHEST CLASS NUMBER
SCDQT1: SETZ T1,
EXCH T1,CLSITM##(T4) ;GET AND CLEAR TIME USED LAST INTERVAL
MOVE T2,CLSEAR##(T4) ;GET LAST AVERAGE
SUB T1,T2
IMUL T1,SCDEXF## ;MULTIPLY BY ALPHA (SCALED BY 10000.)
IMULI T2,^D10000 ;SCALE LAST AVERAGE BY 10000.
ADD T1,T2 ;ADD INTO T1
IDIVI T1,^D10000 ;GET RID OF SCALE FACTOR
MOVEM T1,CLSEAR##(T4) ;SAVE AS NEW AVERAGE
HRRZ T2,CLSSTS##(T4) ;GET QUOTA
IMUL T2,UTMEAR## ;MULTIPLY BY AVAILABLE TIME
IDIVI T2,^D100 ;CONVERT TO A JIFFY QUOTA
LSH T2,1 ;MULTIPLY BY 2
SUB T2,T1 ;MINUS OUT WHAT WE'VE ALREADY GOT
MOVEM T2,CLSQTA##(T4) ;THIS IS THE REAL QUOTA
JUMPLE T2,SCDQT2 ;IF IT'S POSITIVE
AOS RRFLAG## ;INCREMENT COUNT OF CLASSES WITH NONZERO
;QUOTAS
SCDQT2: SOJGE T4,SCDQT1 ;LOOP FOR ALL CLASSES
POPJ P, ;DONE.
>;END IFN FTNSCHED
SUBTTL MINIMUM CORE UTILIZATION CALCULATION
IFN FTNSCHED,<
;HERE EVERY SECOND TO DETERMINE IF ITS TIME TO CALCULATE
; VALUES FOR PROT BASED ON WHICH SWAPPING UNITS
; WE'RE USING. IF MCUINT IS ZERO, NO CALCULATIONS ARE MADE.
MCUCAL::SKIPE T1,MCUINT## ;NON-ZERO INTERVAL SPECIFIED?
SOSLE MCUTIM## ;YES, TIME TO EVALUATE?
POPJ P, ;NO TO EITHER
MOVEM T1,MCUTIM## ;RESTORE MCUTIM FOR NEXT CYCLE
SETZM MCUCKS## ;CLEAR OUT DATA CHANNEL K FOR SWAP
MOVE T1,[MCUCKS##,,MCUCKS##+1]
MOVE T2,CNFCHN##
BLT T1,MCUCKS##-1(T2)
SETZB P1,P2 ;CLEAR OUT P1,P2
SETZ T4, ;T4 USED FOR INDEX TO SWPTAB
SKIPN U,SWPTAB##(T4) ;GET FIRST NONZERO SWPTAB ENTRY
;(MIGHT BE MESSED UP)
AOBJN T4,.-1 ;HAS TO BE AT LEAST ONE, OR ELSE ONCMOD COMPLAINS
;HERE WITH T4 POINTING TO FIRST UNIT IN ASL
MCUCL1: LDB T3,UNYKTP## ;GET KONTROLLER TYPE
MOVE T3,TYPTAB##(T3) ;GET INDEX INTO TABLES FOR KONTROLLER TYPE
LDB T2,UNYUTP## ;UNIT TYPE WITHIN KONTROLLER
ADD T3,T2 ;GET INDEX INTO UNIT TABLES
MOVE T1,MCUALT##(T3) ;GET AVERAGE LATENCY AND SEEK FOR THIS UNIT
IDIV T1,AVJSIZ## ;DIVIDE BY AVERAGE JOB SIZE
ADD T1,MCUATP##(T3) ;PLUS AVERAGE TIME PER PAGE FOR THIS UNIT
LDB T2,UNYK4S## ;GET K FOR SWAPPING FOR THIS UNIT (ALWAYS K)
LSH T2,K2PLSH## ;CONVERT TO PAGES
SUB T2,UNIFKS##(U) ;GET PAGES OF SWAPPING IN USE
LDB T3,UNYSCN## ;GET CHANNEL NUMBER OF THIS UNIT
ADDM T2,MCUCKS##(T3) ;INCREMENT SWAP SPACE IN USE FOR THIS CHANNEL
ADD P2,T2 ;ACCUMULATE TOTAL SWAP SPACE USED
IMUL T1,T2 ;SWAP SPC USED ON UNIT * EXPECTED SWAP TIME IN T2
ADD P1,T1 ;ACCUMULATE THIS
SKIPE U,SWPTAB##+1(T4) ;ANY MORE UNITS IN ACTIVE SWAPPING LIST?
AOJA T4,MCUCL1 ;YES,GO DO MORE CALCULATION.
;HERE WHEN THROUGH WITH FIRST PART OF MCU CALCULATION
;P1 HAS ACCUMULATED RESULT OF EXPECTED SWAP TIME * K IN USE ON
;UNIT FOR ALL UNITS IN ACTIVE SWAPPING LIST, P2 HAS TOTAL K (P) IN
;USE FOR ALL UNITS IN ASL IN CASE THE DESIRED CHANNEL USAGE
;FRACTIONS ARE ALL ZERO (MEANING WE MUST DIVIDE BY TOTAL K IN USE.
MOVEI T4,M.CHN##-1 ;GET MAXIMUM DF10 NUMBER
SETZ T3, ;RESULT WILL BE IN T3
MCUCL2: MOVE T1,.GTDCF##(T4) ;GET PERCENTAGE FOR THIS CHANNEL
IMUL T1,MCUCKS##(T4) ;MULTIPLY BY SPACE USED ON CHANNEL
IDIVI T1,^D100 ;* 100 BECAUSE .GTDCF CONTAINS %AGES
ADD T3,T1 ;ACCUMULATE RESULTS
SOJGE T4,MCUCL2 ;LOOP FOR ALL CHANNELS
JUMPN T3,.+2 ;IF NONZERO, OK
MOVE T3,P2 ;OTHERWISE, USE TOTAL K FOR SWAPPING
;WHICH IS EQUIVALENT TO ALL DCUFS = 100%
LSH P1,1 ;*2 (IN, OUT)
; MOVE T1,MAXMAX## ;GET MAX USER CORE IN WORDS
; LSH T1,W2PLSH## ;CHANGE TO PAGES
; IMUL P1,T1
; SKIPE T1,AVJSIZ## ;IF NOT COMPUTED YET, USE 1 BY SKIPPING
; IDIV P1,T1 ;TIMES MULTIPROGRAM LEVEL (AVG # JOBS IN CORE)
IDIV P1,T3 ;FINAL RESULT OVER DCUF NUMBER
MOVEM P1,PROT## ;SAVE
POPJ P, ;RETURN
>;END FTNSCHED
$LIT
SCHEND: END