Trailing-Edge
-
PDP-10 Archives
-
decuslib20-03
-
decus/20-0081/vtmast.mac
There is 1 other file named vtmast.mac in the archive. Click here to see a list.
TITLE VTMAST -- MASTER PART OF VTTAM SYSTEM
SUBTTL MASTER STOARGE AND CONSTANTS
;TONY LAUCK 2 JUN 71
;VTMAST IS LOADED WITH A COBOL APPLICATION PROGRAM AND IS CALLED
;BY THE APPLICATION PROGRAM WITH ENTER MACRO STATEMENTS.
;VTMAST INTERPRETS THESE CALLS AND COMMUNICATES WITH THE SLAVE JOBS
;THAT DO THE ACTUAL TERMINAL PROCESSING. THIS COMMUNICATION IS VIA
;A SHARED HIGH-SEGMENT. THE COBOL PROGRAM MUST THEREFORE USE A NON-
;REENTRANT COPY OF LIBOL.
;VTMAST COMMUNICATES WITH THE SLAVE JOBS BASED ON VTTAM TERMINAL
;NUMBER, AS REFERENCED BY THE COBOL PROGRAM. IT IS NOT CONCERNED
;WITH MONITOR TTY NUMBERS. THE ACTUAL MAPPING BETWEEN VTTAM TERMINAL
;NUMBERS, SLAVE JOBS, AND MONITOR TTY NUMBERS IS CONTROLLED BY THE
;SLAVE JOBS.
;VTTAM IS HOWEVER CONCERNED WITH THE MONITOR JOB NUMBERS OF SLAVES
;HANDLING EACH VTTAM TERMINAL NUMBER. IT NEEDS THE JOB NUMBER TO
;AWAKEN THE CORRECT SLAVE. SHOULD THE APPLICATION PROGRAM REFER TO
;A VTTAM TERMINAL NUMBER FOR WHICH THERE IS NO RUNNING SLAVE JOB
;THE MASTER (AND HENCE COBOL PROGRAM) WILL HANG.
;ON START UP THE MASTER AND SLAVES MAY BE STARTED IN ANY ORDER. STARTING
;THE MASTER LAST WILL BE MOST EFFECIENT.
;ON SHUT DOWN, THE MASTER STORES THE CLOSING TIME IN THE SHARED
;SEGMENT. AFTER THIS IS DONE, THE SLAVES AND MASTER MAY BE STOPPED.
;SHOULD THE MASTER OR ANY SLAVE RETURN TO MONITOR LEVEL, ALL
;VTTAM JOBS MUST BE RESTARTED. THIS WILL INSURE CORRECT INITIALIZATION
;OF THE SHARED HIGH SEGMENT AS WELL AS PROPER SYNCHRONIZATION
;BETWEEN MASTER AND SLAVES. FAILURE TO DO THIS WILL RESULT IN
;ERRATIC OPERATION, INCLUDING POSSIBLE HUNG CONDITIONS, HALTS, OR
;LOST TRANSACTIONS.
;ACCUMULATORS
A=1 ;G.P. AC'S
B=2
C=3
D=C+1
T=5 ;TEMPS
T1=T+1
;CALLING SEQUENCE AC'S
TT=7 ;VTTAM TERMINAL NUMBER
L=10 ;LINE NUMBER ON CRT SCREEN
SS=11 ;WORD ADDRESS OF USERS SCREEN BUFFER
NW=12 ;NUMBER OF FULL WORDS IN USERS SCREEN BUFFER
NC=13 ;NUMBER OF ODD CHARACTERS IN USERS BUFFER
Q=16 ;POINTER TO CALLING SEQUENCE ARGUMENTS
W=14 ;HOLDS WAKE ENABLE BITS FOR HIBER UUO
P=17 ;PUSH DOWN POINTER
;VT05 PARAMENTERS
SCRCOL=^D72 ;COLUMNS PER LINE OF VT05
SCRLIN=^D20 ;LINES PER SCREEN OF VT05
INTERN SCRCOL,SCRLIN ;FORCE THESE TO MATCH HISEG AND SLAVE
SCRCHR=SCRCOL*SCRLIN ;CHARACTERS PER SCREEN
SCRWDS=<SCRCHR+5>/6 ;WORDS PER SCREEN (DISPLAY-6)
LINWDS=SCRCOL/6 ;WORDS PER LINE
IFN <SCRCOL-<6*LINWDS>>,
<PRINTX NUMBER OF COLUMNS IS NOT A MULTIPLE OF 6>
;LOW SEGMENT STORAGE AREA
QJOBN: BLOCK 1 ;OUR JOB NUMBER SAVED HERE
QWORD: BLOCK 1 ;WORD POINTER TO OUR QBIT ENTRY
QMASK: BLOCK 1 ;BIT MASK TO OUR QBIT ENTRY
PSAV: BLOCK 1 ;SAVE AREA FOR P DURING GETSEG UUO.
; ALSO A FLAG. NON-ZERO MEANS THAT
; THE HIGH SEGMENT IS SET UP.
;HIGH SEGMENT LOCATIONS
EXTERN SHZERL,SHZERH ;LIMITS OF DATA IN HISEG FOR ZEROING
EXTERN JOBTAB ;TABLE INDEXED BY TERMINAL #
; GIVING SLAVE MONITOR JOB #
EXTERN MAXTRM ;MAX NUMBER OF VTTAM TERMINALS
EXTERN STDAY ;DATE SYSTEM STARTED OR STOPPED
EXTERN STTIME ;STARTING TIME MASTER BEGAN OR STOPPED
;START IF POS, STOP IF NEG.
EXTERN MJOBN ;JOB NUMBER OF MASTER
EXTERN SINFLG ;0 IF INPUT BUFFER FREE
;ELSE TERM NO WHICH FILLED IT
EXTERN SINBF ;SHARED INPUT BUFFER
EXTERN SOUTRM ;0 IF OUTPUT BUFFER EMPTY
; ELSE TERMINAL NUMBER OF DATA IN
; SOUTBF
EXTERN SOUMOD ;TYPE OF OUTPUT REQUEST
;-1 ERASE SCREEN, 0 FULL SCREEN, ELSE
; WRITE LINE
EXTERN SOUTBF ;SHARED OUTPUT BUFFER
EXTERN QREQ ;CRITICAL SECTION SYNC COUNT
EXTERN QBITS ;SLAVE SYNC REQUEST BIT-TABLE
EXTERN AVLINP ;ASSIGNMENT WORD FOR SHARED INPUT BUFFER
EXTERN QININP ;PUTTER FOR QUEUE FOR INPUT BUFFER
EXTERN QOUINP ;TAKER FOR QUEUE FOR INPUT BUFFER
EXTERN QBFINP ;QUEUE AREA FOR INPUT BUFFER
EXTERN QSTINP ;BYTE POINTER TO FIRST INPUT BUFFER
; QUEUE ENTRY
EXTERN QFNINP ;BYTE POINTER TO LAST INPUT BUFFER
; QUEUE ENTRY
;MONITOR STUFF
PRJPRG=2 ;GETTAB TABLE FOR PROJECT PROGRAMMER #'S
NSWTBL=12 ;GETTAB TABLE FOR HIGHEST JOB NUMBER
HIGHJB=20 ;GETTAB ENTRY FOR HIGHEST JOB NUMBER
; CURRENTLY ON SYSTEM
WAKPRJ=1B17 ;WAKE UUO ENABLED FOR PROJECT MATCH
OPDEF PJRST [JRST] ;PUSHJ POPJ CONVENTION
SUBTTL VTTAM CALL PROCESSING
ENTRY VTOPEN,VTCLSE,ERSCR,ERLIN,WRSCR,WRLIN,VTWAIT
;HERE ON VTOPEN
VTOPEN: PUSHJ P,SETSEG ;SET UP THE SHARED DATA SEGMENT
SKIPE STTIME ;ARE WE NOW SAFELY STOPPED?
PUSHJ P,VTCLSE ;IF NOT, DO IMPLIED CLOSE
SETZM SHZERL ;ZERO SHARED SEGMENT
MOVE T,[XWD SHZERL,SHZERL+1]
BLT T,SHZERH
PUSHJ P,MQINIT ;SET UP SHARED QUEUE AREAS
PUSHJ P,UQINIT ;SET UP MASTER'S OWN QUEUE AREA
DATE T, ;STORE DATE FOR START-UP MESSAGE
MOVEM T,STDAY
MSTIME T, ;GET TIME
ADDI T,1 ;ADD 1 IN CASE OF MIDNIGHT
MOVEM T,STTIME ;STORE IT TO START SLAVES
PJRST WAKALL ;WAKE ALL THE SLAVES AND RETURN TO COBOL
;HERE ON VTCLSE (ALSO ON VTOPEN TO DO AN IMPLIED CLOSE).
VTCLSE: PUSHJ P,CHKSEG ;CHECK AND GET HISEG IF NEEDED
DATE T, ;STORE DATE FOR SHUT-DOWN MESSAGE
MOVEM T,STDAY
MSTIME T, ;STORE -(TIME+1) TO SHUT DOWN SLAVES
SETCAM T,STTIME
PUSHJ P,WAKALL ;WAKE ALL SLAVES
PUSHJ P,WSTOP ;WAIT FOR ALL SLAVES TO SHUT DOWN
SETZM STTIME ;LEAVE FACT THAT WE ARE SAFELY DOWN
; IN SHARED SEGMENT FOR NEXT VTOPEN.
POPJ P, ;RETURN
;HERE ON ERSCR CALL
ERSCR: PUSHJ P,GETTNO ;GET TERM-NO AND SET UP Q
PUSHJ P,SETRET ;SET UP RETURN ADDRESS ON STACK
PUSHJ P,GETOBF ;GET CONTROL OF SHARED OUTPUT BUFFER
SETOM SOUMOD ;OUTPUT REQUEST TO SLAVE = ERASE
JRST MOUTPB ;GO FINISH UP
;HERE ON ERLIN CALL
ERLIN: PUSHJ P,GETTNO ;GET TERM-NO
PUSHJ P,GETLNO ;GET LINE-NO
PUSHJ P,SETRET ;SET UP RETURN ADDRESS ON STACK
PUSHJ P,GETOBF ;GET CONTROL OF SHARED OUTPUT BUFFER
SETZM SOUTBF ;BLANK 1ST LINE OF SHARED OUTPUT BUFFER
MOVE T,[XWD SOUTBF,SOUTBF+1]
BLT T,SOUTBF+LINWDS-1
MOVEM L,SOUMOD ;TELL SLAVE WHICH LINE NUMBER
JRST MOUTPB ;GO FINISH UP
;HERE ON WRSCR CALL
WRSCR: PUSHJ P,GETTNO ;GET TERM-NO
PUSHJ P,GETSCR ;GET USER BUFFER AND SET UP RETURN ADR
PUSHJ P,GETOBF ;GET CONTROL OF SHARED OUTPUT BUFFER
SETZM SOUMOD ;TELL SLAVE TO WRITE SCREEN
MOVEI T,SCRWDS ;NUMBER OF WORDS TO COPY = SCREEN SIZE
JRST MOUTPA ;GO COPY AND FINISH UP
;HERE ON WRLIN CALL
WRLIN: PUSHJ P,GETTNO ;GET TERM-NO
PUSHJ P,GETLNO ;GET LINE-NO
PUSHJ P,GETSCR ;GET USER BUFFER AND SET UP RETURN ADR
PUSHJ P,GETOBF ;GET CONTROL OF SHARED OUTPUT BUFFER
MOVEM L,SOUMOD ;TELL SLAVE TO WRITE LINE L
MOVEI T,LINWDS ;NUMBER OF WORDS TO COPY = LINE SIZE
;FALL INTO MOUTPA
;HERE ON WRLIN AND WRSCR TO COPY DATA TO SOUTBF.
MOUTPA: PUSHJ P,CPYOUT ;COPY T WORDS FROM USER BUFFER TO SOUTBF
;HERE ON ALL OUTPUT CALLS TO FLAG SOUTBF FULL, WAKE SLAVE, AND RETURN.
MOUTPB: MOVEM TT,SOUTRM ;TELL SLAVE HE HAS OUTPUT NOW
PJRST WAKSLV ;WAKE SLAVE THEN RETURN TO COBOL
;HERE ON VTWAIT
VTWAIT: PUSHJ P,CHKSEG ;CHECK AND GET HISEG IF NEEDED
SKIPG STTIME ;CHECK FOR VTOPEN CALLED
JRST ILLEG ;IF NOT, ILLEGAL TO CALL VTWAIT
MOVE Q,(P) ;SET UP Q BEYOND 1ST ARG.
ADDI Q,1 ; (CAN'T USE GETTNO, CAUSE USER MAY
; HAVE GARBAGE IN TERM-NO.)
PUSHJ P,GETSCR ;GET USER'S BUFFER AND SET UP RETURN ADR
;(LOOP) HERE WAITING FOR DATA FROM A SLAVE
VTWAI1: SKIPLE TT,SINFLG ;IS THERE DATA YET?
JRST VTWAI2 ;YES, GO PROCESS IT
PUSHJ P,MHIBER ;NO, HIBERNATE
JRST VTWAI1 ; AND CHECK AGAIN
;HERE WHEN THERE IS DATA TO PROCESS. TT HOLDS VTTAM TERMINAL NUMBER.
VTWAI2: MOVEM TT,@-3(Q) ;STORE NUMBER FOR COBOL IN TERM-NO
PUSHJ P,CPYIN ;COPY DATA FROM SINBF TO USER'S BUFFER
SETZM SINFLG ;FLAG INPUT BUFFER EMPTY
PJRST RELINP ;RELEASE INPUT BUFFER
; AND RETURN TO COBOL
SUBTTL COBOL LINKAGE ROUTINES
;SUBROUTINE TO SET UP Q (CALLING SEQUENCE POINTER AC),
;PICK UP VTTAM TERMINAL NUMBER IN TT AND CHECK IT,
;AND FINALLY MAKE SURE VTOPEN HAS BEEN CALLED.
;UPON RETURN, Q IS LEFT POINTING BEYOND FIRST ARG PSEUDO-OP.
;NOTE: THIS SUBROUTINE MUST BE CALLED DIRECTLY FROM MAIN LINE.
GETTNO: PUSHJ P,CHKSEG ;CHECK AND GET HISEG IF NEEDED
SKIPG STTIME ;HAS VTOPEN BEEN CALLED?
JRST ILLEG ;IF NOT, ILLEGAL CALL
MOVE Q,-1(P) ;SET UP Q
SKIPLE TT,@(Q) ;GET AND CHECK TT
CAILE TT,MAXTRM
JRST ILLEG ;IF ILLEGAL T
AOJA Q,CPOPJ ;INCREMENT Q AND RETURN
;HERE ON ILLEGAL CALL BY THE COBOL PROGRAM
ILLEG: OUTSTR [ASCIZ /?ILLEGAL VTTAM CALL/] ;TELL LOSER
EXIT ; AND RETURN TO MONITOR
;SUBROUTINE TO SET UP AND CHECK L (LINE-NO).
;ASSUMES Q IS SET UP ON ENTRY AND RETURNS WITH Q POINTING TO NEXT ENTRY
GETLNO: SKIPLE L,@(Q) ;GET AND CHECK L
CAILE L,SCRLIN
JRST ILLEG ;IF BAD
AOJA Q,CPOPJ ;INCREMENT Q AND RETURN
;SUBROUTINE TO SET UP POINTERS TO USER'S SCREEN BUFFER.
;SS IS SET TO WORD ADDRESS OF SCREEN.
;NW IS SET TO NUMBER OF WHOLE WORDS IN SCREEN.
;NC IS SET TO NUMBER OF ODD CHARACTERS IN SCREEN.
;WHEN DONE, SETRET IS CALLED TO SET UP RETURN ADDRESS ON STACK.
GETSCR: MOVE SS,@(Q) ;GET BYTE POINTER TO SCREEN
IBP SS ;MAKE IT A LDB/DPB POINTER
TLC SS,360000 ;IS IT SYNCHRONIZED?
TLCE SS,360000
JRST ILLEG ;IF NOT AN ERROR
HRRZ SS,SS ;GET ADDRESS OF BUFFER
MOVE T1,@1(Q) ;GET BYTE POINTER TO SCREEN-END
IBP T1 ;MAKE IT A LDB/DPB POINTER
ADDI Q,2 ;SET Q BEYOND THESE TWO ARGUMENTS
MOVEI NC,0 ;ZERO PARTIAL CHARACTER COUNT
;LOOP HERE UNTIL T1 IS A SYNCHRONIZED BYTE POINTER.
GETSC1: TLC T1,360000 ;IS T1 SYNCHRONIZED?
TLCE T1,360000
JRST GETSC2 ;NOT YET
HRRZ NW,T1 ;YES, GET NUMBER OF WHOLE WORDS
SUB NW,SS
JUMPE NC,SETRET ;IF T1 WAS ORIGINALLY SYNCHRONIZED, DONE
ADDI NC,6 ; ELSE MAKE NC THE NUMBER OF ODD CHARS
SUBI NW,1 ; AND REDUCE NUMBER OF FULL WORDS BY 1.
;FALL INTO SETRET
;SUBROUTINE TO SET UP POPJ RETURN TO COBOL PROGRAM.
;THIS ROUTINE IS CALLED WHEN CALLING SEQUENCE ARGUMENTS MUST BE SKIPPED.
;AC Q MUST POINT PAST LAST ARGUMENT, AND PDL MUST BE 1 DEEP.
SETRET: HRRM Q,-1(P) ;FIX UP RETUN ADDRESS
POPJ P, ;RETURN
;HERE IN GETSCR WHEN T1 POINTER IS NOT YET SYNCHRONIZED.
GETSC2: IBP T1 ;INCREMENT IT
SOJA NC,GETSC1 ;COUNT DOWN NC AND TRY AGAIN.
SUBTTL DATA MOVING ROUTINES
;SUBROUTINE TO COPY A LINE OR SCREEN FROM USER BUFFER TO SOUTBF.
;CALLED WITH SS,NW, AND NC SET TO USER'S BUFFER PARAMETERS,
; AND WITH T= NUMBER OF WORDS TO COPY.
;UPON RETURN THE DATA IS COPIED WITH TRUNCATION OR BLANK
; FILL IF APPROPRIATE.
;NC IS CLOBBERED.
CPYOUT: CAMLE T,NW ;T1 = MIN(T,NW)
SKIPA T1,NW
MOVE T1,T
JUMPE T1,CPYOU1 ;IF T1=0, NO FULL WORDS TO COPY
HRLZ B,SS ; ELSE BLT T1 WORDS
HRRI B,SOUTBF
BLT B,SOUTBF-1(T1)
;HERE WHEN ANY FULL WORDS HAVE BEEN COPIED
CPYOU1: JUMPE NC,CPYOU3 ;JUMP IF NO PARTIAL WORD
CAML T1,T ;DO WE BLANK FILL?
POPJ P, ;IF NOT, RETURN
SETZM SOUTBF(T1) ;YES, ZERO PARTIAL WORD
MOVSI A,(POINT 6,0(T1)) ;GET BYTE POINTER TO PARTIAL
ADD A,SS ; WORD IN USER'S BUFFER
MOVE B,[POINT 6,SOUTBF(T1)] ;GET BYTE POINTER TO STOW
; PARTIAL WORD IN SOUTBF
;LOOP HERE COPYING CHARACTER OF PARTIAL WORD
CPYOU2: ILDB C,A ;COPY CHARACTER
IDPB C,B
SOJG NC,CPYOU2 ;COUNT AND LOOP
ADDI T1,1 ;WHEN DONE, COUNT THIS WORD AS FINISHED
;HERE WHEN BLANK FILL IS NEEDED AND ANY PARTIAL WORD HAS BEEN COPIED.
;AT THIS POINT, T1 WORDS ARE DONE.
CPYOU3: CAMGE T1,T ;ANY MORE WORDS?
SETZM SOUTBF(T1) ;IF SO, ZERO THE FIRST ONE
CAIL T1,-1(T) ;1 OR FEWER WORDS TO ZERO?
POPJ P, ;IF SO, WE ARE DONE
MOVEI T1,SOUTBF+1(T1) ; ELSE BLT ZEROS TO REST
HRLI T1,-1(T1)
BLT T1,SOUTBF-1(T)
CPOPJ: POPJ P, ;RETURN (DEFINE COMMON POPJ)
;SUBROUTINE TO COPY SHARED INPUT BUFFER TO USER'S BUFFER
; WITH TRUNCATION OR FILL AS NEEDED.
;CALLED WITH SS, NW AND NC SET TO USER'S BUFFER PARAMETERS.
;UPON RETURN, NC IS CLOBBERED.
CPYIN: MOVE T,SS ;T=ADDRESS OF LAST FULL WORD OF USER'S
ADDI T,-1(NW) ; BUFFER
MOVE B,SS ;BLT WORD FOR SINBF TO USER'S BUFFER
HRLI B,SINBF
CAIL NW,SCRWDS ;IS USER BUFFER SHORTER THEN SINBF?
JRST CPYIN3 ;IF NOT, GO TO COPY AND FILL ROUTINE.
;HERE WHEN USER'S BUFFER IS SHORTER THAN SINBF. WE USE ALL OUR DATA.
JUMPE NW,CPYIN1 ;ANY FULL WORDS AT ALL?
BLT B,(T) ;IF SO, COPY THEM
;HERE WHEN ANY FULL WORDS HAVE BEEN COPIED
CPYIN1: JUMPE NC,CPOPJ ;IF NO ODD CHARACTERS, RETURN
MOVE A,[POINT 6,SINBF(NW)] ;ELSE GET BYTE POINTER TO READ
; ODD CHARACTERS
HRLI T,(POINT 6,0,35) ;MAKE T A BYTE POINTER TO STORE
; ODD CHARACTERS
;LOOP HERE COPYING ODD CHARACTERS.
CPYIN2: ILDB C,A ;COPY A CHARACTER
IDPB C,T
SOJG NC,CPYIN2 ;COUNT ODD CHARS LEFT. LOOP IF NOT DONE
POPJ P, ; ELSE RETURN
;HERE WHEN USER'S BUFFER IS NOT SHORTER THAN SINBF. WE MAY HAVE TO FILL.
CPYIN3: BLT B,SCRWDS-1(SS) ;COPY ALL OF SINBF
CAILE NW,SCRWDS ;MORE FULL WORDS IN USER BUFFER?
SETZM SCRWDS(SS) ;IF SO, ZERO 1ST EXTRA WORD
CAIG NW,SCRWDS+1 ;AT LEAST 2 EXTRA WORDS?
JRST CPYIN4 ;IF NOT, SKIP BLT
MOVEI B,SCRWDS+1(SS) ; ELSE BLT ZEROS TO EXTRA WORDS
HRLI B,-1(B)
BLT B,(T)
;HERE WHEN ANY EXTRA WHOLE WORDS HAVE BEEN ZEROED.
;NOW ZERO ANY ODD CHARACTERS.
CPYIN4: JUMPE NC,CPOPJ ;IF NO ODD CHARACTERS, RETURN
MOVEI C,0 ;GET A ZERO
HRLI T,(POINT 6,0,35) ;MAKE T INTO A BYTE POINTER
; TO LAST WORD OF USER'S BUF
;LOOP HERE ZEROING ODD CHARACTERS AT END OF USER'S BUFFER
CPYIN5: IDPB C,T ;STOW A ZERO CHARACTER
SOJG NC,CPYIN5 ;COUNT DOWN ODD CHARACTERS. LOOP IF MORE
POPJ P, ; ELSE RETURN
SUBTTL SEGMENT CONTROL
;SUBROUTINE TO CHECK IF HI-SEGMENT HAS BEEN CALLED
; AND CALL SETSEG ROUTINE IF NOT.
;PSAV IS USED AS A FLAG. IT HOLDS ACCUMULATOR P DURING THE GETSEG UUO,
; AND SO IS NON-ZERO IF NO GETSEG UUO HAS BEEN DONE.
CHKSEG: SKIPN PSAV ;HAS A GETSEG BEEN DONE YET?
PUSHJ P,SETSEG ;IF NOT, SET UP HIGH SEGMENT
POPJ P, ;RETURN
;SUBROUTINE TO SET UP HIGH SEGMENT.
;A GETSEG IS PERFORMED TO DSK:VTTAM.SHR, AND THEN SETUWP IS CALLED
; TO UNLOCK THE HIGH SEGMENT.
;ALL AC'S EXCEPT P ARE CLOBBERED BY THIS ROUTINE.
;UPON EXIT, PSAV IS SET NON-ZERO, TO INDICATE THAT THIS ROUTINE
; WAS CALLED
SETSEG: MOVEM P,PSAV ;SAVE P DURING GETSEG UUO
MOVEI T,SEGBLK ;GET SHARED SEGMENT
GETSEG T,
HALT . ;COULDN'T GET SEGMENT
MOVE P,PSAV ;RESTORE P
MOVEI T,0 ;UNLOCK SHARED SEGMENT
SETUWP T,
HALT . ;COULDN'T UNLOCK SHARED SEGMENT
POPJ P, ;RETURN
;CONTROL BLOCK FOR USE BY GETSEG UUO
SEGBLK: SIXBIT /DSK/ ;GETSEG DEVICE
SIXBIT /VTTAM/ ;FILE
SIXBIT /SHR/ ;EXT
0
0 ;PPN
0
SUBTTL SYNCHRONIZATION AND QUEUEING
;SUBROUTINE TO AWAKEN SLAVE JOB RUNNING VTTAM TERMINAL TT.
;IF THE SLAVE HAS STARTED UP, THIS ROUTINE RETURNS IMMEDIATELY.
;IF THE SLAVE HAS NOT YET STARTED UP, THIS ROUTINE WAITS FOR HIM.
;CALL PUSHJ P,WAKSLV
;BACK HERE TO WAIT FOR SLAVE
WAKSL1: PUSHJ P,MHIBER ;MASTER HIBERNATES
;FALL INTO WAKSLV TO TRY AGAIN
;ENTER HERE
WAKSLV: SKIPG T,JOBTAB(TT) ;GET SLAVE JOB NUMBER
JRST WAKSL1 ;WAIT IF NONE SET UP YET
WAKE T, ; ELSE WAKE SLAVE.
HALT . ;WAKE FAILED
POPJ P, ;RETURN
;SUBROUTINE TO WAKE ALL VTTAM JOBS.
;CALLED BY MASTER ON VTOPEN AND VTCLSE TO AVOID HUNG CONDITIONS.
;IN ORDER TO REDUCE SWAPPING, ONLY JOBS WITH SAME PPN AS MASTER
;ARE AWAKENED.
WAKALL: GETPPN A, ;GET MASTER PPN
JFCL ;IN CASE OF SKIP RETURN
MOVE T,[XWD HIGHJB,NSWTBL] ;GET HIGHEST JOB # IN USE
GETTAB T,
HALT . ;GETTAB FAILED
;LOOP HERE TO AWAKEN JOB T IF IN SAME PROJECT AS MASTER.
WAKAL1: MOVEI B,PRJPRG ;GET PPN OF JOB T
HRL B,T
GETTAB B,
MOVEI B,0 ;IF GETTAB FAILED, NOT A MATCH!
CAMN B,A ;IS ITS PPN = MASTER'S?
WAKE T, ;IF SO WAKE IT
JFCL ;NO-OP IF NO MATCH OR WAKE FAILED
SOJG T,WAKAL1 ;TRY NEXT LOWEST JOB NUMBER IF NOT DONE
POPJ P, ; ELSE RETURN
;SUBROUTINE FOR MASTER TO HIBERNATE.
MHIBER: MOVSI W,(WAKPRJ) ;SET WAKE ENABLE BITS
HIBER W, ;HIBER UUO
HALT . ;HIBER UUO FAILED
POPJ P, ;OK - RETURN
;SUBROUTINE TO WAIT UNTIL ALL SLAVES ARE SAFELY STOPPED.
;CALLED ON VTCLSE AFTER STTIME IS SET NEGATIVE AND ALL SLAVES
; HAVE BEEN AWAKENED.
WSTOP: MOVEI T,MAXTRM ;SET TO SCAN ALL SLAVES
JRST WSTOP2 ;GO DO SO
;BACK HERE TO WAIT AND THEN CHECK A SLAVE AGAIN
WSTOP1: MOVE W,[WAKPRJ!^D5000] ;HIBERNATE 5 SECONDS OR UNTIL
HIBER W, ; WAKE CALLED.
HALT . ;HIBER UUO FAILED
;(WE CAN'T USE INFINITE HIBERNATE
; BECAUSE SLAVE MAY ALREADY BE GONE)
;(LOOP) HERE TO CHECK SLAVE T.
WSTOP2: SKIPE JOBTAB(T) ;IS SLAVE RUNNING?
JRST WSTOP1 ;IF SO, WAIT A WHILE
SOJG T,WSTOP2 ;IF NOT GO CHECK NEXT SLAVE UNLESS DONE
POPJ P, ;DONE, SO RETURN
;SUBROUTINE TO GET CONTROL OF SHARED OUTPUT BUFFER.
;CALLED BY MASTER PRIOR TO ENTERING A REQUEST TO ENSURE THAT BUFFER IS
;FREE.
;WAITS IF NECESSARY UNTIL IT IS FREE.
GETOBF: SKIPN SOUTRM ;IS OUTPUT BUFFER FREE?
POPJ P, ;IF SO RETURN
PUSHJ P,MHIBER ; ELSE HIBERNATE
JRST GETOBF ; AND TRY AGAIN.
;SUBROUTINE TO RELEASE INPUT BUFFER RESOURCE AND WAKE UP THE
;FIRST WAITER (FCFS) IF ANY.
RELINP: PUSHJ P,GETQ ;SYNCHRONIZE
SETZM AVLINP ;MAKE RESOURCE FREE
MOVE T,QININP ;IS THERE A QUEUED REQUEST?
CAMN T,QOUINP
PJRST RELQ ;NO, LEAVE CRITICAL SECTION AND RETURN
ILDB T,QOUINP ;YES, ASSIGN TO FIRST USER
MOVEM T,AVLINP
WAKE T, ;AWAKEN HIM
HALT . ;WAKE SHOULD NEVER FAIL
MOVE T,QSTINP ;SET QOUINP TO START IF AT END
MOVE T1,QFNINP
CAMN T1,QOUINP
MOVEM T,QOUINP
PJRST RELQ ;LEAVE CRITICAL SECTION AND RETURN
;SUBROUTINES TO SYNCHRONIZE CRITICAL (SHORT) NON-REENTRANT SECTIONS.
;THESE ROUTINES MAY BE CALLED BY ANY JOB SHARING THE HIGH-SEGMENT.
;THE INTENTION IS TO USE THESE ROUTINES TO INTERLOCK ONLY A FEW
;INSTRUCTIONS OF A HIGHER LEVEL QUEUEING SYSTEM, IN MUCH THE MANNER
;THE MONITOR OCCASIONALLY USES CONO PI,PIOFF.
;THE QUEUING DISCIPLINE DEPENDS ONLY ON JOB NUMBER.
;IF THERE IS A CONFLICT THE LOSER(S) ARE BLOCKED, AND AWOKEN
;ACCORDING TO THE ABOVE DISCIPLINE.
;CAUTION: THIS CODE FAILS ON MULTI-PROCESSOR SYSTEMS USING DRUM-SPLIT!
;SUBROUTINE TO GET Q RESOURCE, WAITING IF NECESSARY.
GETQ: MOVE T,QMASK ;SET OUR REQUEST BIT
IORM T,@QWORD
AOSN QREQ ;TRY AND GRAB THE INTERLOCK
ANDCAM T,@QWORD ;WON, SO CLEAR REQUEST BIT
;LOOP THRU HERE WHILE WAITING FOR Q RESOURCE
GETQ1: TDNN T,@QWORD ;HAS OUR REQUEST BIT BEEN CLEARED?
POPJ P, ;YES, RETURN
PUSHJ P,MHIBER ;NO, WAIT UNTIL AWOKEN
JRST GETQ1 ;AND CHECK FOR SPURIOUS WAKES
;SUBROUTINE TO RELEASE Q RESOURCE, WAKING UP A WAITER, IF THERE IS ONE.
RELQ: SOSGE QREQ ;COUNT DOWN USE INTERLOCK
POPJ P, ;-1 MEANS NO WAITERS, RETURN
MOVEI C,3 ;SET TO SCAN ALL QBITS WORDS
;LOOP THRU HERE TO SCAN QBITS LOOKING FOR A 1 BIT
RELQ1: SKIPE T,QBITS(C) ;SEE IF WORD IS ZERO
JFFO T,RELQ2 ;NO, SO FIND FIRST ONE BIT
SOJGE C,RELQ1 ;YES, TRY NEXT WORD UNLESS LAST
HALT . ;SHOULD NEVER HAPPEN
;HERE WHEN A WAITER HAS BEEN FOUND.
RELQ2: MOVN T1,T1 ;CLEAR HIS REQUEST BIT
MOVSI T,400000
LSH T,(T1)
ANDCAM T,QBITS(C)
IMULI C,^D36 ;GET HIS JOB NUMBER
SUB C,T1
WAKE C, ;AWAKEN HIM
HALT . ;WAKE SHOULD NEVER FAIL
POPJ P, ;RETURN
;SUBROUTINE TO INITIALIZE MASTER'S QUEUE DATA
UQINIT: PJOB T, ;GET JOB NUMBER
MOVEM T,QJOBN ;SAVE IT
WAKE T, ;WAKE OURSELF UP
HALT . ;WAKE SHOULD NEVER FAIL
IDIVI T,^D36 ;GET WORD AND BIT FOR THIS NUMBER
ADDI T,QBITS
MOVEM T,QWORD ;SAVE WORD ADDRESS
MOVN T1,T1
MOVSI T,400000
LSH T,(T1)
MOVEM T,QMASK ;BIT MASK
PJRST MHIBER ;DUMMY HIBERNATE TO SET MASTER WAKE
; ENABLES, THEN RETURN
;SUBROUTINE FOR MASTER TO INITIAIZE INTERLOCKS AND QUEUES
;(ASSUMES ALL OF SHARED CORE HAS ALREADY BEEN ZEROED.)
MQINIT: MOVE T,QSTINP ;INITIALIZE QUEUE POINTERS
MOVEM T,QININP
MOVEM T,QOUINP
PJOB T, ;STORE MASTER JOB NUMBER
MOVEM T,MJOBN ; SO SLAVES CAN WAKE HIM.
SETOM QREQ ;MAKE Q RESOURCE FREE
POPJ P, ;RETURN
LIT
END