Trailing-Edge
-
PDP-10 Archives
-
de-10-omona-v-mc9
-
kilock.mac
There are 2 other files named kilock.mac in the archive. Click here to see a list.
TITLE KILOCK - KI10 MODULE FOR LOCKING JOBS IN CORE - V7107
SUBTTL J. FLEMMING TS 19 SEP 78
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VKILOK,7107 ;PUT VERSION NUMBER IN STORAGE MAP
ENTRY KILOCK ;ENTRY POINT SYMBOL SO LOADER WILL LOAD KILOCK
; IN A LIBRARY SEARCH
KILOCK: ;ENTRY POINT SYMBOL TO CAUSE LOADING OF KILOCK
EXTERNAL LOKREL,LOCK,CORMIN,PAGSIZ,P2WLSH,W2PLSH,LASLOK
EXTERNAL BIGHOL,CORTAL,JBYHSA,JBYLSA,PAGPTR,PCORSZ,SYSSIZ
EXTERNAL JOBMAX,JBTMAX,.C0JOB
EXTERNAL JBTADR,JBTSTS,JBTUPM
IFN FTSWAP,<
EXTERNAL FORCE0,FIT1,FORIDL
>
IFN FT2REL,<
EXTERNAL TWOREG,JBTSGN
>
EXTERNAL CPOPJ,TPOPJ,T2POPJ
EXTERNAL PCORSZ
INTERNAL FTSWAP,FTPRV,FTRTTRP,FTMETR
INTERNAL LOCK0
SUBTTL SWAP - USER PROGRAM SWAPPING ROUTINES
;ROUTINE TO MOVE A JOB TO A PREDETERMINED PLACE IN CORE AND LOCK IT THERE
;CALLING SEQUENCE:
; HRRZ AC,JOB NUMBER
; HRL AC,HIGH SEGMENT NUMBER
; MOVSM AC,LOCK
;OR IF LOW SEGMENT ONLY JOB
; HRRZ AC,JOB NUMBER
; MOVEM AC,LOCK
;AND
; MOVEI P1,LOK
; IORM P1,JBTSTS(AC) ;SO SCHEDULAR WON'T RUN THE JOB
;AND
; MOVE AC,DESIRED PROTECTION/RELOCATION FOR HIGH SEGMENT OR JOB IF NONE
; MOVEM AC,LOKREL
; PUSHJ P,WSCHED
;RETURN HERE WHEN JOB (BOTH LOW AND HIGH SEGMENTS) ARE IN PLACE AND LOCKED
;NOTE: LOW SEGMENT GOES
; ABOVE THE HIGH SEGMENT
;
;CALLED FROM SCHED WHEN SWAPPER IS IDLE
LKERR1==1
LKERR2==2
LKERR3==3
LKERR4==4
LKERR5==5
LKERR6==6
LKB==1
LKEB==2
LKPB==4
LKCB==10
LOCK0::
IFN FTMOFFL,<
MOVE J,LOCK## ;-1 IF SETTING MEMORY OFF LINE
AOJE J,[HLRZ P2,LOKREL##
IFN FT2SEGMON,<SKIPN MOFLPG##>
JRST LOCK1A ;GO IF NOT SETTING MONITOR MEMORY OFF-LINE
IFN FT2SEGMON,< LDB P2,[POINT 14,MEMSIZ##,26]
LDB P3,[POINT 9,SYSSIZ##,26]
SUB P2,P3 ;FORCE EVERYTHING OUT IF SETTING MONITOR MEMORY OFF
JRST LOCK2>]
>
HRRZ J,LOCK ;SEGMENT NUMBER OF SEGMENT TO BE LOCKED
LOCK1: SKIPN JBTADR(J) ;IS THIS SEGMENT IN CORE?
JRST [MOVE J,LASLOK## ;NO, GO CAUSE IT TO BE SWAPPED IN
JRST FIT1##]
LDB P2,PCORSZ## ;HIGHEST PAGE IN THE SEGMENT
ADDI P2,1 ;NUMBER OF PAGES IN THE SEGMENT
CAIG J,JOBMAX ;IS THIS A LOW SEGMENT?
ADDI P2,UPMPSZ ;YES, ACCOUNT FOR THE UPMP SIZE
LOCK1A: HRRZ P3,LOKREL ;PAGE NUMBER OF STARTING PAGE THIS SEGMENT
; IS TO BE LOCKED IN
LOCK2: SKIPGE T1,PAGTAB(P3) ;IS THIS PAGE ON THE FREE CORE LIST?
JRST LOCK6 ;YES, LOOP ON
IFN FTIPCF,<
TLNE T1,IPCBIT ;AN IPCF PAGE?
POPJ P, ;YES, DELAY UNTIL ITS RECEIVED
>
IFN FTMOFFL,<
SKIPGE LOCK ;SETTING MEMORY OFF-LINE?
TLNN T1,NXMBIT+MONTRB;YES, IGNORE MONITOR AND NON-EXISTANT PAGES
SKIPA P1,P3 ;NO, PAGE NUMBER TO P1
JRST LOCK6 ;LOOK AT THE NEXT PAGE
>
IFE FTMOFFL,<
MOVE P1,P3 ;ITS NOT A FREE PAGE, SEE WHO IT BELONGS TO
>
LSH P1,P2WLSH## ;CONVERT PAGE NUMBER TO AN ABSOLUTE ADDRESS
TLO P1,400000 ;PREVENT CPIASN FROM COMPUTING A VIRTUAL ADDRESS WITHIN SEGMENT
PUSHJ P,CPIASN## ;FIND THE SEGMENT NUMBER OF THE SEGMENT
; CONTAINING THIS PAGE
TDZA T2,T2 ;NOT IN ANY SEGMENT - IT SHOULD BE ON THE
; FREE CORE LIST
JUMPN J,LOCK3 ;WAS A SEGMENT CONTAINING THIS PAGE FOUND?
SKIPN J,T2 ;OR IS THE PAGE SOME JOBS UPMP?
STOPCD .,STOP,SNF, ;++SEGMENT NOT FOUND
LOCK3: HRRZ T1,LOCK ;T1 = SEGMENT NUMBER OF SEGMENT BEING LOCKED
CAIN T1,(J) ;PAGE FOUND CONTAINED IN SEGMENT BEING LOCKED?
JRST LOCK6 ;YES, NO ACTION NECESSARY
CAIG J,JOBMAX ;IS THE SEGMENT CONTAINING THE PAGE WHICH
; MUST BE MOVED A HIGH SEGMENT?
JRST LOCK5C ;NO, JUST SWAP THIS SEGMENT OUT
MOVE P1,JBTSTS(J) ;P1 = INCORE COUNT FOR THIS HIGH SEGMENT
TRNE P1,ICCMSK ;IS THIS A DORMANT OR IDLE HIGH SEGMENT?
JRST LOCK4 ;NO, MUST SWAP OUT THE LOW SEGMENTS SHARING
; IT TO MAKE IT GO AWAY
LOK3A: PUSHJ P,FREC4## ;ITS DORMANT OR IDLE - GO DELETE IT FROM CORE
JRST FORIDL## ;IDLE WITH NO COPY ON THE DISK - WRITE ENABLED
JRST LOCK0 ;THE SEGMENT HAS BEEN DELETED FROM CORE - TRY AGAIN
LOCK4: MOVE T2,J ;SAVE HIGH SEGMENT NUMBER
MOVE J,HIGHJB ;FIND A JOB SHARING IT
LOCK5: SKIPE T1,JBTSGN(J) ;THIS JOB HAVE A HIGH SEGMENT?
CAIE T2,@T1 ;YES, IS IT THE ONE WE WANT TO SWAP?
JRST LOCK5B ;NO, LOOK AT NEXT JOB
SKIPE JBTADR(J) ;IS JOB IN CORE?
JRST LOCK5A ;YES, GO SEE IF IT CAN BE SWAPPED OUT
MOVE T2,J ;SAVE JOB NUMBER BEFORE CALLING DECCNT
EXCH J,T1 ;J=HIGH SEG T1=JOB
PUSHJ P,DECCNT## ;MAKE SURE IN-CORE COUNT IS DECREMENTED
JFCL ;ALREADY DECREMENTED OR JUST WENT TO ZERO
HRRZS J ;GET RID OF HIGH SEGMENT FLAGS
JUMPE T1,LOK3A ;NO MORE JOBS SO SWAP OUT HIGH SEG
EXCH J,T2 ;GET READY TO LOOK AT NEXT JOB
JRST LOCK5B ;GO DO IT
LOCK5A: MOVE T1,JBTSTS(J) ;GET JOB STATUS
TLCE T1,SWP!NSWP ;IS IT LOCKED AND SWAPPED?
TLNE T1,SWP!NSWP ;IF BOTH, SWAPPING IT WON'T HELP
CAIA
JRST LOCK5B ;SO LOOK AT NEXT JOB
TRNE P1,ICCMSK-1 ;IN CORE COUNT = 1?
CAME J,LOCK ;IF NOT, IS THIS THE JOB WE'RE LOCKING?
JRST FORCE0 ;NO, SWAP OUT THE JOB
LOCK5B: SOJG J,LOCK5 ;LOOK AT NEXT JOB
STOPCD .,STOP,SSO, ;++SEGMENT SWAPPED OUT
LOCK5C: PUSHJ P,ANYRUN##
JRST LOCK5D
JRST FORCE0##
LOCK5D: MOVEM J,SW0JOB##
POPJ P,
LOCK6: AOS P3 ;NEXT PHYSICAL PAGE WHICH MUST BE FREED
SOJG P2,LOCK2 ;LOOP UNTIL ALL NECESSARY PAGES ARE AVAILABLE
IFN FTMOFFL,<
SKIPGE T1,LOCK## ;LOCK IS -1 IF SETTING MEMORY OFF
AOJE T1,SETMFL ;GO MOVE THE MONITOR AND SET MEMORY OFF
>
;ALLOCATE CORE, BLT SEGMENT INTO PLACE, AND LOCK IT
HRRZ J,LOCK ;SEGMENT NUMBER OF SEGMENT BEING LOCKED
CAILE J,JOBMAX## ;IS IT A HIGH SEGMENT?
JRST LOCK7 ;NO, DON'T NEED TO ADDRESS THE UPMP
CAME J,.C0JOB## ;IS THIS THE CURRENT JOB? IF SO UPMP IS ADDRESSABLE
PUSHJ P,SVEUB## ;MAKE THE UPMP ADDRESSABLE
LOCK7: MOVE R,JBTADR(J) ;ANYACT REQUIRES THAT R BE SETUP
PUSHJ P,ANYACT## ;ANY ACTIVE I/O?
POPJ P, ;YES, TRY AGAIN NEXT CLOCK TICK
HRRZ J,LOCK ;SEGMENT NUMBER OF SEGMENT BEING LOCKED
MOVEI P1,0 ;P1 = RELATIVE PAGE NUMBER WITHIN THE SEGMENT
; START AT RELATIVE PAGE ZERO
HRRZ P2,LOKREL ;P2 = DESIRED PHYSICAL PAGE NUMBER
CAILE J,JOBMAX ;IS THIS SEGMENT A LOW SEGMENT?
JRST LOCK9 ;NO, NEEDN'T WORRY ABOUT MOVING THE UPMP
HRRZ T1,JBTUPM(J) ;PAGE NUMBER OF UPMP
CAIN T1,(P2) ;IS THE UPMP ALREADY IN PLACE?
JRST LOCK8 ;YES, DOESN'T NEED TO BE MOVED
LDB P3,JBYLSA ;PAGE NUMBER OF FIRST PAGE OF THE JOB
PUSHJ P,PAGMOV ;MOVE THE UPMP TO THE DESIRED POSITION
MOVEI T1,PM.ACC+PM.WRT(P2)
HRLM T1,.EUPMP+.MUPMP;MAKE THE UPMP ADDRESSABLE IN ITS NEW
; POSITION THROUGH THE PER PROCESS MAP
CAIE P2,(P3) ;WAS THE UPMP EXCHANGED WITH THE FIRST PAGE
; OF THE LOW SEGMENT (PAGE CONTAINING JOB
; DATA AREA)?
JRST LOCK8 ;NO
HRRZ T1,.EPMP##+.MECKS
HRRM T1,.EUPMP+.MJDAT;YES, MAKE THE JOB DATA AREA ADDRESSABLE
; THROUGH THE PER PROCESS MAP
LOCK8:
HRRI T1,UPMPSZ## ;+ SIZE OF THE UPMP IN THE RIGHT HALF
ADDM T1,LOKREL ;UPDATE LOKREL TO REFLECT THE FACT THAT
; THE UPMP IS IN PLACE AND LOCKED
HLLZS PAGTAB(P2) ;SIGNAL ONLY THIS PAGE IS ALLOCATED
MOVSI T1,LOKPHB ;AND INDICATE THAT THE UPMP IS LOCKED
IORM T1,PAGTAB(P2) ; IN PHYSICAL MEMORY
HRRM P2,JBTUPM(J) ;STORE THE NEW PAGE NUMBER OF THE UPMP
IFN FTKL10,<
TDO P2,[LG.LUB+LG.IAM]
DATAO PAG,P2
>
IFN FTKI10,<
PUSHJ P,STEUB## ;AND MAKE THE UPMP ADDRESSABLE THROUGH
; THE PER PROCESS MAP (CLEAR THE AM)
>
HRRZ P2,LOKREL ;P2 = PHYSICAL PAGE WHERE FIRST PAGE OF THE
; LOW SEGMENT SHOULD GO
LOCK9: LDB P3,PCORSZ## ;HIGHEST PAGE IN THE SEGMENT
ADDI P3,1 ;NUMBER OF PAGES IN THE SEGMENT
LOCK10: MOVE T2,P1 ;T2 = RELATIVE PAGE NUMBER INTO THIS SEGMENT
PUSHJ P,SNPAGS## ;FIND WHICH PHYSICAL PAGE CONTAINS THE RELATIVE PAGE
CAIE P2,(T1) ;IS THE PAGE ALREADY IN PLACE?
PUSHJ P,PAGMOV ;NO, MOVE IT
JUMPN P1,LOCK12 ;JUMP IF NOT THE FIRST PAGE OF THE SEGMENT
CAILE J,JOBMAX ;IT IS THE FIRST PAGE - IS THIS A LOW SEGMENT?
JRST LOCK11 ;NO, STORE NEW ADDRESS OF FIRST PAGE OF HIGH SEGMENT
MOVEI T1,PM.ACC+PM.WRT(P2)
HRRM T1,.UPMP+.MJDAT ;AND MAKE THE JOB DATA ADDRESSABLE
PUSHJ P,NEWMAP ;CLEAR THE AM SO NEW MAPPING IS IN EFFECT
JRST LOCK12 ;AND CONTINUE ON
LOCK11: DPB P2,JBYHSA ;NEW ADDRESS OF FIRST PAGE OF HIGH SEGMENT
LOCK12:
MOVSI T1,LOKPHB ;INDICATE THIS PAGE IS LOCKED IN PHYSICAL MEMORY
SKIPE P1 ;SKIP IF FIRST PAGE OF THE SEGMENT
IORM T1,PAGTAB-1(P2) ; CONTIGIOUSLY
ADDI P1,1 ;NEXT RELATIVE PAGE WITHIN THE SEGMENT
ADDI P2,1 ;STEP TO NEXT TARGET PAGE
SOJG P3,LOCK10 ;LOCK THE NEXT PAGE
MOVEM T1,PAGTAB-1(P2) ;INDICATE LAST PAGE OF THE SEGMENT
MOVSI T1,NSHF!NSWP ;AFTER ALL THAT WORK
IORM T1,JBTSTS(J) ; MAKE SURE THE SEGMENT DOESN'T SWAP
HLRZS J,LOCK ;GET THE SEGMENT NUMBER OF THE LOW SEGMENT
; IF THERE IS ONE LEFT TO BE LOCKED
JUMPE J,LOCK13 ;JUMP IF DONE
HLRZS LOKREL ;STARTING PAGE NUMBER FOR THE LOW SEGMENT
JRST LOCK1 ;AND GO TRY TO LOCK IT
LOCK13: MOVEI T1,LOK ;SET TO MAKE JOB RUNABLE AGAIN
MOVE J,LASLOK ;GET THE JOB NUMBER OF JOB ISSUING LOCK UUO
MOVSI T2,1001 ;MAKE SURE MAP
IFN FTVM,<
PUSHJ P,[PUSHJ P,SVEUB##
SKIPN .UPMP+.UPVRT ;IF VIRTUAL,
SKIPE .UPMP+.UPREL ;OR NON-CONTIGOUS,
TLZ T2,777 ;THEN, MUST BE LOCKING ONLY HI SEG
POPJ P,]
>
SKIPG JBTSGN##(J) ;SPY OR NO HI SEG?
TLZ T2,777000 ;YES, DON'T REDO HI SEG PART OF THE MAP
ADDM T2,JBTUPM(J) ; GETS REDONE
ANDCAM T1,JBTSTS(J) ;TURN OFF LOK SO SCHEDULAR WILL RUN THE JOB AGAIN
MOVSI T1,SWP ;ASSUME THE HIGH SEGMENT GOT SWAPPED WHILE
; LOCKING THE LOW SEGMENT
SKIPG T2,JBTSGN(J) ;DOES THE JOB HAVE A REAL HIGH SEGMENT?
POPJ P, ;NO, RETURN
SKIPN JBTADR(T2) ;IS THE HIGH SEGMENT IN CORE
IORM T1,JBTSTS(J) ;TURN ON SWP SO THE SCHEDULAR WON'T RUN
; THE JOB UNTIL THE HIGH SEGMENT GETS SWAPPED IN
HRLI T2,0 ;REMOVE LH OF JBTSGN FOR THIS JOB
MOVE T1,HIGHJB ;HIGHEST NUMBERED JOB
MOVSI T3,1000 ;SIGNAL TO MAP HIGH SEGMENT
LOCK14: SKIPLE T4,JBTSGN(T1) ;GET HIGH SEGMENT OF ALL JOBS
SKIPN JBTADR(T1) ;IGNORE IF NOT IN CORE
JRST LOK14A
CAME J,T1 ;DON'T DO IT TO OUR JOB
CAIE T2,@T4 ;SAME HIGH SEGMENT AS OURS?
JRST LOK14A ;NO. LOOK AT NEXT ONE
ADDM T3,JBTUPM(T1) ;YES. ADD TO SIZE SO IT WILL REMAP
TLO T4,SEGMB ;SET SEGMENT MOVED BIT
MOVEM T4,JBTSGN(T1) ;SO IF NEXT JOB WAS LAST JOB, ALL
LOK14A: SOJG T1,LOCK14 ;LOOP FOR ALL JOBS
POPJ P, ;AND RETURN
IFN FTMOFFL,<
SETMFL:
IFN FT2SEGMON,<
;HERE TO MOVE THE MONITOR IF NECESSARY
SKIPN P4,MOFLPG## ;ANY OF THE PAGES BEING SET OFF CONTAIN MONITOR CODE?
JRST SETMF5 ;NO, THEN THIS IS EASY
MOVEI P1,0 ;FOR PAGFRE
LDB P2,[POINT 14,MEMSIZ##,26]
HLRZ P3,LOKREL## ;NUMBER OF PAGES TO BE SET OFF
MOVNS P3 ;MAKE IT NEGATIVE
HRL P3,LOKREL## ;STARTING PAGE NUMBER
MOVSS P3 ;MAKE AN AOBJN POINTER
SETMF1: MOVE T1,PAGTAB(P3) ;GET PAGE DESCRIPTOR BITS
TLNE T1,MONTRB ;DOES THIS PAGE CONTAIN MONITOR CODE?
JRST SETMF2 ;YES
AOBJN P3,SETMF1 ;NO, LOOK AT THE NEXT PAGE
STOPCD .,STOP,MMR, ;++MOVING MONITOR PAGE NOT REQUIRED
;HERE WHEN A MONITOR PAGE HAS BEEN FOUND WITHIN THE RANGE BEING SET
; OFF-LINE, MOVE THE PAGE TO THE HIGHEST POSSIBLE FREE PAGE WHICH DOES
; NOT OVERLAP THE PAGES BEING SET OFF-LINE. THIS TENDS TO KEEP THE MONITOR
; AS HIGH IN CORE AS POSSIBLE SO THAT MORE SPACE IS AVAILABLE FOR
; LOCKING BELOW 112K AND HELPS TO KEEP THE MONITOR FROM BEING WRITTEN
; INTO WITH AN ABSOLUTE ADDRESS WHICH CAN ONLY BE DONE IF ITS BELOW 112K
SETMF2: HRRZ T1,LOKREL## ;LOWEST PAGE BEING SET OFF LINE
HLRZ T2,LOKREL## ;NUMBER OF PAGES BEING SET OFF LINE
ADDI T2,-1(T1) ;HIGHEST PAGE BEING SET OFF LINE
SUBI P2,1 ;CANDIDATE FOR WHERE TO MOVE THIS PAGE
CAIL P2,(T1) ;IS CANDIDATE BELOW FIRST PAGE BEING SET OFF?
CAILE P2,(T2) ;OR ABOVE LAST BEING SET OFF?
SKIPL T1,PAGTAB(P2) ;YES, AND IS THE CANDIDATE PAGE FREE?
; IF NOT, IT MUST CONTAIN A PAGE OF THE MONITOR
JRST SETMF2 ;NO, LOOK AT THE NEXT CANDIDATE
HRRZ T1,P3 ;SOURCE PAGE
PUSHJ P,PAGFRE ;MOVE THE PAGE
STOPCD .,STOP,FPN, ;++FREE PAGE NOT FOUND
;HERE WITH SOURCE PAGE IN RH(P3), DESTINATION PAGE IN P2, FIND THE
; SOURCE PAGE IN THE EXEC MAP AND MAP THE DESTINATION PAGE THROUGH THAT
; MAP SLOT
LDB T1,[POINT 9,SYSLEN##,26]
MOVE T2,[POINT 18,.EPPM##+<MONORG-400000>/<2*1000>]
SETMF3: ILDB T3,T2 ;GET THE NEXT MAP ENTRY
ANDI T3,17777 ;CLEAR ACCESS BITS
CAIN T3,(P3) ;IS THIS THE PAGE WHICH WAS JUST MOVED?
JRST SETMF4 ;YES
SOJG T1,SETMF3 ;LOOP OVER ALL OF THE MONITORS PAGES
STOPCD .,STOP,MPN, ;++MONITOR PAGE NOT FOUND
;HERE WITH THE BYTE POINTER TO THE EXEC MAP SLOT IN T2
SETMF4: LDB T1,T2 ;GET THE CURRENT CONTENTS OF THE MAP SLOT
ANDI T1,760000 ;GET THE ACCESS BITS
ADDI T1,(P2) ;NEW PAGE NUMBER PLUS ACCESS BITS
DPB T1,T2 ;STORE NEW PHYSICAL PAGE NUMBER
SOJG P4,SETMF1 ;MOVE THE NEXT MONITOR PAGE
> ;END FT2SEGMON
; STILL IN FTMOFFL
;HERE WHEN ALL PAGES TO BE SET OFF LINE ARE FREE AND ANY MONITOR
; PAGES WHICH NEEDED TO BE HAVE BEEN MOVED
SETMF5: HRRZ T1,LOKREL## ;FIRST PAGE TO BE SET OFF LINE
IDIVI T1,^D36 ;BIT POSITION AND WORD NUMBER WITHIN NXMTAB
; CORESPONDING TO THE FIRST PAGE SET OFF
MOVE T2,BITTBL##(T2) ;BIT MASK CORRESPONDING TO BIT POSITION
HLRZ T3,LOKREL## ;NUMBER OF PAGES TO SET OFF
SETMF6: IORM T2,NXMTAB##(T1) ;MAKE THE PAGE APPEAR TO BE NON-EXISTANT
ROT T2,-1 ;NEXT BIT POSITION IN NXMTAB
SKIPGE T2 ;PASSED A WORD BOUNDARY?
ADDI T1,1 ;YES, BUMP TO THE NEXT WORD IN NXMTAB
SOJG T3,SETMF6 ;MARK ALL PAGES IN THE REQUEST AS OFF LINE
SETZM LOCK ;INDICATE SUCCESS
SETOM LASLOK ;ALLOW COMMAND TO SIGNAL COMPLETION
PJRST CPINXF## ;FIXUP PAGTAB, CORTAL, BIGHOL, CORMAX, MAXMAX, ETC.
> ;END FTMOFFL
;SUBROUTINE TO SEE IF TARGET PAGE IS ON THE FREE CORE LIST AND
; EXCHANGE IT WITH THE CURRENT PAGE IF SO
;ENTER WITH T1= CURRENT PAGE WHERE JOB IS
; ENTER P2= PAGE WE WANT TO PUT JOB AT
;EXIT CPOPJ1 IF THE TARGET PAGE IS ON THE FREE CORE LIST AND THE
; EXCHANGE HAS TAKEN PLACE
PAGFRE: MOVEI T3,PAGPTR ;PRESET PREDECESSOR
SKIPN T2,PAGPTR ;START LOOKING AT 1ST FREE PAGE
POPJ P, ;NONE FREE
PAGFR1: CAIN P2,(T2) ;TARGET PAGE ON FREE LIST?
JRST PAGFR2 ;YES
MOVEI T3,PAGTAB(T2) ;NO, SET PRED.
SKIPL T2,PAGTAB(T2) ;STEP TO NEXT PAGE IN FREE LIST
STOPCD .,STOP,FPF, ;++PAGE ON THE FREE LIST ISN'T FREE!
TRNE T2,-1 ;END OF FREE LIST?
JRST PAGFR1 ;NO, TEST THIS FREE PAGE
POPJ P, ;YES, TARGET PAGE ISNT FREE
;HERE WHEN TARGET PAGE IS ON THE FREE-PAGE LIST
;EXCHANGE TARGET PAGE AND CURRENT PAGE ON THE FREE LIST
PAGFR2: MOVE T2,PAGTAB(T2) ;SUCCESSOR OF TARGET PAGE
EXCH T2,PAGTAB(T1) ; = SUCCES. OF CURRENT PAGE, GET CURRENT-SUCC.
MOVEM T2,PAGTAB(P2) ;SET NEW SUCC. OF TARGET PAGE
HRRM T1,(T3) ;SET PRED. OF FREE PAGE WE FOUND
SKIPE P1 ;DOES THE CURRENT PAGE HAVE A PRED?
MOVEM P2,PAGTAB-1(P2);YES, SET PRED TO TARGET PAGE
PUSHJ P,BLTPAG ;MOVE CURRENT PAGE TO TARGET PAGE (DATA)
PJRST CPOPJ1 ;AND SKIP-RETURN
;CALL THIS ROUTINE WHEN THE TARGET PAGE ISN'T ON FREE-LIST
;NOTE THAT THE PAGE IS THEREFORE IN THIS SEGMENT'S MAP
PAGFND: LDB T2,JBYLSA ;ASSUME ITS A LOW SEGMENT
CAILE J,JOBMAX ;IS IT?
LDB T2,JBYHSA ;NO
CAIE T2,(P2) ;IS THE TARGET PAGE THE 1ST PAGE OF THE SEG?
JRST PAGFD1 ;NO
MOVE T2,PAGTAB(T1) ;YES, GET SUCC TO CURRENT PAGE
EXCH T2,PAGTAB(P2) ;STORE AS SUCC TO TARGET PAGE
HRRM T2,PAGTAB(T1) ;SUCC TO TARGET INTO CURRENT SUCCESSOR
JRST PAGFD2 ;AND SKIP SOME MAGIC
;HERE WHEN THE TARGET PAGE ISN'T THE 1ST PAGE OF THE SEGMENT
PAGFD1: HRRZ T3,T2 ;SET PREDECESSOR
JUMPE T3,CPOPJ ;ERROR IF LAST PAGE OF SEGMENT
SKIPGE T2,PAGTAB(T3) ;NOT LAST, GET NEXT PAGE
STOPCD .,STOP,PFA, ;++PAGE FREE ALREADY
CAIE T2,(P2) ;IS THIS THE TARGET PAGE?
JRST PAGFD1 ;NO, TRY AGAIN
SKIPGE T2,PAGTAB(T1) ;GET SUCCESSOR TO CURRENT PAGE
STOPCD .,STOP,NPF, ;++NEXT PAGE FREE
HRRM T1,PAGTAB(T3) ;POINT TARGET PRED TO CURRENT PAGE
CAIN P2,(T2) ;IS TARGET = SUCCESSOR OF CURRENT PAGE?
MOVE T2,T3 ;YES, GET PRED TO CURRENT PAGE
EXCH T2,PAGTAB(P2) ;SAVE SUCC TO TARGET, GET SUCC TO CURRENT
HRRM T2,PAGTAB(T1) ;SAVE SUCCESSOR TO CURRENT PAGE
SKIPE P1 ;DOES CURRENT PAGE HAVE A PRED?
HRRM P2,PAGTAB-1(P2);YES, SET PRED TO TARGET PAGE
PAGFD2: PUSHJ P,EXCHPG ;EXCHANGE DATA OF CURRENT AND TARGET PAGES
JRST CPOPJ1 ;AND GIVE GOOD RETURN
;SUBROUTINE TO MAKE TARGET AND SOURCE PAGES ADDRESSABLE IN EXEC
; VIRTUAL MEMORY
;CALLING SEQUENCE:
; MOVE T1,ABSOLUTE PAGE NUMBER OF SOURCE PAGE
; MOVE P2,ABSOLUTE PAGE NUMBER OF TARGET PAGE
; PUSHJ P,SETMAP
;RETURN HERE, SOURCE AND TARGET PAGES ADDRESSABLE THROUGH .ECKSM AND
; .EUPMP RESPECTIVILY
SETMAP: TRO T1,PM.ACC+PM.WRT;ACCESS ALLOWED AND WRITABLE
HRRM T1,.EPMP##+.MECKS
MOVEI T1,PM.ACC+PM.WRT(P2)
HRLM T1,.EPMP##+.MEUPM
; PJRST NEWMAP
NEWMAP:
CLRPGT (0) ;CLEAR THE ASSOCIATIVE MEMORY
; SO THE NEW MAPPING WILL BE IN EFFECT
POPJ P, ;RETURN
;SUBROUTINE TO BLT SOURCE PAGE TO TARGET PAGE WHICH WAS ON THE FREE CORE LIST
;CALLING SEQUENCE:
; MOVE T1,ABSOLUTE PAGE NUMBER OF THE SOURCE PAGE
; MOVE P2,ABSOLUTE PAGE NUMBER OF THE TARGET PAGE
; PUSHJ P,BLTPAG
;RETURN HERE, SOURCE PAGE BLTED TO TARGET PAGE FROM FREE CORE LIST
BLTPAG: PUSHJ P,SETMAP ;MAKE THE SOURCE AND DESTINATION PAGES ADDRESSABLE
MOVSI T1,.ECKSM ;ADDRESS OF THE SOURCE PAGE
HRRI T1,.EUPMP ;ADDRESS OF THE DESTINATION PAGE
;THIS LABEL IS TO DETECT MEMORY PARITY ERROR IN EXEC MODE DURING BLT OF USER CORE
LOKINS::BLT T1,.EUPMP+PAGSIZ##-1
POPJ P, ;MOVE THE PAGE AND RETURN
;SUBROUTINE TO EXCHANGE SOURCE AND TARGET PAGES WHEN THEY ARE BOTH CONTAINED
; WITHIN THE CURRENT SEGMENT
;CALLING SEQUENCE:
; MOVE T1,ABSOLUTE PAGE NUMBER OF THE SOURCE PAGE
; MOVE P2,ABSOLUTE PAGE NUMBER OF THE TARGET PAGE
; PUSHJ P,EXCHPG
;RETURN HERE, SOURCE AND TARGETY PAGES HAVE BEEN EXCHANGED
EXCHPG: PUSHJ P,SETMAP ;MAKE THE SOURCE AND DESTINATION PAGES ADDRESSABLE
MOVNI T1,PAGSIZ## ;- THE NUMBER OF WORDS TO EXCHANGE
HRLZS T1 ;T1 = AN AOBJN POINTER
EXCHP1: MOVE T2,.EUPMP(T1) ;GET A DATA WORD FORM THE DESTINATION PAGE
EXCH T2,.ECKSM(T1) ;EXCHANGE IT WITH THE WORD FROM THE SOURCE PAGE
MOVEM T2,.EUPMP(T1) ;WORD FROM SOURCE PAGE TO DESTINATION PAGE
AOBJN T1,EXCHP1 ;EXCHANGE THE ENTIRE PAGES
POPJ P, ;AND RETURN
;SUBROUTINE TO FIND THE TARGET PAGE ON THE FREE CORE LIST OR WITHIN
; THE CURRENT SEGMENT AND MOVE/EXCHANGE THE SOURCE TO/WITH THE TARGET AS
; APPROPRIATE
;CALLING SEQUENCE:
; MOVE T1,ABSOLUTE PAGE NUMBER OF THE SOURCE PAGE
; MOVE P2,ABSOLUTE PAGE NUMBER OF THE TARGET PAGE
;RETURN HERE - THE SOURCE PAGE HAS BEEN MOVED TO THE TARGET DESTINATION
PAGMOV: PUSHJ P,PAGFRE ;IS THE DESTINATION PAGE ON THE FREE CORE
; LIST? IF SO, MOVE SOURCE PAGE TO DESTINATION
; PAGE AND FIXUP PAGTAB
SKIPA ;TARGET PAGE NOT ON FREE CORE LIST
POPJ P, ;PAGE IS IN PLACE
PUSHJ P,PAGFND ;THE DESTINATION PAGE IS NOT ON THE FREE
; CORE LIST SO IT MUST BELONG TO THIS SEGMENT
; FIND IT WITHIN THE SEGMENT, FIXUP PAGTAB
; AND EXCHANGE THE SOURCE AND TARGET PAGES
STOPCD .,STOP,PNP, ;++PAGE NOT PRESENT
POPJ P, ;RETURN
SUBTTL ERRCON - ERROR HANDLING CODE
;ROUTINE TO CHECK IF JOB HAS BOTH SEG LOCKED
;CALL: MOVE J,JOB NUMBER
; PUSHJ P,LOKCHK
; BOTH LOCKED - J PRESERVED
; NEITHER OR ONLY ONE LOCKED - J PRESERVED
INTERNAL LOKCHK
LOKCHK: PUSHJ P,SAVE2## ;SAVE P1-P2
MOVSI P1,NSHF!NSWP ;NO SHUFFLING OR SWAPPING BITS
TDNE P1,JBTSTS##(J) ;LOW SEG LOCKED?
POPJ P, ;YES
IFN FT2REL,< ;2 RELOC REG FEATURE?
SKIPLE P2,JBTSGN##(J) ;NO, DOES JOB HAVE A HIGH SEG?
TDNN P1,JBTSTS(P2) ;YES, IS IT LOCKED?
JRST CPOPJ1 ;NEITHER SEGMENT LOCKED
POPJ P, ;HIGH SEGMENT LOCKED
>
IFE FT2REL,<
JRST CPOPJ1
>
;SUBROUTINE TO DETERMINE IF A SEGMENT IS LOCKED IN CONTIGUOUS EXEC
; VIRTUAL MEMORY
;CALLING SEQUENCE:
; MOVE J,SEGMENT NUMBER
; PUSHJ P,LOKEVC
; ... RETURN HERE IF SEGMENT IS NOT LOCKED IN EVM
; ... RETURN HERE IF SEGMENT IS LOCKED IN EVM
LOKEVC::PUSHJ P,SAVE2## ;SAVE P1-P2
LDB P1,JBYLSA ;ASSUME A LOW SEGMENT (GET ABSOLUTE PAGE NUMBER OF
; FIRST PAGE OF THE LOW SEGMENT)
CAILE P1,JOBMAX ;IS IT A HIGH SEGMENT
LDB P1,JBYHSA ;YES, GET ABSOLUTE PAGE NUMBER OF FIRST PAGE
; OF THE HIGH SEGMENT
MOVSI P2,LOKEVB ;BIT INDICATING PAGE IS LOCKED IN EVM
TDNE P2,PAGTAB(P1) ;IS IT? (IF FIRST PAGE IS ALL MUST BE)
AOS (P) ;YES
POPJ P, ;GIVE LOCKED OR NOT LOCKED RETURN
SUBTTL UUOCON - UUO HANDLING ROUTINES
;ROUTINE TO SET UP CALL TO SWAPPER FOR LOCKING A JOB IN CORE
;CHECKS VALIDITY OF REQUEST AND TRIES TO FIND A PLACE TO PUT THE
;JOB IN CORE. IT FIRST TRIES THE TOP OF USER CORE, AND IF IT ALREADY
;CONTAINS A LOCKED JOB, THE CALLING JOB IS PUT IN AS LOW CORE AS
;POSSIBLE.
;CALLING SEQUENCE
; PUSHJ P,LOKJOB
; ERROR RETURN
; NORMAL RETURN (NSHF+NSWP SET)
INTERNAL LOKJOB,UNLOCK,UNLOK.
EXTERNAL CORLIM,CORMAX,HIGHJB,JOB
EXTERNAL CAWAIT,MEMSIZ,WSCHED,CPOPJ1,TPOPJ,STOTAC,CAFREE
LOKJOB:
IFN FTVM,<
TRNN T1,-1 ;LOCK THE LOW SEGMENT?
JRST LOKJO0 ;NO
SKIPN .UPMP+.UPVRT ;YES, A VIRTUAL USER?
SKIPE .UPMP+.UPMEM ;NO, LOW SEGMENT NON-CONTIGUOUS?
JRST RTZER## ;YES, NOT IMPLEMENTED
LOKJO0: SKIPLE T2,JBTSGN##(J) ;JOB HAVE A HIGH SEGMENT?
TLNE T2,SHRSEG ;YES, IS IT SHARABLE?
CAIA ;YES
JRST RTZER## ;NO, NOT IMPLEMENTED
>
PUSHJ P,SAVE4## ;SAVE P1-P4
IFN FTPRV,<
MOVSI T1,PVLOCK ;BIT DENOTING PRIVILEDGES TO LOCK
PUSHJ P,PRVBIT## ;IS THIS USER A SUFFICIENT WHEEL?
SKIPA ;YES, PROCEED
JRST ERROR1 ;NO, NOT PRIVILEDGED ERROR RETURN
PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
>
JUMPL T1,[PUSHJ P,LOKARG ;JUMP IF NEW STYLE ARGUMENT LIST
JRST STOTAC ;MALFORMED ARGUMENT LIST, GIVE ERROR RETURN
JRST .+1] ;CONTINUE PROCESSING
MOVSI P1,NSHF!NSWP ;LOCKED BITS
MOVE T2,J ;SAVE JOB NUMBER
MOVEI T3,0 ;ASSUME NO HIGH SEGMENT ADDRESS
IFN FT2REL,<
SKIPE TWOREG ;TWO REGISTER SOFTWARE?
SKIPG J,JBTSGN(J) ;GRAB HIGH SEGMENT NUMBER IF ANY
JRST LOKJ0A ;NO HIGH SEGMENT
LDB T3,JBYHSA ;PHYSICAL ADDRESS OF HIGH SEGMENT
TLNE T1,LKB ;USER LOCKING HIGH SEGMENT?
TDNN P1,JBTSTS(J) ;ALREADY LOCKED?
JRST HGHADR ;NO. GET ADDRESS ANYWAY
MOVE T4,PAGTAB(T3) ;GET STATUS OF LOCKED SEGMENT
PUSHJ P,ARGCK1 ;OK TO LOCK AGAIN?
JRST ERROR7 ;NOT OK. ARGUMENT IS INCORRECT
MOVSI T4,LOKSEG ;DON'T FORGET TO LOCK THIS JOB'S
IORM T4,JBTSGN(T2) ;HIGH SEGMENT
HGHADR: TLNN T1,LKEB ;LOCKED IN EVM?
MOVE T3,JBTADR(J) ;YES, PROVIDE EVA TO USER
>
LOKJ0A: EXCH J,T2 ;J=JOB, T2=HIGH SEGMENT NUMBER
TRNN T1,LKB ;LOCK THE LOW SEGMENT?
JRST LOKJ00 ;NO
TDNN P1,JBTSTS(J) ;IS THE LOW SEGMENT ALREADY LOCKED?
JRST LOKJ01 ;YES
LOKJ00:
IFN FT2REL,<
SKIPE TWOREG ;TWO REGISTER SOFTWARE?
TLNN T1,LKB ;LOCK THE HIGH SEGMENT?
>
JRST ERROR0 ;NO, NOTHING TO DO
IFN FT2REL,<
JUMPE T3,ERROR0 ;JUMP IF NO HIGH SEGMENT
TDNE P1,JBTSTS(T2) ;ALREADY LOCKED?
JRST ERROR0 ;YES, GO CHECK OUT LOW SEGMENT
HRRZ J,T2 ;SAVE HIGH SEGMENT NUMBER
>
LOKJ01: TLZ T1,-1-IFN FT2REL,<LKB>
MOVEI F,0 ;INDICATE NO DDB
PUSHJ P,CAWAIT ;YES, WAIT UNTIL ITS DONE
SETZB P4,T4 ;ZERO LARGEST JOB SEEN SO FAR
PUSH P,J ;SAVE J
IFN FTSWAP,<
MOVEI J,1 ;FIND THE LARGEST JOB NOT LOCKED
LOKJ02: CAMN J,JOB ;DON'T CONSIDER JOB BEING LOCKED
JRST LOKJ04
MOVE T2,JBTSTS(J) ;IS THIS JOB LOCKED?
TLNE T2,NSHF!NSWP
TDZA T2,T2
PUSHJ P,SEGSIZ## ;NOT LOCKED, FIND OUT HOW BIG IT IS
PUSH P,J ;SAVE LOW SEGMENT NUMBER
IFN FT2REL,<
SKIPE TWOREG ;TWO REGISTER SOFTWARE?
SKIPG J,JBTSGN(J) ;DOES IT HAVE A REAL HIGH SEGMENT?
JRST LOKJ03 ;NO
MOVSI P2,NSWP!NSHF
MOVE P1,JOB ;GET OUR JOB #
HRRZ P1,JBTSGN(P1) ;GET OUR HISEG #
TLNE T1,LKB ;IF LOCKING OUR HISEG
CAIE P1,(J) ;AND HE IS USING IT
TDNE P2,JBTSTS(J) ;OR IT IS ALRERADY LOCKED
JRST LOKJ03 ;THEN IGNORE THIS HISEG
MOVE P2,T2 ;COUNT THE SIZE OF THE HIGH SEGMENT
PUSHJ P,SEGSIZ##
ADDI T2,(P2) ;T2_SIZE OF THE JOB
>
LOKJ03: LSH T2,P2WLSH
CAMLE T2,P4 ;LARGEST SO FAR?
MOVE P4,T2 ;YES, SAVE ITS SIZE
POP P,J ;RESTORE JOB NUMBER
LOKJ04: CAMGE J,HIGHJB ;LOOKED AT ALL JOBS YET?
AOJA J,LOKJ02 ;NO
MOVE J,(P)
>
PUSHJ P,SEGSIZ## ;SIZE OF THIS SEGMENT IN PAGES
LSH T2,P2WLSH## ;SIZE IN WORDS
HRRI T1,-1(T2) ;SIZE-1 OF HIGH OR LOW SEGMENT
IFN FT2REL,<
TLZE T1,LKB ;HIGH SEGMENT TO BE LOCKED?
CAILE J,JOBMAX ;LOW SEGMENT ALREADY LOCKED?
JRST LOKJ05 ;YES, JUST LOCK THE HIGH SEGMENT
MOVSI P2,NSHF!NSWP ;HIGH SEGMENT MAY ALREADY BE LOCKED
SKIPLE P1,JBTSGN(J) ;DOES THE JOB HAVE A HIGH SEGMENT?
TDNE P2,JBTSTS(P1) ;IS THE HIGH SEGMENT ALREADY LOCKED?
JRST LOKJ05 ;NEEDN'T BE CONCERNED ABOUT THE HIGH SEGMENT
HRLI P1,(J) ;P1_JOB#,,HIGH SEGMENT#
MOVEM P1,(P) ;SAVE IT
HLRZ P1,JBTADR(P1) ;SIZE OF THE HIGH SEGMENT
ADDI T1,1(P1) ;ADD IT TO THE TOTAL
>
LOKJ05: PUSHJ P,LRGHOL ;COMPUTE THE NUMBER OF PHYSICAL PAGES AVAILABLE
; FOR LOCKING
POP P,P1 ;RESTORE JOB#,,HIGH SEGMENT#
SUBI T2,1(T1) ;T2 = AMOUNT OF CORE LEFT IF THIS JOB IS LOCKED
CAMGE T2,P4 ;WILL ALL EXISTING JOBS BE ABLE TO RUN IN
; THE AMOUNT OF CORE WHICH WILL REMAIN?
JRST ERROR2 ;NO, CAN'T LOCK THE JOB
CAMGE T2,CORMIN ;WOULD LOCKING THIS JOB MAKE CORMAX .LT.
; CORMIN?
JRST ERROR3 ;YES, TELL THE USER HE LOST
MOVEM T2,MAXMAX## ;LARGEST LEGAL CORMAX
HRRZ T1,CORLIM ;UPPER BOUND ON CORMAX
LSH T1,P2WLSH ;CONVERT TO NUMBER OF WORDS MAX
CAMLE T1,T2 ;NUMBER OF PHYSICAL PAGES WHICH WILL REMAIN
; AFTER LOCKING .GT. MAX CORMAX?
MOVE T1,T2 ;YES, NEW CORMAX = NUMBER OF PHYSICAL PAGES
; LEFT AFTER LOCKING
MOVEM T1,CORMAX ;STORE THE UPDATED VALUE OF CORMAX
MOVE J,.C0JOB ;CURRENT JOB NUMBER
MOVSI T1,LOKSEG ;ASSUME THE HIGH SEGMENT IS BEING LOCKED
CAILE P1,JOBMAX ;IS IT?
IORM T1,JBTSGN(J) ;YES, INDICATE HIGH SEGMENT IS LOCKED FOR
; THIS JOB
MOVEM J,LASLOK ;REMEMBER THE JOB NUMBER OF THE LAST JOB
; ISSUING A LOCK UUO
PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
JUMPL T1,LOKEXT ;IF NEGATIVE, PROCESS NEW STYLE ARGUMENT LIST
;DISPATCH TO DO VARIOUS TYPES OF LOCK FOR EACH SEGMENT
IFN FTKL10,<
PUSHJ P,CHKCSH ;CHECK WHETHER THE CACHE SHOULD BE ON OR OFF
>
CAIG P1,JOBMAX ;IS THE HIGH SEGMENT TO BE LOCKED?
JRST LOKJ06 ;NO
TLCE T1,LKB+LKEB+LKPB;DOES THE USER WANT IT LOCKED IN PLACE?
TLNE T1,LKB+LKEB+LKPB; ..
JRST LOKJ06 ;NO, SOME OTHER VARITY OF LOCKING
HRRZ J,P1 ;YES, J = HIGH SEGMENT NUMBER
PUSHJ P,LOKINP ;LOCK THE HIGH SEGMENT IN PLACE
HLRZS P1 ;P1 = LOW SEGMENT NUMBER OR ZERO IF THE
; LOW SEGMENT ISN'T TO BE LOCKED
JUMPE P1,LOKJ14 ;JUMP IF LOW SEGMENT ISN'T TO BE LOCKED
LOKJ06: PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
TRCE T1,LKB+LKEB+LKPB;DOES THE USER WANT THE LOW SEGMENT LOCKED
TRNE T1,LKB+LKEB+LKPB; IN PLACE?
JRST LOKJ07 ;NO, TRY SOME OTHER VARITY OF LOCKING
HRRZ J,P1 ;YES, J = LOW SEGMENT NUMBER
PUSHJ P,LOKINP ;LOCK THE LOW SEGMENT IN PLACE
JRST LOKJ14 ;AND FINISH UP
LOKJ07: PUSHJ P,GETTAC## ;RESTORE USER'S ARGUMENT
MOVEI T2,0 ;ASSUME ONLY THE HIGH SEGMENT IS TO BE LOCKED
TLNE P1,-1 ;LOCKING BOTH SEGMENT?
MOVE T2,[XWD LKPB,LKPB]
CAIG P1,JOBMAX ;LOCKING ONLY THE LOW SEGMENT?
MOVEI T2,LKPB ;YES
SKIPN T2 ;SKIP IF LOCKING ONLY LOW SEGMENT OR BOTH
MOVSI T2,LKPB ;LOCKING ONLY THE HIGH SEGMENT
TDNE T1,T2 ;EITHER SEGMENT TO BE LOCKED PHYSICALLY CONTIGUOUS?
JRST LOKJ11 ;THE USER DOES NOT REQUIRE PHYSICAL CONTIGUITY,
; CHECK FOR CONTIGUOUS IN EVM
PUSHJ P,LOKPHY ;ATTEMPT TO LOCK THE JOB IN PHYSICALLY CONTIGUOUS
; MEMORY
JRST ERRO4A ;COULDN'T MAKE IT, GIVE THE USER AN ERROR RETURN
CAIG P1,JOBMAX ;LOCKING A HIGH SEGMENT?
JRST LOKJ09 ;NO, PROCEED
HLRZ T3,T1 ;YES, T3 = PHYSICAL PAGE NUMBER OF FIRST PAGE OF
; THE HIGH SEGMENT
PUSH P,T1 ;SAVE FIRST PAGE OF HIGH SEGMENT,,FIRST
; PAGE OF LOW SEGMENT
PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMMENT
HRRZ J,P1 ;J = HIGH SEGMENT NUMBER
TLNE T1,LKEB ;DOES THE USER ALSO REQUIRE THAT THE HIGH
; SEGMENT BE CONTIGUOUS IN EVM?
JRST LOKJ08 ;NO, PROCEED
PUSHJ P,LKEVC ;IS THE SEGMENT ALSO CONTIGUOUS IN EVM
; BY VIRTUE OF BEING BELOW 112K?
JRST [POP P,T1 ;NO, RESTORE ADDRESSES OF SEGMENTS
TLZ T1,-1 ;INDICATE HIGH SEGMENT NOT ALREADY LOCKED IN EVM
JRST LOKJ09] ;SEE ABOUT THE LOW SEGMENT
LOKJ08: POP P,T1 ;RESTORE THE ADDRESSES OF THE SEGMENTS
HLRZS P1 ;P1 = LOW SEGMENT NUMBER OR ZERO IF LOW
; SEGMENT IS NOT TO BE LOCKED
JUMPE P1,LOKJ14 ;ALL DONE IF LOW SEGMENT IS NOT TO BE LOCKED
LOKJ09: HRRZ T3,T1 ;T3 = PHYSICAL PAGE NUMBER OF FIRST PAGE OF
; THE LOW SEGMENT
PUSH P,T1 ;SAVE ADDRESSES OF THE SEGMENTS
PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
HRRZ J,P1 ;J = LOW SEGMENT NUMBER
CAILE P1,JOBMAX ;LOCKING THE HIGH SEGMENT ALSO?
HLRZ J,P1 ;YES, THEN THE LOW SEGMENT NUMBER IS IN
; THE LEFT HALF
TRNE T1,LKEB ;DOES THE USER REQUIRE THAT THE LOW SEGMENT
; BE LOCKED IN CONTIGUOUS EVM?
JRST LOKJ10 ;NO, CONTINUE
PUSHJ P,LKEVC ;IS THE LOW SEGMENT ALREADY LOCKED IN
; CONTIGUOUS EVM BY VIRTUE OF BEING LOCKED
; IN PHYSICALLY CONTIGUOUS MEMORY BELOW 112K?
JRST [POP P,T1 ;NO, RESTORE SEGMENTS ADDRESSES
TRZ T1,-1 ;INDICATE THAT THE LOW SEGMENT IS NOT
; ALREADY CONTIGUOUS IN EVM
JRST LOKJ12] ;GO MAKE IT CONTIGUOUS IN EVM
LOKJ10: POP P,T1 ;YES, RESTORE SEGMENTS ADDRESSES
TLZN P1,-1 ;IS THERE STILL A HIGH SEGMENT TO WORRY ABOUT?
JRST LOKJ14 ;NO, FINISH UP
JRST LOKJ12 ;YES
LOKJ11: MOVEI T1,0 ;INDICATE THAT NEITHER SEGMENT IS ALREADY
; LOCKED IN EVM
LOKJ12: MOVE P2,T1 ;P2 = SEGMENTS ADDRESSES IF LOCKED ALREADY
PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
TDCE T1,[XWD LKEB,LKEB]
TDNE T1,[XWD LKEB,LKEB]
SKIPA ;THE USER WANTS ONE OR BOTH SEGMENTS
; LOCKED IN CONTIGUOUS EXEC VIRTUAL MEMORY
JRST LOKJ14 ;ALL DONE
PUSHJ P,GETTAC## ;RESTORE USER'S ARGUMENT
EXCH T1,P2 ;T1 REFLECTS THE PROGRESS SO FAR
CAILE P1,JOBMAX ;LOCKING ONLY THE LOW SEGMENT?
TLNE T1,-1 ;NO, IS THE HIGH SEGMENT ALREADY LOCKED?
JRST LOKJ13 ;GO CHECK THE LOW SEGMENT
TLNE P2,LKEB ;LOCK THE HIGH SEGMENT VIRTUALLY CONTIGUOUS?
JRST LOKJ13 ;NO
PUSH P,T1 ;SAVE THE ADDRESS OF THE LOW SEGMENT
HRRZ J,P1 ;J = THE HIGH SEGMENT NUMBER
PUSHJ P,LOKEVM ;ATTEMPT TO LOCK THE HIGH SEGMENT IN EVM
JRST ERROR4 ;NOT ENOUGH EVM
HRLM T1,(P) ;STORE THE EVA OF THE HIGH SEGMENT
POP P,T1 ;RESTORE THE ADDRESSES OF THE SEGMENTS
HLRZS P1 ;P1 = LOW SEGMENT NUMBER OF LOW SEGMENT IS
; TO BE LOCKED
JUMPE P1,LOKJ14 ;ALL DONE IF NOT LOCKING LOW SEGMENT
LOKJ13: TRNN P2,LKEB ;LOCK THE LOW SEGMENT VIRTUALLY CONTIGUOUS?
TRNE T1,-1 ;YES, IS THE LOW SEGMENT ALREADY LOCKED IN EVM?
JRST LOKJ14 ;YES, FINISH UP
PUSH P,T1 ;SAVE THE ADDRESSES OF THE SEGMENTS
MOVE J,.C0JOB## ;J = LOW SEGMENT NUMBER
PUSHJ P,LOKEVM ;ATTEMPT TO LOCK THE LOW SEGMENT IN EVM
JRST ERROR4 ;NOT ENOUGH EVM
HRRM T1,(P) ;STORE THE EVA OF THE LOW SEGMENT
POP P,T1 ;RESTORE THE ADDRESSES OF THE SEGMENTS
LOKJ14: AOS (P) ;SET FOR OK RETURN
LOKJ15: PUSHJ P,CAFREE ;RETURN THE LOCK RESOURCE
PUSHJ P,STOTAC ;STORE ERROR OR HIGH SEGMENT ADDRESS,,
; LOW SEGMENT ADDRESS
PJRST SETRLH## ;AND REDO THE PAGE MAP
;SUBROUTINE TO LOCK A SEGMENT IN PLACE
;CALLING SEQUENCE:
; MOVE J,SEGMENT NUMBER OF SEGMENT TO BE LOCKED IN PLACE
; PUSHJ P,LOKINP
;RETURN HERE, SEGMENT IS LOCKED IN PLACE
LOKINP: MOVEI T3,LOKIPB ;BIT INDICATING PAGE IS LOCKED IN PLACE
PUSHJ P,LOKBTS ;TURN IT ON FOR EVERY PAGE IN THE SEGMENT
MOVEI T1,0 ;ADDRESS WHERE SEGMENT IS LOCKED IS ZERO
; SINCE NOTHING ELSE IS MEANINGFUL
POPJ P, ;RETURN
LOKARG: HRRI M,(T1) ;POINT AT USER'S ARGUMENT LIST
HLRE T2,T1 ;- LENGTH OF THE ARGUMENT LIST
CAME T2,[-2] ;MUST BE EXACTLY 2 WORDS LONG
JRST LOKAR1 ;BAD ARGUMENT LIST
PUSHJ P,GETWDU## ;GET THE FIRST ARGUMENT (FUNCTION)
JUMPL T1,LOKAR1 ;CAN'T BE NEGATIVE
CAIL T1,MXLFCN ;IS IT A LEGAL FUNCTION?
JRST LOKAR1 ;NO, BAD ARGUMENT LIST
ROT T1,-1 ;DIVIDE BY 2, SAVE THE REMAINDER IN HIGH BIT
SKIPGE T1 ;SKIP IF AN EVEN FUNCTION
SKIPA T1,LOKFCN(T1) ;ODD FUNCTION, GET DISPATCH ADDRESS
MOVS T1,LOKFCN(T1) ;EVEN FUNCTION, GET DISPATCH ADDRESS
TRNN T1,-1 ;IMPLIMENTED FUNCTION?
JRST LOKAR1 ;NO, GIVE BAD ARGUMENT LIST RETURN
AOS (P) ;SET FOR GOOD RETURN
JRST (T1) ;DISPATCH TO THE FUNCTION PROCESSOR
LOKAR1: MOVEI T1,LKERR5 ;BAD ARGUMENT LIST ERROR CODE
POPJ P, ;NON-SKIP RETURN TO CALLER
LOKFCN: LOKHPH,,0
MXLFCN==2*<.-LOKFCN>
LOKHPH: PUSHJ P,GETWD1## ;GET THE SECOND WORD OF THE ARGUMENT LIST
TLZE T1,-1 ;LOCK THE HIGH SEGMENT AT A SPECIFIED ADDRESS?
TLO T1,LKB ;YES, INDICATE HIGH SEGMENT TO BE LOCKED
TRZE T1,-1 ;LOCK THE LOW SEGMENT AT A SPECIFIED ADDRESS?
TRO T1,LKB ;YES, INDICATE LOW SEGMENT TO BE LOCKED
POPJ P, ;AND RETURN
;SUBROUTINE TO LOCK A SEGMENT CONTIGUOUSLY IN EXEC VIRTUAL MEMORY
;CALLING SEQUENCE:
; MOVE J,SEGMENT NUMBER OF SEGMENT TO BE LOCKED IN EVM
; PUSHJ P,LOKEVM
;RETURN HERE IF NOT ENOUGH EVM TO LOCK THE SEGMENT
;RETURN HERE, SEGMENT IS LOCKED IN EVM - T1 = EV PAGE NUMBER OF SEGMENT
LOKEVM: LDB T1,PCORSZ ;SIZE OF THE SEGMENT - 1
ADDI T1,1 ;SIZE OF THE SEGMENT
PUSH P,T1 ;SAVE THAT
IFN FTVM,<
CAIG J,JOBMAX## ;A LOW SEGMENT?
ADDI T1,UPMPSZ## ;YES, UPMP MUST BE MAPPED TOO
>
MOVEI T2,EVMPTR## ;POINT TO BIT MAP OF SLOTS IN THE EXEC MAP
; USED FOR LOCKING IN EVM
MOVE T3,T1 ;AMOUNT OF EVM NEEDED
ADD T3,.C0EVU## ;AMOUNT ALREADY IN USE
CAMG T3,.C0EVM## ;GREATER THAN TOTAL AVAILABLE?
PUSHJ P,GETBIT## ;GET, SET BITS IN THE EVL TABLE
PJRST TPOPJ ;NOT ENOUGH SLOTS AVAILABLE
MOVEI T1,400(T1) ;MAKE RELATIVE LOCATION IN THE MAP INTO PAGE NUMBER
MOVE T2,(P) ;NUMBER OF PAGES IN THIS SEGMENT
IFN FTVM,<
CAIG J,JOBMAX##
ADDI T2,UPMPSZ##
>
ADDM T2,.C0EVU## ;COUNT EVM IN USE FOR LOCKING
IFE FTVM,<
MOVEI T3,0 ;T3 = USER VIRTUAL ADDRESS TO START AT
; WHEN COPYING THE USER'S MAP INTO THE EXEC MAP
CAIG J,JOBMAX ;IS THIS A HIGH SEGMENT
JRST LOKEV2 ;NO
>
IFN FTVM,<
CAILE J,JOBMAX## ;LOW SEG?
JRST LOKEV1 ;NO
MOVE T2,T1 ;PAGE WHERE UPMP IS TO BE MAPPED
ROT T2,-1 ;DIVIDE BY 2
TLZN T2,400000 ;ODD OR EVEN?
TDOA T2,[POINT 18,.EPMP##,17]
TDO T2,[POINT 18,.EPMP##,35]
HLRZ T3,.UPMP+.MUPMP ;PHYSICAL PAGE 3 OF THE UPMP
DPB T3,T2 ;MAP THE UPMP IN THE EXEC MAP
IFN FTMS,<
PUSHJ P,MAPUC## ;MAP IT IN CPU1'S MAP
>
MOVEI T3,0 ;STARTING VIRTUAL ADDRESS
AOJA T1,LOKEV2 ;MAP LOW SEG STARTING AT NEXT PAGE
LOKEV1:>
MOVE T3,T1 ;SAVE STARTING PAGE IN THE EXEC MAP
PUSH P,J ;SAVE HIGH SEGMENT NUMBER
MOVE J,.C0JOB## ;JOB NUMBER
PUSHJ P,HSVAD## ;COMPUTE STARTING VIRTUAL ADDRESS OF THE HIGH SEGMENT
POP P,J
MOVE T1,T3 ;RESTORE T1
MOVE T3,T2 ;T3=VIRTUAL ADDRESS OF HIGH SEGMENT
LOKEV2: MOVE T2,(P) ;NUMBER OF PAGES TO MAP IN THE EXEC MAP
IFN FTMS,<
PUSH P,T3 ;SAVE UVA
>
PUSHJ P,MAPUEV## ;COPY THE USER'S MAP INTO THE EXEC MAP
HRRM T3,JBTADR(J) ;STORE THE EVA OF THIS SEGMENT
IFN FTMS,<
POP P,T3 ;RESTORE UVA
>
MOVE T2,T1 ;T2=EXEC VIRTUAL PAGE NUMBER OF THE SEGMENT
EXCH T2,(P) ;SAVE THAT, RESTORE NUMBER OF PAGES TO BE MAPPED
IFN FTMS,<
PUSHJ P,MAPUEC## ;COPY USER'S MAP TO CPU1'S MAP
>
MOVEI T3,LOKEVB ;BIT INDICATING PAGE IS LOCKED IN EVM
PUSHJ P,LOKBTS ;TURN IT ON FOR EACH PAGE IN THE SEGMENT
PUSHJ P,CONEVA ;COMPLETE LARGEST HOLE IN EVM
PJRST TPOPJ1## ;RESTORE EV PAGE NUMBER AND GIVE SUCCESS RETURN
LOKEXT: HRRI M,(T1) ;POINT M AT THE USER'S ARGUMENT LIST
PUSHJ P,GETWD1## ;GET THE SECOND WORD OF THE ARGUMENT LIST
IFN FTKL10,<
PUSHJ P,GETWDU## ;GET THE USER'S FIRST ARGUMENT
PUSHJ P,CHKCSH ;SEE IF CACHE SHOULD BE OFF OR ON
>
;HERE WITH T1= WHERE HIGH SEGMENT IS TO BE LOCKED,,WHERE LOW SEGMENT
; IS TO BE LOCKED, P1= LOW SEGMENT NUMBER,,HIGH SEGMENT NUMBER
LKSPHY: MOVE P2,T1 ;SAVE WHERE,,WHERE
SETZM LOKREL ;INITIALIZE FOR IORM
TLNN P1,-1 ;LOCKING BOTH SEGMENTS?
JRST LKSPH2 ;NO
HLRZ T2,T1 ;WHERE THE HIGH SEGMENT IS TO BE LOCKED
HRRZ T3,T1 ;WHERE THE LOW SEGMENT IS TO BE LOCKED
LDB T4,PCORSZ## ;HIGHEST PAGE IN THE LOW SEGMENT
ADDI T4,1+UPMPSZ##(T3)
CAIL T2,(T3) ;IF LOCKED AS REQUESTED,
CAIL T2,(T4) ; WILL THE HIGH AND LOW SEGMENTS OVERLAP?
CAIA ;NO
JRST LKSPH1 ;YES, ERROR RETURN
LDB T4,[POINT 9,JBTADR(P1),8]
ADDI T4,1(T2) ;TOP PAGE IN HIGH SEGMENT AFTER LOCKING
CAIL T3,(T2) ;IF LOCKED AS REQUESTED,
CAIL T3,(T4) ; WILL THE HIGH AND LOW SEGMENTS OVERLAP?
JRST LKSPH2 ;NO, ALL IS WELL SO FAR
LKSPH1: MOVEI T1,LKERR6 ;YES, HIGH AND LOW SEGMENTS WILL OVERLAP
JRST LOKJ15 ;GIVE ERROR RETURN
LKSPH2: HLRZ J,P1 ;LOW SEGMENT NUMBER IF LOCKING BOTH SEGMENTS
CAIG P1,JOBMAX ;LOCKING BOTH SEGMENTS OR JUST THE HIGH SEGMENT?
JRST [HRRZ J,P1 ;NO, ONLY LOCKING THE LOW SEGMENT
JRST LKSPH3]
HLRZS T1 ;WHERE THE HIGH SEGMENT IS TO BE LOCKED
HRRZ J,P1 ;HIGH SEGMENT NUMBER
PUSHJ P,PHYPF ;ARE THE PAGES AVAILABLE FOR LOCKING?
JRST LOKJ15 ;NO, ERROR RETURN
HRRZM T1,LOKREL ;STORE WHERE THE HIGH SEGMENT IS TO BE LOCKED
HLRZ J,P1 ;LOW SEGMENT NUMBER IF LOCKING THE LOW SEGMENT
JUMPE J,LKSPH4 ;ALL DONE IF NOT LOCKING THE LOW SEGMENT
LKSPH3: HRRZ T1,P2 ;WHERE THE LOW SEGMENT IS TO BE LOCKED
PUSHJ P,PHYPF ;SEE IF THOSE PAGES ARE AVAILABLE FOR LOCKING
JRST LOKJ15 ;NOT, LOSE
SKIPE LOKREL ;HIGH SEGMENT TO BE LOCKED?
HRLZS T1 ;YES, PAGE NUMBER TO THE LEFT HALF WORD
IORM T1,LOKREL ;WHERE LOW,,WHERE HIGH
LKSPH4: MOVE J,.C0JOB## ;CURRENT JOB NUMBER
PUSHJ P,LOCKIT ;LOCK THE SEGMENTS REQUESTED WHERE REQUESTED
JFCL ;CAN'T HAPPEN
JRST LOKJ14 ;GIVE JOB LOCKED RETURN
;SUBROUTINE TO DETERMINE IF A SEGMENT CAN BE LOCKED IN A SPECIFIC
; PLACE IN PHYSICAL MEMORY. I.E., DETERMINE THAT THE PAGES REQUIRED ARE
; EXISTANT, NOT LOCKED, AND NOT PART OF THE MONITOR.
;CALLING SEQUENCE:
; MOVE T1,STARTING PHYSICAL PAGE #
; MOVE J,SEGMENT #
; PUSHJ P,PHYPF
;RETURN CPOPJ, T1=LKERR6 IF THE PAGES ARE NOT AVAILABLE
; CPOPJ1 IF THEY ARE, T1 PRESERVED
PHYPF: LDB T2,[POINT 9,SYSSIZ,26]
LDB T3,[POINT 14,MEMSIZ,26]
CAIL T1,(T2) ;ABOVE THE MONITOR?
CAIL T1,(T3) ;AND BELOW THE TOP OF MEMORY?
JRST PHYPF2 ;NO, LOSE
LDB T2,PCORSZ## ;HIGHEST PAGE IN THE SEGMENT
ADDI T2,1 ;NUMBER OF PAGES IN THE SEGMENT
CAIG J,JOBMAX ;IF A LOW SEGMENT,
ADDI T2,UPMPSZ ;ACCOUNT FOR THE LOW SEGMENT SIZE
MOVE T3,T1 ;STARTING PAGE FOR LOCKING THE SEGMENT
PHYPF1: MOVE T4,PAGTAB(T3) ;PAGTAB ENTRY REPRESENTING THIS PHYSICAL PAGE
TLNE T4,LKBITS+IPCBIT ;LOCKED OR NON-EXISTANT PAGE?
JRST PHYPF2 ;YES, LOSE
SOSE T2 ;LOOKED AT ALL THE PAGES REQUIRED TO LOCK THE SEGMENT?
AOJA T3,PHYPF1 ;NO, CHECK THE NEXT PHYSICAL PAGE
AOSA (P) ;YES, ALL PAGES ARE FREEABLE SO SKIP RETURN
PHYPF2: MOVEI T1,LKERR6 ;CAN'T LOCK THERE ERROR CODE
POPJ P, ;RETURN
;SUBROUTINE TO LOCK A JOB (ONE OR BOTH SEGMENTS) IN CONTIGUOUS
; PHYSICAL MEMORY
;CALLING SEQUENCE:
; MOVE P1,0,,LOW SEGMENT NUMBER IF LOCKING ONLY LOW SEGMENT, OR
; MOVE P1,0,,HIGH SEGMENT NUMBER IF LOCKING ONLY HIGH SEGMENT, OR
; MOVE P1,LOW SEGMENT NUMBER,,HIGH SEGMENT NUMBER IF LOCKING BOTH
; PUSHJ P,LOKPHY
;RETURN HERE IF NO HOLE IN PHYSICAL MEMORY IS BIG ENOUGH
;RETURN HERE, REQUESTED SEGMENTS ARE LOCKED IN CONTIGUOUS PHYSICAL MEMORY
LOKPHY: HLRZ T1,P1 ;LOW SEGMENT NUMBER OR ZERO
HLRZ T1,JBTADR(T1) ;SIZE OF THE LOW SEGMENT OR ZERO
SKIPE T1 ;SKIP IF LOW SEGMENT NOT BEING LOCKED
ADDI T1,1+UPMSZW## ;ACCOUNT FOR THE UPMP
HLRZ T2,JBTADR(P1) ;SIZE OF THE HIGH SEGMENT OR LOW SEGMENT
; IF HIGH SEGMENT IS NOT BEING LOCKED
ADDI T1,1(T2) ;AMOUNT BEING LOCKED
LSH T1,W2PLSH ;CONVERT TO NUMBER OF PAGES
MOVE T2,SYSSIZ ;LOOK FOR A PLACE TO LOCK IT STARTING AT
; THE TOP OF THE MONITOR
LSH T2,W2PLSH ;CONVERT SYSSIZ TO PAGES
MOVE T3,MEMSIZ ;LOOK THROUGH ALL OF USER CORE
LSH T3,W2PLSH ; A PAGE AT A TIME
LOKPH1: TDZA T4,T4 ;LARGEST HOLE SEEN SO FAR
LOKPH2: ADDI T4,1 ;INCREMENT SIZE OF LARGEST HOLE
LOKPH3: CAIN T3,(T2) ;LOOKED AT ALL OR CORE?
JRST LOKPH4 ;YES, SEE IF A BIG ENOUGH HOLE WAS FOUND
MOVE S,PAGTAB(T2) ;STATUS OF THIS PAGE
TLNN S,LKBITS+IPCBIT ;IS IT LOCKED OR NON-EXISTANT?
AOJA T2,LOKPH2 ;NO, COUNT IT IN THIS HOLE
CAMG T4,T1 ;IS THIS HOLE BIG ENOUGH?
AOJA T2,LOKPH1 ;NO, LOOK HIGHER UP
LOKPH4: CAMG T4,T1 ;IS THE HOLE FOUND BIG ENOUGH?
POPJ P, ;NO, ERROR RETURN
SUBI T2,(T4) ;STARTING PAGE NUMBER OF THE HOLE
HRRZM T2,LOKREL ;SAVE THAT FOR LOCK
HLRZ T1,JBTADR(P1) ;SIZE OF THE FIRST SEGMENT TO BE LOCKED
ADDI T1,1 ; ..
LSH T1,W2PLSH ;CONVERT TO NUMBER OF PAGES
CAIG P1,JOBMAX ;LOCKING HIGH SEGMENT?
ADDI T1,UPMPSZ## ;NO, ACCOUNT FOR THE UPMP
ADD T1,LOKREL ;STORE THAT FOR LOCK
TLNE P1,-1 ;LOCKING BOTH SEGMENT?
HRLM T1,LOKREL ;WHERE TO LOCK THE OTHER SEGMENT
LOCKIT: MOVEM P1,LOCK ;STORE SEGMENT NUMBERS FOR LOCK
MOVEI T1,LOK ;MAKE THE JOB UNRUNNABLE UNTIL LOCKING
IORM T1,JBTSTS(J) ; IS COMPLETE
PUSHJ P,WSCHED ;RESCHEDULE, RETURN WHEN JOB IS LOCKED
RASBAD: LDB T1,JBYLSA ;STARTING PAGE NUMBER OF THE LOW SEGMENT
MOVEI T2,0 ;ASSUME NO HIGH SEGMENT
SKIPLE J,JBTSGN(J) ;JOB HAVE A REAL HIGH SEGMENT?
LDB T2,JBYHSA ;YES, STARTING PAGE NUMBER OF THE HIGH SEGMENT
HRL T1,T2 ;HIGH SEGMENT ADDRESS,,LOW SEGMENT ADDRESS
PJRST CPOPJ1 ;AND GIVE LOCKED RETURN
;
;ROUTINE TO FREE CORE GIVEN UP BY A LOCKED JOB
;CALLED FROM UUOCON ON RESET UUO FROM USER OR
;ON A CALL TO RESET FROM COMCON
;ALSO CALLED FROM KILHGH IN SEGCON
;
IFN FT2REL,<
INTERNAL UNLOKH
UNLOKH: MOVE J,-1-IFN FTSWAP,<1>(P) ;GET JOB NUMBER
MOVSI T1,LKB ;UNLOCK THE HIGH SEGMENT
JRST UNLO00 ;UNLOCK IT IF NOT LOCKED FOR SOME OTHER JOB
>
UNLOCK: SKIPA T1,[XWD LKB,LKB];UNLOCK BOTH LOW AND HIGH SEGMENTS
UNLOK.: AOS (P) ;HERE FROM UNLOCK UUO. ALWAYS GIVE OK RETURN.
UNLO00: PUSHJ P,SAVE4 ;PRESERVE ACCUMULATORS
PUSH P,T1 ;SAVE ARGUMENT WHILE UNLOCKING
ZZ==. ;PLACE ON STACK FOR ARGUMENT (T1)
PUSH P,J ;SAVE JOB NUMBER
ZZ==.-ZZ ;DEPTH ON STACK FOR ARGUMENT (T1)
MOVSI P4,NSHF!NSWP
IFN FT2REL,<
MOVEI J,(J) ;CLEAR POSSIBLE LEFT HALF BITS
CAILE J,JOBMAX ;IS THIS A HIGH SEGMENT?
JRST UNLO04 ;YES IF CALLED FROM SEGCON OR LOKINI
>
TRNE T1,LKB ;UNLOCK THE LOW SEGMENT?
TDNN P4,JBTSTS(J) ;IS IT LOCKED?
JRST UNLO01 ;NO
IFN FTRTTRP,<
EXTERN RTREL
PUSHJ P,RTREL ;RESET REAL TIME
>
PUSHJ P,FRELOK ;UNLOCK THE LOW SEGMENT
IFN FTKL10,<
MOVSI T1,(JS.NCS) ;DON'T CACHE BIT
ANDCAM T1,JBTST2##(J) ;TURN THE CACHE ON AGAIN
MOVE R,JBTADR##(J)
PUSHJ P,MAPLOW## ;TURN ON CACHE BITS IN THE MAP
>
MOVE T1,-ZZ(P) ;RESTORE ARGUMENT
HRROS -ZZ(P) ;FLAG THAT CORE HAS CHANGED (SO CALL LRGHOL)
IFN FT2REL,<
UNLO01: TLNE T1,LKB ;UNLOCK THE HIGH SEGMENT?
SKIPN TWOREG ;TWO SEGMENT HARDWARE?
JRST UNLO05 ;NO
MOVSI P2,LOKSEG+IFN FTKL10,<NCSH>
SKIPLE P3,JBTSGN(J) ;DOES THE JOB HAVE A REAL HIGH SEGMENT
TDNN P2,JBTSGN(J) ;AND IS IT LOCKED
JRST UNLO05 ;NO
ANDCAM P2,JBTSGN(J) ;TURN OFF HIGH SEGMENT LOCKED FOR THIS JOB
IFN FTKL10,<
PUSHJ P,MAPHGH## ;TURN ON CACHE BITS IN THE MAP
>
MOVE T1,HIGHJB ;IS ANOTHER JOB SHARING THE HIGH SEGMENT?
UNLO02: SKIPG JBTSGN##(T1) ;A REAL HIGH SEGMENT?
JRST UNLO03 ;NO
HRRZ P1,JBTSGN(T1)
CAME T1,(P) ;CURRENT JOB?
CAIE P1,(P3) ;SAME HIGH SEGMENT?
JRST UNLO03 ;THIS SEGENT DOESN'T STOP UNLOCKING
TDNE P2,JBTSGN(T1) ;IS THE LOW SEGMENT SHARING LOCKED?
JRST UNLO05 ;YES, CAN'T UNLOCK THE HIGH SEGMENT
UNLO03: SOJG T1,UNLO02
MOVE J,P3
UNLO04: TDNN P4,JBTSTS(J) ;IS HIGH SEGMENT LOCKED?
JRST UNLO05 ;NO, DO NOT UNLOCK HIGH SEGMENT
HRROS -ZZ(P) ;YES, FLAG FACT THAT A SEGMENT HAS
; BEEN UNLOCKED
PUSHJ P,FRELOK ;NO OTHER LOCKED JOB SHARING, UNLOCK IT
>
UNLO05: POP P,J ;RESTORE JOB NUMBER
MOVE R,JBTADR(J) ;AND R
POP P,T1 ;HAS CORE CHANGED?
JUMPGE T1,CPOPJ## ;NO, REMOVE ARGUMENT AND RETURN
COMLIM:
IFN FTSWAP,<
PUSHJ P,LRGHOL ;SET EXTENT OF THE LARGEST HOLE
MOVEM T2,MAXMAX## ;LARGEST LEGAL CORMAX
HRRZ P1,CORLIM ;AND ADJUST CORMAX
ASH P1,P2WLSH
CAMLE P1,T2 ;TO CORLIM OR SIZE OF HOLE
MOVE P1,T2 ;WHICH EVER IS SMALLER
MOVEM P1,CORMAX
>
POPJ P, ;RETURN
FRELOK:
IFN FTMETR,< ;RELEASE ANY METER POINTS EFFECTED
PUSHJ P,METREL##
>
ANDCAM P4,JBTSTS(J) ;TURN OFF NSHF AND NSWP
LDB T1,JBYLSA ;PAGE NUMBER OF FIRST PAGE OF THE LOW SEGMENT
CAILE J,JOBMAX ;IS IT A HIGH SEGMENT?
LDB T1,JBYHSA ;PAGE NUMBER OF FIRST PAGE OF THE HIGH SEGMENT
MOVSI T2,LOKEVB ;BIT INDICATING LOCKED IN EVM
TDNN T2,PAGTAB(T1) ;IS IT?
JRST FRELK4 ;NO, PROCEED
HRRZ T3,JBTADR(J) ;EVA OF THIS SEGMENT
LSH T3,W2PLSH ;CONVERT TO PAGE NUMBER
PUSHJ P,LKEVA ;IS THIS SEGMENT LOCKED IN EVM BY VIRTUE
; OF BEING BELOW 112K?
CAIA ;NO
JRST FRELK2 ;YES, DON'T NEED TO RETURN EVM
PUSH P,T1 ;SAVE STARTING PAGE NUMBER
HLRZ T1,JBTADR(J) ;SIZE OF THIS SEGMENT
LSH T1,W2PLSH ; IN PAGES - 1
ADDI T1,1 ;IN PAGES
SUBI T3,400 ;CONVERT TO RELATIVE PAGE WITHIN EXEC MAP
IFN FTVM,<
CAILE J,JOBMAX## ;A LOW SEGMENT?
JRST FRELK1 ;NO, SKIP ON
ADDI T1,UPMPSZ## ;YES ACCOUNT FOR THE MAP
SUBI T3,UPMPSZ## ; WHICH IS ALSO MAPPED
FRELK1:>
MOVN T4,T1 ;GET THE NUMBER OF PAGES IN SEGMENT
ADDM T4,.C0EVU## ;AND INDICATE THAT EVM IS NO LONGER USED
MOVE T2,EVMPTR## ;AOBJN POINTER FOR RETURNING SLOTS
PUSHJ P,ZERBTS## ;RETURN EVM
PUSHJ P,CONEVA
POP P,T1 ;RESTORE STARTING PAGE NUMBER
FRELK2: MOVE R,JBTADR(J) ;EVA OF SEGMENT
HRRI R,.VJDT ;ASSUME ITS A HIGH SEGMENT
CAILE J,JOBMAX ;IS IT?
JRST FRELK3 ;YES
HRRI R,.JDAT ;ITS A LOW SEGMENT - EVA OF THE JOB DATA AREA
MOVEM R,.C0ADR## ;RESET SOFTWARE RELOCATION INFO
HRRZ T3,P ;DIDDLE THE PUSH DOWN LIST POINTER
MOVEI T2,PDLPNO## ;PAGE NUMBER (EVA) OF THE PUSH DOWN LIST
CAMLE T3,SYSSIZ## ;IS THE PUSH DOWN LIST IN THE MONITOR?
DPB T2,[POINT 9,P,26];NO, AJUST RELOCATION
FRELK3: SKIPE R ;GETTING CORE?
PUSHJ P,IICLNK## ;YES
SKIPN R ;GIVING UP CORE?
PUSHJ P,DICLNK## ;YES
MOVEM R,JBTADR(J) ;STORE DIDDLED RELOCATION
FRELK4: MOVSI T2,LKBITS ;BITS INDICATING A PAGE IS LOCKED
ANDCAB T2,PAGTAB(T1) ;CLEAR THEM
HRRZ T1,T2 ;NEXT PAGE IN THE SEGMENT
JUMPN T1,FRELK4 ;LOOP IF MORE PAGES IN THE SEGMENT
CAILE J,JOBMAX ;IS THIS A LOW SEGMENT?
POPJ P, ;NO, RETURN
HRRZ T1,JBTUPM(J) ;YES, UNLOCK THE UPMP
MOVSI T2,LKBITS ;BITS INDICATING PAGES IS LOCKED
ANDCAM T2,PAGTAB(T1) ;CLEAR THEM FOR THE UPMP
POPJ P, ;AND RETURN
IFN FTMOFFL,<
;SUBROUTINE TO DETERMINE IF A RANGE OF MEMORY OVERLAPS LOCKED JOBS
; AND IF SO, RETURN ALL THE JOBS WHICH OVERLAP THE RANGE
CKLJB:: ADDI J,1 ;NEXT JOB
CAMLE J,HIGHJB## ;UP TO THE HIGHEST JOB IN THE SYSTEM?
POPJ P, ;YES, ALL DONE
MOVE T3,JBTSTS##(J) ;JOB STATUS FOR THE CURRENT JOB
TLNN T3,NSHF!NSWP ;IS IT LOCKED?
JRST CKLJB1 ;NO, CHECK ITS HIGH SEGMENT
HRRZ T3,JBTUPM##(J) ;ADDRESS OF THE JOBS PAGE MAP
PUSHJ P,CKRNG ;SEE IF THATS WITHIN THE RANGE
JRST CPOPJ1## ;YES, INDICATE OVERLAP
PUSHJ P,FSTPG ;GET THE PAGE NUMBER OF THE FIRST PAGE OF THE JOB
PUSHJ P,CKPGS ;SEE IF ANY OF THE JOBS PAGES OVERLAP THE RANGE
JRST CPOPJ1## ;YES, INDICATE THAT TO THE CALLER
CKLJB1: SKIPLE T3,JBTSGN##(J) ;DOES THE JOB HAVE A REAL HIGH SEGMENT?
TLNN T3,LOKSEG ;AND IS IT LOCKED?
JRST CKLJB ;NO, LOOK AT THE NEXT JOB
LDB T3,[POINT 13,JBTHSA##(T3),35]
PUSHJ P,CKPGS ;SEE IF THE HIGH SEGMENT PAGES OVERLAP THE RANGE
JRST CPOPJ1## ;THEY DO, TELL THE CALLER
JRST CKLJB ;THEY DON'T SO LOOK AT THE NEXT JOB
;SUBROUTINE TO DETERMINE IF ATTEMPTING TO SET MONITOR PAGES OFF-LINE
CKMOL:: LDB T3,[POINT 9,SYSSIZ##,26]
CAIL T1,(T3) ;LOWER BOUND BELOW SYSSIZ?
AOS (P) ;NO, INDICATE GOODNESS
POPJ P, ;RETURN
;SUBROUTINE TO COMPUTE THE VALUE CORMAX WOULD HAVE IF A RANGE OF PAGES
; WERE TO BE SET OFF LINE
NEWCMX::MOVEI T3,0 ;NUMBER OF ON LINE PAGES IN THE RANGE
MOVSI T4,NXMBIT ;BIT INDICATING PAGE IS NON-EXISTANT
NEWCM1: TDNN T4,PAGTAB(T1) ;IS THIS PAGE NOW ON LINE
ADDI T3,PAGSIZ## ;YES, COUNT IT
CAIE T1,-1(T2) ;LOOKED AT ALL THE PAGES IN THE RANGE?
AOJA T1,NEWCM1 ;NO, LOOK AT THE NEXT PAGE
MOVE T1,MAXMAX## ;CURRENT MAXIMUM VALUE FOR CORMAX
SUB T1,T3 ;NEW MAXIMUM VALUE FOR CORMAX IF PAGES
; IN THE RANGE WERE SET OFF
POPJ P, ;RETURN THE NUMBER TO THE CALLER
;HERE TO SET MEMORY OFF LINE (T1 = FIRST PAGE TO SET OFF, T2 = HIGHEST
; PAGE TO SET OFF)
MEMOFL::SKIPE LOCK## ;LOCKING IN PROGRESS?
PJRST DLYCM## ;YES, TRY AGAIN WHEN ITS DONE
MOVE T3,LASLOK## ;SETTING MEMORY OFF LINE IN PROGRESS?
SETZM LASLOK## ;NOT ANYMORE IN CASE WE WERE
AOJE T3,MEMOF3 ;JUMP IF A SET MEMORY OFF COMMAND JUST COMPLETED
; (LASLOK GETS SET TO -1 AT COMPLETION BY CLOCK LEVEL CODE)
LDB T3,[POINT 14,MEMSIZ##,26]
CAIL T1,(T3) ;TRYING TO SET MEMORY OFF ABOVE THE TOP OFF MEMORY?
POPJ P, ;YES, ITS ALREADY OFF
CAIL T2,(T3) ;HIGH PAGE ABOVE THE TOP OF MEMORY?
MOVE T2,T3 ;YES, SET HIGH PAGE TO LAST PAGE OF MEMORY
MOVEM T1,LOKREL## ;FIRST PAGE TO SET OFF
SUB T2,T1 ;COMPUTE THE NUMBER OF PAGES IN THE RANGE
HRLM T2,LOKREL## ;STORE THAT FOR LOCK
MOVEI T3,0 ;ASSUME NO MONITOR PAGES TO MOVE AND NO
; ON LINE PAGES TO SET OFF
MEMOF1: MOVE T4,PAGTAB(T1) ;PAGE DESCRIPTOR BITS
IFN FT2SEGMON,<
TLNE T4,MONTRB ;DOES THIS PAGE CONTAIN MONITOR CODE?
ADDI T3,1 ;YES, COUNT UP THE NUMBER OF MONITOR PAGES
>
TLNN T4,NXMBIT ;DOES THIS PAGE EXIST (IS IT ON LINE)?
TLO T3,-1 ;YES, INDICATE AT LEAST ONE ON LINE PAGE SEEN
ADDI T1,1 ;NEXT PAGE IN THE RANGE
SOJG T2,MEMOF1 ;LOOK AT EVERY PAGE IN THE RANGE
JUMPGE T3,CPOPJ## ;EXIT IF NO ONLINE PAGES SEEN
IFN FT2SEGMON,<
HRRZM T3,MOFLPG## ;STORE THE NUMBER OF MONITOR PAGES WHICH MUST BE MOVED
> ;END FT2SEGMON
IFN FTMS&FT2SEGMON,<
TRNN T3,-1 ;IF NOT MOVING MONITOR PAGES, DON'T NEED CPU1 TO STOP
JRST MEMOF2 ;GO SET THE PAGES OFF
PUSHJ P,CP1STP## ;ASK CPU1 TO JUMP INTO ITS ACS
PJRST DLYCM## ;AND WAIT UNTIL IT DOES
MEMOF2:>
AOSE CAREQ## ;CAN'T CALL CAWAIT BECAUSE THAT REQUIRES
; A CORE IMAGE
STOPCD .,STOP,CRW, ;++CA RESOURCE WRONG
SETOM LOCK## ;INDICATE SETTING PAGES OFF LINE IS IN PROGRESS
PJRST DLYCM## ;AND WAIT UNTIL ITS DONE
MEMOF3: SOSL CAREQ## ;MAKE THE LOCK RESOURCE AVAILABLE
SETOM CAAVAL## ;AND WAKE UP THE WAITERS FOR IT
IFN FTMS&FT2SEGMON,<
SETZM MOFLPG## ;NOT SETTING MONITOR PAGES OFF LINE
>
TLO M,CMWRQ## ;GET JOB OUT OF COMMAND WAIT
IFN FTDAEM,<
MOVE T1,[11,,.ERCSC] ;MEMORY OFF-LINE INDICATOR
PUSH P,J ;SAVE J FOR COMRET
PUSHJ P,DAEEIM## ;TELL DAEMON ABOUT THE MEMORY CONFIGURATION CHANGE
PJRST JPOPJ## ;RESTORE J AND RETURN TO COMCON
>
IFE FTDAEM,<
POPJ P, ;IF NO DAEMON, JUST RETURN
>
;SUBROUTINE TO CHECK IF A PAGE LIES WITHIN THE RANGE SPECIFIED BY T1 AND T2
CKRNG: CAIL T3,(T1) ;LESS THAN THE LOWER BOUND?
CAIL T3,(T2) ;OR GREATER THAN THE UPPER BOUND?
AOS (P) ;YES, NOT IN THE RANGE
POPJ P, ;RETURN
;SUBROUTINE TO CHECK IF ANY OF THE PAGES BELONGING TO A SEGMENT LIE
; WITHIN THE RANGE SPECIFIED BY T1 AND T2
CKPGS: PUSHJ P,CKRNG ;CHECK THIS PAGE
POPJ P, ;ITS WITHIN THE RANGE
HRRZ T3,PAGTAB(T3) ;GET THE NEXT PAGE OF THE SEGMENT
JUMPE T3,CPOPJ1## ;GOOD RETURN IF THIS IS THE LAST PAGE OF THE SEGMNET
JRST CKPGS ;CHECK THE NEXT PAGE
;SUBROUTINE TO RETURN THE FIRST PAGE OF A LOW SEGMENT
FSTPG: HRRZ T3,JBTUPM##(J) ;ADDRESS OF THE JOBS UPMP
TRO T3,PM.ACC ;ACCESS ALLOWED
HRLM T3,.EPMP##+.MEUPM ;MAKE IT ADDRESSABLE VIA THE EXEC MAP
CLRPGT (0,.TEMP) ;CLEAR THE AM SO NEW MAPPING IS IN EFFECT
LDB T3,[POINT 13,.EUPMP+.MJDAT,35]
POPJ P, ;RETURN THE FIRST PAGE OF THE JOB
> ;END FTMEMOFL
;SUBROUTINE TO DETERMINE THE NUMBER OF UNLOCKED PAGES IN USER CORE
LRGHOL: PUSHJ P,SAVE3##
MOVEI T2,0
MOVE P1,MEMSIZ
SUB P1,SYSSIZ
LSH P1,W2PLSH
MOVE P2,SYSSIZ
LSH P2,W2PLSH
LRGHL1: MOVE P3,PAGTAB(P2)
TLNN P3,LKBITS
ADDI T2,PAGSIZ
ADDI P2,1
SOJG P1,LRGHL1
POPJ P,
;SUBROUTINE TO TURN ON BITS INDICATING A PAGE IS LOCKED IN A SPECIFIED WAY
LOKBTS: MOVSI T1,NSHF!NSWP
IORM T1,JBTSTS(J)
LDB T1,JBYHSA
CAILE J,JOBMAX
JRST LOKBT1
HRRZ T1,JBTUPM(J)
MOVSI T2,(T3)
IORM T2,PAGTAB(T1)
LDB T1,JBYLSA
LOKBT1: MOVSI T2,(T3)
IORB T2,PAGTAB(T1)
HRRZ T1,T2
JUMPN T1,LOKBT1
POPJ P,
;SUBROUTINE TO DETERMINE IF A SEGMENT IS LOCKED IN EVM BY VIRTURE OF BEING
; BELOW 112K. (PRESERVES T3)
LKEVA: LDB T2,PCORSZ
ADDI T2,1(T3)
CAIG T2,^D224
AOS (P)
POPJ P,
;SUBROUTINE TO LOCK A SEGMENT IN EVM IF IT IS BELOW 112K. (PRESERVES T1)
LKEVC: PUSHJ P,LKEVA
POPJ P,
LKEVS: LSH T3,P2WLSH
HRRM T3,JBTADR(J)
PUSH P,T1
MOVEI T3,LOKEVB
PUSHJ P,LOKBTS
PJRST TPOPJ1##
ERROR0: LDB P1,JBYLSA ;LOW SEGMENT PHYSICAL ADDRESS
TRNN T1,LKB ;LOCKING LOW SEGMENT?
JRST LOWADR ;NO, GET ADDRESS ANYWAY
MOVE T4,PAGTAB(P1) ;LOCK STATUS
MOVSS T1 ;SET UP FOR CHECKING USER ARGUMENT
PUSHJ P,ARGCK1 ;IS LOCK POSSIBLE?
JRST ERROR7 ;NO. USER ARGUMENT IS INVALID
LOWADR: TLNN T1,LKEB ;LOCKED IN EVM?
MOVE P1,JBTADR(J) ;YES. LOAD EVA FOR USER.
MOVE T1,P1 ;LOW ADDRESS
HRL T1,T3 ;HIGH ADDRESS
PJRST STOTC1## ;RETURN TO USER WITH ADDRESSES
ERROR1: MOVEI T1,LKERR1
PJRST STOTAC##
ERROR2: MOVEI T1,LKERR2
PJRST LOKJ15
ERROR3: MOVEI T1,LKERR3
PJRST LOKJ15
ERROR4: POP P,T1
ERRO4A: PUSHJ P,UNLOCK
PUSHJ P,COMLIM ;RECOMP CORMAX/MAXMAX
MOVEI T1,LKERR4
PJRST LOKJ15
;SUBROUTINE TO FIND THE LARGEST CONTIGUOUS CHECK
ERROR7: MOVEI T1,7 ;ATTEMPTED TO CHANGE LOCK STATUS
PJRST STOTAC## ;WITH A LOCK UUO
;SUBROUTINE TO CHECK USER'S ARGUMENT WHEN SEGMENT IS ALREADY LOCKED
ARGCK1: TLNN T4,LOKPHB ;PHYSICALLY CONTIGUOUS?
TLNE T1,LKPB ;ASKING FOR IT?
SKIPA ;NO. SO FAR SO GOOD
POPJ P, ;CAN'T MAKE IT CONTIGUOUS
TLNN T4,LOKEVB ;LOCKED IN EVM?
TLNE T1,LKEB ;ASKING FOR IT?
JRST CPOPJ1 ;NO. ALL IS WELL
POPJ P, ;NOT IN EVM, SO USER CAN'T LOCK IT
;SUBROUTINE TO FIND THE LARGEST CONTIGUOUS CHUNK
; OF EVM AVAILABLE FOR MAPPING BUFFERS
CONEVA: PUSHJ P,SAVE4##
MOVE P1,EVMPTR##
MOVEI P2,0
MOVEI P3,-1
PUSHJ P,GETZ##
MOVEM P2,EVBMAX##
POPJ P,
;SUBROUTINE TO CHECK WHETHER THE CACHE SHOULD BE ON OR OFF
IFN FTKL10,<
CHKCSH: MOVE J,.C0JOB##
SKIPG JBTSGN##(J)
JRST CHKCS1
MOVSI T2,NCSH
TLNE T1,LKB
TLNE T1,LKCB
CAIA
IORM T2,JBTSGN##(J)
CHKCS1: TRNE T1,LKB
TRNE T1,LKCB
POPJ P,
MOVSI T2,(JS.NCS)
IORM T2,JBTST2##(J)
POPJ P,
>
SUBTTL SEGCON - ROUTINES TO HANDLE HIGH SEGMENTS
;
;ROUTINE TO DETERMINE WHETHER THE IDLE HIGH SEGMENT FOR THE JOB CURRENTLY
; BEING SWAPPED CAN BE SWAPPED
;
; CALLING SEQUENCE
;
; MOVE J,HIGH SEGMENT NUMBER
; PUSHJ P,SWPHGH
; ... ;RETURN HERE TO SWAP ONLY THE LOW SEGMENT SINCE
; ; THE HIGH SEGMENT IS LOCKED OR BEING LOCKED
; ; T1 CONTAINS THE LOW SEGMENT NUMBER
; ... ;RETURN HERE IF HIGH SEGMENT CAN BE SWAPPED
;
IFN FT2REL,<
INTERN LOKHGH
LOKHGH: PUSH P,SWPOUT## ;JOB NUMBER OF JOB BEING SWAPPED - MUST
; BE SETUP FOR INCREMENTING IN CORE COUNT
; IF HIGH SEGMENT CANNOT BE SWAPPED
MOVE T1,LOCK ;GET HIGH SEGMENT NUMBER IF LOCKING ONLY
; A HIGH SEGMENT
MOVSI T2,NSHF!NSWP ;CANNOT SWAP THE HIGH SEGMENT IF ITS LOCKED
CAIE T1,(J) ;IS THIS A HIGH SEGMENT WHICH IS CURRENTLY
; BEING LOCKED?
TDNE T2,JBTSTS(J) ;IS IT LOCKED
JRST TPOPJ ;YES, GIVE DON'T SWAP RETURN (T1=JOB #)
HLRZ T1,LOCK ;JOB NUMBER OF JOB BEING LOCKED
CAME T1,SWPOUT## ;SAME AS JOB BEING SWAPPED?
AOS -1(P) ;NO, OK TO SWAP THE HIGH SEGMENT
JRST T2POPJ ;POP OFF JUNK AND GIVE SKIP OR NON-SKIP RETURN
>
LOKEND: END