Trailing-Edge
-
PDP-10 Archives
-
BB-M780B-SM
-
monitor-sources/ipcf.mac
There are 57 other files named ipcf.mac in the archive. Click here to see a list.
; UPD ID= 94, SNARK:<5.1.MONITOR>IPCF.MAC.2, 14-Nov-82 13:59:39 by COBB
;TCO 5.1.1106 - Save T1 and T2 before calls to WAKFRK, prevents ILMNRFs
; UPD ID= 86, FARK:<5-WORKING-SOURCES.MONITOR>IPCF.MAC.3, 5-Aug-82 14:59:25 by MOSER
;EDIT 2643 - More of 2641. Better checking, don't propagate garbage.
; UPD ID= 82, FARK:<5-WORKING-SOURCES.MONITOR>IPCF.MAC.2, 3-Aug-82 16:31:42 by MOSER
;EDIT 2641 - CHECK ONLY IP%CFP IN VALARG
; UPD ID= 400, SNARK:<5.MONITOR>IPCF.MAC.12, 15-Jan-82 15:16:46 by GRANT
;TCO 5.1679 - Create GTPIDL routine to use for obtaining the PID lock
; UPD ID= 25, SNARK:<5.MONITOR>IPCF.MAC.11, 13-Jul-81 13:02:42 by GRANT
;TCO 5.1409 - Fix the locking of the fork lock and the PID lock in MRECV JSYS
; UPD ID= 2198, SNARK:<5.MONITOR>IPCF.MAC.10, 14-Jun-81 10:54:11 by HALL
;FIX PREVIOUS EDIT IN MWAIT
; UPD ID= 2192, SNARK:<5.MONITOR>IPCF.MAC.9, 11-Jun-81 16:50:13 by HALL
;REORDER LOCKS IN MWAIT
; UPD ID= 2062, SNARK:<5.MONITOR>IPCF.MAC.8, 22-May-81 11:16:31 by GRANT
;Again
; UPD ID= 2061, SNARK:<5.MONITOR>IPCF.MAC.7, 22-May-81 10:19:40 by GRANT
;Fix to previous edit - PIDLOK is now PIDLKK
; UPD ID= 2059, SNARK:<5.MONITOR>IPCF.MAC.6, 21-May-81 17:24:47 by SCHMITT
;Tco 5.1341 - Lock up IPCF data base early in PIDJBI
; UPD ID= 1978, SNARK:<5.MONITOR>IPCF.MAC.5, 11-May-81 19:38:32 by ZIMA
;TCO 5.1322 - correct PIDLST initialization for MAXPID odd case.
; UPD ID= 1858, SNARK:<5.MONITOR>IPCF.MAC.4, 21-Apr-81 13:10:50 by SCHMITT
;TCO 5.1291 - Break apart routines MUTFPQ and MUTSPQ
; UPD ID= 1444, SNARK:<5.MONITOR>IPCF.MAC.3, 15-Jan-81 15:56:58 by FLEMMING
;add code for SMAP/RSMAP
; UPD ID= 939, SNARK:<5.MONITOR>IPCF.MAC.2, 20-Aug-80 15:18:10 by ENGEL
;TCO #5.1136 - CHANGE ALL LOCKS TO CONFORM TO THE NEW LOCK SCHEME
; UPD ID= 88, SNARK:<4.1.MONITOR>IPCF.MAC.172, 5-Dec-79 07:40:48 by R.ACE
;ADD COMMENTS TO PIDTBL
; UPD ID= 31, SNARK:<4.1.MONITOR>IPCF.MAC.171, 28-Nov-79 09:46:41 by ENGEL
;AT MWAIT DO PIDLKK FIRST. AVOIDS FLKTIM BUGCHKS
; UPD ID= 29, SNARK:<4.1.MONITOR>IPCF.MAC.170, 28-Nov-79 09:39:05 by ENGEL
;TCO 4.2581 AT MRECV2 DO PIDLKK FIRST. AVOIDS FLKTIM BUGCHKS
;<4.MONITOR>IPCF.MAC.169, 19-Oct-79 15:11:30, EDIT BY HALL
;VALARG - REMOVE CODE TO APPLY PCS TO PAGE NUMBERS BECAUSE FHKPTN
;NOW DOES IT
;<OSMAN.MON>IPCF.MAC.1, 10-Sep-79 15:35:24, EDIT BY OSMAN
;TCO 4.2412 - Move definition of BUGHLTs, BUGCHKs, and BUGINFs to BUGS.MAC
;<4.MONITOR>IPCF.MAC.167, 21-Jul-79 17:22:41, EDIT BY R.ACE
;XCT 10 WON'T DO IT, BACK TO XCT 14 (XCTUU)
;ALSO CHANGE EXECUTED INSTRUCTION FROM XHLLI TO XMOVEI
;<4.MONITOR>IPCF.MAC.166, 21-Jul-79 14:48:09, EDIT BY HALL
;VALARG - GET USER'S SECTION WITH XCT 10 (MAYBE THIS ONE'S RIGHT)
;<4.MONITOR>IPCF.MAC.165, 13-Jul-79 11:33:41, EDIT BY HALL
;CHANGES FOR USER-MODE EXTENDED ADDRESSING:
; SNDPAG - CONVERT PAGE NUMBER TO PTN,,PN
; MSRECP - USE P5 FOR PAGE ID
; VALARG - CLEAR LH OF P4 FOR ADDRESS, ADD PCS TO PAGE NUMBER
;<4.MONITOR>IPCF.MAC.164, 7-Jun-79 09:28:25, Edit by KONEN
;GIVE REASON CODE FOR NOALCM BUGCHK
;<4.MONITOR>IPCF.MAC.163, 18-May-79 13:04:25, EDIT BY KIRSCHEN
;IF NO WAITING FORK DO NOT GIVE INTERRUPT IN CHKFKW
;<4.MONITOR>IPCF.MAC.162, 31-Mar-79 09:58:15, EDIT BY R.ACE
;FIX ARCMSG NOT QUOTE PERIODS IN DIRECTORY NAMES WITH ^V
;<4.MONITOR>IPCF.MAC.161, 12-Mar-79 10:31:32, Edit by KONEN
;MODIFY DISMES TO SEND ALL USAGE INFO TO DEVICE ALLOCATOR
;<4.MONITOR>IPCF.MAC.160, 4-Mar-79 17:30:14, EDIT BY KONEN
;UPDATE COPYRIGHT FOR RELEASE 4
;<4.MONITOR>IPCF.MAC.159, 2-Mar-79 14:51:37, EDIT BY R.ACE
;MOVE PIDRQ AND PIDRC TO WORD 2 TO LEAVE THE COUNT IN WORD 0
; FOR PID HEADERS
;<4.MONITOR>IPCF.MAC.158, 21-Feb-79 13:48:01, EDIT BY HURLEY.CALVIN
; Cause ARCMSG to wait only if over allocation, not if free space exhausted
;<4.MONITOR>IPCF.MAC.157, 13-Jan-79 13:49:43, EDIT BY OSMAN
;create MSHEAD for filling in message header
;<4.MONITOR>IPCF.MAC.156, 17-Dec-78 18:13:58, Edit by HEMPHILL
;TCO 4.2118 - FIX MESTOR RANGE CHECKING ON MESSAGE LENGTHS
;<4.MONITOR>IPCF.MAC.155, 16-Nov-78 14:11:46, Edit by KONEN
;ADD MOUNT/DISMOUNT CODE AS ARGUMENT TO DISMES
;<4.MONITOR>IPCF.MAC.154, 28-Oct-78 08:57:54, EDIT BY R.ACE
;TCO 4.2071 - MAKE MRECV WITH -1 IN .IPCFR FIELD OF PDB BYPASS JOB-WIDE
;PIDS WHEN LOOKING FOR A MESSAGE TO RECEIVE
;TCO 4.2072 - FIX BUG IN MSEND: IF IP%CPD AND IP%JWP ARE SET, THE
;CREATED PID IS DELETED WHEN THE FORK THAT CREATED IT IS KILLED
;<4.MONITOR>IPCF.MAC.152, 27-Oct-78 11:38:59, EDIT BY OSMAN
;TRY TO MAKE IT WORK...
;<4.MONITOR>IPCF.MAC.148, 24-Oct-78 14:13:03, EDIT BY OSMAN
;TCO 4.2060 - add .IPCLL goodies
;<KONEN>IPCF.NEW.4, 3-Aug-78 09:53:30, Edit by KONEN
;<ARC-DEC>IPCF.MAC.17, 11-Oct-78 09:04:26, EDIT BY CALVIN
; Convert to latest QUASAR expectations
;<ARC-DEC>IPCF.MAC.9, 3-Oct-78 14:25:16, EDIT BY CALVIN
; Re-write ARCMSG to not use a page mode message
;[BBN-TENEXD]<3A-EONEIL>IPCF.MAC.4, 30-Aug-78 14:47:29, Ed: CRDAVIS
; Changed ARCMSG to send to Quasar.
;SNARK:<4.MONITOR>IPCF.MAC.145, 17-Oct-78 14:25:39, Edit by MCLEAN
;FIX LOGIMS/LOGOMS TO TAKE A PID
;<4.MONITOR>IPCF.MAC.144, 3-Oct-78 12:54:10, EDIT BY MILLER
;<4.MONITOR>IPCF.MAC.143, 3-Oct-78 12:41:36, EDIT BY MILLER
;ADD IPCMTM FOR SENDING TAPE MESSAGES TO MDA
;<4.MONITOR>IPCF.MAC.142, 9-Aug-78 14:32:40, Edit by;FIX JRST IPCMSR IN DISMES
;<4.MONITOR>IPCF.MAC.141, 2-Aug-78 23:09:03, Edit by MCLEAN
;<4.MONITOR>IPCF.MAC.140, 2-Aug-78 23:04:54, Edit by MCLEAN
;<4.MONITOR>IPCF.MAC.139, 2-Aug-78 23:01:33, Edit by MCLEAN
;MESSAGES FOR DEVICE ALLOCATOR ADDED
;<4.MONITOR>IPCF.MAC.138, 2-Aug-78 22:49:57, Edit by MCLEAN
;<4.MONITOR>IPCF.MAC.137, 31-Jul-78 17:00:49, EDIT BY HURLEY
;FIX KILLED PID FEATURE TO SEND DELETED PID
;<4.MONITOR>IPCF.MAC.136, 19-Jul-78 00:04:04, Edit by MCLEAN
;MOVE ASGSWP/RELSWP/RELMES TO FREE WHERE IT BELONGS
;<4.MONITOR>IPCF.MAC.135, 16-Feb-78 17:42:13, EDIT BY HURLEY
;<4.MONITOR>IPCF.MAC.134, 14-Feb-78 15:37:17, EDIT BY HURLEY
;TCO 1884 - ADD SENDING OF MESSAGES ON DELETED PIDS
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
SEARCH PROLOG
TTITLE IPCF
;IPCF - INTERPROCESS COMMUNICATIONS FACILITY
REPEAT 0,<
;DATA STRUCTURES FOR IPCF
!---------------------------------------------!
PIDLST: ! INDEX OF FIRST FREE PID ON FREE LIST (4) !
!---------------------------------------------!
!---------------------------------------------!
PIDTBL: ! ADR OF PID HEADER 1 ! ADR OF PID HEADER 2 !
!----------------------!----------------------!
! ADR OF PID HEADER 3 ! NEXT FREE PID (5) !
!----------------------!----------------------!
! 6 ! 7 !
!----------------------!----------------------!
! 10 ! 0 !
!----------------------!----------------------!
PIDTBS = SIZE OF PIBTBL
MAXPID = HIGHEST LEGAL HALF WORD INDEX INTO PIDTBL
NOTE: IF THE VALUE OF A PIDTBL ENTRY IS LESS THAN SWFREE, IT SIGNIFIES
A FREE ENTRY, AND THE VALUE IS THE NUMBER OF THE NEXT FREE PID. IF THE
VALUE OF THE ENTRY IS GREATER THAN OR EQUAL TO SWFREE, THE PID IS IN
USE, AND THE PIDTBL ENTRY IS THE ADDRESS OF THE HEADER FOR THAT PID.
;PID HEADER FORMAT
!----------------------!----------------------!
!PIDUN: ! !
! UNIQUE # ! LENGTH OF THIS BLOCK !
! (LH OF PID) ! !
!-------------!--------!----------!-----------!
!PIDFLG: !PIDCHN: !PIDFW: !
! FLAGS ! CHN ! FORK NUMBER OF !
! ! # ! WAITING FORK !
!-------------!--------!----------------------!
! PIDRQ: ! PIDRC: !PIDFO: !
! RECEIVE ! RECEIVE ! FORK NUMBER !
! QUOTA ! COUNT ! OF OWNER !
!-----------!----------!----------------------!
! PIDKMP: !
! PID TO RECEIVE A MESSAGE IF !
! THIS PID GETS DELETED !
!----------------------!----------------------!
!PIDNL: !PIDOL: !
! LINK TO ! LINK TO !
! NEWEST MESSAGE ! OLDEST MESSAGE !
!----------------------!----------------------!
;MESSAGE FORMAT
!----------------------!----------------------!
!MESLNK: !MESLEN: !
! LINK TO NEXT MESSAGE ! LENGTH OF THIS BLOCK !
!----------------------!----------------------!
!MESSJN: !MESFLG: !
! SENDER'S JOB NUMBER ! FLAGS !
!----------------------!----------------------!
!MESSPD: !
! SENDER'S PID !
!---------------------------------------------!
!MESLDN: !
! LOGGED IN DIRECTORY !
!---------------------------------------------!
!MESENB: !
! ENABLED CAPABILITIES !
!---------------------------------------------!
!MESCDN: !
! CONNECTED IN DIRECTORY !
!---------------------------------------------!
!MESACT: ACCOUNT STRING !
! BLOCK MESALN !
! !
!---------------------------------------------!
!MESLLO: LOGICAL LOCATION STRING !
! BLOCK MESLLN !
! !
!---------------------------------------------!
!MESWD0: (MESPTN) !
! MESSAGE !
! (PTN.PN IN PAGE MODE) !
!---------------------------------------------!
!MSFTM: !
! FORK TABLE MASK !
! (PAGE MODE ONLY) !
!----------------------!----------------------!
!MESPAC: !MSFTI: !
! ACCESS BITS ! INDEX INTO !
! OF PAGE ! FORK TABLE !
!----------------------!----------------------!
;MESSAGE SPACE POOL FORMAT (DICTATED BY ASGFRE)
!----------------------!----------------------!
SWPFRE: ! ADR OF 1ST FREE BLOCK! UNUSED !
!----------------------!----------------------!
! LOCK ON FREE SPACE !
!---------------------------------------------!
! SPACE COUNTER !
!---------------------------------------------!
! MOST COMMON BLOCK SIZE !
!----------------------!----------------------!
! MAX TOP OF FREE AREA ! BOTTOM OF FREE AREA !
!----------------------!----------------------!
! TEMPORARY WORK SPACE !
!---------------------------------------------!
! TEMPORARY WORK SPACE !
!---------------------------------------------!
SWFREE: ! FREE SPACE POOL !
! !
! SPACE FOR THE ASSIGNMENT OF: !
! PID HEADERS !
! AND !
! MESSAGES !
!---------------------------------------------!
;QUOTA TABLE (INDEXED BY JOB NUMBER)
!-----------!----------!----------!-----------!
PIDCNT: !PIDSQ: !PIDSC: !PIDPQ: !PIDPC: !
! SEND ! SEND ! PID ! PID !
! QUOTA ! COUNT ! QUOTA ! COUNT !
!-----------!----------!----------!-----------!
! ! ! ! !
! ETC. ! ETC. ! ETC. ! ETC. !
! ! ! ! !
!-----------!----------!----------!-----------!
! ! ! ! !
>
;DATA STRUCTURE FOR IPCF PID HEADERS AND MESSAGES
;LOCAL STORAGE DECLARED IN STG.MAC
EXTN <HSHTBL,ENQBKS,HSHLEN,ENFREL,ENFKTB>
EXTN <PIDHDS,MESHDS,PAGMSZ,MAXMSL,MAXSMS,MINPHL,SWOPTL,PIDSSQ>
EXTN <PIDSRQ,PIDSPQ,IPCCFL,PIDTBS,MAXPID,PDFREL>
EXTN <SWFREL,MAXPIT,PIDPBL,PIDFTL,PIDTBL,SPDTBL>
EXTN <NXTPID,INFOPD,INFOPV,PIDLST,PIDMXP,PIDPBT>
EXTN <PIDFTB,SWPFRE,SWFREE,PIDCNT,PDFKTB,PDFKTL>
SWAPCD
;PID HEADER
DEFSTR(PIDUN,0,17,18) ;UNIQUE NUMBER IN LH OF PID
DEFSTR(PIDFLG,1,11,12) ;PID FLAGS
PD%NOA==1 ;NO ACCESS BY OTHER FORKS
PD%CHN==2 ;A CHANNEL IS SET UP TO GET INTERRUPTS
PD%DIS==4 ;PID IS DISABLED
PD%JWP==10 ;PID IS A JOB WIDE PID
DEFSTR(PIDCHN,1,17,6) ;CHANNEL # TO INTERRUPT WAITING FORK ON
DEFSTR(PIDFW,1,35,18) ;FORK WAITING FOR MESSAGE TO THIS PID
DEFSTR(PIDRQ,2,8,9) ;RECEIVE QUOTA FOR THIS PID
DEFSTR(PIDRC,2,17,9) ;RECEIVE COUNT FOR THIS PID
DEFSTR(PIDFO,2,35,18) ;FORK # OF OWNER OF THIS PID
DEFSTR(PIDKMP,3,35,36) ;PID TO RECEIVE DELETED PID MESSAGE
DEFSTR(PIDNL,4,17,18) ;LINK TO NEWEST MESSAGE
DEFSTR(PIDOL,4,35,18) ;LINK TO OLDEST MESSAGE
;MESSAGE
DEFSTR(MESLNK,0,17,18) ;LINK TO NEXT MESSAGE - 0 IF LAST MESS
DEFSTR(MESLEN,0,35,18) ;LENGTH OF THIS MESSAGE BLOCK
DEFSTR(MESSJN,1,17,18) ;SENDER'S JOB NUMBER
DEFSTR(MESFLG,1,35,18) ;FLAGS FOR THIS MESSAGE
DEFSTR(MESSPD,2,35,36) ;SENDER'S PID
DEFSTR(MESLDN,3,35,36) ;LOGGED IN DIR # OF SENDER
DEFSTR(MESENB,4,35,36) ;ENABLED CAPABILITIES OF SENDER
DEFSTR(MESCDN,5,35,36) ;CONNECTED DIR # OF SENDER
MESACT==6 ;BEGINNING OF BLOCK WHICH HOLDS ACCOUNT STRING OF SENDER
MESALN==MAXLW ;SIZE OF BLOCK FOR ACCOUNT STRING
MESLLO==MESACT+MESALN ;BLOCK FOR LOGICAL LOCATION
MESLLN==WPN ;SIZE OF BLOCK FOR LOGICAL LOCATION STRING
MESWDI==MESLLO+MESLLN ;OFFSET OF FIRST DATA WORD IN MESSAGE
;HEY, Y'ALL... DUE TO SPLATTERED DATABASE DEFINITION, YOU MUST CHANGE
;DEFINITION OF MESHDS IN STG EVERY TIME YOU ADD TO THIS DATABASE!!
DEFSTR(MESWD0,MESWDI,35,36) ;FIRST WORD OF MESSAGE
DEFSTR(MESPTN,MESWDI,35,36) ;PTN.PN OF PAGE (PAGE MODE ONLY)
DEFSTR(MSFTM,MESWDI+1,35,36) ;MASK INTO FORK PAGE BIT TABLE
DEFSTR(MESPAC,MESWDI+2,17,18) ;ACCESS BITS FOR PAGE
DEFSTR(MSFTI,MESWDI+2,35,18) ;INDEX INTO FORK BIT TABLE
;PID QUOTA TABLE
DEFSTR(PIDSQ,PIDCNT,8,9) ;SEND QUOTA FOR JOB
DEFSTR(PIDSC,PIDCNT,17,9) ;SEND COUNT FOR JOB
DEFSTR(PIDPQ,PIDCNT,26,9) ;PID QUOTA FOR JOB
DEFSTR(PIDPC,PIDCNT,35,9) ;PID COUNT FOR JOB
MAXQTA==777 ;MAXIMUM PID QUOTA
SPMHDS==5 ;SPOOL MESSAGE HEADER SIZE
LOGMSZ==3 ;LOGOUT MESSAGE SIZE
LGMHDS==2 ;LOGOUT MESSAGE HEADER SIZE
LG2MSZ==^D9 ;LOGOUT MESSAGE TO CREATOR SIZE
LG2MHS==^D8 ;LOGOUT MESSAGE TO CREATOR HEADER SIZE
DISMSZ==3 ;MOUNT COUNT DECREMENT MESSAGE SIZE
DSMHDS==2 ;MOUNT COUNT DECREMENT HEADER SIZE
PKMHDS==2 ;LENGTH OF DELETED PID MESSAGE
ARMSSZ==^D60 ; Archive message size
; Various Quasar parameters for sending a CREATE message
%%.QSR==33 ; Quasar version
.QOCRE==7 ; CREATE message type
EQHSIZ==^D18 ; Size of CREATE header
FPMSIZ==5 ; Size of File Param area
; Table of SIXBIT queue names. Indexed by ARCMSG function code.
ARDVTB: SIXBIT/RET/ ; Name of retrieval queue
SIXBIT/NOT/ ; Name of notification queue
;THE IPCF RECEIVE JSYS - USED TO RECEIVE MESSAGES FROM A PID
;CALL:
; MOVEI 1,N ;NUMBER OF WORDS IN PACKET DESCRIPTOR
; MOVEI 2,ADR ;ADDRESS OF PACKET DESCRIPTOR BLOCK
; MRECV
; ERROR RETURN ;ERROR CODE IN AC1
; SUCCESSFUL ;MESSAGE RETURNED AS DIRECTED
.MRECV::MCENT ;ENTER SLOW CODE
CALL VALARG ;VALIDATE THE CALLER'S ARGUMENT LIST
RETERR ;SOMETHING WRONG, ERROR CODE IN T1
TRNN P1,IP%CFV ;PAGE MODE?
JRST MRECV2 ;NO
HRLI T1,.FHSLF ;YES, SEE IF PAGE EXISTS IN DEST PAGE
HRR T1,P4 ;GET AN IDENTIFIER FOR THE PAGE
TRNN P1,IP%EPN ;TREAT ARGUMENT AS AN EXTENDED PAGE NUMBER?
TDZA T2,T2 ;NO, USE PC SECTION
MOVX T2,PM%EPN ;YES, USE SECTION NUMBER SPECIFIED BY THE USER
CALL FKHPTN ;...
RETERR ;SHOULD NEVER HAPPEN...
MOVE P5,T1 ;SAVE IDENTIFIER
CALL MRPACS ;GET INFO ABOUT PAGE
TXNN T1,PA%PEX ;PAGE EXIST?
JRST MRECV2 ;NO, THAT IS GOOD
SETO T1, ;YES, GET RID OF IT
HRLI T2,.FHSLF
HRR T2,P4 ;BUILD PMAP ARGS
SETZ T3,
PMAP ;GET RID OF THE PAGE
MRECV2: CALL GTLCKS ;GET FORK LOCK AND PIDLKK
MRECV0: TRNN P1,IP%CFV ;PAGE MODE?
JRST MRECV3 ;NO
MOVE T1,P5 ;YES, CHECK IF STILL NO PAGE
CALL MRPACS
TXNE T1,PA%PEX ;PAGE EXIST?
JRST [ MOVEI T1,IPCF34 ;YES, PAGE MUST BE EMPTY TO RECIEVE
JRST MULKER] ;GO GIVE ERROR RETURN
MRECV3: MOVE T1,P3 ;GET RECEIVERS PID
CAMN T1,[-1] ;USER WANT ANY MESSAGE FOR THIS FORK?
JRST [ CALL MRECFK ;YES, GO GET A PID FOR THIS FORK TO READ
JRST MULKER ;SOMETHING WENT WRONG, GO UNLOCK
JRST MRECV1] ;GO READ IN THE MESSAGE
CAMN T1,[-2] ;USER WANT ANY MESSAGE FOR THIS JOB?
JRST [ CALL MRECJB ;YES, GO FIND A MESSAGE FOR THIS JOB
JRST MULKER ;ERROR OF SOME FLAVOR, GO UNLOCK
JRST MRECV1] ;GO READ IN MESSAGE
CALL VALPDJ ;NO, SEE IF PID IS VALID TO RECEIVE ON
JRST [ MOVEI T1,IPCFX4 ;NO, GET ILLEGAL RECEIVER'S PID CODE
JRST MULKER] ;GO UNLOCK AND GIVE ERROR RETURN
CALL CHKNOA ;CHECK THE ACCESS BY THIS FORK
JRST MULKER ;NOT ACCESSABLE
MRECV1: CALL MESREC ;GO COPY A MESSAGE TO USER SPACE
JRST MRECER ;NONE THERE, GO SEE IF WE NEED TO WAIT
UNLOKK PIDLKK ;FREE THE LOCKS
OKINT
CALL FUNLK ;UNLOCK FORK LOCK
UMOVEM T1,1 ;RETURN INFO ABOUT NEXT MESSAGE
SMRETN ;GIVE SUCCESSFUL RETURN
MRECER: JUMPN T1,MULKER ;IF T1 IS NON-ZERO, THIS IS AN ERROR
TLNE P1,(IP%CFB) ;NO MESSAGE, SEE IF WANT TO BLOCK
JRST MNOMES ;NO, GIVE ERROR RETURN
LOAD T4,PIDFO,(T2) ;GET FORK NUMBER OF OWNER
CAMN T4,FORKX ;THIS US?
JRST MRECE1 ;YES, WE CAN WAIT
CALL CHKNOA ;SEE IF NO ACCESS ON
RET ;YES, GIVE ERROR RETURN
CALL CHKPDW ;SEE IF WAITING ALLOWED FOR THIS PID
JRST MULKER ;NO, GIVE ERROR RETURN
MRECE1: MOVE T3,FORKX ;SET UP TO WAIT
STOR T3,PIDFW,(T2)
CALL MWAIT ;YES, GO WAIT FOR A MESSAGE
JRST MRECV0 ;TRY AGAIN
MNOMES: MOVEI T1,IPCFX2 ;NO MESSAGES READY
MULKER: UNLOKK PIDLKK ;UNLOCK THE LOCKS
OKINT
CALL FUNLK ;UNLOCK FORK LOCK
RETERR ;GIVE ERROR RETURN TO USER
;ROUTINE TO FIND A PID WITH A MESSAGE READY BELONGING TO THIS FORK
; CALL MRECFK
;RETURNS +1: UNSUCCESSFUL, ERROR CODE IN T1
; +2: SUCCESSFUL - A MESSAGE WAS FOUND
; T1/ PID
; T2/ POINTER TO PID HEADER
MRECFK: STKVAR <PDFKC,MRCFKE>
MRCFK0: CALL FNDNMF ;FIND THE NEXT MESSAGE FOR THIS FORK
JRST [ JUMPG T1,MRCFK2 ;IF ANY PIDS SEEN, GO WAIT MAYBE
RETBAD (IPCF15)] ;NO PIDS SEEN, GIVE ERROR
RETSKP ;FOUND A NON-EMPTY PID
MRCFK2: TLNE P1,(IP%CFB) ;USER WANT TO BLOCK?
RETBAD (IPCFX2) ;NO, RETURN TO HIM NOW
SETZB T1,PDFKC ;INITIALIZE PID COUNTER
MRCFK1: MOVE T2,FORKX ;GET OUR FORK #
CALL GETNPF ;GET NEXT PID FOR THIS FORK
JRST MRCFKW ;NO MORE PIDS
CALL CHKPDW ;SEE IF LEGAL TO WAIT ON THIS PID
JRST [ MOVEM T1,MRCFKE ;SAVE ERROR
CALL ENDWAT ;STOP WAITING ON OTHER PIDS
MOVE T1,MRCFKE ;GET BACK ERROR CODE
RET] ;AND RETURN
MOVE T3,FORKX ;GET OUR FORK NUMBER
STOR T3,PIDFW,(T2) ;MARK THAT THIS FORK IS WAITING
AOS PDFKC ;MARK THAT WE ARE WAITING ON A PID
JRST MRCFK1 ;LOOP BACK FOR ALL PIDS
MRCFKW: SKIPG PDFKC ;ANY PIDS SEEN?
RETBAD (IPCF15) ;NO, TELL USER
CALL MWAIT ;GO WAIT
JRST MRCFK0 ;LOOP BACK TO SEE IF A MESSAGE IS THERE
;ROUTINE TO FIND A NON-EMPTY PID FOR THIS JOB
; CALL MRECJB
;RETURNS +1: ERROR - ERROR CODE IN T1
; +2: T1/ PID
; T2/ POINTER TO PID HEADER
MRECJB: STKVAR <PDJBC,MRCJBT>
MRCJB0: CALL FNDNMJ ;FIND A MESSAGE FOR THIS JOB
JRST [ JUMPG T1,MRCJB3 ;NO MESSAGES, WERE ANY PIDS SEEN?
RETBAD (IPCF14)] ;NO, GIVE ERROR RETURN
RETSKP ;MESSAGE FOUND
MRCJB3: TLNE P1,(IP%CFB) ;USER WANT TO BLOCK?
RETBAD (IPCFX2) ;NO, TELL HIM NO MESSAGES READY
SETZM PDJBC ;INITIALIZE COUNT OF PIDS FOR JOB
SETZM MRCJBT ;START AT PID 0
MRCJB1: MOVE T2,FORKX ;GET NUMBER OF OUR FORK
HLRZ T2,FKJOB(T2) ;GET OUR JOB NUMBER
MOVE T1,MRCJBT ;GET PID INDEX
CALL GETNPJ ;GET NEXT PID FOR THIS JOB
JRST MRCJBW ;NO MORE PIDS
MOVEM T1,MRCJBT ;SAVE NEW PID
CALL CHKNOA ;SEE IF NO ACCESS BY OTHER FORKS
JRST MRCJB1 ;YES, IGNORE IT
CALL CHKPDW ;CHECK IF WE CAN WAIT ON THIS PID
JRST [ MOVEM T1,MRCJBT ;SAVE ERROR CODE
CALL ENDWAT ;CLEAN UP WAITING PIDS
MOVE T1,MRCJBT ;GET BACK ERROR CODE
RET] ;AND GIVE ERROR RETURN
MRCJB2: AOS PDJBC ;COUNT UP PIDS SEEN
MOVE T3,FORKX ;GET OUR FORK NUMBER
STOR T3,PIDFW,(T2) ;MARK THAT WE ARE WAITING FOR A MES
JRST MRCJB1 ;LOOP BACK FOR ALL PIDS
MRCJBW: SKIPG PDJBC ;ANY PIDS SEEN?
RETBAD (IPCF14) ;NO, TELL USER NONE AVAILABLE
CALL MWAIT ;GO WAIT FOR A MESSAGE
JRST MRCJB0 ;GO TRY AGAIN
;ROUTINE TO FIND A MESSAGE FOR THIS FORK
; CALL FNDNMF
;RETURNS +1: NO MESSAGES, T1 CONTAINS # OF PIDS SEEN FOR THIS FORK
; +2: MESSAGE FOUND
; T1/ PID
; T2/ PID HEADER ADDRESS
FNDNMF: STKVAR <FNDMFC>
SETZB T1,FNDMFC ;START AT FIRST PID
FNDMFL: MOVE T2,FORKX ;GET CURRENT FORK INDEX
CALL GETNPF ;GET THE NEXT PID BELONGING TO THIS FORK
JRST FNDMFD ;NO MORE PIDS FOR THIS FORK
LOAD T4,PIDRC,(T2) ;DOES THIS PID HAVE ANY MESSAGES?
JUMPG T4,[LOAD T4,PIDFLG,(T2) ;YES, GET PID FLAGS
TRNE T4,PD%JWP ;IS THIS A JOB-WIDE PID?
JRST FNDMFL ;YES, BYPASS IT
RETSKP] ;ELIGIBLE PID WITH A MESSAGE WAS FOUND
AOS FNDMFC ;REMEMBER THAT A PID WAS SEEN
JRST FNDMFL ;LOOP BACK UNTIL ALL PIDS CHECKED
FNDMFD: MOVE T1,FNDMFC ;GET COUNT OF PIDS SEEN
RET ;AND GIVE ERROR RETURN
;ROUTINE TO FIND A MESSAGE FOR THE JOB
; CALL FNDNMJ
;RETURNS +1: NO MESSAGES, T1 CONTAINS # OF PIDS SEEN FOR JOB
; +2: MESSAGE FOUND
; T1/ PID
; T2/ PID HEADER ADDRESS
FNDNMJ: STKVAR <FNDMJC>
SETZB T1,FNDMJC ;INITIALIZE PID INDEX
FNDMJL: MOVE T2,FORKX ;GET OUR FORK NUMBER
HLRZ T2,FKJOB(T2) ;GET JOB NUMBER OF FORK
CALL GETNPJ ;GET THE NEXT PID FOR THIS JOB
JRST FNDMJD ;NO MORE PIDS
CALL CHKNOA ;SEE IF ACCESSIBLE BY THIS FORK
JRST FNDMJL ;NO, LOOP BACK FOR ALL PIDS
LOAD T4,PIDRC,(T2) ;GET COUNT OF MESSAGES FOR THIS PID
JUMPG T4,RSKP ;IF ONE THERE, GO READ MESSAGE
AOS FNDMJC ;REMEMBER THAT A PID WAS SEEN
JRST FNDMJL ;LOOP BACK FOR ALL PIDS
FNDMJD: MOVE T1,FNDMJC ;GET COUNT OF PIDS SEEN
RET ;AND RETURN TO USER
;ROUTINE TO COPY A MESSAGE INTO USER SPACE
;ACCEPTS IN T1: PID
; T2: ADDRESS OF PID HEADER
; Q1: COUNT OF ITEMS IN PACKET DESCRIPTOR BLOCK
; Q2: ADDRESS OF PACKET DESCRIPTOR BLOCK IN USER SPACE
; Q3: # OF WORDS TO RECEIVE
; P5: PAGE ID FOR PAGE TO RECEIVE MESSAGE (IF PAGE MODE)
; CALL MESREC
;RETURNS IN +1: T1=0 MEANS NO MESSAGES
; T1 NOT 0 MEANS ERROR CODE
; +2: MESSAGE COPIED SUCCESSFULLY
; T1/ XWD LENGTH,FLAGS - FOR NEXT MESSAGE IN QUEUE
MESREC: STKVAR <MESPID,MESRPH,MESADR>
MOVEM T1,MESPID ;SAVE PID
MOVEM T2,MESRPH ;SAVE PID HEADER ALSO
LOAD T3,PIDRC,(T2) ;GET COUNT OF MESSAGES FOR PID
JUMPE T3,[SETZ T1, ;IF NONE, RETURN
RET]
LOAD T3,PIDOL,(T2) ;GET POINTER TO MESSAGE
MOVEM T3,MESADR ;SAVE ADDRESS OF START OF MESSAGE
LOAD T1,MESFLG,(T3) ;GET FLAGS OF THAT MESSAGE
XOR T1,P1 ;SEE IF MODES MATCH
TRNE T1,IP%CFV ;...
RETBAD (IPCF16) ;NO, FLAG THIS AS AN ERROR
LOAD T1,MESLEN,(T3) ;GET MESSAGE SIZE
SUBI T1,MESHDS ;GET ACTUAL SIZE OF SENT MESSAGE
TRNE P1,IP%CFV ;PAGED MODE?
MOVEI T1,PGSIZ ;YES, USE LENGTH OF A PAGE
LOAD T4,MESFLG,(T3) ;GET FLAGS OF MESSAGE TO RETURN TO USER
SUBI T1,0(Q3) ;DID USER GIVE A BIG ENOUGH BUFFER
SKIPG T1
TLZA T4,(IP%TTL) ;YES, CLEAR TTL BIT
TLOA T4,(IP%TTL) ;NO, SET TRUNCATED BIT
JRST MESRC0 ;MESSAGE SIZE ALRIGHT
TLNN P1,(IP%TTL) ;DOES USER WANT TO TRUNCATE?
RETBAD (IPCFX3) ;NO, GIVE ERROR RETURN
MESRC0: TRNN P1,IP%CFP ;CALLER WANT PRIV'D MESSAGE?
TRZ T4,IP%CFP ;NO, HE DOESNT CARE IF MESSAGE WAS PRIV'D
UMOVEM T4,.IPCFL(Q2) ;STORE FINAL FLAGS
CALL GETMES ;GET THE OLDEST MESSAGE FROM LIST IN T3
JRST [ BUG(IPCMCN)
SETZ T1, ;PRETEND NO MESSAGES IF CONTINUED
RET] ;AND RETURN
MOVE T1,MESPID ;GET BACK PID
CALL CPYMHD ;COPY MESSAGE HEADER TO USER SPACE
;.. ;MESSAGE SIZE IS RETURNED IN T1
;..
MOVE T3,MESADR ;GET BACK POINTER TO MESSAGE
TRNE P1,IP%CFV ;PAGE MODE RECEIVE?
JRST MSRECP ;YES, GO TRANSFER THE PAGE
JUMPE Q3,MSRECD ;USER DOES NOT WANT MESSAGE IF 0
CAML Q3,T1 ;GET SMALLER OF TWO LENGTHS
MOVE Q3,T1 ;SENDER'S MESSAGE IS SMALLER
XCTU [HRLM Q3,.IPCFP(Q2)] ;STORE LENGTH OF MESSAGE SENT
MOVNS Q3 ;SET UP AN AOBJN POINTER
HRLZS Q3
HRR Q3,P4 ;GET POINTER INTO USER SPACE FOR MESS
MSRECL: LOAD T1,MESWD0,(T3) ;GET NEXT WORD IN MESSAGE
UMOVEM T1,0(Q3) ;STORE IN USER SPACE
AOS T3 ;ADVANCE POINTER TO MESSAGE
AOBJN Q3,MSRECL ;LOOP BACK FOR ALL WORDS IN MESSAGE
MSRECD: MOVE T1,MESADR ;GET POINTER TO START OF MESSAGE
CALL RELMES ;GO RELEASE THE MESSAGE SPACE TO POOL
MOVE T2,MESRPH ;GET POINTER TO PID HEADER
LOAD T2,PIDOL,(T2) ;GET POINTER TO OLDEST MESSAGE
JUMPE T2,[SETZ T1, ;IF NO MESSAGE, RETURN 0
RETSKP]
LOAD T1,MESLEN,(T2) ;GET LENGTH OF MESSAGE BLOCK
HRLI T1,-MESHDS(T1) ;GET LENGTH OF MESSAGE IN LH OF T1
LOAD T3,MESFLG,(T2) ;GET FLAGS OF NEXT MESSAGE IN QUEUE
TRNE T3,IP%CFV ;PAGE MODE MESSAGE?
MOVSI T1,PGSIZ ;YES, SET LENGTH TO BE ONE PAGE
HRR T1,T3 ;SET UP LENGTH,,FLAGS
RETSKP ;EXIT SUCCESSFULLY
MSRECP: LOAD T1,MSFTI,(T3) ;GET INDEX INTO FORK BIT TABLE
LOAD T2,MSFTM,(T3) ;GET MASK FOR THIS PAGE
IORM T2,PIDPBT(T1) ;MAKE THIS PAGE AVAILABLE TO BE USED
LOAD T1,MESPTN,(T3) ;GET PTN.PN OF PAGE
MOVE T2,P5 ;GET ID FOR PAGE TO RECEIVE INTO
LOAD T3,MESPAC,(T3) ;GET ACCESS BITS FOR PAGE
HRLZS T3
JUMPE Q3,[SETZB T2,T3 ;USER WANT THIS PAGE?
EXCH T2,T1 ;NO, THEN THROW IT AWAY
JRST .+1]
CALL SETPT ;GO MAP IT INTO USER'S FORK
JRST MSRECD ;GO FINISH UP AND RETURN
;ROUTINE TO COPY A MESSAGE HEADER TO USER SPACE
;ACCEPTS IN T1/ PID
; T2/ PID HEADER ADDRESS
; T3/ MESSAGE HEADER ADDRESS
; Q1/ LENGTH OF HEADER IN USER SPACE
; Q2/ ADDRESS OF HEADER SPACE IN USER'S AREA
; CALL CPYMHD
;RETURNS +1: ALWAYS - T1/ LENGTH OF MESSAGE DATA AREA
CPYMHD: TRVAR <MHA>
MOVEM T3,MHA ;REMEMBER MESSAGE HEADER ADDRESS
UMOVEM T1,.IPCFR(Q2) ;STORE RECEIVER'S PID
LOAD T1,MESSPD,(T3) ;GET SENDER'S PID
UMOVEM T1,.IPCFS(Q2) ;STORE SENDER'S PID IN USER SPACE
LOAD T4,MESLDN,(T3) ;GET LOGGED IN DIR NUMBER
CAILE Q1,.IPCFD ;USER WANT LOGGED IN DIR?
UMOVEM T4,.IPCFD(Q2) ;YES, GIVE IT TO USER
LOAD T1,MESENB,(T3) ;GET SENDER'S ENABLED CAPABILITIES
CAILE Q1,.IPCFC ;USER WANT THEM?
UMOVEM T1,.IPCFC(Q2) ;YES, GIVE HIM CAPABILITIES OF SENDER
LOAD T1,MESCDN,(T3) ;GET CONNECTED DIR NUMBER
CAILE Q1,.IPCSD ;USER WANT SENDER'S CONNECTED DIR?
UMOVEM T1,.IPCSD(Q2) ;YES
CAILE Q1,.IPCAS ;USER WANT ACCOUNT STRING?
CALL CPYACT ;YES, GIVE IT TO HIM
CAILE Q1,.IPCLL ;USER WANT LOGICAL LOCATION?
CALL CPYLLO ;YES, GIVE IT TO HER
MOVE T3,MHA ;ASSUME ROUTINES CLOBBERED T3
LOAD T1,MESLEN,(T3) ;GET LENGTH OF MESSAGE BLOCK
SUBI T1,MESHDS ;GET LENGTH OF MESSAGE DATA AREA
RET ;RETURN TO CALLER
;ROUTINE TO COPY SENDER'S JOB ACCOUNT STRING TO CALLER'S ADDRESS SPACE,
;USING BYTE POINTER SUPPLIED BY RECEIVER IN WORD .IPCAS OF HEADER BLOCK
CPYACT: UMOVE A,.IPCAS(Q2) ;GET USER'S BYTE POINTER
MOVEI B,MESACT-1(T3) ;GET ADDRESS OF ACCOUNT STRING(MINUS 1!)
MOVEI C,.IPCAS(Q2) ;USER ADDRESS INTO WHICH TO RETURN UPDATED BYTE POINTER
CALLRET CPYTU1 ;COPY THE STRING AND RETURN
;SIMILAR ROUTINE TO ABOVE, WHICH COPIES CALLER'S LOGICAL LOCATION
CPYLLO: UMOVE A,.IPCLL(Q2) ;GET POINTER TO WHERE CALLER WANTS STRING PUT
MOVE C,MHA ;CPYACT CLOBBERED IT
MOVEI B,MESLLO-1(C) ;GET ADDRESS OF STRING IN MONITOR SPACE (MINUS 1!)
MOVEI C,.IPCLL(Q2) ;USER ADDRESS FOR UPDATED BYTE POINTER
CALLRET CPYTU1 ;DO IT AND EXIT
;THE MESSAGE SEND JSYS - MSEND
;THIS JSYS ALLOWS ONE PROCESS SEND MESSAGES TO ANY PROCESS IN THE SYSTEM
;ACCEPTS IN 1: COUNT OF ITEMS IN THE HEADER
; 2: LOCATION OF MESSAGE HEADER
; MSEND
;RETURNS +1: ERROR - CODE IN 1
; +2: SUCCESSFUL - PID OF SENDER IN USER'S DESCRIPTOR BLOCK
.MSEND::MCENT ;ENTER SLOW CODE
CALL VALARG ;READ IN ARGUMENTS AND CHECK VALIDITY
RETERR ;SOMETHING NOT RIGHT - ERROR CODE IN T1
NOINT ;LOCK THE LOCKS
CALL GTPIDL ;GET THE PID LOCK
CALL MESSND ;SEND THE MESSAGE
JRST [UNLOKK PIDLKK ;NO GOOD
OKINT
RETERR ()] ;GIVE ERROR RETURN TO USER
UNLOKK PIDLKK ;OK, UNLOCK EVERYTHING
OKINT
CALL STOSPD ;STORE SENDER'S PID IN DESCRIPTOR BLOCK
SMRETN
;ROUTINE TO DO THE SENDING
;ACCEPTS IN ACS: ACS SET UP FROM VALARG
; CALL MESSND
;RETURNS +1: ERROR CODE IN T1
; +2: SUCCESSFUL
MESSND: HRRZ T4,FORKX ;GET JOB # OF FORK DOING JSYS
HLRZ T1,FKJOB(T4)
LOAD T3,PIDSQ,(T1) ;GET CURRENT SEND QUOTA FOR THIS JOB
LOAD T4,PIDSC,(T1) ;GET SEND COUNT
TLNE P1,(IP%CFO) ;ALLOW ONE MORE MESSAGE BIT ON?
ADDI T3,1 ;YES, MAKE QUOTA ONE BIGGER
CAMG T3,T4 ;ROOM FOR ANOTHER MESSAGE?
RETBAD (IPCFX6) ;NO, GIVE ERROR RETURN
CAME P3,INFOPV ;IS THIS THE PUBLIC VALUE OF INFO?
JRST MSEND0 ;NO, DONT GET INFO'S PID
SETZ T1, ;YES, SET UP INDEX TO POINT TO OUR JSB
CALL GTINFO ;GET PID OF INFO FOR THIS JOB
RET ;THERE ISNT AN INFO
MOVE P3,T2 ;STORE PID OF INFO AS RECEVIER'S PID
MSEND0: TLNE P1,(IP%CPD) ;USER WANT A PID CREATED ON CALL?
JRST MSEND2 ;YES, GO CREATE ONE
JUMPE P2,MSEND1 ;0 PID FOR SENDER MEANS NO PID
TRNE P1,IP%CFP ;PRIVELEGED CALL?
CALL CHKPRV ;YES, CHECK CALLERS PRIV'S
SKIPA T1,P2 ;NO PRIVELEGES, CHECK SENDER'S PID
JRST MSEND1 ;PRIVELEGED, DONT CHECK PID OF SENDER
CALL VALPDJ ;CHECK IF PID OF THIS JOB
RETBAD (IPCFX9) ;NOT LEGAL FOR THIS JOB
MSEND1: MOVE T1,P3 ;GET PID OF RECEIVER
MOVEI T2,0 ;GET A BLOCK FOR THIS MESSAGE
CALL MESTOR ;GO ADD THIS MESSAGE TO THE PID
RET ;SOMETHING WAS NOT LEGAL, GIVE ERROR RET
STOR P2,MESSPD,(T1) ;STORE SENDER'S PID IN MESSAGE
SKIPG Q3 ;ZERO LENGTH MESSAGE?
TXO P1,IP%CFZ ;YES, SET ZERO FLAG
MOVE T2,P1 ;FLAGS FOR MESSAGE HEADER
MOVE T3,JOBNO ;GET JOB NUMBER OF SENDER
LOAD T4,PIDSC,(T3) ;GET SENDER'S SEND COUNT
ADDI T4,1 ;INCREMENT IT
STOR T4,PIDSC,(T3) ;STORE UPDATED COUNT
CALL MSHEAD ;FILL IN MESSAGE HEADER
TRNE P1,IP%CFV ;IS THIS A PAGE SEND?
JRST MSEND3 ;PAGE HAS ALREADY BEEN TRANSFERED
JUMPE Q3,MSEND3 ;MESSAGE SIZE = 0?
MOVN T3,Q3 ;NO, SET UP AOBJN WORD
HRLZS T3
HRR T3,T1 ;GET POINTER TO MESSAGE BLOCK
MSENDL: UMOVE T4,0(P4) ;GET WORD FROM USER MESSAGE
STOR T4,MESWD0,(T3) ;STORE IN MESSAGE BLOCK
AOS P4 ;STEP POINTER TO USER MESSAGE
AOBJN T3,MSENDL ;LOOP BACK FOR REST OF MESSAGE
MSEND3: RETSKP ;RETURN SUCCESSFULLY
MSEND2: HRRZ T1,FORKX ;GET THIS FORK #
SETZ T2, ;SET UP FLAGS FOR NEW PID
TLNE P1,(IP%JWP) ;JOB WIDE PID?
JRST [ TRO T2,PD%JWP ;YES, MARK IT AS JOB WIDE
MOVE T1,JOBNO ;GET USER'S JOB#
HRRZ T1,JOBPT(T1) ;JWP'S BELONG TO TOP FORK OF JOB
JRST .+1]
TLNE P1,(IP%NOA) ;NO ACCESS BY OTHER FORKS?
TRO T2,PD%NOA ;YES, MARK THAT ALSO
CALL CREPID ;CREATE THE PID
RET ;ERROR OF SOME KIND
MOVEM T1,P2 ;REMEMBER NEW PID VALUE
CALL STOSPD ;STORE SENDER'S PID IN DESCRIPTOR BLOCK
JRST MSEND1 ;GO BACK TO MAIN FLOW
;ROUTINE TO FILL IN MESSAGE HEADER
;ACCEPTS: T1/ HEADER ADDRESS
; T2/ FLAGS
; T3/ VALUE FOR JOB-#-OF-SENDER FIELD
;RETURNS: +1
MSHEAD: STOR T2,MESFLG,(T1) ;STORE FLAGS
STOR T3,MESSJN,(T1) ;STORE JOB # OF SENDER
MOVE T3,JOBNO ;GET REAL JOB NUMBER
HRRZ T3,JOBDIR(T3) ;GET LOGGED IN DIR
HRLI T3,USRLH ;BUILD THE USER NUMBER
STOR T3,MESLDN,(T1) ;STORE LOGGED IN DIR
LOAD T2,JSUC ;BUILD THE CONNECTED DIR #
LOAD T3,JSDIR ;GET DIR NUMBER
HRL T3,T2 ;GET STR NUMBER,, DIR #
STOR T3,MESCDN,(T1) ;STORE IT TOO
MOVE T3,CAPENB ;GET JOB CAPABILITIES
STOR T3,MESENB,(T1) ;STORE THEM IN MESSAGE HEADER
HRLI T3,ACCTSR ;GET POINTER TO SENDER'S ACCOUNT STRING
HRRI T3,MESACT(T1) ;POINTER TO BLOCK INTO WHICH TO COPY IT
BLT T3,MESACT+MESALN-1(T1) ;COPY IT IN CASE RECEIVER WANTS IT
HRLI T3,LLSR ;POINTER TO SENDER'S LOGICAL LOCATION
HRRI T3,MESLLO(T1) ;POINT TO MESSAGE BLOCK
BLT T3,MESLLO+MESLLN-1(T1) ;COPY LOGICAL LOCATION IN CASE CALLER WANTS IT
RET
;ROUTINE TO STORE THE SENDER'S PID IN THE DESCRIPTOR BLOCK
STOSPD: MOVEI T2,.IPCFS(Q2) ;GET ADR OF WHERE TO STORE THE PID
TLNE P1,(IP%CFS) ;INDIRECT POINTER?
UMOVE T2,0(T2) ;YES, GET ACTUAL ADDRESS
UMOVEM P2,0(T2) ;STORE THE PID
RET ;DONE
;ROUITNE TO PUT A MESSAGE ONTO A PID'S LIST
;ACCEPTS IN T1/ PID
; T2/ POINTER TO MESSAGE, 0 TO GET A BLOCK FOR THE MESSAGE
; Q3/ LENGTH OF MESSAGE DATA AREA IF T2 IS 0
; P1/ FLAGS FOR SEND FUNCTION (IE. PAGE MODE)
; CALL MESTOR
;RETURNS +1: ERROR - ERROR CODE IN T1
; +2: SUCCESSFUL - POINTER TO MESSAGE BLOCK IN T1
MESTOR: STKVAR <MESHED,MESPHD,MESERC>
MOVEM T2,MESHED ;SAVE POINTER TO MESSAGE BLOCK
CALL VALPID ;SEE IF DESTINATION IS LEGAL
RETBAD (IPCFX4) ;NOT A KNOWN PID
MOVEM T2,MESPHD ;SAVE POINTER TO PID HEADER
LOAD T3,PIDFLG,(T2) ;GET FLAGS OF THAT PID
TRNE T3,PD%DIS ;PID DISABLED?
RETBAD (IPCFX5) ;YES, THEN PID CANT BE SENT TO
LOAD T3,PIDRC,(T2) ;GET COUNT OF MESSAGES FOR THIS PID
LOAD T4,PIDRQ,(T2) ;GET QUOTA OF MESSAGES
CAML T3,T4 ;ROOM FOR ONE MORE?
RETBAD (IPCFX7) ;NO, DONT SEND TO IT
SKIPE T1,MESHED ;IS THERE ALREADY A MESSAGE BLOCK?
JRST MESTO1 ;YES, DONT GET ANOTHER
MOVEI T1,MESHDS(Q3) ;GET LENGTH OF MESSAGE BLOCK NEEDED
CAIGE T1,MESHDS ;WAS USER ARGUMENT NEGATIVE?
RETBAD (IPCF24) ;YES
TRNE P1,IP%CFV ;PAGE MODE TRANSFER?
MOVEI T1,PAGMSZ ;YES, GET SIZE OF PAGE MODE MESSAGE
CAILE T1,MAXMSL+MESHDS ;MESSAGE LENGTH OK?
JRST [ TXNE P1,IP%INT ; Internal call?
CAILE T1,MAXSMS+MESHDS ; Ok for system?
RETBAD (IPCF24) ;NO, MESSAGE TOO LARGE
JRST .+1]
CALL ASGSWP ;GET SPACE FOR MESSSAGE
RET ;NOT ENOUGH ROOM
MOVEM T1,MESHED ;SAVE POINTER TO MESSAGE BLOCK
TRNN P1,IP%CFV ;PAGE MODE TRANSFER?
JRST MESTO1 ;NO
CALL SNDPAG ;YES, GO STORE PAGE IN FORK OF JOB 0
JRST [ MOVEM T1,MESERC ;SAVE ERROR CODE
MOVE T1,MESHED ;GET ADDRESS OF MESSAGE BLOCK
CALL RELMES ;RELEASE THE SPACE
MOVE T1,MESERC ;GET BACK ERROR CODE
RET] ;AND GIVE NON-SKIP RETURN
;..
;..
MESTO1: MOVE T1,MESHED ;GET ADDRESS OF MESSAGE
SETZRO MESLNK,(T1) ;CLEAR OUT GARBAGE IN MESLNK
MOVE T2,MESPHD ;GET POINTER TO PID HEADER AGAIN
LOAD T3,PIDNL,(T2) ;GET POINTER TO END OF MESS LIST
SKIPE T3 ;ANY MESSAGES?
STOR T1,MESLNK,(T3) ;YES, ADD THIS MESSAGE TO END OF LIST
SKIPN T3 ;WAS THIS THE FIRST MESSAGE FOR THE PID?
STOR T1,PIDOL,(T2) ;YES, INITIALIZE OLDEST MESSAGE POINTER
STOR T1,PIDNL,(T2) ;UPDATE POINTER TO NEWEST MESSAGE
LOAD T3,PIDRC,(T2) ;GET RECEIVE COUNT
ADDI T3,1 ;INCREMENT IT
STOR T3,PIDRC,(T2) ;STORE IT IN HEADER
CAIN T3,1 ;DID COUNT JUST GO NON-ZERO?
CALL CHKFKW ;SEE IF A FORK IS WAITING AND WAKE IT
MOVE T1,MESHED ;GET BACK POINTER TO MESSAGE BLOCK
RETSKP ;GIVE OK RETURN
;ROUTINE TO PUT A PAGE INTO A FORK OF JOB 0 AWAITING RECEIVING
;ACCEPTS:
; T1/ ADDRESS OF MESSAGE BLOCK
; P4/ PAGE NUMBER TO SEND FROM
; CALL SNDPAG
;RETURNS +1: ERROR, ERROR CODE IN T1
; +2: SUCCESSFUL, MESSAGE BLOCK PROPERLY UPDATED
SNDPAG: STKVAR <SNDPGM,SNDPGP>
MOVEM T1,SNDPGM ;REMEMBER THE MESSAGE ADDRESS
HRLI T1,.FHSLF ;T1/ (THIS FORK,,PAGE NUMBER)
HRR T1,P4 ;PAGE NUMBER TO SEND FROM
MOVEI T2,0 ;USE PC SECTION NUMBER
CALL FKHPTN ;GET PAGE ID
RETBAD ()
MOVEM T1,SNDPGP ;SAVE PTN.PN
CALL MRPACS ;GET ACCESSIBILITY OF PAGE
TLNN T1,(1B10) ;IS THIS A PRIVATE PAGE?
RETBAD (IPCF32) ;NO, GIVE ERROR RETURN
CALL PIDFFP ;GET A FREE FORK PAGE TO USE
RET ;NONE LEFT
ANDCAM T3,PIDPBT(T4) ;MARK THAT THIS PAGE IS IN USE
HLL T2,PIDFTB(T1) ;GET PTN.PN IN T2
MOVE T1,SNDPGM ;GET BACK MESSAGE ADDRESS
STOR T2,MESPTN,(T1) ;SAVE PTN.PT FOR RECEIVER
STOR T3,MSFTM,(T1) ;SAVE MASK
STOR T4,MSFTI,(T1) ;AND INDEX FOR RELEASING PAGE SLOT
MOVEI T3,(PM%MVP!PM%RD!PM%WT!PM%EX)
STOR T3,MESPAC,(T1) ;SAVE ACCESS OF PAGE
HRLZS T3 ;GET BITS INTO LEFT HALF WORD
MOVE T1,SNDPGP ;GET PTN.PN OF PAGE TO BE SENT
CALL SETPT ;TRANSFER THE PAGE
RETSKP ;GIVE OK RETURN
;ROUTINE TO FIND A FREE FORK PAGE TO HOLD A PAGE IN TRANSIT
; CALL PIDFFP
;RETURNS +1: NO MORE PAGES LEFT - ERROR CODE IN T1
; +2: SUCCESSFUL
; T1/ INDEX INTO PIDFTB
; T2/ PAGE # OF DESTINATION FORK
; T3/ MASK IN PAGE BIT TABLE (PIDPBT)
; T4/ INDEX INTO BIT TABLE (PIDPBT)
PIDFFP: MOVSI T4,-PIDPBL ;GET LENGTH OF BIT TABLE
PIDFF0: SKIPE T1,PIDPBT(T4) ;GET NEXT WORD FROM BIT TABLE
JFFO T1,PIDFF1 ;ANY 1 BITS?
AOBJN T4,PIDFF0 ;NO, TRY NEXT WORD
RETBAD (IPCFX8) ;NO MORE PAGES LEFT
PIDFF1: MOVEI T1,^D36 ;FOUND A FREE PAGE
IMULI T1,0(T4) ;TURN IT INTO A PAGE NUMBER
ADDI T1,0(T2) ;...
CAML T1,PIDMXP ;TOO LARGE?
RETBAD (IPCFX8) ;NO MORE ROOM
MOVSI T3,400000 ;NOW CREATE A MASK
MOVNS T2 ;GET NUMBER OF BITS TO SHIFT RIGHT
LSH T3,0(T2) ;MAKE MASK
IDIVI T1,^D512 ;GET PIDFTB INDEX IN T1 AND PN IN T2
RETSKP ;AND RETURN SUCCESSFULY
;THE MUTIL JSYS - MESSAGE UTILITY FUNCTION
;ACCEPTS IN 1: COUNT OF ARGUMENTS IN BLOCK
; 2: LOCATION OF ARGUMENT BLOCK
; MUTIL
;RETURNS +1: ERROR, ERROR CODE IN T1
; +2: SUCCESSFUL
.MUTIL::XCTU [SKIPG Q1,1] ;ANY ARGUMENTS?
RETERR (IPCF17) ;NO, GIVE ERROR RETURN
UMOVE Q2,2 ;GET POINTER TO ARGUMENT BLOCK
UMOVE Q3,0(Q2) ;GET FUNCTION CODE
SKIPLE Q3 ;GREATER THAN ZERO?
CAILE Q3,MAXFUN ;WITHIN BOUNDS?
RETERR (IPCF18) ;NO, GIVE ERROR RETURN
HLRZ P1,MUTLTB-1(Q3) ;GET LENGTH OF MINIMUM ARG BLOCK SIZE
TRZN P1,400000 ;PRIVILEGES REQUIRED?
JRST MUTIL1 ;NO
CALL CHKPRV ;YES, CHECK THEM
RETERR ;USER DOES NOT HAVE PRIV'S
MUTIL1: CAMGE Q1,P1 ;ENOUGH WORDS IN ARG LIST?
RETERR (IPCF17) ;NO, GIVE USER AN ERROR RETURN
HRRZ T1,MUTLTB-1(Q3) ;GET ADDRESS OF ROUTINE
NOINT ;LOCK UP
CALL GTPIDL ;GET THE PID LOCK
CALL (T1) ;DISPATCH TO ROUTINE
JRST [UNLOKK PIDLKK ;ERROR RETURN
OKINT
RETERR()]
UNLOKK PIDLKK ;SUCCESSFUL
OKINT
SMRETN
MUTLTB: 2,,MUTENB ;(1) ENABLE A PID
2,,MUTDIS ;(2) DISABLE A PID
3,,MUTGTI ;(3) GET PID OF INFO
400003,,MUTCPI ;(4) CREATE A PRIVATE INFO FOR A JOB
2,,MUTDES ;(5) DESTROY A PID
3,,MUTCRE ;(6) CREATE A PID
400003,,MUTSSQ ;(7) SET SEND AND RECEIVE QUOTAS
3,,MUTCHO ;(10) CHANGE OWNER OF A PID
3,,MUTFOJ ;(11) FIND OWNER'S JOB NUMBER
3,,MUTFJP ;(12) FIND JOB'S PIDS
3,,MUTFSQ ;(13) FIND SEND AND RECEIVE QUOTAS
1,,MUTILL ;(14) ILLEGAL FUNCTION
3,,MUTFFP ;(15) FIND THE FORK'S PIDS
400003,,MUTSPQ ;(16) SET PID QUOTA
3,,MUTFPQ ;(17) FIND PID QUOTA
5,,MUTQRY ;(20) QUERY
3,,MUTAPF ;(21) ASSOCIATE A PID WITH A FORK
3,,MUTPIC ;(22) PUT A PID ON AN INTERRUPT CHANNEL
400002,,MUTDFI ;(23) DEFINE PID OF [SYSTEM]INFO
400003,,MUTSPT ;(24) SET SYSTEM PID TABLE
3,,MUTSPT ;(25) READ SYSTEM PID TABLE
2,,MUTMPS ;(26) GET MAX PACKET SIZE
3,,MUTSKP ;(27) SET PID TO RECEIVE DELETED PID MESSAGES
3,,MUTRKP ;(30) GET PID TO RECEIVE DELETED PID MESSAGES
2,,MUTSPS ;(31) Get max system packet size
MAXFUN==.-MUTLTB ;MAXIMUM DEFINED FUNCTION
;MUTIL FUNCTIONS 1 AND 2 - ENABLE AND DISABLE A PID
MUTDIS: SKIPA T4,[TRO T3,PD%DIS] ;SET UP TO DISABLE PID FROM RECEIVING
MUTENB: MOVE T4,[TRZ T3,PD%DIS] ;SET UP TO ENABLE PID FOR RECEIVING
UMOVE T1,1(Q2) ;GET PID
PUSH P,T4 ;SAVE FUNCTION
CALL VALPDJ ;VALIDATE THIS PID
JRST [ POP P,(P) ;NOT LEGAL PID OF THIS JOB
RET]
CALL CHKNOA ;SEE IF NO ACCESS BY THIS FORK
JRST [ POP P,(P) ;NO ACCESS
RET] ;GIVE ERROR RETURN
POP P,T4 ;GET BACK FUNCTION
LOAD T3,PIDFLG,(T2) ;GET PID FLAGS
XCT T4 ;PERFORM OPERATION
STOR T3,PIDFLG,(T2) ;PUT FLAGS BACK
RETSKP ;GIVE OK RETURN
;MUTIL FUNCTION 3 - GET [SYSTEM]INFO FOR THIS JOB
MUTGTI: UMOVE T1,1(Q2) ;GET PID OR JOB NUMBER
CALL GETJNO ;GET A JOB NUMBER
RET ;ILLEGAL ARGUMENT
CALL SETJSB ;MAP IN THE APPROPRIATE JSB
CALL GTINFO ;GET THE PID OF INFO FOR THE JOB
SETZ T2, ;NONE, RETURN 0
UMOVEM T2,2(Q2) ;STORE THIS VALUE
PUSH P,T2 ;SAVE PID
CALL CLRJSB ;UNMAP JSB
POP P,T2 ;GET BACK PID
SKIPN T2 ;WAS THERE A PID
RETBAD (IPCF19) ;NO, TELL USER OF THIS
RETSKP ;EXIT SUCCESSFULLY
;MUTIL FUNCTION 4 - CREATE A PRIVATE INFO FOR A JOB
MUTCPI: STKVAR <MUTCPT>
UMOVE T1,1(Q2) ;GET THE NEW INFO PID
CALL VALPID ;IS IT OK?
RET ;NO
MOVEM T1,MUTCPT ;REMEMBER PID
UMOVE T1,2(Q2) ;GET JOB NUMBER OR PID
CALL GETJNO ;GET JOB NUMBER
RET ;ILLEGAL VALUE
CALL SETJSB ;MAP IN JSB OF THIS JOB
MOVE T2,MUTCPT ;GET BACK PID
MOVEM T2,JBINFO(T1) ;STORE PID INTO JSB
CALL CLRJSB ;UNMAP THE JSB
RETSKP ;RETURN SUCCESSFULLY
;MUTIL FUNCTION 5 - DESTROY A PID
MUTDES: STKVAR <MUTDEP,MUTDEQ>
UMOVE T1,1(Q2) ;GET PID TO BE DESTROYED
CALL VALPDJ ;VALIDATE IT
RET ;NOT A LEGAL PID FOR THIS JOB
CALL CHKNOA ;CHECK NO ACCESS BY THIS FORK
RET ;NOT ACCESSABLE, GIVE ERROR RETURN
MOVEM T1,MUTDEP ;SAVE PID BEING DELETED
CALL DELPID ;DELETE THE PID
RET ;COULD NOT DELETE IT
MOVEM Q3,MUTDEQ ;SAVE Q3
MOVEI Q3,3 ;GET LENGTH OF MESSAGE FOR INFO
CALL IPCDEL ;SET UP A MESSAGE FOR INFO
JRST MUTDE1 ;CANNOT GET SPACE FOR MESSAGE
MOVE T2,MUTDEP ;RETREIVE PID THAT WAS DROPPED
STOR T2,MESWD0,(T1) ;PUT IT INTO THE MESSAGE
MUTDE1: MOVE Q3,MUTDEQ ;RESTORE Q3
RETSKP ;RETURN SUCCESSFULLY
;MUTIL FUNCTION 6 - CREATE A PID
MUTCRE: XCTU [HRRZ T1,1(Q2)] ;GET FORK HANDLE OR JOB NUMBER
CAIN T1,-1 ;THIS JOB?
MOVE T1,JOBNO ;YES, GET OUR JOB NUMBER
TRNE T1,400000 ;FORK OR JOB NUMBER?
JRST [ TRNE T1,200000 ;SPECIAL DESIGNATOR?
RETBAD (IPCF20) ;YES, NOT ALLOWED
CALL MFLOCK ;LOCK UP FORK LOCK
CALL STJFKR ;GET JOB FORK INDEX FROM HANDLE
JRST [ CALL MFUNLK ;BAD FORK HANDLE
RETBAD (IPCF20)]
HRRZ T1,SYSFK(T1) ;GET SYSTEM FORK HANDLE
CALL MFUNLK ;UNLOCK FORK LOCK
JRST MUTCR1] ;GO CREATE THE PID
CAIL T1,NJOBS ;WITHIN BOUNDS AS A JOB NUMBER?
RETBAD (IPCF21) ;NO
HRRZ T1,JOBPT(T1) ;YES, GET TOP FORK OF THAT JOB
MUTCR1: XCTU [HLLZ T3,1(Q2)] ;GET FLAGS
HLRZ T2,FKJOB(T1) ;GET JOB NUMBER OF OWNER
HRRZ T2,JOBPT(T2) ;GET TOP FORK OF OWNER
TLNE T3,(IP%JWP) ;USER WANT A JOB WIDE PID?
MOVE T1,T2 ;YES, USE THE TOP FORK OF JOB AS OWNER
SETZ T2, ;INITIALIZE FLAGS ARGUMENT
TLNE T3,(IP%JWP) ;JOB WIDE PID?
TRO T2,PD%JWP ;YES, CREATE THIS PID FOR TOP FORK
TLNE T3,(IP%NOA) ;NO ACCESS BY OTHER FORKS?
TRO T2,PD%NOA ;YES, MARK IT AS SUCH
CALL CREPID ;CREATE THE PID
RET ;ERROR
UMOVEM T1,2(Q2) ;STORE PID IN USERS SPACE
RETSKP ;AND RETURN
;MUTIL FUNCTION 7 - SET SEND AND RECEIVE QUOTAS
MUTSSQ: UMOVE T1,1(Q2) ;GET PID TO BE SET FOR
CALL VALPID ;VALIDATE IT
RET ;ILLEGAL PID
UMOVE T3,2(Q2) ;GET QUOTAS
LDB T4,[POINT 9,T3,35] ;GET RECEIVE QUOTA
STOR T4,PIDRQ,(T2) ;STORE NEW QUOTA
LDB T4,[POINT 9,T3,26] ;GET SEND QUOTA
LOAD T3,PIDFO,(T2) ;GET JOB NUMBER OF OWNER
HLRZ T3,FKJOB(T3) ;...
STOR T4,PIDSQ,(T3) ;STORE SEND QUOTA FOR JOB
RETSKP
;MUTIL FUNCTION 10 - CHANGE OWNER OF A PID
MUTCHO: STKVAR <SAVCHO>
CALL CHKWHL ;MUST BE A WHEEL FOR THIS FUNCTION
RET ;NOT A WHEEL
UMOVE T1,2(Q2) ;GET PID OR JOB NUMBER OF NEW OWNER
SKIPL T1 ;SEE IF IT IS A JOB #
CAIL T1,NJOBS ;...
JRST [ CALL VALPID ;NOT A JOB #, TRY FOR A PID
RET ;NOT A LEGAL PID
LOAD T3,PIDFO,(T2) ;GET FORK # OF OWNER
JRST MUTCH1] ;GO CHANGE OWNER
HRRZ T3,JOBPT(T1) ;JOB # SPECIFIED, USE TOP FORK OF JOB
MUTCH1: MOVEM T3,SAVCHO ;SAVE FORK # OF OWNER
UMOVE T1,1(Q2) ;GET PID TO BE CHANGED
CALL VALPID ;VALIDATE IT
RET ;ILLEGAL
MOVE T3,SAVCHO ;GET FORK # AGAIN
HLRZ T4,FKJOB(T3) ;GET JOB NUMBER
LOAD T3,PIDPQ,(T4) ;GET PID QUOTA FOR THIS JOB
LOAD T1,PIDPC,(T4) ;AND GET THE ACTUAL COUNT OF PIDS
CAMG T3,T1 ;IS THERE ROOM FOR ONE MORE?
RETBAD (IPCF13) ;NO, GIVE ERROR RETURN
AOS T1 ;COUNT UP COUNT OF PIDS
STOR T1,PIDPC,(T4) ;SAVE NEW COUNT OF PIDS
CALL CHKFKW ;SEE IF A FORK IS WAITING, AND WAKE IT
MOVEI T3,-1 ;NOW CLEAR OUT WAITING FORK
STOR T3,PIDFW,(T2) ;...
LOAD T3,PIDFLG,(T2) ;GET FLAGS
TRZ T3,PD%CHN ;CLEAR OUT CHANNEL ASSIGNED BIT
STOR T3,PIDFLG,(T2) ;USER WILL HAVE TO SET CHANNEL BACK UP
LOAD T3,PIDFO,(T2) ;GET PREVIOUS OWNER
HLRZ T3,FKJOB(T3) ;GET ITS JOB NUMBER
LOAD T4,PIDPC,(T3) ;GET PRESENT COUNT OF PIDS IN THAT JOB
SOJL T4,[BUG(PIDOD1)
JRST MUTCH2] ;DONT STORE BAD COUNT
STOR T4,PIDPC,(T3) ;STORE BACK UPDATED PID COUNT
MUTCH2: MOVE T3,SAVCHO ;GET NEW FORK # OF OWNER
STOR T3,PIDFO,(T2) ;PUT IT BACK IN THE PID HEADER
RETSKP ;AND RETURN
;MUTIL FUNCTION 11 - FIND OWNER OF A PID
MUTFOJ: UMOVE T1,1(Q2) ;GET PID
CALL VALPID ;VALIDATE IT
RET ;NOT A LEGAL PID
LOAD T3,PIDFO,(T2) ;GET FORK NUMBER OF OWNER
HLRZ T3,FKJOB(T3) ;CONVERT IT INTO A JOB NUMBER
UMOVEM T3,2(Q2) ;STORE IT IN ARG LIST
RETSKP ;RETURN SUCCESSFULLY
;MUTIL FUNCTIONS 12 AND 15 - FIND PIDS OF A JOB AND OF A FORK
MUTFJP: UMOVE T1,1(Q2) ;GET ARGUMENT
CALL GETJNO ;TURN IT INTO A JOB NUMBER
RET ;ILLEGAL ARGUMENT
MOVE T2,[CALL GETNPJ] ;GET ROUTINE TO BE CALLED
JRST MUTFPC ;GO TO COMMON CODE
MUTFFP: UMOVE T1,1(Q2) ;GET PID
CALL VALPID ;SEE IF IT IS A LEGAL PID
RET ;NO LEGAL
LOAD T1,PIDFO,(T2) ;GET FORK NUMBER OF PID OWNER
MOVE T2,[CALL GETNPF] ;GET ROUTINE TO BE CALLED
MUTFPC: STKVAR <MUTFJI,MUTFJN>
MOVEM T1,MUTFJN ;STORE JOB NUMBER OR FORK NUMBER
MOVEM T2,MUTFJI ;SAVE INSTRUCTION
MOVEI T1,0 ;START AT PID INDEX 0
AOS Q2 ;START ANSWER AT LOC+2
SOJLE Q1,RSKP ;COUNT DOWN SPACE COUNTER
MUTFPL: AOS Q2 ;ADVANCE POINTER TO USER AREA
SOJLE Q1,RSKP ;ANY MORE ROOM?
MOVE T2,MUTFJN ;GET JOB NUMBER OR FORK NUMBER
XCT MUTFJI ;YES, GET NEXT PID FOR JOB OR FORK
JRST MUTFPD ;NO MORE, GO TACK 0 ON END OF LIST
UMOVEM T1,0(Q2) ;STORE PID
AOS Q2
SOJLE Q1,RSKP ;ANY MORE ROOM FOR FLAGS?
LOAD T3,PIDFLG,(T2) ;GET FLAGS
SETZ T4, ;INITIALIZE ANSWER
TRNE T3,PD%JWP ;IS THIS A JOB WIDE PID?
TLO T4,(IP%JWP) ;YES, SET FLAG
TRNE T3,PD%NOA ;NO ACCESS BY OTHER FORKS
TLO T4,(IP%NOA) ;YES, SET BIT
UMOVEM T4,0(Q2) ;STORE FLAGS
JRST MUTFPL ;LOOP BACK FOR ALL PIDS
MUTFPD: XCTU [SETZM 0(Q2)] ;END LIST WITH A ZERO
RETSKP ;AND EXIT
;MUTIL FUNCTION 13 - FIND SEND AND RECEIVE QUOTAS
MUTFSQ: UMOVE T1,1(Q2) ;GET PID
CALL VALPID ;VALIDATE IT
RET ;ILLEGAL PID
LOAD T3,PIDFO,(T2) ;GET FORK NUMBER OF OWNER
HLRZ T3,FKJOB(T3) ;TRANSLATE INTO JOB NUMBER
LOAD T3,PIDSQ,(T3) ;GET SEND QUOTA OF JOB
LOAD T4,PIDRQ,(T2) ;GET RECEIVE QUOTA OF PID
DPB T3,[POINT 9,T4,26] ;SET UP ANSWER
UMOVEM T4,2(Q2) ;GIVE ANSWER TO USER
RETSKP
;MUTIL FUNCTION 14 - ILLEGAL
MUTILL: RETBAD (IPCF18) ;ILLEGAL FUNCTION
;MUTIL FUNCTIONS 16 AND 17 - SET AND FIND PID QUOTA
MUTSPQ: UMOVE T1,1(Q2) ;GET ARGUMENT
CALL GETJNO ;GET THE JOB NUMBER DESIRED
RET ;ILLEGAL ARGUMENT
UMOVE T2,2(Q2) ;GET SECOND ARGUMENT
SKIPL T2 ;IS THIS A LEGAL VALUE?
CAILE T2,MAXQTA ;...
RETBAD (IPCF35) ;NO
STOR T2,PIDPQ,(T1) ;STORE NEW QUOTA
RETSKP ;AND RETURN SUCCESS
MUTFPQ: UMOVE T1,1(Q2) ;GET ARGUMENT
CALL GETJNO ;GET THE JOB NUMBER DESIRED
RET ;ILLEGAL ARGUMENT
LOAD T2,PIDPQ,(T1) ;GET QUOTA
UMOVEM T2,2(Q2) ;WRITE ANSWER BACK
RETSKP
;ROUTINE TO GET A JOB NUMBER OF A PID GIVEN A PID OR A JOB NUMBER
;ACCEPTS IN T1/ JOB NUMBER OR PID
; CALL GETJNO
;RETURNS +1: ERROR, ILLEGAL ARG
; +2: T1/ JOB NUMBER
GETJNO: CAMN T1,[-1] ;IS THIS A REQUEST FOR OUR JOB?
JRST [ MOVE T1,JOBNO ;YES, GET OUR JOB NUMBER
RETSKP] ;AND RETURN
TLNN T1,-1 ;IS THIS A JOB NUMBER?
JRST GETJN1 ;YES, GO CHECK ITS LEGALITY
CALL VALPID ;NOT A JOB #, TRY A PID
RET ;NOT A PID EITHER
LOAD T3,PIDFO,(T2) ;GET FORK # OF OWNER
HLRZ T1,FKJOB(T3) ;GET JOB NUMBER
GETJN1: CAIL T1,NJOBS ;IS THIS A LEGAL JOB NUMBER
RETBAD (IPCF21) ;NO, GIVE ILLEGAL JOB NUMBER RETURN
SKIPGE JOBRT(T1) ;IS THE JOB LOGGED IN
RETBAD (IPCF30) ;NOT IN EXISTENCE
RETSKP
;MUTIL FUNCTION 20 - QUERY
MUTQRY: UMOVE T1,1(Q2) ;GET PID
CAMN T1,[-1] ;IS THIS A REQUEST FOR THE WHOLE FORK?
JRST [ CALL FNDNMF ;YES, GO FIND THE NEXT MESSAGE FOR FORK
RETBAD (IPCFX2) ;THERE ARE NO MESSAGES READY
JRST MUTQR1] ;GO RETURN INFO ABOUT THIS MESSAGE
CAMN T1,[-2] ;IS THIS A REQUEST FOR THE WHOLE JOB?
JRST [ CALL FNDNMJ ;YES, FIND THE NEXT MESSAGE FOR THE JOB
RETBAD (IPCFX2) ;THERE ARE NO MESSAGES WAITING
JRST MUTQR1] ;GO GIVE USER INFO ABOUT THIS MESSAGE
CALL VALPDJ ;VALIDATE THAT THIS IS LEGAL PID FOR JOB
RET ;ILLEGAL PID FOR THIS JOB TO QUERY
CALL CHKNOA ;SEE IF ACCESSABLE BY THIS FORK
RET ;NOT ACCESSABLE, GIVE ERROR RETURN
MUTQR1: LOAD T3,PIDOL,(T2) ;GET POINTER TO OLDEST MESSAGE IN QUEUE
JUMPE T3,[RETBAD (IPCFX2)] ;NO MESSAGES IN THE QUEUE
SOS Q1 ;SET UP TO COPY HEADER
AOS Q2 ;POINT TO AREA TO RECEIVE DATA
LOAD T4,MESFLG,(T3) ;GET FLAGS OF MESSAGE
UMOVEM T4,.IPCFL(Q2) ;GIVE THEM TO THE USER
LOAD T4,PIDRC,(T2) ;GET NUMBER OF MESSAGES IN QUEUE
XCTU [HRRM T4,.IPCFP(Q2)] ;RETURN COUNT TO USER
CALL CPYMHD ;GIVE USER THE MESSAGE HEADER
XCTU [HRLM T1,.IPCFP(Q2)] ;STORE MESSAGE LENGTH ALSO
RETSKP ;ALL THROUGH
;MUTIL FUNCTION 21 - ASSIGN A PID TO A FORK
MUTAPF: STKVAR <MUTAPT>
UMOVE T1,2(Q2) ;GET FORK HANDLE
TRNE T1,200000 ;SPECIAL FUNCTION?
RETBAD (IPCF20) ;YES, GIVE ERROR RETURN
CALL MFLOCK ;LOCK UP FORK LOCK
CALL STJFKR ;GET JOB FORK HANDLE
JRST [ CALL MFUNLK ;ILLEGAL FORK HANDLE
RETBAD (IPCF20)]
HRRZ T1,SYSFK(T1) ;GET SYSTEM WIDE FORK HANDLE
MOVEM T1,MUTAPT ;SAVE IT
CALL MFUNLK ;UNLOCK FORK LOCK
UMOVE T1,1(Q2) ;GET PID
CALL VALPDJ ;VALIDATE IT
RET ;ILLEGAL
MOVE T3,MUTAPT ;GET FORK #
STOR T3,PIDFO,(T2) ;SET UP NEW OWNER
RETSKP ;AND RETURN
;MUTIL FUNCTION 22 - PUT A PID ON AN INTERRUPT CHANNEL
MUTPIC: STKVAR <MUTPIT>
UMOVE T1,1(Q2) ;GET PID
CALL VALPDJ ;LEGAL PID FOR THIS JOB?
RET ;NO, GIVE ERROR RETURN
UMOVE T3,2(Q2) ;GET CHANNEL
CAMN T3,[-1] ;REMOVING IT
JRST MUTPI1 ;YES, GO DO SO
SKIPL T3 ;CHECK LEGALITY OF CHANNEL
CAIL T3,^D36 ;...
RETBAD (IPCF22) ;NOT BETWEEN 0 AND 35
MOVEM T3,MUTPIT ;SAVE CHANNEL NUMBER
CALL MFLOCK ;LOCK UP FORK LOCK
CALL VALPDJ ;MUST RE-VALIDATE THE PID
JRST [ CALL MFUNLK ;PID WENT AWAY
RET] ;GIVE ERROR RETURN
CALL CHKNOA ;NO ACCESS BY THIS FORK
JRST [ CALL MFUNLK ;YES, GIVE ERROR RETURN
RET]
CALL CHKPDW ;SEE IF LEGAL TO PUT PID ON A CHANNEL
JRST [ CALL MFUNLK ;NO, A SUPERIOR FORK HAS IT
RET]
MOVE T3,MUTPIT ;GET BACK CHANNEL NUMBER
STOR T3,PIDCHN,(T2) ;STORE CHANNEL NUMBER
LOAD T3,PIDFLG,(T2) ;GET FLAGS
TRO T3,PD%CHN ;MARK THAT A CHANNEL IS SET UP
STOR T3,PIDFLG,(T2) ;SAVE NEW FLAGS
MOVE T3,FORKX ;GET OUR FORK NUMBER
STOR T3,PIDFW,(T2) ;MARK THAT WE ARE WAITING FOR INTERRUPTS
LOAD T3,PIDRC,(T2) ;ANY MESSAGES FOR THIS PID?
SKIPE T3 ;...
CALL CHKFKW ;YES, GO CAUSE AN INTERRUPT
CALL MFUNLK ;UNLOCK THE FORK LOCK
RETSKP ;ALL THRU
MUTPI1: MOVEI T4,-1 ;SET UP TO CLEAR WAITER
LOAD T3,PIDFLG,(T2) ;GET PID FLAGS
TRZE T3,PD%CHN ;CLEAR THE FLAG THAT SAYS A CHN EXISTS
STOR T4,PIDFW,(T2) ;CLEAR WAITING PID ONLY IF ONE WAS THERE
STOR T3,PIDFLG,(T2) ;SAVE NEW FLAGS
RETSKP ;ALL DONE
;MUTIL FUNCTION 23 - DEFINE PID OF [SYSTEM]INFO
MUTDFI: SKIPE INFOPD ;ALREADY HAVE A PID FOR INFO?
RETBAD (IPCF23) ;YES, THIS IS AN ERROR
UMOVE T1,1(Q2) ;GET NEW PID
CALL VALPID ;VALIDATE IT
RET ;NOT A VALID PID
MOVEM T1,INFOPD ;SAVE NEW VALUE OF [SYSTEM]INFO PID
MOVEM T1,.SPINF+SPIDTB ;PUT IT IN SYSTEM PID TABLE ALSO
RETSKP ;AND RETURN
;MUTIL FUNCTION 24 AD 25 - SET AND READ SYSTEM PID TABLE
MUTSPT: UMOVE T1,2(Q2) ;GET PID IF SPECIFIED
XCTU [HRRZ T2,1(Q2)] ;GET INDEX INTO TABLE
CAIL T2,SPDTBL ;IS THIS A LEGAL INDEX VALUE?
RETBAD (IPCF33) ;NO, GIVE ERROR RETURN
CAIE Q3,.MUSSP ;IS THIS A SET REQUEST?
JRST MUTSP1 ;NO
MOVEM T1,SPIDTB(T2) ;YES, STORE NEW PID
JUMPE T1,RSKP ;IF ARG IS 0, THEN CLEARING LOCATION
MUTSP1: SKIPN T1,SPIDTB(T2) ;IS THERE A PID THERE?
RETBAD (IPCF27) ;NO, NOT A DEFINED PID THERE
PUSH P,T2 ;SAVE INDEX
CALL VALPID ;IS THIS A LEGAL PID?
JRST [ POP P,T2 ;NO, GET BACK INDEX INTO TABLE
SETZM SPIDTB(T2) ;CLEAR OUT BAD PID
RET] ;AND GIVE ERROR RETURN
POP P,T2 ;GET BACK INDEX
MOVE T1,SPIDTB(T2) ;AND GET BACK PID
CAIN Q3,.MURSP ;IS THIS A READ REQUEST?
UMOVEM T1,2(Q2) ;YES, RETURN PID TO USER
RETSKP ;GIVE OK RETURN
;MUTIL FUNCTION 26 - GET MAXIMUM PACKET SIZE
MUTMPS: MOVEI T1,MAXMSL ;GET MAX MESSAGE SIZE ALLOWED
UMOVEM T1,1(Q2) ;GIVE IT TO USER
RETSKP ;AND EXIT
;MUTIL FUNCTION 27 - GET MAXIMUM SYSTEM PACKET SIZE
MUTSPS: MOVEI T1,MAXSMS ; Get max size allowed
UMOVEM T1,1(Q2) ; Hand to the user
RETSKP ; And exit
;MUTIL FUNCTION 27 - SET PID TO RECEIVE DELETED PID MESSAGES
MUTSKP: STKVAR <MUTSKT>
UMOVE T1,1(Q2) ;GET THE PID
CALL VALPDJ ;SEE IF WE ARE ALLOWED TO DO THIS
RETBAD ;NO
CALL CHKNOA ;MAKE SURE THAT ACCESS IS LEGAL
RETBAD
MOVEM T2,MUTSKT ;SAVE THE PID INDEX
UMOVE T1,2(Q2) ;GET THE RECEIVER PID
CALL VALPID ;VALIDATE THE RECEIVER PID
RET ;ILLEGAL PID
MOVE T2,MUTSKT ;GET BACK ORIGINAL PID HEADER ADR
STOR T1,PIDKMP,(T2) ;STORE THE PID IN THE HEADER
RETSKP ;DONE
;MUTIL FUNCTION 30 - READ PID TO RECEIVE DELETED PID MESSAGES
MUTRKP: UMOVE T1,1(Q2) ;GET THE PID
CALL VALPDJ ;VALIDATE IT
RETBAD
LOAD T3,PIDKMP,(T2) ;GET THE PID TO RECEIVE DELETED MESSAGE
UMOVEM T3,2(Q2) ;RETURN IT TO THE USER
RETSKP
;ROUTINE TO VALIDATE THE USERS ARGUMENTS AND SET UP Q1-Q2, P1-P4
; CALL VALARG
;RETURNS +1: SOMETHING ILLEGAL - ERROR CODE IN T1
; +2: Q1/ COUNT OF WORDS IN PID DISCRIPTOR BLOCK FROM USER
; Q2/ USER ADDRESS OF PID DESCRIPTOR BLOCK
; Q3/ SIZE OF MESSAGE AREA FROM USER
; P1/ FLAGS FROM USER
; P2/ SENDER'S PID
; P3/ RECEIVER'S PID
; P4/ ADDRESS OF MESSAGE IN USER SPACE
VALARG: XCTU [HRRZ Q1,1] ;GET LENGTH OF DESCRIPTOR BLOCK
UMOVE Q2,2 ;GET POINTER TO DESCRIPTOR BLOCK
CAIGE Q1,MINPHL ;LONG ENOUGH?
RETBAD (IPCFX1) ;NO
UMOVE P1,.IPCFL(Q2) ;GET FLAGS
;**;[2643]CHANGE 1 LINE AT VALARG:+5L TAM 4-AUG-82
TXZ P1,IP%INT+IP%CFZ ;[2643]Clear impossible bits
UMOVE P2,.IPCFS(Q2) ;GET SENDER'S PID
TLNE P1,(IP%CFS) ;INDIRECT SENDER'S PID?
UMOVE P2,0(P2) ;YES, GET ACTUAL PID
UMOVE P3,.IPCFR(Q2) ;GET RECEIVER'S PID
TLNE P1,(IP%CFR) ;INDIRECT POINTER?
UMOVE P3,0(P3) ;YES, GET ACTUAL VALUE
UMOVE P4,.IPCFP(Q2) ;GET POINTER TO MESSAGE
HLRZ Q3,P4 ;SET UP Q3 WITH LENGTH OF MESSAGE
HRRZS P4 ;CLEAR LEFT HALF OF ADDRESS
TRNN P1,IP%CFV ;PAGE MODE?
JRST VALAR1 ;NO
TRNE P4,777000 ;IS THE PAGE NUMBER LEGAL?
RETBAD (IPCF31) ;NO
TLNE P1,(IP%TTL) ;TRUNCATE IF TOO LONG?
JUMPE Q3,VALAR1 ;YES, 0 IS OK FOR PAGE MODE
CAIE Q3,PGSIZ ;OTHERWISE, LENGTH MUST BE 1 PAGE
RETBAD (IPCF24) ;NOT LEGAL SIZE
VALAR1: CALL CHKPRV ;SEE IF CALLER IS PRIV'D
;**;[2643]CHANGE 1 2641 LINE AT VALAR1:+1L TAM 4-AUG-82
;**;[2641]CHANGE 1 LINE AT VALAR1:+1L TAM 3-AUG-82
TXNN P1,IP%CFP+IP%CFC+IP%CFM ;[2641][2643] NO, PRIVELEGED FUNCTION?
RETSKP ;NOT PRIV'D FUNCTION OR USER HAS PRIV'S
RET ;YES, GIVE ERROR RETURN
;ROUTINE TO VALIDATE A PID AS BELONGING TO THE CURRENT JOB
;ACCEPTS IN 1: PID
; CALL VALPDJ
;RETURNS +1: PID NOT VALID FOR THIS JOB
; +2: PID LEGAL FOR THIS JOB
; T1/ PID
; T2/ POINTER TO PID HEADER
VALPDJ: CALL VALPID ;SEE IF PID IS LEGAL AT ALL
RET ;IT ISNT
LOAD T3,PIDFO,(T2) ;GET FORK # OF OWNER
HRRZ T4,FORKX ;GET CURRENT FORK #
HLRZ T3,FKJOB(T3) ;GET JOB # OF PID OWNER
HLRZ T4,FKJOB(T4) ;GET JOB # OF THIS JOB
CAME T3,T4 ;SAME JOB?
RETBAD (IPCF25) ;NO
RETSKP ;YES
;ROUTINE TO SEE IF A PID IS A VALID ONE
;ACCEPTS IN 1: PID
; CALL VALPID
;RETURNS +1: ERROR RETURN, PID IS NOT VALID
; +2: SUCCESSFULL
; T1/ PID
; T2/ ADDRESS OF PID HEADER BLOCK
VALPID: CALL GETPID ;GET HALF WORD ENTRY FROM PID TABLE
RET ;ILLEGAL PID TABLE INDEX
CAIGE T2,SWFREE ;IS THIS PID ON THE FREE LIST?
RETBAD (IPCF27) ;YES, GIVE ERROR RETURN
LOAD T3,PIDUN,(T2) ;GET UNIQUE NUMBER FROM PID HEADER
HRL T3,T1 ;BUILD THE FULL PID
MOVSS T3 ;GET PID IN RIGHT ORDER
CAME T3,T1 ;DO THE TWO PIDS MATCH?
RETBAD (IPCF27) ;NO, INVALID PID
RETSKP ;YES, PID IS VALID
;ROUTINE TO WAIT FOR A MESSAGE TO ARRIVE FOR A PID OR MULTIPLE PIDS
;THIS ROUTINE ASSUMES THAT "PIDFW" HAS BEEN SET UP FOR EACH PID
; CALL MWAIT
;RETURNS +1: ALLWAYS, AFTER A WAKE UP OCCURED. ALL LOCKS SET.
MWAIT: MOVE T1,FORKX ;WAIT THIS FORK
CALL GETMSK ;GET MASK INTO PDFKTB IN T2
ANDCAM T2,PDFKTB(T1) ;CLEAR THE WAITING BIT
UNLOKK PIDLKK ;UNLOCK THE LOCKS WHILE WAITING
OKINT
CALL FUNLK ;UNLOCK THE FORK LOCK
HRRI T1,PIDWAT ;SET UP FOR MDISMS
HRL T1,FORKX ;XWD DATA,ADDRESS OF TEST ROUTINE
MOVEI T2,^D50 ;HOLD IN THE BALANCE SET FOR 50 MS
HDISMS ;DISMIS UNTIL TEST SUCCEEDS
CALL GTLCKS ;GET FORK LOCK AND PID LOCK
CALLRET ENDWAT ;CLEAR PIDFW
;ROUTINE TO CLEAR PIDFW WHERE EVER FORKX IS THE FORK NUMBER IN PIDFW
; CALL ENDWAT
;RETURNS +1: ALWAYS, FORKX NO LONGER WAITING ON ANY PID
ENDWAT: MOVEI T1,1 ;NOW CLEAR PIDFW FOR THIS FORK
ENDWT1: CALL GETPID ;LOOP THRU ALL PIDS
RET ;NO MORE TO LOOK AT
CAIGE T2,SWFREE ;IS THIS A PID ON THE FREE LIST?
AOJA T1,ENDWT1 ;YES, IGNORE IT
LOAD T3,PIDFLG,(T2) ;GET FLAGS FOR THIS PID
TRNE T3,PD%CHN ;IS THIS PID ON AN INTERRUPT CHANNEL?
AOJA T1,ENDWT1 ;YES, IGNORE IT ALSO
LOAD T3,PIDFW,(T2) ;GET WAITING FORK NUMBER
CAMN T3,FORKX ;THIS OUR FORK NUMBER?
MOVEI T3,-1 ;YES, SET TO -1 TO MEAN NOBODY WAITING
STOR T3,PIDFW,(T2) ;PUT BACK VALUE
AOJA T1,ENDWT1 ;LOOP FOR ALL PIDS
;ROUTINE TO GET BOTH THE FORK LOCK AND THE PID LOCK
;RETURNS: +1 NOINT WITH BOTH LOCKS
;To avoid deadly embrace, give up the first one if we can't get the
;second one, wait a while, and try again.
GTLCKS: CALL FLOCK ;GET THE FORK LOCK
NOINT ;NOINT FOR PID LOCK
LOKK PIDLKK,<JRST GTLCK1>
RET ;GOT IT, DONE
;COULDN'T GET PIDLKK. GIVE UP FORK LOCK AND WAIT A WHILE
GTLCK1: OKINT
CALL FUNLK ;UNLOCK FORK LOCK
MOVEI T1,^D200 ;WAIT 200 MS BEFORE RECHECKING
DISMS
JRST GTLCKS ;GO GET BOTH LOCKS
;GET THE PID LOCK. THIS ROUTINE IS CALLED WHILE NOINT.
GTPIDL: LOKK PIDLKK,<JRST GTPIDF> ;GET THE PID LOCK
RET ;GOT IT
GTPIDF: OKINT ;INTERRUPTABLE NOW
PUSH P,T1 ;PRESERVE IT
MOVEI T1,^D200 ;WAIT A BIT BEFORE
DISMS ; CHECKING AGAIN
POP P,T1 ;GET IT BACK
NOINT ;NOT INTERRUPTABLE WHILE GETTING LOCK
JRST GTPIDL ;GO TRY IT AGAIN
RESCD
;ROUTINE CALLED BY SCHED TO SEE IF THIS FORK HAS BEEN WOKEN
;ACCEPTS IN T1: DATA FROM MDISMS (FORK NUMBER)
; JSP T4,PIDWAT
;RETURNS +1: THIS FORK HAS NOT BEEN AWAKENED
; +2: THE BIT IN PDFKTB WAS SET AND THIS FORK SHOULD BE RUN
PIDWAT::PUSH P,T4 ;SAVE RETURN
CALL GETMSK ;GET BIT MASK INTO T2
TDNN T2,PDFKTB(T1) ;IS THIS FORK TO BE AWAKENED?
RET ;NO
RETSKP ;YES
;ROUTINE TO GET A BIT MASK FOR THE PDFKTB FOR A PARTICULAR FORK
;ACCEPTS IN T1: FORK NUMBER
; CALL GETMSK
;RETURNS +1: ALWAYS
; T1/ INDEX INTO PDFKTB
; T2/ BIT MASK FOR THIS FORK
GETMSK::IDIVI T1,^D36 ;GET BIT POSITION
MOVN T3,T2 ;SET UP FOR SHIFT
MOVSI T2,400000 ;INITIALIZE BIT MASK
LSH T2,(T3) ;GET THE MASK
RET ;AND RETURN
SWAPCD
;ROUTINE TO SEE IF A FORK IS WAITING FOR A MESSAGE AND TO WAKE IT
;ACCEPTS IN T1/ PID
; T2/ PID HEADER ADDRESS
; CALL CHKFKW
;RETURNS +1: ALWAYS - FORK WAKENED IF ONE WAS WAITING
CHKFKW: SAVEAC <T1,T2> ;PRESERVE THESE
LOAD T4,PIDFW,(T2) ;GET WAITING FORK
CAIN T4,-1 ;ANY FORK WAITING?
RET ;NO, DONE
LOAD T3,PIDFLG,(T2) ;GET FLAGS OF PID
TRNE T3,PD%CHN ;IS THERE A CHANNEL SET UP FOR THIS PID?
CALL INTFRK ;YES, GO INTERRUPT THE FORK
LOAD T1,PIDFW,(T2) ;GET WAITING FORK
CALL WAKFRK ;GO WAKE FORK
RET ;AND RETURN
;ROUTINE TO WAKE UP A FORK THAT IS WAITING FOR A MESSAGE
;ACCEPTS IN T1: FORK NUMBER TO BE AWAKENED
; CALL WAKFRK
;RETURNS +1: ALWAYS
WAKFRK: PUSH P,T1 ;SAVE FORK INDEX
CALL GETMSK ;GET BIT MASK INTO PDFKTB
IORM T2,PDFKTB(T1) ;SET THE BIT
POP P,T1 ;GET BACK FORK INDEX
CALLRET UNBLKF ;GO UNBLOCK THE FORK
;ROUTINE TO CAUSE A SOFTWARE INTERRUPT TO A FORK WAITING FOR A PID
;ACCEPTS IN T1: PID
; T2: POINTER TO PID HEADER
; CALL INTFRK
;RETURNS +1: ALWAYS
INTFRK: PUSH P,T1 ;SAVE PID
PUSH P,T2 ;AND POINTER
LOAD T1,PIDCHN,(T2) ;GET CHANNEL NUMBER TO INTERRUPT ON
LOAD T2,PIDFW,(T2) ;GET FORK NUMBER TO BE AWAKENED
CALL PSIRQ ;GO INTERRUPT
POP P,T2
POP P,T1
RET ;AND RETURN
;ROUTINE TO SEE IF THIS FORK HAS SC%IPC OR SC%WHL PRIVILEGES
; CALL CHKPRV
;RETURNS +1: DOES NOT HAVE SC%WHL OR SC%IPC PRIVS
; +2: THIS FORK HAS ONE OF THOSE PRIVILEGES
CHKPRV: MOVE T1,CAPENB ;GET ENABLED CAPABILITIES
TRNN T1,SC%WHL!SC%OPR!SC%IPC ;SEE IF EITHER PRIVILEGE IS SET
RETBAD (IPCF11) ;NOT SET
RETSKP ;PRIVILEGES SET
;ROUTINE TO SEE IF THE CALLER HAS SC%WHL OR OPERATOR PRIV'S
; CALL CHKWHL
;RETURNS +1: SC%WHL NOT SET
; +2: SC%WHL SET
CHKWHL: MOVE T1,CAPENB ;GET CAPABILITIES
TRNN T1,SC%WHL!SC%OPR ;SC%WHL SET?
RETBAD (IPCF10) ;NO
RETSKP ;YES
;ROUTINE TO SEE IF PID HAS NO ACCESS BY OTHER FORKS BIT SET
;ACCEPTS IN T1/ PID
; T2/ PID HEADER
; CALL CHKNOA
;RETURNS +1: NO ACCESS BIT IS SET
; +2: ACCESS BY OTHER FORKS IS ALLOWED
CHKNOA: LOAD T4,PIDFO,(T2) ;GET OWNER OF PID
CAMN T4,FORKX ;IS THIS OUR FORK
RETSKP ;YES, THEN WE CAN ACCESS IT
LOAD T4,PIDFLG,(T2) ;GET FLAGS
TRNE T4,PD%NOA ;IS THIS PID NO ACCESS BY OTHER FORKS?
RETBAD (IPCF28) ;YES
RETSKP ;NO
;ROUTINE TO CHECK IF A PID CAN BE WAITED ON BY THIS FORK
;ACCPETS IN T1/ PID
; T2/ PID HEADER
; FORK LOCK MUST BE SET DURING CALLS TO CHKPDW
; CALL CHKPDW
;RETURNS +1: NOT ALLOWED TO WAIT ON THIS PID
; +2: WAITING IS ALLOWED
CHKPDW: SAVEAC <T1,T2>
LOAD T4,PIDFW,(T2) ;GET FORK # OF WAITING FORK
CAIE T4,-1 ;NOBODY WAITING?
CAMN T4,FORKX ;OR OUR FORK?
RETSKP ;YES, OK TO WAIT
LOAD T3,PIDFLG,(T2) ;GET FLAGS
TRNE T3,PD%CHN ;A CHANNEL SET UP BY SOME FORK?
RETBAD (IPCF29) ;YES, THEN NOT ALLOWED TO WAIT
MOVSI T3,-NFKS ;SET UP AOBJN POINTER
CHKPDL: SKIPGE T1,SYSFK(T3) ;IS THERE A FORK IN THIS SLOT
JRST CHKPDD ;NO, GO TRY OTHER SLOTS
CAIE T4,(T1) ;IS THIS THE ONE WE WANT?
JRST CHKPDD ;NO, GO TRY REST
MOVEI T1,(T3) ;GET LOCAL FORK HANDLE
CALL SKIIF ;SEE IF INFERIOR TO OURSELVES
RETBAD (IPCF29) ;NO, GIVE ERROR RETURN
MOVE T1,T4 ;GET FORK OF WAITER ON THIS PID
CALL WAKFRK ;WAKE THIS FORK UP
RETSKP ;OK TO WAIT ON THIS PID NOW
CHKPDD: AOBJN T3,CHKPDL ;LOOP BACK FOR ALL FORKS
BUG(IPCFKH)
RETBAD (IPCF29) ;GIVE ERROR RETURN
;ROUTINES TO GET THE NEXT PID FOR A JOB OR FOR A FORK
;ACCEPTS IN 1/ PID INDEX (STARTING AT 0)
; 2/ FORK # OR JOB #
; CALL GETNPF OR CALL GETNPJ
;RETURNS +1: NO MORE PIDS FOR THIS FORK OR JOB
; +2: SUCCESSFUL, T1=PID, T2=POINTER TO PID HEADER
GETNPF: STKVAR <SAVFRK>
MOVEM T2,SAVFRK ;SAVE FORK NUMBER
GTNPFL: AOS T1 ;COUNT UP PID INDEX
CALL GETPID ;GET POINTER TO PID HEADER IF THERE
RET ;NO MORE PIDS
CAIGE T2,SWFREE ;IS THIS A PID ON THE FREE LIST?
JRST GTNPFL ;YES, LOOP BACK
LOAD T3,PIDFO,(T2) ;NO, GET OWNER OF PID
CAME T3,SAVFRK ;FOUND A MATCH?
JRST GTNPFL ;NO, LOOP BACK
LOAD T3,PIDUN,(T2) ;GET UNIQUE NUMBER
HRL T1,T3 ;SET UP ACTUAL PID IN T1
RETSKP ;GIVE OK RETURN
GETNPJ: STKVAR <SAVJOB>
MOVEM T2,SAVJOB ;SAVE JOB NUMBER
GTNPJL: AOS T1 ;COUNT UP PID INDEX
CALL GETPID ;GET POINTER TO PID HEADER
RET ;NO MORE PIDS
CAIGE T2,SWFREE ;IS THIS A PID ON THE FREE LIST?
JRST GTNPJL ;YES, GO GET ANOTHER ONE
LOAD T3,PIDFO,(T2) ;GET OWNER FORK NUMBER
HLRZ T4,FKJOB(T3) ;GET JOB NUMBER
CAME T4,SAVJOB ;IS THIS A MATCH?
JRST GTNPJL ;NO, LOOP BACK FOR OTHER PIDS
LOAD T3,PIDUN,(T2) ;GET UNIQUE NUMBER FOR THIS PID
HRL T1,T3 ;SET UP PID
RETSKP ;GIVE OK RETURN
;ROUTINE TO RETREIVE THE PER PID INFORMATION FROM PIDTBL
;ACCEPTS IN 1: PID
; CALL GETPID
;RETURNS +1: ILLEGAL PID INDEX
; +2: SUCCESSFUL
; T1/ PID
; T2/ CONTENTS OF APPROPRIATE HALF WORD FROM PIDTBL
GETPID: PUSH P,T1 ;SAVE PID
HRRZS T1 ;CLEAR OUT UNIQUE NUMBER
SOSL T1 ;ZERO IS NOT A LEGAL PID #
CAIL T1,MAXPID ;PID LEGAL?
JRST [ POP P,(P) ;NO
RETBAD (IPCF27)] ;GIVE ERROR RETURN
ROT T1,-1 ;GET LOW ORDER BIT AS SIGN BIT
HLRZ T2,PIDTBL(T1) ;ASSUME PID IS EVEN FIRST
SKIPGE T1 ;IS IT EVEN?
HRRZ T2,PIDTBL(T1) ;NO, GET CORRECT INFO
POP P,T1 ;RESTORE PID
RETSKP ;AND RETURN
;ROUTINE TO STORE NEW DATA IN THE PID HALF WORD TABLE (PIDTBL)
;ACCEPTS IN T1: PID
; T2: NEW DATA RIGHT JUSTIFIED
; CALL PUTPID
;RETURNS +1: ILLEGAL PID
; +2: SUCCESSFUL, ACS UNCHANGED
PUTPID: PUSH P,T1 ;SAVE ALL REGISTERS
HRRZS T1 ;CLEAR OUT UNIQUE NUMBER FROM LH OF PID
SOSL T1 ;0 IS NOT A LEGAL PID #
CAIL T1,MAXPID ;PID WITHIN BOUNDS?
JRST [ POP P,T1 ;NO, GIVE ERROR RETURN
RETBAD (IPCF27)]
ROT T1,-1 ;GET LOW ORDER BIT AS SIGN BIT
JUMPL T1,[HRRM T2,PIDTBL(T1)
JRST PUTPD1] ;STORE IN RIGHT HALF WORD IF PID IS ODD
HRLM T2,PIDTBL(T1) ;STORE IN LEFT HALF WORD IF PID IS EVEN
PUTPD1: POP P,T1 ;RESTORE PID
RETSKP ;AND RETURN
;ROUTINE TO CREATE A PID
; THIS ROUTINE GETS A FREE PID FROM THE FREE LIST AND ASSIGNS
; SPACE FROM THE FREE POOL FOR THE PID HEADER
;ACCEPTS IN T1: FORK OF NEW OWNER
; T2: FLAGS OF NEW PID
; CALL CREPID
;RETURNS +1 NO MORE PIDS AVAILABLE, ERROR CODE IN T1
; +2 PID CREATED
; T1/ PID (36 BITS)
; T2/ POINTER TO PID HEADER
CREPID: STKVAR <CREFKO,CREPDF,CREPDT>
MOVEM T1,CREFKO ;STORE FORK NUMBER AWAY
MOVEM T2,CREPDF ;AND FLAGS
HLRZ T2,FKJOB(T1) ;GET JOB NUMBER OF OWNER
MOVE T3,FORKX ;SEE IF CALLER ALLOWED TO CREATE PID
HLRZ T3,FKJOB(T3) ;GET JOB NUMBER OF CALLER
CAMN T2,T3 ;SAME AS ONE OF CREATED PID?
JRST CREPD1 ;YES, THEN THIS IS OK
MOVEM T2,CREPDT ;SAVE JOB NUMBER
CALL CHKPRV ;SEE IF PRIVILEGES SET
RET ;NO, CREATING NOT ALLOWED
MOVE T2,CREPDT ;GET BACK JOB NUMBER
CREPD1: HRRZ T3,JOBPT(T2) ;GET TOP FORK OF JOB IN CASE JOB WIDE PID
MOVE T4,CREPDF ;GET FLAGS OF PID
TLNE T4,(IP%JWP) ;JOB WIDE PID WANTED?
MOVEM T3,CREFKO ;YES, STORE FORK NUMBER OF TOP FORK
LOAD T3,PIDPQ,(T2) ;IS THIS JOB OVER ITS PID QUOTA
LOAD T4,PIDPC,(T2) ;GET CURRENT PID COUNT
CAML T4,T3 ;SEE IF OVER QUOTA
RETBAD (IPCF13) ;YES, GIVE ERROR RETURN
SKIPN T1,PIDLST ;ANY FREE PIDS AVAILABLE?
RETBAD (IPCF12) ;NO PID'S FREE
CALL GETPID ;GO GET LINK TO NEXT PID IN FREE LIST
JRST [ BUG(PIDFLF)
RET] ;GIVE ERROR RETURN FROM CREATE PID
EXCH T2,PIDLST ;STORE NEW LINK WORD
MOVEM T2,CREPDT ;SAVE PID NUMBER
MOVEI T1,PIDHDS ;GO GET FREE SPACE FOR HEADER
CALL ASGSWP ;...
JRST [ MOVE T2,CREPDT ;NO ROOM FOR HEADER, RESTORE PIDLST
MOVEM T2,PIDLST ;...
RET] ;NO FREE SPACE LEFT ERROR
AOS T2,NXTPID ;GET A UNIQUE NUMBER FOR LH OF PID
STOR T2,PIDUN,(T1) ;STORE UNIQUE NUMBER IN PID HEADER
HRLM T2,CREPDT ;PUT UNIQUE NUMBER IN PID ITSELF
MOVE T2,T1 ;GET POINTER TO HEADER INTO T2
;..
;..
MOVEI T1,0 ;CLEAR RECEIVE COUNT
STOR T1,PIDRC,(T2) ;...
MOVEI T1,PIDSRQ ;GET STANDARD RECEIVE QUOTA
STOR T1,PIDRQ,(T2) ;STORE IT IN PID HEADER
MOVE T1,CREPDF ;GET FLAGS
STOR T1,PIDFLG,(T2) ;STORE THEM IN HEADER
MOVE T1,CREFKO ;GET OWNER FORK
STOR T1,PIDFO,(T2) ;STORE IT TOO
HLRZ T3,FKJOB(T1) ;GET JOB NUMBER OF OWNER FORK
LOAD T4,PIDPC,(T3) ;GET PID COUNT
ADDI T4,1 ;UPDATE THE COUNT
STOR T4,PIDPC,(T3)
MOVEI T1,-1 ;MARK THAT NO FORK IS WAITING
STOR T1,PIDFW,(T2) ;...
MOVE T1,CREPDT ;GET BACK PID
CALL PUTPID ;PUT POINTER TO HEADER INTO PIDTBL
JRST [ BUG(ILPID1)
RET] ;GIVE ERROR RETURN
RETSKP ;RETURN TO CALLER
;ROUTINE TO DELETE A PID AND RETURN IT TO THE FREE LIST
;ACCEPTS IN T1: PID
; CALL DELPID
;RETURNS +1: NOT A LEGAL PID
; +2: PID DELETED
DELPID: SAVEQ
CALL VALPID ;VALIDATE THIS PID FIRST
RET ;ILLEGAL PID, OR NOT IN USE
DMOVE Q1,T1 ;SAVE THE PID AND PID INDEX
MOVEI Q3,PKMHDS ;SET UP TO SEND A DELETED PID MESSAGE
LOAD T1,PIDKMP,(Q2) ;GET PID TO SEND TO
MOVE T2,Q1 ;GET DELETED PID
SKIPE T1 ;IS THERE ONE SET UP?
CALL IPCPKM ;YES, GO SEND A MESSAGE TO THAT PID
JFCL ;NOTHING TO DO IF MESSAGE NOT SENT
LOAD T3,PIDFO,(Q2) ;GET OWNER OF PID
HLRZ T3,FKJOB(T3) ;GET JOB NUMBER OF OWNER
LOAD T4,PIDPC,(T3) ;DECREMENT THE PID COUNT FOR THIS JOB
SOJL T4,[BUG(PIDOD2)
JRST DELPD1] ;DONT STORE BAD COUNT
STOR T4,PIDPC,(T3) ;PUT BACK UPDATED PID COUNT
DELPD1: DMOVE T1,Q1 ;SET UP PID AND INDEX
CALL MESRET ;RETURN ALL MESSAGES IN QUEUE
MOVE T2,Q2 ;GET PID HEADER ADDRESS
MOVEI T1,PIDHDS ;GET LENGTH OF HEADER
MOVEM T1,0(T2) ;PUT IN FIRST WORD OF HEADER BLOCK
HRRZ T1,T2 ;GET POINTER TO PID HEADER
CALL RELMES ;RELEASE THE HEADER TO THE FREE POOL
MOVE T1,Q1 ;GET BACK THE PID
CAMN T1,INFOPD ;IS THIS THE [SYSTEM]INFO PID GOING AWAY
SETZM INFOPD ;YES, MARK THAT NO PID EXISTS FOR INFO
MOVE T2,PIDLST ;GET POINTER TO NEXT PID ON LIST
CALL PUTPID ;STORE POINTER TO THIS PID IN TABLE
JRST [ BUG(ILPID2)
RET] ;GIVE ERROR RET
HRRZM T1,PIDLST ;MAKE THIS PID BE FIRST ON LIST
RETSKP ;AND EXIT SUCCESSFULLY
;ROUTINE TO RETURN ALL MESSAGES BELONGING TO A PID TO THE SENDER
; OF EACH MESSAGE.
;ACCEPTS IN T1/ PID
; T2/ PID HEADER POINTER
; CALL MESRET
;RETURNS +1: ALWAYS - NO MORE MESSAGES IN THIS PID QUEUE
MESRET: STKVAR <MSRTPD,MSRTPH,MSRTMH>
MOVEM T1,MSRTPD ;SAVE PID
MOVEM T2,MSRTPH ;SAVE PID HEADER
MESRT0: MOVE T2,MSRTPH ;GET PID HEADER POINTER
CALL GETMES ;GET NEXT MESSAGE FROM PID QUEUE
RET ;NO MORE MESSAGES IN THE QUEUE
MOVEM T3,MSRTMH ;SAVE ADDRESS OF MESSAGE HEADER
LOAD T4,MESFLG,(T3) ;GET FLAGS OF MESSAGE
TROE T4,.IPCFN ;ALREADY BEEN TURNED AROUND ONCE?
JRST MESRT1 ;YES, THROW THE MESSAGE AWAY
STOR T4,MESFLG,(T3) ;STORE NEW FLAGS
LOAD T1,MESSPD,(T3) ;GET SENDER'S PID
JUMPE T1,MESRT1 ;IF 0 JUST THROW IT AWAY
CAMN T1,MSRTPD ;SENDING TO SAME PID?
JRST MESRT1 ;YES, JUST THROW IT AWAY
MOVE T2,T3 ;GET POINTER TO MESSAGE
MOVE T3,MSRTPD ;GET OLD PID OF THIS MESSAGE
STOR T3,MESSPD,(T2) ;MAKE THIS BE THE NEW SENDER'S PID
CALL MESTOR ;GO PUT MESSAGE ON QUEUE
JRST MESRT1 ;FAILURE, THROW MESSAGE AWAY
LOAD T3,MESSJN,(T1) ;GET JOB NUMBER OF SENDER
CAIN T3,-1 ;IF ONE STILL EXISTS
JRST MESRT0 ;NO JOB #, JUST LOOP BACK
LOAD T4,PIDSC,(T3) ;GET THE SENDER'S COUNT
ADDI T4,1 ;INCREMENT IT
STOR T4,PIDSC,(T3) ;PUT BACK NEW COUNT
JRST MESRT0 ;LOOP BACK FOR ALL MESSAGES
MESRT1: MOVE T1,MSRTMH ;GET POINTER TO MESSAGE BLOCK
LOAD T2,MESFLG,(T1) ;GET FLAGS OF MESSAGE
TRNN T2,IP%CFV ;IS THIS A PAGE MODE MESSAGE?
JRST MESRT2 ;NO, NO NEED TO DELETE THE PAGE
LOAD T2,MSFTI,(T1) ;GET INDEX INTO PAGES BIT TABLE
LOAD T3,MSFTM,(T1) ;GET BIT MASK
IORM T3,PIDPBT(T2) ;RETURN THIS PAGE TO THE FREE POOL
LOAD T2,MESPTN,(T1) ;GET PTN,,PN OF PAGE IN TRANSIT
SETZB T1,T3 ;MARK THAT IT IS TO BE DELETED
CALL SETPT ;GO REMOVE AND DISCARD THIS PAGE
MESRT2: MOVE T1,MSRTMH ;GET ADDRESS OF MESSAGE BLOCK
CALL RELMES ;RELEASE THE SPACE TO THE FREE POOL
JRST MESRT0 ;LOOP BACK FOR ALL MESSAGES
;ROUTINE TO GET THE OLDEST MESSAGE FROM A PID AND DECREMENT THE COUNTS
;ACCEPTS IN T1/ PID
; T2/ PID HEADER POINTER
; CALL GETMES
;RETURNS +1: NO MORE MESSAGES
; +2: SUCCESSFUL - MESSAGE REMOVED FROM LIST
; T3/ POINTER TO MESSAGE BLOCK
GETMES: LOAD T1,PIDRC,(T2) ;GET COUNT OF MESSAGES ON LIST
SOSGE T1 ;ANY THERE?
RET ;NO, JUST RETURN
STOR T1,PIDRC,(T2) ;STORE DECREMENTED COUNT
LOAD T3,PIDOL,(T2) ;GET ADDRESS OF OLDEST MESSAGE
LOAD T4,MESLNK,(T3) ;GET POINTER TO NEXT MESSAGE ON LIST
STOR T4,PIDOL,(T2) ;MAKE PID POINT TO SECOND MESSAGE
SKIPN T4 ;IS THE LIST EMPTY NOW?
STOR T4,PIDNL,(T2) ;YES, ZERO THE POINTER TO THE NEWEST
LOAD T4,MESSJN,(T3) ;GET JOB NUMBER OF SENDER OF MESSAGE
CAIN T4,-1 ;HAS JOB LOGGED OUT ALREADY?
RETSKP ;YES, THEN DONT DECREMENT COUNT
LOAD T1,PIDSC,(T4) ;GET COUNT OF MESSAGES SENT
SOJL T1,[BUG(IPCSOD)
JRST GETMS1]
STOR T1,PIDSC,(T4) ;PUT BACK THE UPDATED COUNT
GETMS1: RETSKP ;GIVE OK RETURN
;ROUTINE TO GET THE PID OF INFO FOR SOME JOB
;ACCEPTS IN T1/ INDEX THAT MAPS JSB ADDRS INTO WHERE THE JSB IS MAPPED
; CALL GTINFO
;RETURNS +1: NO INFO FOR THIS JOB, ERROR CODE IN T1
; +2: T2/ PID OF INFO
GTINFO: STKVAR <GTINFT>
MOVEM T1,GTINFT ;SAVE INDEX
SKIPN T1,JBINFO(T1) ;GET PID IF ANY
JRST GTINFP ;NONE, GET [SYSTEM]INFO
CALL VALPID ;VALIDATE THIS PID
JRST [ MOVE T1,GTINFT ;GET BACK INDEX
SETZM JBINFO(T1) ;ZERO OUT BAD PID
JRST GTINFP] ;GO GET PUBLIC VALUE OF INFO
GTINFD: MOVE T2,T1 ;GET PID INTO T2
MOVE T1,GTINFT ;GET BACK INDEX
RETSKP ;AND RETURN TO CALLER
GTINFP: MOVE T1,INFOPD ;GET PUBLIC PID OF INFO
CALL VALPID ;VALIDATE IT
RETBAD (IPCF19) ;GIVE ERROR RETURN
JRST GTINFD ;GO CLEAN UP AND RETURN OK
;ROUTINES TO LOCK AND UNLOCK THE FORK LOCKS AND OTHER LOCKS
; ALL PIDS MUST BE RECHECKED SINCE PIDLKK IS TURNED OFF
;CALL MUST BE MADE WITH PIDLKK ON AND NOINT
; CALL MFLOCK
;RETURNS +1: ALWAYS - PIDLKK, FLOCK, AND NOINT ARE ALL SET
MFLOCK: UNLOKK PIDLKK ;UNLOCK THE LOCKS
OKINT
CALL GTLCKS ;GET FORK LOCK AND PID LOCK
RET ;ALL LOCKS SET AGAIN
; CALL MFUNLK
;RETURNS +1: ALWAYS - JOB IS NOINT AND PIDLKK IS SET, FLOCK OFF
MFUNLK: UNLOKK PIDLKK ;UNLOCK IN THE REVERSE ORDER
CALL FUNLK ;CLEAR FORK LOCK
NOINT ;GO NOINT AGAIN
CALL GTPIDL ;GET THE PID LOCK
RET
;ROUTINE TO INITIALIZE THE JOB QUOTAS WHEN A JOB IS CREATED
; THIS ROUTINE ALSO CLEARS THE SENDER'S JOB NUMBER FIELD IN ALL
; MESSAGES THAT WERE SENT BY THE PREVIOUS OWNER OF THIS JOB NUMBER.
; THIS PREVENTS THE NEW OWNER OF THE JOB NUMBER FROM HAVING HIS
; SEND COUNT INCORRECTLY DECREMENTED.
;ACCEPTS IN T1/ JOB NUMBER
; CALL PIDJBI
;RETURNS +1: ALWAYS
PIDJBI::STKVAR <PIDJBJ,PIDJBC>
NOINT ;LOCK UP DATA BASE
CALL GTPIDL ;GET THE PID LOCK
MOVEI T2,PIDSSQ ;GET STANDARD SEND QUOTA
STOR T2,PIDSQ,(T1) ;SET UP STANDARD QUOTAS
MOVEI T2,PIDSPQ ;GET STANDARD PID QUOTA
STOR T2,PIDPQ,(T1)
LOAD T3,PIDSC,(T1) ;GET THE SEND COUNT OF LAST USER
MOVEI T2,0 ;CLEAR OTHER FIELDS
STOR T2,PIDSC,(T1) ;SEND COUNT = 0
STOR T2,PIDPC,(T1) ;PID COUNT = 0
JUMPE T3,PIDJBR ;IF PREVIOUS SEND COUNT WAS 0, EXIT
MOVEM T1,PIDJBJ ;SAVE JOB NUMBER
MOVEM T3,PIDJBC ;SAVE NUMBER OF OUTSTANDING MESSAGES
MOVEI T1,1 ;SET UP TO FIND MESSAGES FROM THIS JOB
PIDJBL: CALL GETPID ;GET POINTER TO PID HEADER IF ANY
JRST PIDJBR ;LOOKED AT ALL PIDS, GO UNLOCK AND EXIT
CAIGE T2,SWFREE ;IS THIS A PID ON THE FREE LIST
PIDJBD: AOJA T1,PIDJBL ;YES, INCREMENT PID INDEX AND LOOP BACK
LOAD T3,PIDOL,(T2) ;GET POINTER TO START OF MESSAGE LIST
PIDJBM: JUMPE T3,PIDJBD ;ANY MESSAGES ON THIS LIST?
LOAD T4,MESSJN,(T3) ;YES, GET JOB NUMBER OF SENDER
CAMN T4,PIDJBJ ;SAME AS OUR'S?
JRST [ MOVEI T4,-1 ;YES, CLEAR OUT THE JOB NUMBER
STOR T4,MESSJN,(T3)
SOSG PIDJBC ;ANY MORE MESSAGES TO BE FOUND?
JRST PIDJBR ;NO, GO UNLOCK AND RETURN
JRST .+1] ;YES, CONTINUE SEARCHING
LOAD T3,MESLNK,(T3) ;GET POINTER TO THE NEXT MESSAGE ON LIST
JRST PIDJBM ;LOOP BACK FOR ALL MESSAGES
PIDJBR: UNLOKK PIDLKK ;UNLOCK THE LOCKS
OKINT
RET ;AND EXIT
;ROUTINES TO DELETE ALL PIDS BELONGING TO A FORK DURING A FORK KILL
; OR A RESET. JOB WIDE PIDS ARE NOT DELETED ON RESET.
;ACCEPTS IN T1/ FORK #
; CALL PIDKFK OR CALL PIDRFK
;RETURNS +1: ALWAYS
PIDKFK::TDZA T2,T2 ;KILL ALL PIDS OF FORK
PIDRFK::MOVEI T2,PD%JWP ;DONT KILL JOB WIDE PIDS DURING RESET'S
STKVAR <SAVKFK,SAVKFP,SAVKF3,SAVINF,SAVKFT>
MOVEM T2,SAVKFT ;SAVE THE TEST BITS
MOVEM Q3,SAVKF3 ;SAVE Q3
MOVEM T1,SAVKFK ;SAVE THE FORK BEING KILLED
HLRZ T2,FKJOB(T1) ;GET JOB NUMBER OF FORK
LOAD Q3,PIDPC,(T2) ;GET COUNT OF PIDS OWNED BY THIS JOB
JUMPE Q3,PIDKFR ;IF NONE, DONT BOTHER TO DELETE ANY
NOINT ;LOCK UP
CALL GTPIDL ;GET THE PID LOCK
SETZ T1, ;CLEAN UP ALL PIDS WAITED ON BY FORK
PIDKF3: MOVE T2,SAVKFK ;GET JOB NUMBER OF THIS FORK
HLRZ T2,FKJOB(T2) ;...
CALL GETNPJ ;GET NEXT PID OF THIS JOB
JRST PIDKF4 ;NO MORE PIDS FOR JOB
LOAD T3,PIDFW,(T2) ;GET FORK WAITING ON THIS PID
MOVEI T4,-1 ;PREPARE TO INITIALIZE PIDFW
CAMN T3,SAVKFK ;IS THIS THE FORK BEING KILLED?
STOR T4,PIDFW,(T2) ;YES, CLEAR OUT FORK NUMBER
JRST PIDKF3 ;LOOP BACK FOR ALL PIDS OF THE JOB
PIDKF4: SETZB Q3,T1 ;INITIALIZE INDEX INTO JSB
CALL GTINFO ;GET PID OF INFO FOR THIS JOB
JRST PIDKF2 ;NO INFO FOR THIS JOB
MOVEM T2,SAVINF ;SAVE PID OF INFO
PIDKF0: MOVE T2,SAVKFK ;GET FORK NUMBER
CALL GETNPF ;GET NEXT PID OF THIS FORK
JRST PIDKF1 ;NO MORE PID'S
LOAD T3,PIDFLG,(T2) ;GET FLAGS OF PID
TDNE T3,SAVKFT ;IS THIS PID NOT TO BE KILLED?
JRST PIDKF0 ;YES, DONT COUNT IT
CAME T1,SAVINF ;IS THIS THE PID OF INFO FOR THIS JOB
AOJA Q3,PIDKF0 ;NO, LOOK AT EACH PID OF THIS FORK
SETZ Q3, ;YES, DONT SEND A MESSAGE TO THIS INFO
PIDKF1: JUMPE Q3,PIDKF2 ;ANY PIDS SEEN?
ADDI Q3,2 ;YES, GET LENGTH OF MESSAGE FOR INFO
CALL IPCDEL ;SET UP A MESSAGE FOR INFO
TDZA Q3,Q3 ;NO ROOM FOR MESSAGE
MOVE Q3,T1 ;GET ADDRESS OF MESSAGE AREA INTO Q3
PIDKF2: MOVEI T1,0 ;START AT PID INDEX 0
;..
;..
PIDKFL: MOVE T2,SAVKFK ;GET FORK # AGAIN
CALL GETNPF ;GET THE NEXT PID OF THE FORK
JRST PIDKFD ;ALL DONE, GO UNLOCK
MOVEM T1,SAVKFP ;SAVE PID INDEX
LOAD T3,PIDFLG,(T2) ;GET FLAGS OF PID
TDNE T3,SAVKFT ;IS THIS PID TO BE DELETED?
JRST PIDKFL ;NO, JUST LOOP BACK
CALL DELPID ;GO DELETE THIS PID
BUG(NOPID)
MOVE T1,SAVKFP ;GET BACK PID INDEX
JUMPE Q3,PIDKFL ;ARE WE BUILDING A MESSAGE FOR INFO?
STOR T1,MESWD0,(Q3) ;YES, STORE PID IN MESSAGE
AOJA Q3,PIDKFL ;LOOP BACK FOR OTHER PIDS
PIDKFD: UNLOKK PIDLKK ;CLEAN UP
OKINT
PIDKFR: MOVE Q3,SAVKF3 ;RESTORE Q3
RET ;AND RETURN
;ROUTINE TO SEND A MESSAGE TO QUASAR ON CLOSEING OF A SPOOLED FILE
;ACCEPTS IN T1/ JFN (ALREADY SHIFTED BY SJFN)
; T2/ FBBYV
; T3/ FBSIZ
; CALL SPLMES
;RETURNS +1: ERROR - COULD NOT SEND MESSAGE
; +2: SUCCESSFUL
SPLMES::SAVEQ ;SAVE ALL THE PERMANENT ACS USED
STKVAR <SPLMSV,SPLMSZ>
MOVEM T1,Q1 ;SAVE JFN IN PERMANENT AC
MOVEM T2,SPLMSV ;SAVE FBBYV FOR LATER
MOVEM T3,SPLMSZ ;SAVE FBSIZ
NOINT ;DONT ALLOW INTERRUPTIONS
CALL GTPIDL ;GET THE PID LOCK
SKIPL T1,CTRLTT ;SET BATCH BIT IN JBFLAG
CALL PTYGBB ;SEE IF JOB IS CONTROLLED BY BATCH
SETZ T1, ;NO, IT ISNT
STOR T1,JSBAT ;STORE BIT IN FLAG WORD
MOVEI Q3,MAXLW+SPMHDS ;CALCULATE # OF WORDS NEEDED FOR MESSAGE
HLRZ T2,FILNEN(Q1) ;GET POINTER TO NAME STRING
HRRZ T1,0(T2) ;GET LENGTH OF STRING
ADD Q3,T1 ;UPDATE COUNT OF WORDS NEEDED
HRRZ T2,FILNEN(Q1) ;GET POINTER TO EXTENSION STRING
HRRZ T1,0(T2) ;GET LENGTH OF EXT STRING
ADD Q3,T1 ;UPDATE COUNTER
MOVE T1,SPIDTB+.SPQSR ;GET PID OF QUASAR
CALL VALPID ;MAKE SURE IT IS STILL VALID
JRST [ SETZM SPIDTB+.SPQSR ;NOT VALID, ZERO ENTRY IN TABLE
JRST IPCMSR] ;GIVE OK RETURN TO AVOID BUG CHECK
CALL IPCMES ;GO PUT MESSAGE ONTO QUASAR'S QUEUE
JRST IPCMSE ;COULD NOT SEND MESSAGE
MOVEI T2,.IPCSU ;GET FUNCTION CODE OF SPOOLED FILE CLOSE
STOR T2,MESWD0,(T1) ;PUT IT IN MESSAGE FOR QUASAR TO SEE
HRRZI T1,MESWDI(T1) ;GET POINTER TO ACTUAL MESSAGE
MOVE T2,JOBNO ;GET JOB NUMBER
HRLI T2,SPMHDS ;GET HEADER SIZE
PUSH T1,T2 ;STORE HEADER SIZE ,, JOB NUMBER
HLLZ T3,JBFLAG ;GET FLAGS TO BE SENT
PUSH T1,T3 ;STORE FLAGS ,, STATION # (0 FOR NOW)
HRRZS T2
PUSH T1,JOBPNM(T2) ;SAVE PROGRAM NAME
PUSH T1,SPLMSV ;STORE FBBYV
PUSH T1,SPLMSZ ;AND FBSIZ
HRLI T1,(POINT 7,0,35) ;MAKE A BYTE POINTER
LOAD T2,FILUC,(Q1) ;GET UNIQUE CODE OF STR
HRLS T2 ;BUILD A DIR NUMBER
HRR T2,FILDDN(Q1) ;ADD IN THE DIRECTORY NUMBER
DIRST ;PUT DIRECTORY NAME INTO STRING
ERJMP [BUG(NODIR1)
JRST .+1]
;..
;..
HLRZ T2,FILNEN(Q1) ;NOW ADD ON THE NAME
HRLI T2,(POINT 7,0,35) ;MAKE A STRING POINTER
SETZ T3,
SOUT ;NAME FIELD
MOVEI T2,"." ;PUT IN PUNCTUATION
IDPB T2,T1 ;...
HRRZ T2,FILNEN(Q1) ;NOW GET POINTER TO EXTENSION
HRLI T2,(POINT 7,0,35)
SOUT ;PUT EXTENSION INTO STRING
MOVEI T2,PNCVER ;NOW PUT IN VERSION NUMBER
IDPB T2,T1 ;PUT IN PUNCTUATION
HRRZ T2,FILVER(Q1) ;GET VERSION NUMBER
MOVEI T3,12 ;MAKE IT DECIMAL
NOUT
BUG(NOUTF2)
IPCMSR: AOS 0(P) ;SET UP FOR SUCCESSFUL RETURN
IPCMSE: UNLOKK PIDLKK ;FREE UP DATA BASE
OKINT
RET ;AND EXIT
;ROUTINE TO SEND A MESSAGE TO PID ON LOGOUT/LOGIN
; ACCEPTS:
; T1/ ADDRESS OF PID
; CALL LOGOMS
; CALL LOGIMS
;RETURNS +1: COULD NOT SEND MESSAGE
; +2: SUCCESSFUL
LOGIMS::SKIPA T2,[.IPCLI] ;LOGIN MESSAGE CODE
LOGOMS::MOVEI T2,.IPCSL ;LOGOUT MESSAGE CODE
NOINT ;LOCK UP IPCF DATA BASE
CALL GTPIDL ;GET THE PID LOCK
SAVEQ ;PRESERVE Q1-Q3
STKVAR <LOGMSC,LOGPID>
MOVEM T1,LOGPID ;SAVE PID
MOVEM T2,LOGMSC ;SAVE THE MESSAGE CODE
SKIPL T1,CTRLTT ;SET BATCH BIT IN JBFLAG
CALL PTYGBB ;SEE IF JOB IS CONTROLLED BY BATCH
SETZ T1, ;NO, IT ISNT
STOR T1,JSBAT ;STORE BIT IN FLAG WORD
MOVEI Q3,LOGMSZ ;GET A MESSAGE FOR LOGOUT
MOVE T1,@LOGPID ;GET PID OF PID
CALL VALPID ;MAKE SURE IT IS STILL VALID
JRST [ SETZM @LOGPID ;IT ISNT VALID, CLEAR TABLE
JRST IPCMSE] ;CANNOT SEND MESSAGE
CALL IPCMES ;GET MESSAGE PUT ONTO QUASAR'S QUEUE
JRST IPCMSE ;FAILED
MOVE T2,LOGMSC ;GET THE MESSAGE CODE
STOR T2,MESWD0,(T1) ;PUT IT IN THE MESSAGE
MOVEI T1,MESWDI(T1) ;GET ACTUAL ADR OF MESSAGE AREA
MOVSI T2,LGMHDS ;GET HEADER SIZE
HRR T2,JOBNO ;GET JOB NUMBER OF JOB LOGGING OUT
PUSH T1,T2 ;STORE IT IN MESSAGE
HLLZ T3,JBFLAG ;GET SPOOL FLAGS ,, STATION #
PUSH T1,T3 ;STORE IT IN MESSAGE
JRST IPCMSR ;AND EXIT
;ROUTINE TO SEND A MSG TO A JOB'S CREATOR ON LOGOUT.
; MOVE T1,PID-OF-CREATOR
; CALL LOGOMO
;RETURNS +1: COULD NOT SEND MESSAGE
; +2: SUCCESSFUL
LOGOMO::NOINT ;LOCK IPCF DATA BASE
CALL GTPIDL ;GET THE PID LOCK
SAVEQ ;SOME AC'S TO WORK WITH
MOVEI Q3,LG2MSZ ;SIZE OF MESSAGE NEEDED
CALL VALPID ;SEE IF PID IN T1 IS STILL GOOD
JRST IPCMSR ;NO. GIVE SUCCESS RETURN
CALL IPCMES ;OK, PUT THE MSG ON CREATORS QUEUE
JRST IPCMSE ;COULDN'T. FAIL RETURN.
MOVEI T2,.IPCLO ;MSG NOT YET SENT. PUT DATA IN IT.
STOR T2,MESWD0,(T1) ;DESCRIPTOR OF MSG
MOVEI T1,MESWDI(T1) ;SET TO PUSH DATA THRU T1
MOVSI T2,LG2MHS ;ALL BUT HEADER MAKES SIZE FOR USER
HRR T2,JOBNO ;IDENTITY OF LOGGING-OUT JOB
PUSH T1,T2 ;PUT THOSE IN MESSAGE
HRRZS T2 ; Just job # for later (index JOBRT)
HLLZ T3,JBFLAG ;SPOOLED FLAGS, REASON FOR LOGOUT.
PUSH T1,T3 ;INTO MESSAGE
MOVE T3,TODCLK ;MY CONSOLE TIME
SUB T3,CONSTO ; IS NOW MINUS WHEN I LOGGED IN
PUSH T1,T3 ; (PLUS OR MINUS CACCT)
PUSH T1,JOBRT(T2) ;MY JOB RUN TIME
PUSH T1,CTRLTT ;MY TERMINAL
PUSH T1,JSLOJB ;JOB WHO LOGGED ME OUT, IF ANY.
PUSH T1,[0] ;SPECED AS REASONS FOR ERROR LOGOUT
PUSH T1,LSTERR ;LAST JSYS ERROR CODE
JRST IPCMSR ;SEND THIS MESSAGE AND RETURN.
; Routine to send ARCSYS a message for various reasons
; Function code in AC1 RH, reason modifier in AC1 LH
; AC2 is offset to FDB of file in question
; Returns: +1 failed, +2 msg sent
ARCMSG::NOINT
CALL GTPIDL ;GET THE PID LOCK
ACSAV ; Cover ourself, leave all intact
STKVAR <FNCD,ARFDB>
MOVEM T1,FNCD ; Save fnc,,reason
MOVEM T2,ARFDB ; Offset to FDB of file in question
ARCMSA: MOVEI Q3,ARMSSZ ; Size our message will be
MOVE T1,SPIDTB+.SPQSR ; Get PID to use
CALL VALPID ; Still ok?
JRST ARCMS1 ; Fails, take a way out
MOVX P1,IP%INT ; Flag internal call
CALL IPCMES ; Put message on Quasar's Q
JRST ARCMS2 ; Couldn't, fail
ADDI T1,MESWDI ; Point to data area of msg
PUSH P,T1 ; Save ptr
XMOVEI T3,10(T1) ; Where account goes in the msg
XMOVEI T2,ACCTSR ; Current job account
MOVE T1,ACCTSL ; Size of move
CALL XBLTA ; Copy the account
POP P,T1 ; Recover blk addr
MOVE Q1,ARFDB ; Get FDB offset
MOVE Q2,DIRORA ; Get directory addr
MOVEI T2,-1(T1) ; Set up to PUSH thru T2
PUSH T2,[ARMSSZ,,.IPCSR] ; Length,,msg type
PUSH T2,FNCD ; Put in function code & modifier
HRRZ T1,.FBPRT(Q1) ; Get file's protection
PUSH T2,T1 ; Store that
PUSH T2,.FBTP1(Q1) ; Tape #1 ID
PUSH T2,.FBSS1(Q1) ; Tape #1 TSN,,TFN
PUSH T2,.FBTP2(Q1) ; Tape #2 ID
PUSH T2,.FBSS2(Q1) ; Tape #2 TSN,,TFN
PUSH T2,.FBTDT(Q1) ; Tape write time & date
; Now we need to do a JFNS into the blk, however, the directory may be
; locked (if EXPUNGE case, is for sure). So..., we'll do our own,
; considerably simpler JFNS here; However, we are forced to use
; directory information
ADDI T2,10 ; Skip over account string
HRLI T2,(<POINT 7,0,35>) ; Need to cause IDPB to go to next wrd
LOAD T4,CURSTR ; Structure no. for this directory
ADDI T4,DVXST0
MOVE T4,DEVNAM(T4) ; Get mounted structure name
ARCSTR: SETZ T3, ; Loop to convert str. name to ASCII
LSHC T3,6 ; Sixbit char. in T3
JUMPE T3,ARDIRS ; Done on null
ADDI T3,40 ; Convert char. to ASCII
IDPB T3,T2 ; Put the character into the str name
JRST ARCSTR ; Back for next char.
ARDIRS: MOVEI T1,":"
IDPB T1,T2 ; Punctuation
MOVEI T1,"<" ; Start directory
IDPB T1,T2
LOAD T1,DRNAM,(Q2) ; Get directory name ptr
MOVEI T3,"." ;DON'T QUOTE PERIODS WITHIN DIR NAME
CALL ARCPY
MOVEI T1,">" ; End directory name
IDPB T1,T2
LOAD T1,FBNAM,(Q1) ; Get name ptr
SETZ T3,
CALL ARCPY ; Put it in blk too
MOVEI T1,"." ; Punct
IDPB T1,T2
LOAD T1,FBEXT,(Q1) ; Extention blk
SETZ T3,
CALL ARCPY
MOVEI T1,PNCVER ; Punc before version
IDPB T1,T2
LOAD T1,FBGEN,(Q1) ; Get file generation
EXCH T1,T2
MOVEI T3,^D10
NOUT
BUG(ARCVER)
SETZ T2,
IDPB T2,T1 ; End it
MOVEI T2,1(T1) ; Point to next word
CALLRET IPCMSR ; Send this message and return
;ARCPY - COPY STRING FROM DIRECTORY TO OUTPUT STRING WITH QUOTING
; T1/ OFFSET INTO DIRECTORY OF WORD BEFORE SOURCE STRING
; T2/ OUTPUT BYTE POINTER
; T3/ CHARACTER TO BE EXEMPTED FROM QUOTING, OR 0 IF NONE
;RETURNS +1: ALWYAS, T2/ UPDATED OUTPUT POINER
ARCPY: STKVAR <ARCPOP,ARCPEC>
MOVEM T2,ARCPOP ;SAVE OUTPUT POINTER
MOVEM T3,ARCPEC ;SAVE CHARACTER EXEMPTED FROM QUOTING
ADD T1,[POINT 7,0(Q2),35] ; Use dirora offset & make valid ptr
ARCPY1: ILDB T4,T1 ; Get a char
JUMPE T4,[MOVE T2,ARCPOP ;NULL HIT, RETRIEVE OUTPUT POINTER
RET]
MOVE T2,T4 ;COPY CHARACTER FOR DIVISION
IDIVI T2,^D36/CCSIZE ; CCSIZE and CPTAB and char type
LDB T3,CPTAB(T3) ; are found in GTJFN.MAC
JUMPE T3,ARCPY2 ; 0 class is normal alphas
CAME T4,ARCPEC ;CHARACTER EXEMPTED FROM QUOTING?
CAIN T3,30 ; Minus is not special
JRST ARCPY2
CAIL T3,21
CAILE T3,24
JRST [ MOVEI T3,.CHCNV ; Special quote char
IDPB T3,ARCPOP ; Insert a quote
JRST .+1]
ARCPY2: IDPB T4,ARCPOP ;DEPOSIT CHARACTER FROM INPUT STRING
JRST ARCPY1 ; Loop over entire string
ARCMS1: BUG(NOARCS)
SETZM SPIDTB+.SPQSR
JRST IPCMSR ; Cannot send message
; This wait for IPCFX7 is wrong, but will work, probably the returned
; packet is one of the quota you've exceeded... (until more stuff uses
; IPCF anyway)
ARCMS2: CAIE T1,IPCFX7 ; Over allocation?
JRST IPCMSE ; No, some other failure
UNLOKK PIDLKK
OKINT
AOS IPPKFR ; Say we're waiting
MOVEI T1,IPPKFR
CALL DISE ; Wait for one to free up
NOINT
CALL GTPIDL ;GET THE PID LOCK
JRST ARCMSA ; Go try again
;ROUTINE CALLED FROM TAPE TO SEND A MESSAGE.
; T1/ FUNCTION SUBCODE
; T2/ LENGTH OF ADDITIONAL DATA
; T3/ ADDRESS OF ADDITIONAL DATA
;RETURNS: +1 FAILED
; +2 SENT
IPCMTM::ASUBR <SUBCOD,ARGLEN,ARGADR,UNITNO>
SAVEQ
MOVEI Q3,3(T2) ;GET MESSAGE SPACE
SKIPN T1,SPIDTB+.SPMDA ;HAVE A PID?
RET ;NO. BOO AND HIS
CALL ALOMDM ;YES. GET SPACE
JRST IPCMSE ;FAILED
MOVEI T2,.IPCTR ;TAPE REQUEST
STOR T2,MESWD0,(T1) ;SAVE FUNCTION
MOVE T2,SUBCOD ;GET SUBFUNCTION
MOVEM T2,MESWDI+1(T1) ;STASH IT AS WELL
MOVE T2,UNITNO ;GET UNIT NUMBER
MOVEM T2,MESWDI+2(T1) ;SAVE IT
MOVE T3,ARGADR ;GET ADDRESS OF ADDITIONAL ITEMS
MOVE T2,T1 ;COPY ADDRESS
ADDI T2,2 ;SKIP THREE ARGS SO FAR STORED
IPCMT0: SOSGE ARGLEN ;MORE ARGS?
JRST IPCMSR ;NO. ALL DONE
MOVE Q2,0(T3) ;GET NEXT ITEM
MOVEM Q2,MESWDI+1(T2) ;SAVE IT
ADDI T2,1 ;NEXT ITEM
AOJA T3,IPCMT0 ;AND DO THEM ALL
;ALCMES - ROUTINE TO SET UP A MESSAGE AREA FOR AN ALLOCATE MESSAGE
; THIS MESSAGE GETS SENT WHENEVER AN ALLOCATED DEVICE IS RELEASED
;ACCEPTS IN T1/ DEVICE DESIGNATOR
; CALL ALCMES
;RETURNS +1: NO MESSAGE CAN BE SENT
; +2: MESSAGE SENT
ALCMES::SAVEQ ;SAVE THE PERMANENT ACS
MOVE Q2,T1 ;SAVE DEVICE DESIGNATOR
MOVEI Q3,2 ;GET SIZE OF MESSAGE
SKIPN T1,SPIDTB+.SPMDA ;GET PID OF ALLOCATOR
RET ;NO PID CAN'T SEND
CALL ALOMDM ;ALLOCATE A BLOCK
JRST IPCMSE ;CAN'T DO IT
MOVEI T2,.IPCSA ;GET FUNCTION CODE
STOR T2,MESWD0,(T1) ;STORE IT IN MESSAGE
MOVEM Q2,MESWDI+1(T1) ;SET UP POINTER TO MESSAGE AREA
JRST IPCMSR ;GO TAKE SUCCESS RETURN
; ROUTINE TO SEND A MESSAGE TO THE ALLOCATOR WHEN MOUNT COUNT
; OF A STRUCTURE IS DECREMENTED
;
; ACCEPTS IN P6/ POINTER FOR TRVAR
; CALL DISMES
; RETURNS: +1 FAILED, MESSAGE NOT SENT
; +2 SUCCESS, MESSAGE WAS SENT
DISMES::SAVEQ ;PRESERVE THE Q-AC'S
MOVE Q2,1(P6) ;GET HEADER WORD
HRRZ Q3,Q2 ;GET SIZE OF MESSAGE
AOS Q3
SKIPN T1,SPIDTB+.SPMDA ;IS THERE A PID FOR THE DEVICE ALLOCATOR ?
JRST RSKP ;NO, RETURN SUCCESS ANYWAY...
CALL ALOMDM ;ALLOCATE BLOCK
JRST IPCMSE ;FAILED
HLRZ T2,Q2 ;GET FUNCTION CODE
STOR T2,MESWD0,(T1) ;ADD FUNCTION CODE TO MESSAGE
MOVEI T1,MESWDI+1(T1) ;GET ADDRESS OF DATA PORTION OF MESSAGE
MOVEM Q3,(T1) ;STORE LENGTH
AOS T1 ;GET NEXT DATA WORD
MOVEI T2,-3(Q3) ;SET UP LAST WORD FOR TRANSFER
ADD T2,T1
HRLI T1,2(P6) ;SET UP BLT POINTER
BLT T1,@T2 ;MOVE DATA
JRST IPCMSR ;RETURN SUCCESS...
;
;MTAMES - ROUTINE TO SEND A MESSAGE TO THE DEVICE ALLOCATIOR
;
;ACCEPTS IN T1/MESSAGE TO BE SENT
; CALL ALCMES
;RETURNS +1: NO MESSAGE CAN BE SENT
; +2: MESSAGE SENT
;
MTAMES::SAVEQ ;SAVE REGISTERS
MOVE Q2,T1 ;SAVE CALLING ARGUMENTS
MOVE Q1,T2
MOVE Q3,2 ;SIZE OF BLOCK
SKIPN T1,SPIDTB+.SPMDA ;IS THERE A PID FOR THE DEVICE ALLOCATOR?
RET ;NO JUST RETURN
CALL ALOMDM ;ALLOCATE A BLOCK
JRST IPCMSE ;NO CAN'T ALLOCATE A MESSAGE
STOR Q1,MESWD0,(T1) ;STORE FUNCTION CODE
MOVEM Q2,MESWDI+1(T1) ;STORE DATA
JRST IPCMSR ;GO TAKE SUCCESS RETURN
ALOMDM: NOINT ;LOCK UP IPCF DATA BASE
CALL GTPIDL ;GET THE PID LOCK
CALL VALPID ;VALIDATE IT
JRST [ SETZM SPIDTB+.SPMDA ;NOT A VALID PID, ZERO ENRTY IN TABL
RET] ;AND GIVE NON-SKIP RETURN
CALL IPCMES ;GO GET MESSAGE
JRST [ BUG(NOALCM,<<T1,D>>)
RET] ;GO GIVE NON-SKIP RETURN
RETSKP ;SUCCESS RETURN
;ROUTINE TO SET UP A MESSAGE FOR INFO WHEN DELETING A PID
;ACCEPTS IN Q3/ LENGTH OF MESSAGE DATA AREA
; CALL IPCDEL
;RETURNS +1: NO ROOM FOR MESSAGE
; +2: T1/ POINTER TO FIRST DATA WORD INDEXED BY MESWD0
IPCDEL: SETZ T1, ;GET PID OF INFO FOR THIS JOB
CALL GTINFO ;...
RET ;NO INFO FOR THIS JOB
MOVE T1,T2 ;GET PID OF INFO
CALL IPCMES ;SEND THE MESSAGE TO INFO
RET ;COULD NOT SEND FOR SOME REASON
MOVEI T2,.IPCSS ;GET FUNCTION CODE
STOR T2,MESWD0,(T1) ;PUT IT AS FIRST WORD OF MESSAGE
ADDI T1,2 ;MAKE POINTER POINT TO FIRST PID
RETSKP
;ROUTINE TO SEND A MESSAGE WHEN A PID IS DELETED
;ACCEPTS IN T1/ PID TO SEND TO
; T2/ DELETED PID
; Q3/ LENGTH OF MESSAGE DATA AREA
; CALL IPCPKM
;RETURNS +1: FAILED
; +2: MESSAGE IS SENT
IPCPKM: ASUBR <IPCPKP,IPCPKD>
CALL VALPID ;VALIDATE THE PID
RET
CALL IPCMES ;GET THE MESSAGE AREA
RETBAD
MOVEI T2,.IPCKP ;GET FUNCTION CODE
STOR T2,MESWD0,(T1) ;STORE THE FUNCTION CODE
MOVE T2,IPCPKD ;GET THE DELETED PID
MOVEM T2,MESWDI+1(T1) ;SAVE THE PID THAT IS BEING DELETED
RETSKP
;ROUTINE TO SEND MESSAGES FROM IPCC TO A PID
;ACCEPTS IN T1/ PID TO SEND TO
; Q3/ LENGTH OF MESSAGE (NOT INCLUDING HEADER)
; CALL IPCMES
;RETURNS +1: COULD NOT SEND TO THAT PID FOR SOME REASON
; +2: SUCCESSFUL - T1/ ADDRESS OF MESSAGE
IPCMES: STKVAR <IPCMSP>
MOVEM P1,IPCMSP ;SAVE THE PERMANENT ACS
SETZ T2, ; Get the message space
TXZ P1,IP%CFV ; Not page mode
CALL MESTOR ;GO PUT MESSAGE ON PID QUEUE
SKIPA P1,IPCMSP ;RESTORE PERMANENT AC
SKIPA P1,IPCMSP ;DITTO
RETBAD () ;AN ERROR OCCURED ON SEND
MOVEI T2,IPCCFL ;GET FLAGS FOR INFO TO SEE
MOVEI T3,-1 ;JOB NUMBER -1 SO SEND COUNT DOESN'T GET DECREMENTED
CALL MSHEAD ;FILL IN MESSAGE HEADER
RETSKP ;GIVE SUCCESSFUL RETURN
;ROUTINE TO INITIALIZE THE FREE SPACE AND THE PID FREE LIST
; CALL PIDINI
;RETURNS +1: ALWAYS
PIDINI::STKVAR <PIDINX>
SETZM PIDMXP ;INIT # OF PAGES IN TRANSIT ALLOWED
SETOM PIDPBT ;INITIALIZE BIT TABLE
MOVE T1,[PIDPBT,,PIDPBT+1]
BLT T1,PIDPBT+PIDPBL-1 ;MAKE ALL PAGES AVAILABLE (SET TO 1)
MOVSI T1,-PIDFTL ;INITIALIZE FORK TABLE TO 0
SETZM PIDFTB(T1)
AOBJN T1,.-1 ;LOOP BACK TIL ALL ZERO
SKIPE JOBNO ;IS THIS JOB ZERO?
BUG(IPCJB0)
MOVSI T4,-PIDFTL ;SET UP TO CREATE FORKS
PIDIN1: MOVEM T4,PIDINX ;SAVE COUNTER AND INDEX VALUE
SETZB T1,T2 ;CREATE A FORK
CFORK ;UNDER JOB 0
JRST PIDINB ;CANNOT CREATE A FORK, GO BUGCHK
HRLZS T1 ;NOW GET PTN.PN OF THIS FORK
MOVEI T2,0 ;...
CALL FKHPTN ;...
JRST PIDINB ;FAILED
MOVE T4,PIDINX ;GET BACK INDEX
MOVEM T1,PIDFTB(T4) ;STORE PTN IN FORK TABLE
MOVEI T2,^D512 ;UPDATE MAX PAGES ALLOWED
ADDM T2,PIDMXP ; FOR IN-TRANSIT PAGES
AOBJN T4,PIDIN1 ;LOOP BACK TIL ALL FORKS CREATED
PIDIN2: SETZM INFOPV ;INITIALIZE PUBLIC VALUE OF SYSTEM INFO
SETZM NXTPID ;INITIALIZE UNIQUE NUMBER LOCATION
;THERE IS NO MISTAKE IN THE NEXT TWO INSTRUCTIONS. REFER TO THE
;DESCRIPTION OF PIDTBL AT THE BEGINNING OF THE MODULE, AND TO BUGS.MAC.
MOVEI T1,SWFREE ;CHECK IF PIDS AND FREE POOL OVERLAP
CAIGE T1,MAXPID ;OTHERWISE IPCF WONT WORK
BUG(IPCOVL)
MOVE T1,[SWFREE,,SWFREE+1]
SETZM SWFREE ;ZERO THE FREE POOL
BLT T1,SWFREE+SWFREL-1 ;...
MOVEI T1,SWFREE ;GET ADR OF FREE POOL
HRLOM T1,SWPFRE ;INITIALIZE POINTER TO FREE BLOCK
MOVEI T1,SWFREL ;GET LENGTH OF FREE AREA
HRRZM T1,SWFREE ;MAKE IT ONE LARGE BLOCK
MOVEM T1,SWPFRE+2 ;STORE IN SPACE COUNTER
SETOM SWPFRE+1 ;INITIALIZE LOCK ON FREE STORE
MOVE T1,[XWD SWFREE+SWFREL,SWFREE]
MOVEM T1,SWPFRE+4 ;SET UP TOP AND BOTTOM POINTERS
MOVEI T1,SWOPTL ;GET OPTIMUM LENGTH OF MESSAGES
MOVEM T1,SWPFRE+3 ;SAVE IN HEADER BLOCK
;..
;..
SETZM PDFKTB ;INITIALIZE WAKE UP TABLE
MOVE T1,[PDFKTB,,PDFKTB+1]
MOVEI T2,PDFKTL
CAILE T2,1 ;DONT BLT IF ONLY ONE WORD TO BE ZEROED
BLT T1,PDFKTB-1+PDFKTL
MOVSI T1,-PIDTBS ;GET LENGTH OF PIDTBL
MOVE T2,[XWD 2,3]
PIDINL: MOVEM T2,PIDTBL(T1) ;SET UP PID FREE LIST
ADD T2,BHC+2 ;ADD 2,,2
AOBJN T1,PIDINL ;LOOP FOR AWHOLE PID TABLE
MOVEI T1,1 ;START PID TABLE FREE LIST AT 1
MOVEM T1,PIDLST ;MAKE FREE LIST START AT PID 1
MOVEI T1,MAXPID ;FREE LIST IS TERMINATED
SETZ T2, ; WITH A ZERO
CALL PUTPID ;SO DO IT
NOP
LCKINI PIDLKK ;INITIALIZE LOCK
RET ;AND EXIT
PIDINB: BUG(IPCFRK)
JRST PIDIN2 ;CONTINUE ON
TNXEND
END