Google
 

Trailing-Edge - PDP-10 Archives - AP-D543V_SB - kalock.mac
There are 2 other files named kalock.mac in the archive. Click here to see a list.
TITLE KALOCK - MODULE FOR LOCKING JOBS IN CORE ON A KA10 - V1103
SUBTTL J. FLEMMING  TS  10 MAY 77
	SEARCH	F,S
	$RELOC
	$HIGH



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VKALOK,1103

ENTRY	KALOCK

KALOCK:	;ENTRY POINT SYMBOL TO CAUSE LOADING OF LOKCON

EXTERNAL LOKREL,LOCK,CORMIN,PAGSIZ,P2WLSH,W2PLSH,LASLOK
EXTERNAL HOLEF,HOLES,SHFWAT
EXTERNAL JOBMAX,JBTMAX
EXTERNAL JBTADR,JBTDAT,JBTSTS
EXTERNAL CORST0,CORST1,DIDLE,SHFLOP,ANYACT,SAVE4
IFN FTSWAP,<
EXTERNAL FORCE0,FIT1,FORIDL,XPANDH
EXTERNAL HOLEF1,HOLTOP,IMGIN
>
IFN FTPRV,<
EXTERNAL JBTPRV
>
IFN FT2REL,<
EXTERNAL TWOREG,JBTSGN
>
EXTERNAL CPOPJ,TPOPJ,T2POPJ
EXTERNAL FREC4
INTERNAL FTSWAP,FTPRV,FTRTTRP,FTMETR
INTERNAL LOCK0,SETLPR
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 BELOW HIGH SEGMENT IF HIGH SEGMENT IN TOP OF CORE
;	ABOVE THE HIGH SEGMENT IF IN LOW CORE
;
;CALLED FROM SCHED WHEN SWAPPER AND SHUFFLER ARE IDLE

LKERR1==1
LKERR2==2
LKERR3==3

LKB==1
LOCK0:	MOVE	J,LOCK
LOCK1:
IFN FTSWAP,<
	SKIPN	JBTADR(J)	;WAS LOW SEGMENT SWAPPED WHILE LOCKING HIGH?
	JRST	[MOVE J,LASLOK##  ;YES
		 JRST FIT1##]
>
	SKIPN	P1,LOKREL	;SEGMENT JUST SHUFFLED INTO PLACE?
	JRST	LOCK6		;YES, SET NSHF AND NSWP
	CAMN	P1,JBTADR(J)	;ALREADY IN PLACE?
	JRST	LOCK5A		;YES, GO SET BITS IN CORTAB
	MOVEI	T1,(J)		;T1_JOB NUMBER OR HIGH SEGMENT NUMBER
	HLRZ	P2,P1		;P1 WILL CONTAIN THE LOWEST ADDRESS NEEDED CLEAR
	MOVEI	P1,(P1)		;CLEAR LEFT HALF OF P1
	ADDI	P2,(P1)		;P2 THE HIGHEST
	MOVEI	J,JBTMAX
LOCK2:	CAIN	T1,(J)		;DON'T CHECK JOB BEING LOCKED
	JRST	LOCK4
	HRRZ	P3,JBTADR(J)	;IS THIS JOB IN THE WAY?
	JUMPE	P3,LOCK4	;CAN'T POSSIBLY BE IF NOT IN CORE
	CAIGE	P3,(P1)		;DOES THIS JOB START BELOW THE AREA?
	JRST	LOCK3		;YES
	CAIL	P3,(P2)		;DOES IT START IN THE AREA?
	JRST	LOCK4		;NO - ITS NOT IN THE WAY
	JRST	LOCK9		;IN THE ROAD - MOVE IT
LOCK3:	HLRZ	P4,JBTADR(J)	;STARTED BELOW BUT DOES IT EXTEND INTO AREA
	ADD	P3,P4		;P3_LAST LOCATION IN THIS JOB
	CAIL	P3,(P1)
	JRST	LOCK9		;AN OFFENDER - MOVE HIM
LOCK4:	SOJG	J,LOCK2		;EVERY JOB IS A CANDIDATE
	HRRZ	J,LOCK		;THE DESIRED AREA IS FREE
	HRRZ	P3,JBTADR(J)	;IS THE JOB BEING LOCKED ABOVE OR IN THE AREA
	CAIG	P1,(P3)
	JRST	LOCK10		;YES - LET THE SHUFFLER MOVE IT DOWN
	MOVE	R,JBTDAT(J)	;ANYACT REQUIRES R
	PUSHJ	P,ANYACT	;ANY ACTIVE I/O DEVICES?
	POPJ	P,		;YES, TRY AGAIN NEXT TIC
	HLRZ	T4,LOKREL	;NO - COMPUTE PARAMETERS TO MOVE IT UP
	ASH	T4,W2PLSH
	MOVEI	T4,1(T4)	;T4_NUMBER OF 1K BLOCKS IN THE SEGMENT
	PUSH	P,T4		;SAVE IT FOR LATER
	MOVE	T3,JBTADR(J)	;T3_CURRENT PROTECTION/RELOCATION FOR THE SEGMENT
	MOVEI	P1,0		;RETURN CURRENT CORE TO FREE POOL
	PUSHJ	P,CORST1
	HRLZ	P1,JBTADR(J)	;SET BLT POINTER
	ADD	P1,JBTADR(J)
	HRRI	P1,(P2)
	AOBJN	P1,.+1
IFN FTMEMPAR,<			;MEMORY PARITY?
;THE FOLLOWING SYMBOLS ARE USED BY THE APR MEMORY PARITY ERROR INTERRUPT
; ROUTINE WHICH HAPPENS AT HIGH PRIORITY PI LEVEL
	MOVEM	J,.C0LSB##	;FOR PARITY CHECK
	XP	BLTAC,P1
>
	MOVE	T4,(P)		;T4_NUMBER OF 1K BLOCKS TO MOVE
LOCK5:	SUB	P1,[XWD PAGSIZ,PAGSIZ]
	PUSH	P,P1		;SAVE IN CASE INTERRUPTED
LOKINS::BLT	P1,(P2)		;MOVE UP A 1K BLOCK
	SUBI	P2,PAGSIZ	;NEXT 1K IS 1K LOWER
	POP	P,P1		;RESTORE POINTER
	SOJG	T4,LOCK5	;MOVE NEXT BLOCK
	POP	P,T4		;RESTORE T4 FOR UPDATING CORTAB
	PUSH	P,T3		;SAVE T3 FOR DIDDLE
	HRRI	T3,1(P2)	;T3_NEW RELOCATION
	MOVEI	P1,2		;MARK CORE AS IN USE
	PUSHJ	P,CORST1
	MOVE	R,T3		;SET PARAMETERS FOR DIDDLE
	POP	P,T4
	MOVEI	T3,(T3)		;CLEAR LH OF T3
	PUSHJ	P,DIDLE		;RELOCATE JOB DATA AREA
	 JFCL			;ALWAYS SKIP RETURN
	JRST	LOCK6
LOCK5A:	MOVE	R,LOKREL	;WHERE THE SEGMENT IS
	MOVEI	P1,6		;INDICATE THE SEGMENT IS LOCKED
	PUSHJ	P,CORST0	;TURN THE BITS ON IN CORTAB
LOCK6:	MOVE	J,LOCK
	MOVSI	P1,NSWP!NSHF	;SEE THAT JOB STAYS PUT AFTER ALL THAT WORK
	IORM	P1,JBTSTS(J)
	HLRZM	J,LOCK		;LOCK_LOW SEGMENT# OR 0 IF DONE
IFN FT2REL,<
	TLNN	J,-1		;DONE?
>
	JRST	LOCK16		;YES
IFN FT2REL,<
	HLRZ	P1,JBTADR(J)	;CALCULATE WHERE TO PUT THE LOW SEGMENT
	ADD	P1,JBTADR(J)	;P1_HIGH SEGMENT PROTECTION+RELOCATION
	HRRZS	P1		;P1 FIRST LOCATION AOBVE THE JOB
	ADDI	P1,1
	HRRZ	P3,JBTADR(J)
	HLRZ	J,J		;J_LOW SEGMENT NUMBER
	HLRZ	P2,JBTADR(J)	;P2_SIZE OF THE LOW SEGMENT
IFN FTSWAP,<
	JUMPN	P2,LOCK7	;IS THE LOW SEGMENT IN CORE?
	LDB	P2,IMGIN	;NO, BUT WHEN IT COMES IN
	ASH	P2,P2WLSH	;IT WILL HAVE THIS RELOCATION
	SUBI	P2,1
>
LOCK7:	CAME	P1,MEMSIZ	;HIGH SEGMENT AT TOP OF CORE?
	JRST	LOCK8		;NO, LOCK LOW SEGMENT ABOVE THE HIGH SEGMENT
	HRRZ	P1,P3		;YES, PUT LOW SEGMENT BELOW IT
	SUBI	P1,1(P2)	;PUT IT AT MEMSIZ - THE SUM OF THE SEGMENT SIZES
LOCK8:	HRLI	P1,(P2)		;SET LOW SEGMENT PROTECTION
	MOVEM	P1,LOKREL
	JRST	LOCK1		;GO MAKE A HOLE AND LOCK IT THERE
>
LOCK9:	SKIPN	P3,HOLEF	;JOB IN DESIRED AREA, MOVE IT
	JRST	LOCK11		;TRY SHUFFLING FIRST
	HLRZ	P4,JBTADR(J)	;THERE IS A HOLE, WILL THE JOB FIT IN IT?
	ADD	P3,P4
	CAIGE	P3,(P1)		;WILL SHUFFLING GET IT OUT OF THE AREA
	CAMLE	P4,HOLES	;AND IS THE HOLE BIG ENOUGH
	JRST	LOCK11		;NO TO EITHER QUESTION, SWAP IT
LOCK10:	PUSHJ	P,SHFLOP	;MAKE A HOLE
	SKIPE	SHFWAT		;SHUFFLER WAITING FOR I/O TO STOP?
	POPJ	P,		;YES - TRY AGAIN NEXT TIC
	JRST	LOCK0		;GO SEE IF AREA IS EMPTY NOW
LOCK11:
IFN FT2REL,<
	CAIG	J,JOBMAX	;IS IT A HIGH SEGMENT?
>
IFN FTSWAP,<
	JRST	FORCE0		;NO - JUST SWAP IT
>
IFE FTSWAP,<
	JRST	LOCK4
>
IFN FT2REL,<
	MOVE	P1,JBTSTS(J)	;SINCE ITS A HIGH SEGMENT, MAY BE DORMANT OR IDLE
IFN FTSWAP,<
	TRNE	P1,ICCMSK	;IS IT?
	JRST	LOCK12		;SWAP ALL LOW SEGMENTS SHARING IT
>
IFE FTSWAP,<
	TRNN	P1,ICCMSK	;IT IS?
>
LOK11A:	PUSHJ	P,FREC4		;YES - GO DELETE IT
IFN FTSWAP,<
	JRST	FORIDL		;NO - MUST BE SWAPPED OUT
>
IFE FTSWAP,<
	JRST	LOCK4
>
	JRST	LOCK0		;SKIP RETURN FROM FREC2, TRY AGAIN
IFN FTSWAP,<
LOCK12:	MOVE	T2,J		;SAVE HIGH SEGMENT NUMBER
	MOVE	J,HIGHJB	;FIND A JOB SHARING IT
LOCK13:	SKIPE	T1,JBTSGN(J)	;DOES THIS JOB HAVE A HIGH SEGMENT?
	CAIE	T2,@T1		; AND IS IT THE ONE WE WANT TO SWAP?
	JRST	LOCK14		;NO
	SKIPE	JBTADR(J)	;YES. IS THIS JOB IN CORE?
	JRST	LOK13A		;YES. SEE IF WE CAN SWAP IT OUT
	MOVE	T2,J		;SAVE JOB BEFORE CALLING DECCNT
	EXCH	J,T1		;J=HIGH SEG T1=JOB NUMBER
	PUSHJ	P,DECCNT##	;BE SURE IN CORE COUNT IS DECREMENTED
	  JFCL			;ALREADY DECREMENTED OR JUST WENT TO ZERO
	HRRZS	J		;GET RID OF HIGH SEG FLAGS
	JUMPE	T1,LOK11A	;NO MORE JOBS, GO SWAP HIGH SEGMENT
	EXCH	J,T2		;GET READY TO LOOK AT NEXT JOB
	JRST	LOCK14		; AND GO DO IT
LOK13A:	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	LOCK14		; SO LOOK AT NEXT JOB
	TRNE	P1,ICCMSK-1	;IN CORE COUNT =1?
	CAME	J,LOCK		;NO, THIS THE JOB BEING LOCKED?
	JRST	FORCE0		;NO. SWAP IT OUT
LOCK14:	SOJG	J,LOCK13	;TRY NEXT JOB
	SETZM	LOCK		;GIVE UP
	STOPCD	CPOPJ##,DEBUG,ICW, ;INCORE COUNT IS WRONG
>
>
LOCK16:	MOVEI	P1,LOK		;TURN OFF LOK BIT SO SCHEDULAR WILL RUN THE JOB
	MOVE	J,LASLOK	;GET JOB #
	ANDCAM	P1,JBTSTS(J)
	MOVSI	P1,SWP		;IF HIGH SEGMENT NOT IN CORE SET SWP
	SKIPG	P2,JBTSGN(J)	;DOES IT HAVE A HIGH SEGMENT?
	POPJ	P,		;NO, CANNOT BE SWAPPED
	SKIPN	JBTADR(P2)	;HIGH SEGMENT IN CORE?
	IORM	P1,JBTSTS(J)	;NO, MARK THE JOB AS SWAPPED SO SWAPPER
				;  WILL SWAP IT IN
	POPJ	P,		;RETURN TO THE SCHEDULAR

SUBTTL CORE1 - PHYSICAL CORE ALLOCATION ROUTINES

;ROUTINE TO SET UP T3 AND T4 FOR THE SHUFFLER WHEN THE PLACE
;THAT THE JOB CAN BE LOCKED IS NOT NECESSARLY WHERE THE SHUFFLER
;WOULD PUT IT
;
;	CALLING SEQUENCE -
;
;		PUSHJ	P,SETLPR
;		...			;RETURN HERE WITH T3 AND T4 SET
;		...			;RETURN HERE WHEN THIS JOB IS NOT 
;					;BEING LOCKED
;
EXTERNAL FIT
SETLPR:
IFN FTSWAP,<
	SKIPE	FIT		;SWAP-IN IN PROGRESS
	JRST	CPOPJ1		;YES, LET CORE1 ALLOCATE CORE
>
	SKIPE	T2,LOCK		;ANY JOB CURRENTLY BEING LOCKED?
	CAIE	J,(T2)		;AND IS IT THE JOB THE SHUFFLER IS WORKING ON
	JRST	CPOPJ1		;NO TO EITHER QUESTION, GIVE SKIP RETURN
IFE FTSWAP,<
	SETZM	LOKREL
	JRST	CPOPJ1
>
IFN FTSWAP,<
	SKIPN	JBTADR(T2)	;IS JOB BEING LOCKED SWAPPED?
	JRST	CPOPJ1		;YES, LET CORE1 ALLOCATE CORE
	HRRZ	T3,LOKREL	;THIS JOB IS BEING LOCKED
	HLRZ	T4,LOKREL	;RETURN T3 AND T4
	SETZM	LOKREL		;SIGNAL JOB HAS BEEN MOVED INTO PLACE
	POPJ	P,		;AND GIVE NON-SKIP 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

	TDNN	P1,JBTSTS##(J)	;LOW SEG LOCKED?
	JRST	CPOPJ1##	;NO, GIVE YES (NOT LOCKED) RETURN
IFN FT2REL,<			;2 RELOC REG FEATURE?
	SKIPLE	P2,JBTSGN##(J)	;NO, DOES JOB HAVE A HIGH SEG?
	TDNE	P1,JBTSTS(P2)	;YES, IS IT LOCKED?
	POPJ	P,		;NO, GIVE BOTH LOCKED RETURN
>
	JRST	CPOPJ1		;YES, GIVE NEITHER OR ONLY ONE LOCKED RETURN
 
SUBTTL UUOCON - UUO HANDLING ROUTINES

;ROUTINE TO SET UP CALL TO SWAPPER FOR LOCKING A JOB IN CORE
;CALLED FROM ACTIVATE UUO
;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, RTJ NOT SET)

INTERNAL LOKJOB,UNLOCK,UNLOK.
EXTERNAL CORLIM,CORMAX,CORST2,HIGHJB,HOLSRP,HOLSRT,JOB
EXTERNAL CAREQ,CAWAIT,MEMSIZ,WSCHED,CAAVAL,CPOPJ1,TPOPJ,STOTAC

LOKJOB:	PUSHJ	P,SAVE4##	;SAVE P1-P4
	JUMPL	T1,[MOVEI T1,0
		    JRST STOTAC##]
IFN FTPRV,<
	MOVE	P1,T1		;SAVE USER ARG
	MOVSI	T1,PVLOCK	;DOES THIS JOB HAVE LOCKING PRIVILEDGES?
	PUSHJ	P,PRVBIT##	;NONSKIP MEANS BIT IS SET OR 1,2
	SKIPA			;OR JACCT
	JRST	ERROR1		;NO, ERROR RETURN (ERROR CODE=1)
	MOVE	T1,P1		;RESTORE
>
	MOVSI	P1,NSHF!NSWP
	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,<
	SKIPG	T2,JBTSGN(J)	;DOES JOB HAVE A REAL HIGH SEGMENT
	JRST	ERROR0		;NO
	TDNE	P1,JBTSTS(T2)	;IS THE HIGH SEGMENT LOCKED?
	JRST	LERROR		;NO, NOTHING TO DO
	HRRZ	J,T2
>
LOKJ01:	TLZ	T1,-1-IFN FT2REL,<LKB>
	MOVEI	F,0		;INDICATE NO DDB
	PUSHJ	P,CAWAIT	;YES, WAIT UNTIL ITS DONE
	SETZB	P4,T4
	PUSH	P,J
IFN FTSWAP,<
	MOVEI	J,1		;FIND THE LARGEST JOB NOT LOCKED
LOKJ02:	MOVEI	P1,0
	MOVE	P2,JBTSTS(J)	;IS THIS JOB LOCKED?
	CAMN	J,JOB		;DON'T CONSIDER JOB BEING LOCKED
	JRST	LOKJ04
	TLNN	P2,NSHF!NSWP
	PUSHJ	P,SIZSEG	;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	P3,JOB		;GET OUR JOB #
	HRRZ	P3,JBTSGN(P3)	;GET OUR HISEG #
	TLNE	T1,LKB		;IF LOCKING OUR HISEG
	CAIE	P3,(J)		;AND HE IS SHARING IT
	TDNE	P2,JBTSTS(J)	;OR HIGH SEG ALREADY LOCKED?
	JRST	LOKJ03		;YES, IGNORE THIS HISEG
	PUSH	P,P1		;COUNT THE SIZE OF THE HIGH SEGMENT
	PUSHJ	P,SIZSEG
	POP	P,P2		;RESTORE SIZE OF LOW SEGMENT
	ADDI	P1,(P2)		;P1_SIZE OF THE JOB
>
LOKJ03:	CAMLE	P1,P4		;LARGEST SO FAR?
	MOVE	P4,P1		;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)
>
	HLR	T1,JBTADR(J)	;CALCULATE THE SIZE OF THIS JOB
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
	SKIPG	P1,JBTSGN(J)	;JOB HAVE A HIGH SET?
	JRST	LOKJ05		;NO
	TDNN	P2,JBTSTS(P1)	;IS HIGH SEG LOCKED?
	JRST	LOKJ4A		;NO, GO FINISH SETTING UP P1.
	MOVSI	T3,LOKSEG	;YES, INSURE LOKSEG GETS SET FOR HI SEG.
	IORM	T3,JBTSGN(J)
	JRST	LOKJ05		;ALREADY LOCKED SO SKIP P1 SETUP
LOKJ4A:	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:	MOVE	T3,MEMSIZ	;WILL THE JOB FIT AT THE TOP OF CORE?
	SUBI	T3,1(T1)	;WHERE IT WOULD START IF IT WILL
	PUSH	P,T1		;SET BYTE POINTER FOR MEMSIZ-SEGSIZ
	PUSHJ	P,CORST2
	MOVE	P1,T1		;HOLSRC REQUIRES BYTE POINTER IN P1
	POP	P,T1		;RESTORE JOB SIZE
IFN FTSWAP,<
	MOVEI	P3,1		;HOLES OR TIME-SHARING JOBS THAT CAN BE SWAPPED
>
IFE FTSWAP,<
	MOVEI	P3,0		;ONLY HOLES IF NON-SWAPPING SYSTEM
>
	PUSHJ	P,HOLSRP
	JRST	LOKJ06		;NOT ENOUGH ROOM
	MOVE	P2,MEMSIZ	;IF IT WILL FIT IT WILL GO AT THE TOP OF MEMORY
	MOVE	P3,(P)		;CALCULATE WHERE IT MUST GO
	HLRZ	T3,JBTADR(P3)
	SUBM	P2,T3		;PUT IT AT MEMSIZ-THIS SEGMENTS SIZE
IFN FTSWAP,<
	CAMN	P2,HOLTOP
	SOJA	T3,LOKJ07	;IN THE LARGEST HOLE BUT STILL MIGHT FIT
>
	SOJA	T3,LOKJ09	;LOCK IT
LOKJ06:
IFE FTSWAP,<
	MOVEI	P3,1
	MOVEI	T1,0
>
	PUSHJ	P,HOLSRT	;FIND A HOLE IT WILL FIT IN
	STOPCD	.,STOP,NHF,	;++NO HOLE TO FIT
IFN FTSWAP,<
	CAMGE	T3,HOLEF1	;IS THE HOLE FOUND IN THE LARGEST HOLE?
	JRST	LOKJ09		;NO, LOCK THE JOB THERE
LOKJ07:	MOVE	P2,HOLTOP	;WILL THIS JOB FIT?
	SUB	P2,HOLEF1	;P2_SIZE OF THE BIGGEST CONTIGOUS HOLE
	SUBI	P2,1(T1)	;SUBTRACT OUT THE ROOM THIS JOB WILL TAKE
	CAML	P2,CORMIN	;WILL CORMAX BE LESS THAN CORMIN?
	CAILE	P4,(P2)		;WILL THE LARGEST TIME-SHARING JOB STILL FIT?
	JRST	LOKJ08		;NO, BUT IT MIGHT STILL FIT HIGHER UP
	MOVEM	P2,MAXMAX##	;LARGEST LEGAL CORMAX
	HRRZ	P3,CORLIM	;CORMAX_
	ASH	P3,12
	CAILE	P3,(P2)		;MIN(ADMINSTRATION DEFINED MAXIMUM JOB SIZE,
	MOVE	P3,P2		;SIZE OF THE LARGEST CONTIGOUS HOLE THAT
	MOVEM	P3,CORMAX	;CAN BE MADE BY SWAPPING EVERYTHING SWAPPABLE)
	JRST	LOKJ09		;GO LOCK IT
LOKJ08:	PUSH	P,P2		;SAVE P2 IN CASE OF ERROR RETURN
	ADDI	T3,1(T4)	;START THE SEARCH ABOVE THE BIGGEST HOLE
	PUSHJ	P,HOLSRP	;IS THERE ANOTHER HOLE IT WILL FIT IN?
	JRST	ERROR2		;NO, POP OFF JUNK AND GIVE ERROR RETURN
	POP	P,P2		;POP OFF JUNK SINCE OK RETURN
	ADDI	T3,PAGSIZ##	;T3 = START OF THE HOLE
>
LOKJ09:	POP	P,P2		;SET LOCK AND LOKREL
	MOVE	J,JOB		;RESTORE JOB NUMBER
	MOVSI	T1,LOKSEG	;IF LOCKING THE HIGH SEGMENT, SET HIGH SEGMENT
				; LOCKED FOR THIS JOB BIT
	CAILE	P2,JOBMAX	;IS THE HIGH SEGMENT BEING LOCKED
	IORM	T1,JBTSGN(J)	;YES, LIGHT THE BIT FOR UNLOCK
	MOVEM	P2,LOCK
	HLL	T3,JBTADR(P2)	;T3_WHERE TO PUT THIS SEGMENT
	MOVEM	T3,LOKREL
	MOVEI	P2,LOK		;SET LOK SO SCHEDULAR WON'T RUN
	MOVEM	J,LASLOK	;SAVE JOB NUMBER (FOR DEBUGGING AND SO
				; AND SO LOCK CAN TURN OFF THE LOK BIT (HIGH
				; SEGMENT ONLY LOCK)
	IORM	P2,JBTSTS(J)	;THE JOB WHILE ITS BEING LOCKED
	PUSHJ	P,WSCHED	;RUN LOCK CODE WHEN SWAPPER IS IDLE
IFN FTSWAP,<
	PUSHJ	P,LRGHOL	;COMPUTE THE EXTENT OF THE NEW BIGGEST HOLE
>
	PUSHJ	P,RABSAD	;RETURN ABSOLUTE ADDRESS OF SEGMENTS
LOKJ10:	PUSHJ	P,CAFREE##	;DECREMENT THE USE COUNT
				; AND FLAG THIS RESOURCE AS AVAILABLE
	JRST	STOTAC		;STORE ERROR CODE OR ADDRESS AND RETURN
;
;ROUTINE TO RETURN THE ABSOLUTE ADDRESS OF THE LOW AND HIGH SEGMENTS
;OF A JOB
;
;	CALLING SEQUENCE -
;
;		PUSHJ	P,RABSAD
;		...			;RETURN HERE, LEFT HALF OF T1 CONTAINS
;					;ABSOLUTE ADDRESS OF HIGH SEGMENT
;					;SHIFTED RIGHT NINE BITS
;					;RIGHT HALF OF T1 CONTAINS ABSOLUTE
;					;ADDRESS OF LOW SEGMENT 
;					;SHIFTED RIGHT NINE BITS
;

RABSAD:	MOVE	J,JOB
	HRRZ	T1,JBTADR(J)	;LOW SEGMENT ADDRESS
	LSH	T1,-11		;SHIFTED RIGHT NINE BITS
	MOVEI	T2,0
IFN FT2REL,<
	SKIPN	TWOREG		;TWO REGISTER SOFTWARE?
	JRST	RABSA0		;NO
	SKIPLE	T3,JBTSGN(J)
	HRRZ	T2,JBTADR(T3)	;HIGH SEGMENT ADDRESS IF THERE IS ONE
	LSH	T2,-11		;SHIFTED RIGHT NINE BITS
>
RABSA0:	HRLI	T1,(T2)		;T1_RH(JBTADR(JBTSGN(J))/2**9,,RH(JBTADR(J))/2**9
	AOS	-1(P)		;OK RETURN TO USER
	POPJ	P,		;RETURN

;
;ROUTINES TO GIVE ERROR RETURNS
;

LERROR:	MOVSI	T1,LOKSEG	;INDICATE THE HIGH SEGMENT IS LOCKED
	IORM	T1,JBTSGN(J)	;FOR THIS JOB
ERROR0:	PUSHJ	P,RABSAD	;RETURN ABSOLUTE ADDRESS
	JRST	STOTAC
IFN FTPRV,<

ERROR1:	MOVEI	T1,LKERR1	;NOT PRIVILEGED
	JRST	STOTAC		;TELL THE USER
>
IFN FTSWAP,<

ERROR2:	MOVEI	T1,LKERR2	;NOT ENOUGH CORE FOR T1-S JOBS
	POP	P,T2		;DETERMINE REASON FOR FAILURE
	CAMGE	T2,CORMIN	;CORMAX WOULD HAVE BEEN LESS THAN CORMIN
ERROR3:	MOVEI	T1,LKERR3	;YES, ERROR CODE 3
	POP	P,T2		;POP OFF JUNK
	MOVE	J,JOB		;RESTORE JOB NUMBER
	JRST	LOKJ10		;FREE UP RESOURCE
>
;
;ROUTINE TO CALCULATE THE AMOUNT OF CORE WHICH MUST BE
;AVAILABLE IF THIS SEGMENT IS TO RUN
;
;	CALLING SEQUENCE -
;
;		PUSHJ	P,SIZSEG
;		...			;RETURN HERE, P1 CONTAINS AMOUNT NEEDED
;

IFN FTSWAP,<
SIZSEG:	LDB	P1,IMGIN	;COUNT CORE SWAPPED OUT OR MARKED TO GO
	JUMPE	P1,SIZS01	;NONE SWAPPED, WORRY ABOUT WHATS IN CORE
	ASH	P1,P2WLSH	;NEED AT LEAST THIS MUCH FOR JOB TO RUN
	POPJ	P,
SIZS01:	HLRZ	P2,JBTADR(J)
	HRRZ	P3,JBTADR(J)
	CAMGE	P2,HOLEF1	;IS THE SEGMENT BELOW THE HOLE?
	POPJ	P,		;YES, THAT CORE IS AVAILABLE
	ADD	P3,P2
	CAMG	P3,HOLTOP	;IS THE SEGMENT ABOVE THE HOLE?
	MOVEI	P1,1(P2)	;NO, ACCOUNT FOR USAGE
	POPJ	P,
>
;
;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 LOW AND HIGH SEG
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
	MOVE	T1,-ZZ(P)	;RESTORE ARGUMENT
	HRROS	-ZZ(P)		;FLAG THAT CORE HAS CHANGED (SO CALL LRCHOL)
IFN FT2REL,<
UNLO01:	TLNE	T1,LKB		;UNLOCK THE HIGH SEGMENT?
	SKIPN	TWOREG		;TWO SEGMENT HARDWARE?
	JRST	UNLO05		;NO
	MOVSI	P2,LOKSEG
	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
	MOVE	T1,HIGHJB	;IS ANOTHER JOB SHARING THE HIGH SEGMENT?
UNLO02:	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 SEG LOCKED?
	JRST	UNLO05		;NO, DO NOT UNLOCK HIGH SEG
	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
	SKIPL	(P)		;HAS LOCKED CORE CHANGED?
	JRST	TPOPJ##		;NO, REMOVE ARG AND RETURN
IFN FTSWAP,<
	PUSHJ	P,LRGHOL	;SET EXTENT OF THE LARGEST HOLE
	MOVEM	T4,MAXMAX##
	AOS	MAXMAX##	;LARGEST LEGAL CORMAX##
	HRRZ	P1,CORLIM	;AND ADJUST CORMAX
	ASH	P1,P2WLSH
	CAILE	P1,1(T4)	;TO CORLIM OR SIZE OF HOLE
	MOVEI	P1,1(T4)	;WHICH EVER IS SMALLER
	MOVEM	P1,CORMAX
>
	JRST	TPOPJ##		;REMOVE ARG AND RETURN

FRELOK:
IFN FTMETR,<			;RELEASE ANY METER POINTS EFFECTED
	PUSHJ	P,METREL##
>
	ANDCAM	P4,JBTSTS(J)	;TURN OFF NSHF AND NSWP
	MOVE	R,JBTADR(J)	;WHERE IT IS NOW
	MOVEI	P1,5		;SET CORE STATE TO INUSE BUT NOT LOCKED
				; DO NOT CHANGE COUNT OF FREE+DORMANT+IDLE CORE
				; SINCE THIS IS ONLY A REASSIGNMENT
	PJRST	CORST0##	;CHANGE SYSTEM CORE TABLE TO ASSIGNED
				; BUT NOT LOCKED
;
;ROUTINE TO FIND THE LARGEST CONTIGOUS BLOCK OF CORE THAT CAN BE MADE
;BY SWAPPING EVERY THING SWAPPABLE
;
;	CALLING SEQUENCE -
;
;		PUSHJ	P,LRGHOL
;		...			;RETURN HERE WITH HOLEF1 AND HOLTOP
;					;SET TO THE EXTREMITIES OF THE HOLE
;

IFN FTSWAP,<
LRGHOL:	MOVEI	P3,1		;LOOK FOR HOLES OR TIME-SHARING JOBS
	MOVEI	T1,-1		;GET THE SIZE OF THE HOLE FIRST
	PUSHJ	P,HOLSRT
	MOVEI	T1,-1(P2)	;FOUND OUT HOW BIG IT IS
	PUSHJ	P,HOLSRT	;NOW FIND OUT WHERE IT IS
	JFCL			;ALWAYS SKIP RETURN
	MOVEM	T3,HOLEF1	;HOLEF1_THE BOTTOM OF THE HOLE
	ADDI	T3,1(T4)
	MOVEM	T3,HOLTOP	;HOLTOP_THE TOP OF THE HOLE + 1
	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