Trailing-Edge
-
PDP-10 Archives
-
BB-M080M-SM
-
monitor-sources/cfssrv.mac
There are 21 other files named cfssrv.mac in the archive. Click here to see a list.
; *** Edit 7348 to CFSSRV.MAC by LOMARTIRE on 1-Aug-86
; Prevent OPNX9 errors from stale ENQ tokens remaining on system
; *** Edit 7330 to CFSSRV.MAC by LOMARTIRE on 27-Jun-86, for SPR #21275
; Prevent CFSTUC BUGHLTs
; *** Edit 7315 to CFSSRV.MAC by LOMARTIRE on 11-Jun-86, for SPR #21144
; Prevent OPNX9 from ENQ tokens remaining after STRTAB is zeroed - for SPR
; 21144A
;------------------------- Autopatch Tape # 13 -------------------------
; *** Edit 7247 to CFSSRV.MAC by LOMARTIRE on 19-Feb-86
; Implement OFN caching
;Edit 7247 - Implement file access token caching portion of OFN caching
; *** Edit 7211 to CFSSRV.MAC by GRANT on 18-Dec-85
; Add CI counters for WATCH
;------------------------- Autopatch Tape # 12 -------------------------
; Edit 7152 to CFSSRV.MAC by GRANT on 15-Oct-85
; Don't BUGHLT if there are more than 4 KLs in the cluster.
; Remove check against CFSMAX when making a connection.
; Edit 7144 to CFSSRV.MAC by LOMARTIRE on 10-Sep-85 (TCO 6-1-1534)
; Make sure that CFS connects only to TOPS-20 hosts
; UPD ID= 2324, SNARK:<6.1.MONITOR>CFSSRV.MAC.380, 5-Sep-85 09:59:41 by LOMARTIRE
;TCO 6.1.1535 - Fix CFSBEF to use the correct transaction number
; UPD ID= 2278, SNARK:<6.1.MONITOR>CFSSRV.MAC.379, 25-Jun-85 14:58:36 by GRANT
;TCO 6.1.1473 - In CFSJYN, check for node in maintenance state
; UPD ID= 2110, SNARK:<6.1.MONITOR>CFSSRV.MAC.378, 3-Jun-85 16:14:30 by LOMARTIRE
;TCO 6.1.1374 - Make the delay time a function of the number of nodes on CI
; UPD ID= 2055, SNARK:<6.1.MONITOR>CFSSRV.MAC.376, 3-Jun-85 14:19:48 by MCCOLLUM
;TCO 6.1.1406 - Update copyright notice.
; UPD ID= 1998, SNARK:<6.1.MONITOR>CFSSRV.MAC.375, 23-May-85 14:27:36 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1995, SNARK:<6.1.MONITOR>CFSSRV.MAC.374, 21-May-85 12:32:12 by LOMARTIRE
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1960, SNARK:<6.1.MONITOR>CFSSRV.MAC.373, 13-May-85 09:15:29 by LOMARTIRE
;TCO 6.1.1375 - Add missing index register in BRDTIM
; UPD ID= 1867, SNARK:<6.1.MONITOR>CFSSRV.MAC.372, 4-May-85 10:53:46 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1809, SNARK:<6.1.MONITOR>CFSSRV.MAC.371, 24-Apr-85 14:23:31 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1783, SNARK:<6.1.MONITOR>CFSSRV.MAC.370, 23-Apr-85 12:30:13 by MCCOLLUM
;TCO 6.1.1238 - Fix typos in BUG. documentation
; UPD ID= 1778, SNARK:<6.1.MONITOR>CFSSRV.MAC.369, 22-Apr-85 23:12:56 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1763, SNARK:<6.1.MONITOR>CFSSRV.MAC.368, 17-Apr-85 14:01:57 by LOMARTIRE
;TCO 6.1.1327 - Prevent PITRAPs by locking down correct page in CFCARV
; UPD ID= 1722, SNARK:<6.1.MONITOR>CFSSRV.MAC.367, 8-Apr-85 10:43:07 by MCCOLLUM
;TCO 6.1.1238 - Fix BUG. documentation
; UPD ID= 1644, SNARK:<6.1.MONITOR>CFSSRV.MAC.366, 18-Mar-85 08:10:55 by GRANT
;More TCO 6.1.1245 - minor enhancements
; UPD ID= 1623, SNARK:<6.1.MONITOR>CFSSRV.MAC.365, 12-Mar-85 15:56:34 by LOMARTIRE
;TCO 6.1.1247 - Improve CFSJYN and update table of contents
; UPD ID= 1615, SNARK:<6.1.MONITOR>CFSSRV.MAC.364, 11-Mar-85 09:57:31 by GRANT
;TCO 6.1.1245 - Add routines CFCBRD, CHKCLC, and CFCEAS for ^ECEASE protocol
; UPD ID= 1548, SNARK:<6.1.MONITOR>CFSSRV.MAC.363, 20-Feb-85 15:26:11 by LOMARTIRE
;TCO 6.1.1200 - Add the CFSDSN routine to handle a swap of a DSN on a DSA disk
; UPD ID= 1533, SNARK:<6.1.MONITOR>CFSSRV.MAC.362, 19-Feb-85 10:33:12 by LOMARTIRE
;TCO 6.1.1207 - Calculate HSHCOD correctly in CFRDSN
; UPD ID= 1531, SNARK:<6.1.MONITOR>CFSSRV.MAC.361, 19-Feb-85 10:10:33 by LOMARTIRE
;TCO 6.1.1194 - Return an error number when returning a no vote response.
; Have the requesting side interpret this number and form a TOPS-20 error code.
; UPD ID= 1447, SNARK:<6.1.MONITOR>CFSSRV.MAC.360, 1-Feb-85 14:17:26 by LOMARTIRE
;Add new symbols to describe the priority used by SC.SMG
; UPD ID= 1440, SNARK:<6.1.MONITOR>CFSSRV.MAC.359, 31-Jan-85 16:14:56 by MOSER
;TCO 6.1.1166 - *PERFORMANCE* - OFN MANAGEMENT - CANNOT USE MAXSPL ANYMORE
; UPD ID= 1405, SNARK:<6.1.MONITOR>CFSSRV.MAC.358, 25-Jan-85 09:35:11 by WAGNER
;TCO 6.1.1155 - *PERFORMANCE* - Change HSHLEN to be Prime
; UPD ID= 1350, SNARK:<6.1.MONITOR>CFSSRV.MAC.357, 16-Jan-85 16:43:02 by MOSER
;TCO 6.1.1139 - *PERFORMANCE* - CHANGE PSKED REFS TO PSKD1
; UPD ID= 1285, SNARK:<6.1.MONITOR>CFSSRV.MAC.356, 8-Jan-85 10:09:05 by GRANT
;Change comments in header of routine CFRDSN.
; UPD ID= 1245, SNARK:<6.1.MONITOR>CFSSRV.MAC.355, 31-Dec-84 09:32:39 by LOMARTIRE
;TCO 6.1.1096 - Make ASC8T7 global for use by new .CFHSC funciton of CNFIG%
; UPD ID= 1213, SNARK:<6.1.MONITOR>CFSSRV.MAC.354, 17-Dec-84 16:30:24 by TBOYLE
;Change use of MAXNDS in CFS tables to HSTSIZ in CNFIG functions..
; UPD ID= 1192, SNARK:<6.1.MONITOR>CFSSRV.MAC.353, 12-Dec-84 09:50:56 by GRANT
;TCO 6.1.1084 - In CFDIAG, put serial number in OLDTAB so CFRECN will happen.
; UPD ID= 1055, SNARK:<6.1.MONITOR>CFSSRV.MAC.351, 13-Nov-84 09:04:51 by LOMARTIRE
;Use new sending priority symbols in SC.SMG calls.
;Rearrange CFSGET routine.
; UPD ID= 4877, SNARK:<6.MONITOR>CFSSRV.MAC.350, 25-Sep-84 14:00:01 by GRANT
;DLYTIM is now the time between loading the KLIPA and reconnecting
; UPD ID= 4862, SNARK:<6.MONITOR>CFSSRV.MAC.349, 21-Sep-84 14:00:26 by HALL
;Add documentation to CFSGFA routine
;Subtitles and comments
; UPD ID= 4782, SNARK:<6.MONITOR>CFSSRV.MAC.348, 30-Aug-84 21:58:53 by MCLEAN
;MOVE CALLS TO PYCOFF AND PYCON
; UPD ID= 4767, SNARK:<6.MONITOR>CFSSRV.MAC.347, 29-Aug-84 13:30:12 by MCLEAN
;MISSED A CALL TO CIONLT FOR BOTH PATH CHANGE
; UPD ID= 4753, SNARK:<6.MONITOR>CFSSRV.MAC.346, 26-Aug-84 21:01:41 by MCLEAN
;REMOVE PHYMPR/PHYUPR NO LONGER NEEDED
; UPD ID= 4667, SNARK:<6.MONITOR>CFSSRV.MAC.345, 8-Aug-84 15:18:34 by LOMARTIRE
;Add subtitles and table of contents
; UPD ID= 4647, SNARK:<6.MONITOR>CFSSRV.MAC.344, 7-Aug-84 10:21:58 by LOMARTIRE
;Fix handling of .SSPBC callback since now we can get an extra one.
; UPD ID= 4640, SNARK:<6.MONITOR>CFSSRV.MAC.343, 31-Jul-84 14:52:25 by PURRETTA
;Add copyright statement, remove brackets in comments.
; UPD ID= 4562, SNARK:<6.MONITOR>CFSSRV.MAC.342, 18-Jul-84 19:31:25 by HALL
;Comments
; UPD ID= 4495, SNARK:<6.MONITOR>CFSSRV.MAC.341, 12-Jul-84 19:52:27 by LOMARTIRE
;Overhaul callback table. Remove .SSCBD and replace with .SSDDG.
;Code for AC change in .SSDGR/.SSMGR callbacks.
;Remove .SSNWO and .SSMNT from callback table.
; UPD ID= 4423, SNARK:<6.MONITOR>CFSSRV.MAC.340, 3-Jul-84 14:26:05 by LOMARTIRE
;Make call to SC.RCD pass in the address of the argument block.
;Obtain block from free space since SC.RCD no longer does so.
; UPD ID= 4420, SNARK:<6.MONITOR>CFSSRV.MAC.339, 3-Jul-84 09:55:25 by HALL
;CFSJYN - Don't check on nodes until online callback
; UPD ID= 4406, SNARK:<6.MONITOR>CFSSRV.MAC.338, 28-Jun-84 13:24:53 by TBOYLE
;CNFIG% - At .CFCSE, CFCSEB does not have unused bits zeroed.
; UPD ID= 4376, SNARK:<6.MONITOR>CFSSRV.MAC.337, 22-Jun-84 16:28:26 by TBOYLE
;CNFIG% - Put CFS routines in here.
; UPD ID= 4210, SNARK:<6.MONITOR>CFSSRV.MAC.336, 11-May-84 12:14:50 by GRANT
;In CFSJYN, remove call to SRVCFS (it's now at RUNDD2 in MEXEC)
; UPD ID= 4160, SNARK:<6.MONITOR>CFSSRV.MAC.335, 1-May-84 07:35:54 by HALL
;Add Q2 to the AC's saved by CFSRTV. This was confusing SCAPOL.
; UPD ID= 4143, SNARK:<6.MONITOR>CFSSRV.MAC.334, 25-Apr-84 17:50:37 by HALL
;TRY TO GET THE IFNS RIGHT
; UPD ID= 4138, SNARK:<6.MONITOR>CFSSRV.MAC.333, 25-Apr-84 14:38:21 by HALL
;Rearrange SCA interface routines
;CFSCPS - Get rid of BLOCK. (and the bug that went with it), and use a
;subroutine to disconnect duplicate connections.
; UPD ID= 4135, SNARK:<6.MONITOR>CFSSRV.MAC.332, 25-Apr-84 13:03:05 by LOMARTIRE
;Replace all .SCFxx error codes with equivalent SCSxxx error codes
; UPD ID= 4114, SNARK:<6.MONITOR>CFSSRV.MAC.331, 24-Apr-84 12:58:40 by TGRADY
;TCO 6.2041 - ILSPTI BUGHLT's on Non-CFS monitors.
; Remove conditional assembly switches around global job numbers code
; UPD ID= 4085, SNARK:<6.MONITOR>CFSSRV.MAC.330, 15-Apr-84 10:01:36 by HALL
;Add comments and subtitles
; UPD ID= 4042, SNARK:<6.MONITOR>CFSSRV.MAC.329, 3-Apr-84 14:32:59 by LOMARTIRE
;Add node number and connect ID to CFACCF, CFCCLZ, and CFRECN BUGxxx's
; UPD ID= 3974, SNARK:<6.MONITOR>CFSSRV.MAC.328, 25-Mar-84 11:16:44 by HALL
;Add SAVET to ONLINE and OFLINE
; UPD ID= 3947, SNARK:<6.MONITOR>CFSSRV.MAC.327, 20-Mar-84 03:03:37 by HALL
;Add node number and CID to OFLINE and ONLINE
; UPD ID= 3926, SNARK:<6.MONITOR>CFSSRV.MAC.326, 14-Mar-84 13:02:05 by TGRADY
;TCO 6.1999 - Remove edit 3840, and conditionally define MXGLBS in STG
; UPD ID= 3863, SNARK:<6.MONITOR>CFSSRV.MAC.325, 7-Mar-84 05:50:00 by GRANT
;Fix CFFCTB to handle new callbacks. Clarify some comments.
; UPD ID= 3843, SNARK:<6.MONITOR>CFSSRV.MAC.324, 4-Mar-84 06:26:51 by GRANT
;Add cell CONCID in which the CID for the current connection attempt is saved.
; UPD ID= 3840, SNARK:<6.MONITOR>CFSSRV.MAC.323, 2-Mar-84 15:59:23 by TGRADY
;Correct last edit - use NJOBS, not MXGLBS, for non-CFS range check.
; UPD ID= 3836, SNARK:<6.MONITOR>CFSSRV.MAC.322, 1-Mar-84 15:22:31 by TGRADY
; Make GL2LCL still do range check even on non-cfs monitors.
; UPD ID= 3794, SNARK:<6.MONITOR>CFSSRV.MAC.321, 29-Feb-84 01:41:07 by TGRADY
; One more fix to GL2LCL for Job 0...
; UPD ID= 3777, SNARK:<6.MONITOR>CFSSRV.MAC.320, 28-Feb-84 10:32:12 by MOSER
;TCO 6.1562 - TELL MSCP SERVER WHEN TO OPEN A LISTNER
; UPD ID= 3761, SNARK:<6.MONITOR>CFSSRV.MAC.319, 26-Feb-84 23:53:49 by TGRADY
; Add LCL2GL to look up a Global Job number, given a local job index.
; UPD ID= 3748, SNARK:<6.MONITOR>CFSSRV.MAC.318, 24-Feb-84 20:59:32 by GRANT
;In LSNUP, start a new listener after rejecting an incoming connection.
;Add reporting of CFS disconnect.
; UPD ID= 3742, SNARK:<6.MONITOR>CFSSRV.MAC.317, 23-Feb-84 14:13:47 by GRANT
;STRVER is only for CFS monitors.
; UPD ID= 3722, SNARK:<6.MONITOR>CFSSRV.MAC.316, 22-Feb-84 05:37:15 by GRANT
;Add CFSJ0 to do STRVER stuff
; UPD ID= 3711, SNARK:<6.MONITOR>CFSSRV.MAC.315, 21-Feb-84 12:58:51 by CDUNN
;Change LISNAM to use a 16 byte 8 bit ASCII string. Also change calls to SC.CON
;and SC.LIS to pass the address of the string, not a byte pointer.
; UPD ID= 3678, SNARK:<6.MONITOR>CFSSRV.MAC.314, 8-Feb-84 21:50:15 by MILLER
;Remove call to STRVER for now. Put it back when job 0 knows how to call it
; UPD ID= 3668, SNARK:<6.MONITOR>CFSSRV.MAC.313, 8-Feb-84 10:05:49 by MILLER
;select the A path for the loopback message
; UPD ID= 3667, SNARK:<6.MONITOR>CFSSRV.MAC.312, 8-Feb-84 09:55:20 by MILLER
;Add STRVER and use it during CI joining
; UPD ID= 3661, SNARK:<6.MONITOR>CFSSRV.MAC.311, 7-Feb-84 16:07:27 by MILLER
;Fix CFSSMT and friends for better resolution on DSN conflicts
; UPD ID= 3748, SNARK:<6.MONITOR>CFSSRV.MAC.318, 24-Feb-84 20:59:32 by GRANT
;In LSNUP, start a new listener after rejecting an incoming connection.
;Add reporting of CFS disconnect.
; UPD ID= 3742, SNARK:<6.MONITOR>CFSSRV.MAC.317, 23-Feb-84 14:13:47 by GRANT
;STRVER is only for CFS monitors.
; UPD ID= 3722, SNARK:<6.MONITOR>CFSSRV.MAC.316, 22-Feb-84 05:37:15 by GRANT
;Add CFSJ0 to do STRVER stuff
; UPD ID= 3711, SNARK:<6.MONITOR>CFSSRV.MAC.315, 21-Feb-84 12:58:51 by CDUNN
;Change LISNAM to use a 16 byte 8 bit ASCII string. Also change calls to SC.CON
;and SC.LIS to pass the address of the string, not a byte pointer.
; UPD ID= 3678, SNARK:<6.MONITOR>CFSSRV.MAC.314, 8-Feb-84 21:50:15 by MILLER
;Remove call to STRVER for now. Put it back when job 0 knows how to call it
; UPD ID= 3668, SNARK:<6.MONITOR>CFSSRV.MAC.313, 8-Feb-84 10:05:49 by MILLER
;select the A path for the loopback message
; UPD ID= 3667, SNARK:<6.MONITOR>CFSSRV.MAC.312, 8-Feb-84 09:55:20 by MILLER
;Add STRVER and use it during CI joining
; UPD ID= 3661, SNARK:<6.MONITOR>CFSSRV.MAC.311, 7-Feb-84 16:07:27 by MILLER
;Fix CFSSMT and friends for better resolution on DSN conflicts
; UPD ID= 3657, SNARK:<6.MONITOR>CFSSRV.MAC.310, 4-Feb-84 11:33:29 by MILLER
;fix typeo
; UPD ID= 3655, SNARK:<6.MONITOR>CFSSRV.MAC.309, 4-Feb-84 10:32:23 by MILLER
;Add routine BRDTIM, to send TAD to appropriate other hosts.
; UPD ID= 3610, SNARK:<6.MONITOR>CFSSRV.MAC.308, 31-Jan-84 17:20:47 by TGRADY
; In JBGET1, don't increment & decrement the Global job number assigned. User
; gets returned the Global Job number +1 when this is done.
; UPD ID= 3594, SNARK:<6.MONITOR>CFSSRV.MAC.307, 31-Jan-84 04:04:53 by TGRADY
;Make GL2LCL RETBAD if the local job number found is out of range (1-NJOBS)
;Make JBGET1 and JBAVAL handle Job 0 (Ignore it)
; UPD ID= 3583, SNARK:<6.MONITOR>CFSSRV.MAC.306, 28-Jan-84 19:14:59 by MILLER
;Remove use of MAXVWT for now
; UPD ID= 3581, SNARK:<6.MONITOR>CFSSRV.MAC.305, 28-Jan-84 17:41:09 by MILLER
;Change MAXVWT to 1
; UPD ID= 3516, SNARK:<6.MONITOR>CFSSRV.MAC.304, 23-Jan-84 18:29:01 by MOSER
;CHANGE MSTX16 AND MSTX17 TO BE MSTX45 AND MSTX46 SO AS NOT TO CONFLICT
; WITH THE OTHER MSTX16 AND MSTX17
; UPD ID= 3501, SNARK:<6.MONITOR>CFSSRV.MAC.303, 20-Jan-84 18:29:40 by MILLER
;Add prcoessor serial number to CFONLN BUGINF
; UPD ID= 3494, SNARK:<6.MONITOR>CFSSRV.MAC.302, 20-Jan-84 11:12:46 by CDUNN
;More TCO 6.1127 - Change call to SC.LIS to not allow buffers to be queued
; UPD ID= 3458, SNARK:<6.MONITOR>CFSSRV.MAC.301, 14-Jan-84 12:43:31 by MILLER
;One more stab at drive online stuff.
; UPD ID= 3443, SNARK:<6.MONITOR>CFSSRV.MAC.300, 12-Jan-84 12:06:49 by MILLER
;Handle credit low and arrival without races
; UPD ID= 3435, SNARK:<6.MONITOR>CFSSRV.MAC.299, 11-Jan-84 10:52:35 by MILLER
; UPD ID= 3432, SNARK:<6.MONITOR>CFSSRV.MAC.298, 10-Jan-84 19:51:36 by MILLER
;More of the previous
; UPD ID= 3417, SNARK:<6.MONITOR>CFSSRV.MAC.297, 6-Jan-84 08:58:25 by MILLER
;use two-word DSNs
; UPD ID= 3401, SNARK:<6.MONITOR>CFSSRV.MAC.296, 3-Jan-84 15:28:59 by MILLER
;Add a BUGCHK to CFSRDR if directory is not locked
; UPD ID= 3395, SNARK:<6.MONITOR>CFSSRV.MAC.295, 3-Jan-84 09:55:31 by MILLER
;CFSRDR should not do ECSKED if DIRECTORY was not locked
; UPD ID= 3392, SNARK:<6.MONITOR>CFSSRV.MAC.294, 30-Dec-83 08:22:56 by MILLER
;Check for both drives the same in CFRDSN
; UPD ID= 3334, SNARK:<6.MONITOR>CFSSRV.MAC.293, 16-Dec-83 15:51:28 by MILLER
;Add CFONLN BUGINF for debugging
; UPD ID= 3300, SNARK:<6.MONITOR>CFSSRV.MAC.292, 13-Dec-83 09:10:39 by MILLER
;Enhance CFCCLZ BUGCHK to include the SCA error code
; UPD ID= 3298, SNARK:<6.MONITOR>CFSSRV.MAC.291, 13-Dec-83 08:34:55 by MILLER
;Add CFDIAG to clean up on "CI OFFLINE" call
; UPD ID= 3289, SNARK:<6.MONITOR>CFSSRV.MAC.290, 11-Dec-83 20:20:35 by GRANT
;In CFSCTH, use new symbol VC.OPN
; UPD ID= 3240, SNARK:<6.MONITOR>CFSSRV.MAC.289, 30-Nov-83 22:01:54 by MILLER
;Add "guard word" to verify VOTE packets
; UPD ID= 3236, SNARK:<6.MONITOR>CFSSRV.MAC.288, 30-Nov-83 17:39:40 by MILLER
;Previsou fix not right. Revert to old way
; UPD ID= 3233, SNARK:<6.MONITOR>CFSSRV.MAC.287, 30-Nov-83 11:24:20 by MILLER
;Fix allocation of vote packets
; UPD ID= 3211, SNARK:<6.MONITOR>CFSSRV.MAC.286, 23-Nov-83 13:36:41 by MILLER
;More work on CI error recovery
; UPD ID= 3195, SNARK:<6.MONITOR>CFSSRV.MAC.285, 18-Nov-83 15:03:44 by MILLER
;More of the previous
; UPD ID= 3194, SNARK:<6.MONITOR>CFSSRV.MAC.284, 18-Nov-83 14:35:53 by MILLER
;Add "temp" code to try out new CI error recovery. More to come!
; UPD ID= 3187, SNARK:<6.MONITOR>CFSSRV.MAC.283, 17-Nov-83 16:21:08 by CDUNN
;More TCO 6.1127 - Fix calls to SC.SMG to conform to new calling sequence
; UPD ID= 3100, SNARK:<6.MONITOR>CFSSRV.MAC.282, 4-Nov-83 16:56:47 by MILLER
; UPD ID= 3099, SNARK:<6.MONITOR>CFSSRV.MAC.281, 4-Nov-83 16:13:40 by MILLER
;Add CFSFDF entry to use from CFSUW0
; UPD ID= 3081, SNARK:<6.MONITOR>CFSSRV.MAC.280, 26-Oct-83 07:41:18 by MILLER
;CFSRTV must refuse a request if this node has a commit (HSHDLY <>0)
; UPD ID= 3080, SNARK:<6.MONITOR>CFSSRV.MAC.279, 26-Oct-83 07:16:31 by MILLER
;Must be CSKED during vote waiting
; UPD ID= 3061, SNARK:<6.MONITOR>CFSSRV.MAC.278, 24-Oct-83 10:20:03 by MILLER
;Fix typeo in CFAREM
; UPD ID= 3053, SNARK:<6.MONITOR>CFSSRV.MAC.277, 21-Oct-83 17:17:37 by MILLER
;Fix storing of node name from connect optional data
; UPD ID= 3050, SNARK:<6.MONITOR>CFSSRV.MAC.276, 20-Oct-83 16:38:22 by MILLER
;Fix bugs in previous edits
; UPD ID= 3048, SNARK:<6.MONITOR>CFSSRV.MAC.275, 19-Oct-83 18:25:13 by MILLER
;Once more. Do NODE% in proper place
; UPD ID= 3047, SNARK:<6.MONITOR>CFSSRV.MAC.274, 19-Oct-83 16:11:29 by MILLER
;Rearrange optional data so we an pass DECnet node name
; UPD ID= 3043, SNARK:<6.MONITOR>CFSSRV.MAC.273, 18-Oct-83 18:21:26 by MILLER
;Fix CFSDAU to handle temoprary entires
; UPD ID= 3035, SNARK:<6.MONITOR>CFSSRV.MAC.272, 13-Oct-83 11:54:36 by MILLER
; UPD ID= 3027, SNARK:<6.MONITOR>CFSSRV.MAC.271, 11-Oct-83 10:25:58 by MILLER
;TCO 6.1824. Add CFSPRT for IPCF to use
; UPD ID= 3018, SNARK:<6.MONITOR>CFSSRV.MAC.270, 10-Oct-83 13:44:37 by MILLER
;Change buffer count
; UPD ID= 3008, SNARK:<6.MONITOR>CFSSRV.MAC.269, 7-Oct-83 20:03:39 by MILLER
; UPD ID= 3007, SNARK:<6.MONITOR>CFSSRV.MAC.268, 7-Oct-83 18:31:25 by MILLER
; UPD ID= 2976, SNARK:<6.MONITOR>CFSSRV.MAC.267, 3-Oct-83 18:40:08 by MILLER
; UPD ID= 2951, SNARK:<6.MONITOR>CFSSRV.MAC.266, 28-Sep-83 07:11:55 by MILLER
;The last typeo
; UPD ID= 2950, SNARK:<6.MONITOR>CFSSRV.MAC.265, 28-Sep-83 05:54:32 by GRANT
;Fix typos in recent edits
; UPD ID= 2948, SNARK:<6.MONITOR>CFSSRV.MAC.264, 27-Sep-83 21:11:12 by MILLER
; UPD ID= 2946, SNARK:<6.MONITOR>CFSSRV.MAC.263, 27-Sep-83 20:48:44 by MILLER
; UPD ID= 2943, SNARK:<6.MONITOR>CFSSRV.MAC.262, 27-Sep-83 20:27:17 by MILLER
;More work for TCO 6.1806
; UPD ID= 2929, SNARK:<6.MONITOR>CFSSRV.MAC.261, 23-Sep-83 13:52:20 by MILLER
; UPD ID= 2927, SNARK:<6.MONITOR>CFSSRV.MAC.260, 23-Sep-83 10:59:38 by MILLER
;Fix typeos in previous edit
; UPD ID= 2925, SNARK:<6.MONITOR>CFSSRV.MAC.259, 23-Sep-83 10:34:05 by MILLER
;TCO 6.1806. Add TAD stuff
; UPD ID= 2923, SNARK:<6.MONITOR>CFSSRV.MAC.258, 23-Sep-83 10:05:01 by MILLER
;Add job number assigner
; UPD ID= 2893, SNARK:<6.MONITOR>CFSSRV.MAC.257, 12-Sep-83 19:53:49 by MILLER
;Turn off OFN bit in CFSUWT
; UPD ID= 2887, SNARK:<6.MONITOR>CFSSRV.MAC.256, 12-Sep-83 11:35:28 by MILLER
;Make sure always in section 1
; UPD ID= 2884, SNARK:<6.MONITOR>CFSSRV.MAC.255, 9-Sep-83 19:16:30 by MILLER
;New buffer management to avoid free space failures
; UPD ID= 2877, SNARK:<6.MONITOR>CFSSRV.MAC.254, 6-Sep-83 09:25:05 by MILLER
;More fixes to CFSSMT
; UPD ID= 2873, SNARK:<6.MONITOR>CFSSRV.MAC.253, 1-Sep-83 10:30:28 by MILLER
;fix CFSSMT
; UPD ID= 2871, SNARK:<6.MONITOR>CFSSRV.MAC.252, 31-Aug-83 15:32:11 by MILLER
; UPD ID= 2830, SNARK:<6.MONITOR>CFSSRV.MAC.251, 12-Aug-83 14:17:17 by MILLER
;prevent MONPDL in CFSDAU
; UPD ID= 2775, SNARK:<6.MONITOR>CFSSRV.MAC.250, 28-Jul-83 12:14:43 by MILLER
; UPD ID= 2774, SNARK:<6.MONITOR>CFSSRV.MAC.249, 27-Jul-83 16:22:10 by MILLER
; UPD ID= 2770, SNARK:<6.MONITOR>CFSSRV.MAC.248, 27-Jul-83 10:09:35 by MILLER
;Add check for illegal reconnect
; UPD ID= 2717, SNARK:<6.MONITOR>CFSSRV.MAC.247, 22-Jul-83 14:52:58 by MILLER
; UPD ID= 2712, SNARK:<6.MONITOR>CFSSRV.MAC.246, 20-Jul-83 16:58:19 by MURPHY
;Take out setup of MSECTB+CFSSEC because it's already done by PGRINI.
; UPD ID= 2710, SNARK:<6.MONITOR>CFSSRV.MAC.245, 20-Jul-83 09:59:36 by MILLER
;Clean up CFSCMC and pending connections in SCABRK
; UPD ID= 2697, SNARK:<6.MONITOR>CFSSRV.MAC.244, 13-Jul-83 14:22:39 by MILLER
;More editing fixes
; UPD ID= 2696, SNARK:<6.MONITOR>CFSSRV.MAC.243, 13-Jul-83 10:24:17 by MILLER
;Add commentary.
; UPD ID= 2693, SNARK:<6.MONITOR>CFSSRV.MAC.242, 11-Jul-83 17:40:35 by MILLER
;Yet more CI error recovery fixes
; UPD ID= 2681, SNARK:<6.MONITOR>CFSSRV.MAC.241, 6-Jul-83 12:56:31 by MILLER
;More fixes for CI error recovery
; UPD ID= 2679, SNARK:<6.MONITOR>CFSSRV.MAC.239, 6-Jul-83 10:09:57 by MILLER
;Add and maintain CFSCMC
; UPD ID= 2670, SNARK:<6.MONITOR>CFSSRV.MAC.238, 5-Jul-83 16:03:15 by MILLER
; UPD ID= 2654, SNARK:<6.MONITOR>CFSSRV.MAC.237, 2-Jul-83 08:37:58 by MILLER
;Must always create a CFSSTK pointer, even if CFSSCA=0
; UPD ID= 2612, SNARK:<6.MONITOR>CFSSRV.MAC.236, 21-Jun-83 09:47:07 by MILLER
; UPD ID= 2611, SNARK:<6.MONITOR>CFSSRV.MAC.235, 20-Jun-83 21:18:24 by MILLER
; UPD ID= 2591, SNARK:<6.MONITOR>CFSSRV.MAC.234, 20-Jun-83 10:05:44 by HALL
;TCO 6.1689 - Move fork tables to extended section
; Reference FKSTA2 via DEFSTR
; UPD ID= 2587, SNARK:<6.MONITOR>CFSSRV.MAC.233, 17-Jun-83 14:01:37 by MILLER
;Improve handling of HSHLNK and avoid a few bugs as well
; UPD ID= 2583, SNARK:<6.MONITOR>CFSSRV.MAC.232, 15-Jun-83 10:13:49 by MILLER
;Yet more fixes!
; UPD ID= 2582, SNARK:<6.MONITOR>CFSSRV.MAC.231, 15-Jun-83 09:31:03 by MILLER
;More fixes for dual-port devices
; UPD ID= 2576, SNARK:<6.MONITOR>CFSSRV.MAC.230, 8-Jun-83 21:35:17 by MILLER
;Improve recovery when free space queue is exhausted.
; UPD ID= 2571, SNARK:<6.MONITOR>CFSSRV.MAC.229, 8-Jun-83 14:23:03 by MILLER
;Make FILRST correct, but leave it out anyway
; UPD ID= 2570, SNARK:<6.MONITOR>CFSSRV.MAC.228, 8-Jun-83 13:35:43 by MILLER
;Remove FILRST
; UPD ID= 2569, SNARK:<6.MONITOR>CFSSRV.MAC.227, 8-Jun-83 13:29:50 by MILLER
;Don't set CFSSKC in CFSDIN
; UPD ID= 2550, SNARK:<6.MONITOR>CFSSRV.MAC.226, 1-Jun-83 07:40:17 by MILLER
;Remove CFSCFL BUGHLT
; UPD ID= 2542, SNARK:<6.MONITOR>CFSSRV.MAC.225, 31-May-83 14:03:43 by MILLER
; UPD ID= 2530, SNARK:<6.MONITOR>CFSSRV.MAC.224, 26-May-83 14:10:18 by MILLER
; UPD ID= 2529, SNARK:<6.MONITOR>CFSSRV.MAC.223, 26-May-83 14:08:57 by MILLER
;Add more BUGHLTs for whenever SCA fails
; UPD ID= 2525, SNARK:<6.MONITOR>CFSSRV.MAC.222, 26-May-83 11:56:22 by MILLER
;Fix CFSCHK to do CFONLT only after the monitor is initialized
; UPD ID= 2522, SNARK:<6.MONITOR>CFSSRV.MAC.221, 25-May-83 20:14:33 by MILLER
;Only do CI check if CFSSCA
; UPD ID= 2514, SNARK:<6.MONITOR>CFSSRV.MAC.220, 25-May-83 09:17:54 by MILLER
;Do a full CI check every five seconds
; UPD ID= 2500, SNARK:<6.MONITOR>CFSSRV.MAC.219, 23-May-83 11:14:27 by MILLER
;Remove dummy def of CIONLT
; UPD ID= 2478, SNARK:<6.MONITOR>CFSSRV.MAC.218, 17-May-83 10:24:07 by MILLER
;Account for CFSNDO skip return in CFSDEQ
; UPD ID= 2451, SNARK:<6.MONITOR>CFSSRV.MAC.217, 10-May-83 10:31:13 by MILLER
;Fix CFSOVT test on HSHBTF
; UPD ID= 2359, SNARK:<6.MONITOR>CFSSRV.MAC.216, 27-Apr-83 13:29:03 by MILLER
; UPD ID= 2356, SNARK:<6.MONITOR>CFSSRV.MAC.215, 27-Apr-83 11:43:28 by MILLER
; UPD ID= 2355, SNARK:<6.MONITOR>CFSSRV.MAC.214, 27-Apr-83 08:11:58 by MILLER
; UPD ID= 2308, SNARK:<6.MONITOR>CFSSRV.MAC.213, 19-Apr-83 20:04:35 by MILLER
;DOn't need POLCNT test - PHYKLP does it correctly
; UPD ID= 2298, SNARK:<6.MONITOR>CFSSRV.MAC.212, 17-Apr-83 18:45:49 by MILLER
;Add message statistics
; UPD ID= 2273, SNARK:<6.MONITOR>CFSSRV.MAC.211, 13-Apr-83 14:27:48 by MILLER
;TCO 1.1610. Add CFONLT
; UPD ID= 2240, SNARK:<6.MONITOR>CFSSRV.MAC.210, 12-Apr-83 12:07:16 by MILLER
;Remove dummy defs of PHYMPR and PHYUPR
; UPD ID= 2236, SNARK:<6.MONITOR>CFSSRV.MAC.209, 12-Apr-83 09:31:22 by MILLER
;Check SCAFL1 in CFSJYN to see if we should turn on dual-port disks
; UPD ID= 2235, SNARK:<6.MONITOR>CFSSRV.MAC.208, 12-Apr-83 07:12:16 by MILLER
;Fixes to CFSJYN and CFSNDU.
; UPD ID= 2232, SNARK:<6.MONITOR>CFSSRV.MAC.207, 11-Apr-83 13:22:31 by MILLER
;Fixes to CFSJYN
; UPD ID= 2223, SNARK:<6.MONITOR>CFSSRV.MAC.206, 8-Apr-83 17:33:21 by MILLER
; UPD ID= 2222, SNARK:<6.MONITOR>CFSSRV.MAC.205, 8-Apr-83 15:36:03 by MILLER
;Join only when CFSINI called AND CFSJYN called
; UPD ID= 2184, SNARK:<6.MONITOR>CFSSRV.MAC.204, 7-Apr-83 15:21:54 by MILLER
;Avoid CFSLOK at interrupt level
; UPD ID= 2169, SNARK:<6.MONITOR>CFSSRV.MAC.203, 5-Apr-83 16:23:29 by MILLER
;TCO 6.1094. Move RS defs to STG
; UPD ID= 2155, SNARK:<6.MONITOR>CFSSRV.MAC.202, 4-Apr-83 17:31:32 by MILLER
;TCO 6.1588. Make sure vote buffers are usable
; UPD ID= 2143, SNARK:<6.MONITOR>CFSSRV.MAC.201, 4-Apr-83 07:42:35 by MILLER
;TCO 6.1094. Make length of vote packets an even number of words
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
;OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1976, 1985.
;ALL RIGHTS RESERVED.
SEARCH PROLOG,SCAPAR,PHYPAR
TTITLE CFSSRV
EXTN <CFSSEC>
DEBUG==1 ;Do debugging
IFE CFSSCA,<CFSDUM==0> ;If no SCA, define this as a dummy as well
SUBTTL Table of Contents
; Table of Contents for CFSSRV
;
;
; Section Page
; 1. Design Notes . . . . . . . . . . . . . . . . . . . . . 3
; 2. Data definitions . . . . . . . . . . . . . . . . . . . 7
; 3. Macros . . . . . . . . . . . . . . . . . . . . . . . . 11
; 4. Initialization
; 4.1. CFSINI (SCA initialization routine) . . . . . 12
; 4.2. CFSDIN (Initialize CFS database). . . . . . . 12
; 4.3. CFSJYN/CFSJYX (Join the CFS network). . . . . 13
; 4.4. CFSCSC (Create private pages) . . . . . . . . 14
; 5. Support Routines
; 5.1. CFONLT (Test state of connection) . . . . . . 15
; 5.2. PRTOFL (Turn off dual port access). . . . . . 15
; 5.3. PRTONL (Turn on dual port access) . . . . . . 15
; 5.4. CFSKPR (KLIPA ucode reloaded) . . . . . . . . 15
; 5.5. DEDKLP (KLIPA is dead). . . . . . . . . . . . 15
; 5.6. CFSCTH (Connect to host). . . . . . . . . . . 16
; 5.7. HASHN (Compute hash for resource) . . . . . . 17
; 5.8. HSHLOK (Locate hash entry for resource) . . . 17
; 5.9. GNAME (Get structure name). . . . . . . . . . 18
; 5.10. CFSULL (Unlock CFS database). . . . . . . . . 19
; 5.11. CFSMAP (Map entries onto function). . . . . . 20
; 5.12. CFSRSE (Remove stale entries) . . . . . . . . 21
; 5.13. CFSSPC (Obtain request block space) . . . . . 22
; 5.14. CFCARV (Carve a block from page pool) . . . . 23
; 5.15. CFSSBB (Place OFN in SDB) . . . . . . . . . . 24
; 5.16. CFSWUP (General wait routine) . . . . . . . . 25
; 5.17. CFSRSV (Restart vote) . . . . . . . . . . . . 26
; 5.18. CFTADC (Get CFS time and date). . . . . . . . 27
; 5.19. SNDTIM (Send date and time to new node) . . . 28
; 5.20. BRDTIM (Send date and time at startup). . . . 28
; 5.21. CFTADB (Broadcast date and time via STAD) . . 29
; 5.22. CFSPRT (Return local port number) . . . . . . 29
; 5.23. CFCNCK (Check for CFS connection to node) . . 29
; 6. Resource manager
; 6.1. CFSGET (Acquire a resource) . . . . . . . . . 30
; 6.2. CFSRMV (Remove entry from hash table) . . . . 36
; 6.3. CFSNDO (Undeclare a resource) . . . . . . . . 37
; 6.4. CFSOHS (Notify rejected hosts after undeclare) 39
; 6.5. CFSUGD (Upgrade or downgrade a resource lock) 40
; 7. The voter
; 7.1. VOTEW (Start vote and wait for results) . . . 42
; 7.2. GVOTE (Get a vote buffer) . . . . . . . . . . 47
; 8. Periodic check
; 8.1. CFSCHK (Scheduler poller) . . . . . . . . . . 48
; 8.2. SCAPOL (Process incoming SCA messages). . . . 49
; 9. Call from SCA. . . . . . . . . . . . . . . . . . . . . 50
; 9.1. Message Received
; 9.1.1. SCAIN (Receive message from SCA) . . 51
; 9.1.2. SCMSG (Process a single received message) 52
; 9.1.3. CFSRTV (Vote or seize) . . . . . . . 53
; 9.1.4. CFSRVT (Reply to vote) . . . . . . . 56
; 9.1.5. CFSRFR (Resource freed). . . . . . . 57
; 9.1.6. CFSOFC (OFN change). . . . . . . . . 58
; 9.1.7. CFSEFC (EOF received). . . . . . . . 58
; 9.1.8. CFTADA (Time and date arrived) . . . 58
; 9.1.9. CFCEAS (Cease) . . . . . . . . . . . 59
; 9.2. SCABRK (Node went away) . . . . . . . . . . . 64
; 9.3. LSNUP (Connect to listen) . . . . . . . . . . 65
; 9.4. Connect response available
; 9.4.1. CFSCPS (Connect response available). 66
; 9.4.2. CFSCPX (Disconnect duplicate connection) 68
; 9.5. CFSWDN (Write completed). . . . . . . . . . . 69
; 9.6. CFSNDU (Node up). . . . . . . . . . . . . . . 70
; 9.7. CFSOKS (Ok to send) . . . . . . . . . . . . . 71
; 9.8. SCACRA (Credit available) . . . . . . . . . . 72
; 10. Sending Messages
; 10.1. SCAENQ (Enqueue a SCA message). . . . . . . . 73
; 10.2. SCASND (Send a message) . . . . . . . . . . . 74
; 10.3. SENDQ (Maintain send queue) . . . . . . . . . 75
; 11. Queuing Message Buffers
; 11.1. SCARET (Queue packet as message buffer) . . . 76
; 12. Declare a listener
; 12.1. CFSLSN (Declare CFS listener) . . . . . . . . 77
; 13. Connection Management
; 13.1. CHKOLD (Manage connect serial number) . . . . 78
; 13.2. CHKOL0 (Generate old/new bit) . . . . . . . . 78
; 13.3. PUTOLD (Install serial number). . . . . . . . 78
; 13.4. CLRDLY (Clear delay bit in OLDTAB entries). . 78
; 13.5. CHKDLY (Check for delayed entries). . . . . . 78
; 14. Directory lock resource manager
; 14.1. CFSLDR (Lock directory) . . . . . . . . . . . 79
; 14.2. CFSRDR (Unlock directory) . . . . . . . . . . 81
; 14.3. CFSDAU (Acquire allocation entry) . . . . . . 82
; 14.4. CFAFND/CFAGET (Find/Get allocation table) . . 82
; 14.5. CFASTO (Store new allocation value) . . . . . 84
; 14.6. CFAULK (Unlock allocation entry). . . . . . . 84
; 14.7. CFAREM (Remove allocation entry). . . . . . . 84
; 14.8. CFAUPB (Undo keep here bit) . . . . . . . . . 84
; 14.9. CFAVOK (Vote to be approved). . . . . . . . . 85
; 14.10. CFADAR (Optional data present). . . . . . . . 85
; 14.11. CFARMV (Voter remove entry) . . . . . . . . . 85
; 14.12. GETDBK (Find resource block). . . . . . . . . 86
; 15. File open resource manager
; 15.1. CFSGFA (Acquire file opening locks) . . . . . 87
; 15.2. CFSFFL (Release file locks) . . . . . . . . . 88
; 15.3. CFSURA (Downgrade to promiscuous) . . . . . . 89
; 16. Frozen writer resource manager
; 16.1. CFSGWL (Get write access) . . . . . . . . . . 90
; 16.2. CFSFWL (Free write access). . . . . . . . . . 91
; 17. BAT block resource manager
; 17.1. CFGBBS (Set BAT block lock) . . . . . . . . . 93
; 17.2. CFFBBS (Release BAT block lock) . . . . . . . 94
; 18. File access token resource manager
; 18.1. CFSGWT (Get write token value). . . . . . . . 95
; 18.2. CFSAWP/CFSAWT (Acquire write token) . . . . . 96
; 18.3. CFSDWT (Write token revoked). . . . . . . . . 99
; 18.4. CFSOVT (Approve sharing of OFN resource). . . 99
; 18.5. CFSGOC (Get count of resource sharers). . . . 100
; 18.6. CFSDAR (Optional data for access token) . . . 101
; 18.7. CFSFWT (Free write token) . . . . . . . . . . 101
; 18.8. CFSUWT (Release access token) . . . . . . . . 102
; 18.9. CFSBOW (Broadcast OFN update) . . . . . . . . 104
; 18.10. CFSBEF (Broadcast EOF). . . . . . . . . . . . 105
; 18.11. CFSBRD (Main broadcast routine) . . . . . . . 106
; 18.12. CFSFOD (DDMP force out done). . . . . . . . . 107
; 19. Structure resource manager
; 19.1. CFSSMT (Acquire structure resource) . . . . . 109
; 19.2. CFMNAM (Register structure name). . . . . . . 111
; 19.3. CFMDSN (Register drive serial number) . . . . 112
; 19.4. CFSSUG (Upgrade or downgrade mount) . . . . . 113
; 19.5. CFMDER (Mount/Dismount error) . . . . . . . . 114
; 19.6. CFSSDM (Release mount resource) . . . . . . . 115
; 19.7. STRVER (Structure verify) . . . . . . . . . . 116
; 20. File enqueue resource manager
; 20.1. CFSENQ (Get ENQ resource) . . . . . . . . . . 117
; 20.2. CFSDEQ (Release ENQ resource) . . . . . . . . 118
; 21. Global Job Number Routines
; 21.1. JBAVAL (Manage job bit table) . . . . . . . . 119
; 21.2. JBGET1 (Get global job number for local job). 119
; 21.3. GL2LCL (Return local job number). . . . . . . 120
; 21.4. LCL2GL (Return global job number) . . . . . . 120
; 21.5. CFGTJB (Get jobs at system startup) . . . . . 121
; 22. Miscellaneous Interfaces
; 22.1. FILRST (Reset all files at startup) . . . . . 122
; 22.2. CFSERR (Illegal configuration). . . . . . . . 123
; 22.3. CFRDSN (Read drive serial number) . . . . . . 124
; 22.4. CFSDSN (Swap drive serial number) . . . . . . 124
; 22.5. CFCBRD (Broadcast system cease) . . . . . . . 126
; 23. DIAG% JSYS Support
; 23.1. CFDIAG (Code for Set CI Unavailable). . . . . 128
; 24. CNFIG% JSYS Support
; 24.1. CFCIN (Return CFS information). . . . . . . . 129
; 24.2. CFCSE (Return serial numbers of CFS nodes). . 130
; 24.3. CFCND (Return list of node names) . . . . . . 131
; 25. End of CFSSRV. . . . . . . . . . . . . . . . . . . . . 131
SUBTTL Design Notes
COMMENT #
This module is the Common File System (CFS) support module. It contains
the CFS protocol routines, the CFS data base support routines and
the glue that makes a system out of a bunch of machines.
The CFS support code is really a "global lock manager". The manager
supports a "named locking scheme" as follows:
A lock is a multi-part name. The first part of the name is the "root".
The remaining part of the name defines a tree structure under the root.
Locks have names, owners, state and data.
The CFS protocol uses SCA to send and receive packets.
Aside from the lock management function, this module also
implements the CFS configuration manager. It handles nodes
coming into the CFS network as well as nodes leaving the
CFS network. CFSCON relies heavily on SCA to provide
up-to-date information on the physical configuration,
including notification of any configuration change.
Locks are in one of several states. First, a lock may be owned
locally. In this case, any attempts to share this lock
must conform to the current level of ownership. Second, a lock
may reside on the local node, but be unowned. A request for
ownership may be granted as long as the request is equal to
or less than the current level. Finally, a lock may be unknown
on the local node. In any case where the lock cannot be immediately
granted, a vote must be taken. A vote simply is a "braodcasting" of
the lock request to all other CFS nodes. The reqeust is successful
is no reply denies the request. Note this scheme has the advantage
that locks need not be permanent and no single node is ever
responsible for keeping track of a dormant lock. In principle, this
will most likely happen, but it needn't. Furthermore, there is
no a priori assignment of node to lock. This means that if the owner
of a lock crashes, there is no special error recovery method. The
next node to request the lock will simply discover that its vote
is successful.
The obvious disadvantage of this scheme is that requesting a lock
has a fixed cost; the cost being the same to "create" a lock.
However, if the CFS network is small, this cost is negligible
and in fact the trade-off versus an elaborate "permanent owner"
scheme is well justified.
Configurations:
The conditional assemblies control configurations as follows:
CFSDUM: This is a "reduced" CFS. This system is on the CI and uses
SCA to connect to other CI-based systems. However, this processor
will not share structures with any other system but will insure
that the structures it is using are mutually exclusive from structures
used by any other CI-based TOPS-20 system. This implies that this
system will establish connections to other reduced or full CFS systems
and will participate in strcuture mounting votes.
CFSSCA: If zero, this processor is not on a CI with any other processor.
SCA may be in the monitor, but the CFS SYSAP is not present. This
processor offers no assurances that it will not interfere with any
other CI activity. If this is zero, CFSDUM will be defined. If this
is a one, CFSDUM is defined independently of this conditional. If CFSSCA=0,
then this should processor should either not be on a CI at all, or should
be on a CI with no other TOPS-20 host systems. Any other configuration is
unsupported and not likely to operate correctly.
In addition, the CFS network number, MYPOR2, defines the CFS subnet
that this processor is in. This value is only significant if
CFSSCA=1 and CFSDUM is not defined.
The tables CFSHST, CFSHNM, and CFHSTS describe the states of the
connections to the other nodes, and one listener. THe following
indicates the contents of these tables are various stages in the
life of a connection.
CFSHST CFSHNM CFHSTS
Unused 0 - -
After CFSCTH SBI,,-1 -1 0
At CFSCPS if close 0 -1 0
At CFSCPS if open CID serial -1,,type
After CFSLSN -1 CID 0
After LSNUP if reject 0 CID 0
After LSNUP if accept CID serial 0,,type
After CFSOKS if disc. 0 serial 0,,type
After CFSOKS if conn. CID serial -1,,type
After SCABRK 0 - -
Popular combinations
Fully open CID serial -1,,type
Listener -1 CID 0
Connection requested SBI,,-1 -1 0
Waiting for OKS CID serial 0,,type
The parts of CFHSTS:
L.H.
-1 when fully open
0 when being opened
1B0 turned off when disconnect happens and interlock is set
1B17 turned off to indicate lack of credit
R.H. is type:
-1 full CFS node
0 not full CFS node
Deciding what to disconnect when there is a conflict:
Connect response available (our initiator):
We're lower: close new one (our initiator)
They're lower: close already open one (their initiator)
Connect to listener (our listener):
We're lower: accept connection, wait for OK to send
They're lower: reject connection
OK to send (our listener):
We're lower: close already open one (our initiator)
They're lower: close new one (their initiator)
Major routines for managing resources:
File open CFSGFA CFSFFL
Frozen writer of file CFSGWL CFSFWL
File access token CFSAWT CSFAWP
Directory lock CFSLDR CFSRDR
Directory allocation CFSDAU
Structure mounting CFSSMT CFSSDM CFSSUG
File enqueue CFSENQ CFSDEQ
BAT blocks CFGBBS CFFBBS
Unique code:
Outgoing vote: HSHUNQ --> CFUNQ
Incoming request to vote: CFUNQ --> HSHVVL
Outgoing response to request to vote: CFUNQ(in) --> CFUNQ(out)
#
SUBTTL Data definitions
;Special defs
;**;[7152] Remove 1 line at (WRTTIM==^D200)-1 CEG 15-Oct-85
WRTTIM==^D200 ;Minimum hold time for token
DIRTIM==^D200 ;Minimum hold time for a directory
MAXHLT==^D3000 ;Max time to hold token under demand
;Note: The trailing space are required by SCA. The string must be 16 bytes
;padded with spaces as necessary.
LISNAM: ASCI8 (<LCS20$CFS >) ;Our name
RCRDIT==2 ;MIN RECEIVE CREDIT
SCRDIT==2 ;MIN SEND CREDIT
MAXVWT==5 ;MAX TIME (MS) TO WAIT FOR VOTE RESULTS
BUFSCT==5 ;# of receive buffers per CFS circuit
IFN CFSSCA,<
HSHLEN==^D509 ;SIZE OF HASH TABLE (should be prime)
> ;IFN CFSSCA
IFE CFSSCA,<
HSHLEN==^D251
> ;IFE CFSSCA
IFN CFSSCA,< ;If SCA present
CFSSLN==^D100 ;Size of CFS stack
> ;IFN CFSSCA
IFE CFSSCA,< ;If no SCA
CFSSLN==20 ; then small private stack needed
> ;IFE CFSSCA
CFNBC==OFNBC
CFNBSZ==OFNBSZ ;Defs in OFNLEN
;Bits in SCAFLG
DEFSTR SCRSV,SCAFLG,0,1 ;RESTART VOTE BIT
DEFSTR SCDIS,SCAFLG,1,1 ;Disconnect pending
DEFSTR SCDDP,SCAFLG,2,1 ;Need DDMP soon
DEFSTR SCCNC,SCAFLG,3,1 ;We got connected flag
DEFSTR SCWKP,SCAFLG,2,3 ;Bits to cause a scheduler pass
DEFSTR SCVER,SCAFLG,4,1 ;Set if structure verify needed
;Descriptions of this node. First offset contains serial number
IFDEF CFSDUM,< ;If we are to be a dummy
RS MYPORT,4 ;Both of these are zero
> ;IFDEF CFSDUM
IFNDEF CFSDUM,< ;If we are for real
RSI MYPORT,<0,<-1,,0>,0,0,-1> ;Make it so
> ;IFNDEF CFSDUM
MYPOR1==:MYPORT+1 ;type,, net number
MYPOR2==:MYPOR1+1 ;name
MYPOR3==:MYPOR2+1 ;rest of name + old/new flag
MYPOR4==:MYPOR3+1 ;Our CI node number
RSI CFSIFL,<-2> ;Init init flag
TIMSE0==^D600/5 ;Ten minutes of five second chunks
RSI CFSTTM,<TIMSE0> ;Full scheduler check time
;Optional data in connect_request or accept_request
OPDSER==0 ;serial number in optional data
OPDTYP==1 ;type in optional data,,net number
OPDNAM==2 ;first word of name
OPDNEW==3 ;last 2 chars of name,,old/new flag
DEFSTR ONFLG,,31,8 ;Old/new byte in optional data
OF%NEW==0 ;Unknown host
OF%DLY==1 ;In dealy for this host
OF%OLD==2 ;It is old
IFN CFSSCA,< ;If SCA is around
RS CONCID,1 ;CID FOR CURRENT CONNECTION ATTEMPT
RS OLDTAB,1
RS DLYLOK,1 ;Word to do delay stuff
RSI DLYTIM,<^D5000> ;Delay time on CI failure per node
;RS DLYFLG,1 ;Flag to say if delay being honored
> ;IFN CFSSCA
NSPCQ==5 ;NUMBER TO PREALLOCATE
IFNDEF CFSDUM,< ;For a full CFS, get lots of packets
NSPCQ0==^D600 ;Number to stack from private stock
> ;IFN CFSDUM
IFDEF CFSDUM,< ;For a reduced CFS
NSPCQ0==^D150 ;Just get a few for allocation entries
> ;IFDEF CFSDUM
NSPCQ1==^D250 ;Number of long pakcets to get
CLCCNT==^D350 ;Number to collect when we are desparate
SKDCNT==^D200 ;Number to collect in the background
CFSCTM==^D10000
RS CFNXPG,1 ;Page pool address
RSI CFNXSZ,<PGSIZ> ;Space available in pool
RS CFTADL,1 ;Time and date cell
;Definitions for hash table
;Description of a resource block. Offsets HSHROT and HSHQAL are hashed
;to provide offset into HSHTBL. Entries that conflict are chained together
;via offsets HSHLNK and HSHBKP.
HSHLNK==0 ;OFFSET FOR LINK WORD
HSHROT==1 ;ROOT NUMBER
HSHQAL==2 ;QUALIFIER
HSHTIM==3 ;TIME STAMP OF GRANT
HSFLAG==4 ;Offset for the flags
DEFSTR HSHWVT,4,0,1 ;IF ON, WE ARE VOTING
DEFSTR HSHYES,4,1,1 ;YES/NO VOTE (1 if anyone said no)
DEFSTR HSHTYP,4,5,4 ;TYPE OF ENTRY
.HTPLH==0 ;Place-holder entry
.HTOAD==1 ;OWNED FOR FULL SHARING
.HTOSH==2 ;OWNED READ-ONLY SHARED
.HTOEX==3 ;OWNED EXCLUSIVELY
.HTOPM==4 ;OWNED FOR PROMISCOUS READ
DEFSTR HSHTWF,4,6,1 ;"token" wait flag (see CFSUGW)
DEFSTR HSHRTY,4,7,1 ;RETRY NOW BIT
DEFSTR HSHLSG,4,8,1 ;ENTRY BEING RELEASED
DEFSTR HSHVRS,4,9,1 ;VOTE RESTART FLAG
DEFSTR HSHLOS,4,10,1 ;LONG/SHORT FLAG (1 if block is long)
DEFSTR HSHUGD,4,11,1 ;VOTING FOR AN UPGRADE
DEFSTR HSHODA,4,12,1 ;OPtional data valid
DEFSTR HSHKPH,4,13,1 ;Don't pruge this entry
DEFSTR HSHVTP,4,17,4 ;TYPE WE ARE VOTING ON
DEFSTR HSHDWT,4,18,1 ;If here, waiting for delay to be up
DEFSTR HSVUC,4,19,1 ;Bit to indicate vote must include HSHCOD
DEFSTR HSHLCL,4,20,1 ;Local exclusive
DEFSTR HSHRFF,4,21,1 ;For tokens only
DEFSTR HSHAVT,4,22,1 ;Vote on all nodes, even reduced CFS nodes
DEFSTR HSHBTF,4,23,1 ;If set, this is a bit-table file
DEFSTR HSHTAM,4,24,1 ;[7247] Cached file access token (cached OFN)
DEFSTR HSHCNT,4,35,11 ;[7247] Count of sharers
HSHCOD==5 ;UNIQUE CODE USED FOR ID
HSHPST==6 ;POST ADDRESS WHEN RESOURCE IS WITHDRAWN
HSHVWD==7 ;Word used by voter
DEFSTR HSHLKF,HSHVWD,11,12 ;Lock field
DEFSTR HSHVCT,HSHVWD,17,6 ;VOTE COUNT
DEFSTR HSHUNQ,HSHVWD,35,18 ;VOTE CODE
HSHVRW==10 ;Vote reply word
DEFSTR HSHDRC,HSHVRW,35,18 ;Reason code for denial on NO return to vote
HSHNBT==11 ;NODE BIT TABLE
HSHRET==12 ;RETURN ADDRESS ON DEASSIGN
HSHDVD==13 ;RELEASE VOTE DATA ("Deferred vote data")
DEFSTR HSHRHN,HSHDVD,17,18 ;DEST PORT I.D.
DEFSTR HSHVVL,HSHDVD,35,18 ;VOTE CODE
HSHMSK==14 ;Delay mask and fork word
DEFSTR HSHDLY,HSHMSK,17,18 ;Delay mask
DEFSTR HSHFRK,HSHMSK,35,18 ;Owning fork
HSHOPT==HSHMSK+1 ;Optional data from vote
HSHOP1==HSHOPT+1 ; Second opt data word
HSHOKV==HSHOP1+1 ;Call-back when a vote is OKed
HSHCDA==HSHOKV+1 ;Call-back when optional data is present in vote
HSHFCT==HSHCDA+1 ;Fairness timer
HSHWTM==HSHFCT+1 ;revote wait time
HSHBKP==HSHWTM+1 ;Back pointer
HSHSIZ==HSHBKP+1 ;SIZE OF A HASH ENTRY
;Start of a long block. Remaining words are bit mask of waiting forks.
HSHBTT==HSHSIZ+1 ;FIRST WORD OF BIT TABLE
HSHDRI==1+<NFKS+^D35>/^D36 ;ADDITIONAL WORDS FOR DIR LOCKS
WRDHSH==NSPCQ0*HSHSIZ ;Words in hash packets
LNGHSH==NSPCQ1*<HSHSIZ+HSHDRI> ;Words in long packets
;Defs for CFS block
NVOTQ==^D4 ;# OF VOTE PACKETS TO STOCK FROM FREE SPACE
IFNDEF CFSDUM,< ;If a real CFS
NVOTQ0==^D75 ;# of packet to get from private stock
> ;IFNDEF CFSDUM
IFDEF CFSDUM,< ;If a reduced CFS
NVOTQ0==^D10 ;Just get a few
> ;IFNDEF CFSDUM
;Contents of a packet sent via SCA.
SCALEN==.MHSTS+1 ;First word past SCA header
DEFSTR CFFLG,SCALEN,11,12 ;Flags
DEFSTR CFODA,SCALEN,0,1 ;Opt data present
DEFSTR CFVUC,SCALEN,1,1 ;Vote to include HSHCOD
DEFSTR CFCOD,SCALEN,17,6 ;OPCODE FOR VOTING
.CFVOT==1 ;VOTER
.CFREP==2 ;REPLY TO VOTE
.CFRFR==3 ;RESOURCE FREED
.CFCEZ==4 ;SEIZE RESOURCE
.CFBOW==5 ;Broadcast OFN change
.CFBEF==6 ;Broadcast EOF
.CFTAD==7 ;Time and date arrived
.CFSHT==10 ;Shutdown of system is pending
.CFMAX==10 ;MAX FNC WE DO
DEFSTR CFUNQ,SCALEN,35,18 ;NUMBER OF THIS VOTE OR REQ UNIQUE CODE
CFROT==SCALEN+1 ;ROOT CODE FOR THIS VOTE
CFQAL==SCALEN+2 ;QUALIFIER CODE FOR THIS VOTE
CFTYP==SCALEN+3 ;Access required, or answer
CFDAT==SCALEN+4 ;Optional data, it present
CFDT1==SCALEN+5
CFDST0==CFDT1+1 ;STR free count in bit table
CFDST1==CFDST0+1 ;Transaction count of CFDST0
CFVGRD==CFDST1+1 ;Guard word,,Denial reason code
DEFSTR CFGWD,CFVGRD,17,18 ;Unique value - used for debugging
DEFSTR CFDRC,CFVGRD,35,18 ;Field for reason code returned with a NO
.CDDWT==1 ;Denied - we are in VOTDWT
.CDVUC==2 ;Denied - HSHCODs are unequal
.CDYUX==3 ;Denied - voting, HSHYES, we have .HTOEX
.CDYUN==4 ;Denied - voting, HSHYES, unequal access
.CDVDL==5 ;Denied - voting, HSHDLY set
.CDVLN==6 ;Denied - voting, tie, our serial # bigger
.CDVUX==7 ;Denied - voting, tie, HSHUGD, he wants .HTOEX
.CDVUN==10 ;Denied - voting, tie, HSHUGD, unequal access
.CDOCT==11 ;Denied - we own, conflicting access, HSHCNT
.CDOFC==12 ;Denied - we own, conflicting access, HSHFCT
;Values in CFTYP reply:
; 0 OK
; -1 OK with delay (see call to CFSRMX in CFSRTV)
; -2 Conditional OK (set when DDMP finishes with delayed yes in CFSFOD)
; 1 NO
VOTSIZ==CFVGRD+1 ;Actual size of a packet
VOTSZB==VOTSIZ-1 ;SIZE OF BUFFER IN BYTES
VOTLEN==NVOTQ0*VOTSIZ ;words on all vote packets
;Definitions of "resource names"
;These values are used as qualifiers in numbered resources
DRBASE==<17777,,0> ;DIR BASE OFFSET for DIRECTORY locks
DRBAS0==<37777,,0> ;Allocation table offset for allocation
FILEWL==DSKAB_1 ;File write lock (frozen writer)
FILEWT==DSKAB_3 ;Access token bias
STRCTK==5B2 ;Structure designator
STRCTN==<-2,,0>-DSKAB ;Name register
FILEEQ==DSKAB_2 ;File enqueue token
CFJBAS==<47777,,0> ;Base for job number assignment
REPEAT 0,<
RESOURCE ROOT QUALIFIER
file open str. name XB address
frozen writer str. name XB address + FILEWL
file access (OFN) str. name XB address + FILEWT
directory lock str. name directory no. + DRBASE
directory allocation str. name directory no. + DRBAS0
structure name str. alias STRCTN
drive serial no. serial no. STRCTK + high order D.S.N.
file enqueue str. name XB address + FILEEQ
BAT blocks str. name -1
RESOURCE HSHCOD
file open --
frozen writer --
file access (OFN) OFN
directory lock DRBASE
directory allocation --
structure name Drive serial no. words XORd
drive serial no. Structure alias
file enqueue --
BAT blocks --
>
;Random definitions
DEFSTR STCRA,CFHSTS,17,1 ;Bit to control "credit available"
SUBTTL Macros
;CFS interlock macros
;The CFS interlock exists to insure that the CFS hash table
;does not change.
DEFINE CFSINO <
CALL SCAPOL
>
;MACRO to test if the structure is part of CFS or is local to this machine.
; T1/ Structure number
DEFINE TSTRMT <
CALL RMT.TS
>
;macro to save P1-P5
DEFINE SAVEP5,<
JSP CX,SAVP5>
;Routine to test for a structure being part of CFS or being local
;to this host.
; T1/ STR index
;Returns:
; +1 is local
; +2 is shared
RMT.TS: PUSH P,T1 ;Save STR index
MOVE T1,STRTAB(T1) ;Get SDB address
TMNE STEXL,(T1) ;Local?
JRST PA1 ;Yes
POP P,T1 ;No
RETSKP
;Routine to save P1-P5
SAVP5: ADJSP P,5 ;Get five locs
DMOVEM P1,-4(P) ;Save
DMOVEM P3,-2(P) ;Save some more
MOVEM P5,0(P) ;Finish it up
CALL 0(CX) ;And return
SKIPA
AOS -5(P) ;Skip return
DMOVE P1,-4(P) ;Restore
DMOVE P3,-2(P) ;Some more
MOVE P5,0(P) ;The rest
ADJSP P,-5 ;Clean up the stack
RET ;And done
SUBTTL Initialization -- CFSINI (SCA initialization routine)
;SCA Initialization routine for CFS code.
;If MEXEC has not yet called CFSJYN, this call to CFSJYX won't do much.
CFSINI::
IFN CFSSCA,<
CALL CHKCFS ;Verify the UCODE
CALL CFSJYX ;See if we need to join the network
> ;IFN CFSSCA
RET ;Done
SUBTTL Initialization -- CFSDIN (Initialize CFS database)
;Routine to intialize CFS data base. Called from CFSCSC
CFSDIN:
IFN CFSSCA,<
ISB SCDCHN ;And get its attention
> ;IFN CFSSCA
SETOM ALCLOK ;INIT CFS allocation lock
XMOVEI T1,SCAQ ;Get head of queue
MOVEM T1,SCTAIL ;Init queue
MOVSI T1,CFSSEC ;form address of hash table
MOVEM T1,CFHSHT ;Store it
MOVE T1,APRSER ;GET SERIAL NUMBER
LSH T1,4 ;Use left-most 32 bits
MOVEM T1,MYPORT
RET ;And done for now
SUBTTL Initialization -- CFSJYN/CFSJYX (Join the CFS network)
;Routine to join the CFS network. This is called after SETSPD has run
;so that all of the system configuration options have been selected.
;Accepts no arguments, and gives no backtalk (a fair arrangement)
;CFSIFL starts at -2. CFSINI calls CFSJYX, which increments it and
;returns.
CFSJYN:: ;Do the join
IFN CFSSCA,< ;If want an SCA interface
MOVEI T1,.NDGLN ;Set up to get our name
MOVEI T2,T3 ;The argument block
MOVE T3,[POINT 8,MYPOR2] ;Where to stash the name
NODE% ;Get it
ERJMP .+1 ;If no name, move on
CFSJYX: AOSE CFSIFL ;Time to join up?
RET ;No
SAVEAC <P1> ;Save a reg
CALL CFSLSN ;OPEN A LISTENER FIRST
NOP ;BETTER WORK
BLCAL. (SC.SOA,<<.,CFSSTS>>) ;Want to know about configuration changes
;NOTE: This will callback at CFSSTS for nodes
; that are already online
NOP
; Now we must wait until we have a CFS connection open to every TOPS-20
; system already up. This will allow for a deterministic way to insure that
; we are fully joined to the CI once we return from this routine.
CALL CFSPRT ;(/T1) Get our own port number
MOVEM T1,MYPOR4 ;Store it
MOVSI P1,-C%SBLL ;Loop for all the nodes
DO.
HRRZ T1,P1 ;Get the current node
CAMN T1,MYPOR4 ;Is this our node?
JRST CFSJY1 ;Yes, skip it
CALL PTHSTS ;(T1/T1,T2) What is path status to node
EXIT. ;The port is not running - quit
TXNN T2,UDB%WA+UDB%WB ;No-response on both wires?
JRST CFSJY1 ;Yes, skip it
TXNE T2,UDB%MA ;No, is node in maintenance mode?
JRST CFSJY1 ;Yes, skip it
SKIPN SBLIST(P1) ;No, have we created a system block yet?
JRST CFSJY2 ;No, we must wait then
HRRZ T2,P1 ;Get the node number again
CALL ISIT20 ;(T2/) Is this a TOPS-20 system?
JRST CFSJY1 ;No, skip it
HRRZ T1,P1 ;Get node number
CALL CFCNCK ;(T1) Is there is a CFS connection?
IFNSK. ;No, there should be so we will wait
CFSJY2: MOVX T1,^D1000 ;Wait for a second
DISMS
LOOP. ;Try again
ENDIF.
CFSJY1: AOBJN P1,TOP. ;Continue with next node
ENDDO. ;All done - we have joined the cluster
REPEAT 0,<
MOVSI P1,-C%SBLL
DO.
MOVEI T1,0(P1) ;Get the index
BLCAL. (SC.RCD,<T1>) ;GET DATA FOR THIS INDEX
IFNSK. ;IF AN ERROR
AOBJN P1,TOP. ;DO MORE IF MORE TO DO
EXIT. ;Else, all done
ENDIF.
CALL RELRES ;Get rid of the data block
MOVEI T1,0(P1) ;Get SBI
CALL CFSCTH ;Connect to a host on this SBI
NOP
AOBJN P1,TOP. ;DO ALL CI BLOCKS
ENDDO. ;NO
> ;END OF REPEAT 0
SETONE SCVER ;str verify in job 0
AOS JB0FLG ; so awake it
> ;IFN CFSSCA
RET ;AND DONE
SUBTTL Initialization -- CFSCSC (Create private pages)
;Routine called from JOB 0 start up to create private stock of pages.
CFSCSC::EA.ENT
SAVEQ
CALL CFSDIN ;Do basic set up
REPEAT 0,< ;DONE IN PGRINI, NOT NEEDED HERE
CALL ASSPTL ;Get an SPT slot for the map
TDO T1,SHRPTR ;Make a share pointer out of it
MOVEM T1,MSECTB+CFSSEC ;Stash in the EPT
;Section map all set up. Now put a page in it.
HRRZS T1 ;Get SPT index only
CALL SWPIN1 ;Create a page table for our use
>
MOVEI Q1,LNGHSH ;Get words in long entries
ADDI Q1,WRDHSH ;Add words in short entries
ADDI Q1,HSHLEN+CFSSLN+PGSIZ+PGSIZ-1 ;Add extra words
IFN CFSSCA,< ;If an SCA interface...
ADDI Q1,NOFN+HSTSIZ ;Add in extra data bases
ADDI Q1,VOTLEN+STRN ;And the extras if SCA is supported
> ;IFN CFSSCA
LSH Q1,-PGSFT
MOVNI Q1,1(Q1) ;Get -(n+1)
HRLZS Q1
DO.
MOVSI T1,CFSSEC ;The section
HRRI T1,0(Q1) ;The page
CALL MLKMA ;Lock it down
ADDI Q1,PGSIZ-1 ;Increase by appropriate amount
AOBJN Q1,TOP. ;Do them all
ENDDO. ;All pages now created
;Now create queue entries
;First, the vote queues
MOVSI Q2,CFSSEC ;Start at the beginning
HRRI Q2,HSHLEN ;Start after the hash table
IFN CFSSCA,< ;Only need this if doing SCA stuff
MOVEM Q2,OLDTAB ;Base of OLDTAB
ADDI Q2,HSTSIZ
MOVEI Q1,NVOTQ0 ;Number of vote packets
DO.
LOAD T1,PGWD,Q2 ;Get page offset in the address
ADDI T1,VOTSIZ-1 ;See if this fits on the page
CAIL T1,PGSIZ ;Does it?
IFNSK. ;If not
MOVE T1,Q2 ;No. See if they are usable anyway
CALL CPPCON ;Check if they are contiguous
ANNSK. ;If not
TXZ Q2,PGWD ;put on page boundary
ADDI Q2,PGSIZ ; next page, that is
ENDIF.
IFN DEBUG,<
MOVE T3,[252525]
STOR T3,CFGWD,(Q2) ;Store unique guard word
> ;IFN DEBUG
MOVE T3,Q2 ;The address
PIOFF
CALL CFSWDN ;Enqueue this one
PION
ADDI Q2,VOTSIZ ;Next address
SOJG Q1,TOP. ;Do them all
ENDDO. ;Vote packets on the queue
> ;IFN CFSSCA
;Now do the hash packest
MOVEI Q1,NSPCQ0 ;The number to do
DO.
MOVE T1,Q2 ;Next one
EXCH T1,CFSPCQ ;Put it on
MOVEM T1,@CFSPCQ ;And link rest to it
ADDI Q2,HSHSIZ ;Next entry
SOJG Q1,TOP. ;Do them all
ENDDO. ;All done
;Now allocate long packets. Always need these, even for non-SCA systems
MOVEI Q1,NSPCQ1 ;Number to get
DO.
MOVE T1,Q2 ;Next one
EXCH T1,CFSPQL ;Enqueue it
MOVEM T1,@CFSPQL ;Link it in
ADDI Q2,HSHSIZ+HSHDRI ;Length of an entry
SOJG Q1,TOP.
ENDDO.
IFN CFSSCA,< ;If SCA present
MOVEM Q2,CFSSTR ;STR transaction table
ADDI Q2,STRN ;# of structures
MOVEM Q2,CFSOFN ;Beginning of OFN pointer table
ADDI Q2,NOFN
> ;IFN CFSSCA
MOVEM Q2,CFSSTK ;Put the stack here
ADDI Q2,PGSIZ+CFSSLN ;Get to the guard page
MOVE T1,Q2 ;Copy it
ADDI Q2,PGSIZ ;Get to the next page
TXZ Q2,PGSIZ-1 ;And to the first word
MOVEM Q2,CFNXPG ;Next free cell
CALL FPTA ;Get ID
MOVX T2,PTCACH ;Read-only
CALLRET MSPACS ;Set it
SUBTTL Support Routines -- CFONLT (Test state of connection)
;Routine to test state of network connection. Called from the scheduler
;on demand
CFONLT::
IFN CFSSCA,< ;If SCA is around
SETZ T1,0 ;Either path
CALL CIONLT ;Check out the port
CALL DEDKLP ;Oops.
> ;IFN CFSSCA
RET ;Done
SUBTTL Support Routines -- PRTOFL (Turn off dual port access)
;Routines to diddle state of the dual-port access
;Turn it off if necessary
PRTOFL:
IFN CFSSCA,< ;Only if real CFS
SETOM SCAFL1 ;remember we did this
> ;IFN CFSSCA
RET ;And done
SUBTTL Support Routines -- PRTONL (Turn on dual port access)
;Turn it back on
PRTONL:
IFN CFSSCA,<
SETZM SCAFL1 ;It's clear
> ;IFN CFSSCA
RET
SUBTTL Support Routines -- CFSKPR (KLIPA ucode reloaded)
;Routine called when KLIPA UCODE is reloaded
CFSKPR::
IFN CFSSCA,< ;If a full CFS
;CALLRET DEDKLP ;Then we are in trouble
>
IFE CFSSCA,<RET> ;If not a full CFS
SUBTTL Support Routines -- DEDKLP (KLIPA is dead)
DEDKLP:
SETZM CFSTIM ;Make sure poller works soon
; TMNN SCCNC ;Anybody ever out there?
SKIPE SCAFL1 ;Already off?
IFSKP. <CALLRET PRTOFL> ;If allowable
RET
SUBTTL Support Routines -- CFSCTH (Connect to host)
IFN CFSSCA,< ;Only if supporting SCA interface
;Routine to connect to a host.
; T1/ SBI
;Returns:
; +1 couldn't send message
; +2 connet request sent. T1/ Host number of connect
CFSCTH: SAVEQ ;Get some work regs
MOVEI Q2,0(T1) ;Copy SBI
MOVE T1,[XWD .RESP1,.RDLEN] ;Priority,,length of free space
MOVEI T2,.RESGP ;Get space from resident free pool
CALL ASGRES ;(T1,T2/T1) Obtain block
RETBAD() ;Error - could not get a free space block
BLCAL.(SC.RCD,<<Q2>,<T1>>) ;Get config data
IFNSK. ;No. Forget it then
EXCH T1,T2 ;Get block address and save error code
CALL RELRES ;(T1) Return block to pool
MOVE T1,T2 ;Get error code
RETBAD() ;Return failure
ENDIF.
LOAD Q3,RDVCST,(T2) ;GET VC STATE
CAIE Q3,VC.OPN ;OPEN?
IFNSK. ;No. Forget it then
MOVE T1,T2 ;Get block address
CALL RELRES ;(T1) Return block to pool
RET ;No. Forget it then
ENDIF.
;**;[7144] Replace 1 line at CFSCTH:+20 DML 29-Aug-85
MOVE Q3,.RDDST(T2) ;[7144] Get destination software type
MOVE T1,T2 ;Get block address
CALL RELRES ;(T1) Return block to pool
;**;[7144] Replace 1 line at CFSCTH:+23 DML 29-Aug-85
CAME Q3,[BYTE (8) "T","-","2","0"] ;[7144] Is this a TOPS-20 node?
RETBAD() ;No. Can't be running CFS then
MOVSI Q1,-HSTSIZ ;Size of host table
PIOFF ;Own machine for a bit
DO.
SKIPN CFSHST(Q1) ;This one free?
EXIT. ;If so, use it
AOBJN Q1,TOP. ;Scan them all
PION ;Oops. None free
RETBAD() ;Can't do it
ENDDO.
HRLOM Q2,CFSHST(Q1) ;Store SBI
SETOM CFSHNM(Q1) ;Indicate doing connect
SETZM CFHSTS(Q1) ;INIT status
PION ;And allow others to proceed
MOVEI T2,0(Q1) ;Index into table
AOS CFSCMC ;Note we are doing a connect
BLCAL. (SC.CON,<<.,LISNAM>,<.,LISNAM>,Q2,[SCRDIT],[RCRDIT],<.,CFSSTS>,T2,<.,MYPORT>,[BUFSCT],[0]>) ;Do connect
IFNSK.
SETZM CFSHST(Q1) ;Didn't make it
SETZM CONCID
SOS CFSCMC
RETBAD()
ENDIF.
MOVEM T1,CONCID ;SAVE THE CID
MOVEI T1,0(Q1) ;Get index we used
RETSKP ;OK.
> ;IFN CFSSCA
SUBTTL Support Routines -- HASHN (Compute hash for resource)
;ROUTINE TO COMPUTE HASH FOR NUMBERED RESOURCES
; T1/ROOT NUMBER
; T2/ QUALIFIER NUMBER
;RETURNS:
; +1 ALWAYS. T1=HASH
HASHN: TSC T1,T2 ;Combine them
IDIVI T1,HSHLEN ;DO MOD FUNCTION
MOVM T1,T2 ;GET RESIDUE
RET ;AND DONE
SUBTTL Support Routines -- HSHLOK (Locate hash entry for resource)
;ROUTINE TO LOOK FOR A HASH ENTRY IN A TABLE FOR A NUMBERED RESOURCE
; T1/ ROOT NUMBER
; T2/ QUALIFER
;RETURNS:
; +1 NOT FOUND AC1/ POINTER TO ENTRY POINT
; +2 FOUND. AC1/ PTR TO ENTRY
; AC2/ PREVIOUS ENTRY
;Clobbers T1 and T2 only
HSHLOK: SAVEQ
DMOVE Q1,T1 ;Save args
IFN DEBUG,< ;If debugging
TMNN VSECNO,0(P) ;Make sure this is a non-zero section
BUG.(HLT,CFSSEZ,CFSSRV,SOFT,<CFSSRV - Section 0>,,<
Cause: HSHLOK was called from section zero. HSHLOK must be called from a
non-zero section.
Action: Examine the stack and change the caller of HSHLOK to run in a
non-zero section
>)
> ;IFN DEBUG
CALL HASHN ;GET HASH
ADD T1,CFHSHT
DO.
SKIPN Q3,(T1) ;ANYTHING HERE?
RET
;HAVE A NEW ENTRY TO EXAMINE
MOVE T2,T1
MOVE T1,Q3
CAMN Q1,HSHROT(Q3) ;This match?
CAME Q2,HSHQAL(Q3) ;Yes, this one too?
LOOP. ;NO
ENDDO.
RETSKP ;YEP. ALL DONE THEN
SUBTTL Support Routines -- GNAME (Get structure name)
;Routine to get the structure name given a structure number
; T1/ structure number
;Returns: +1 always. Sixbit name in T1
;Clobber only T1
GNAME: MOVE T1,STRTAB(T1) ;Get SDB address
SKIPE SDBALS(T1) ;An alias?
SKIPA T1,SDBALS(T1) ;Yes. Get it
MOVE T1,SDBNAM(T1) ;No. Use physical name
RET
;variant of above using AC2
GNAME2: PUSH P,T1
MOVE T1,T2
CALL GNAME
MOVE T2,T1
CALLRET PA1 ;Done
SUBTTL Support Routines -- CFSULL (Unlock CFS database)
;Called when CFSULK is done
;Returns: +1 always
CFSULL::
IFN CFSSCA,< ;If SCA present
SOSN SCAILK ;Last one?
IFNSK. ;If so.
TMNN SCWKP ;Any need to action?
SKIPE SCAQ ;No. ANything here?
ANNSK. ;If so
SAVET ;Save vulnerable regs
CALL CFSCH1 ;Yes. Do a check pass now
ENDIF.
OKSKED ;Allow scheduling now
> ;IFN CFSSCA
IFE CFSSCA,< ;If no SCA
SKIPG SCAILK ;Need to undo a lock?
IFSKP. ;If so
SOS SCAILK ;Do it
OKSKED ;And fix scheduler interlock
ENDIF.
> ;IFE CFSSCA
RET
SUBTTL Support Routines -- CFSMAP (Map entries onto function)
;Routine to map selected entries onto a function.
; T1/ mask
; T2/ comparator
; T3/ routine to call on match. Must be a "global address"
; T4/ monitor match,, count match
;This routine computes <mask AND cfscod> for each entry
;with the proper count. If the result matches the comparator,
;the routine is called.
;The coroutine in T3 is called:
; T1/ Resource block
; All Ps are preserved into the coroutine
;Call with CFSLOK or from interrupt left unlocked. Returns same
;Returns:
; +1 Stop mapping and return
; +2 continue
CFSMAP::ASUBR <AC1,AC2,AC3,AC4> ;SAVE INCOMING ARGS
SAVEQ ;SAVE REGS
MOVEI Q3,HSHLEN ;LENGTH OF THE HASH TABLE
MOVE Q1,CFHSHT ;GET TO BASE OF HASH TABLE
;LOOK FOR A HASH CHAIN
CFSMP0: SKIPN Q2,0(Q1) ;ANYTHING HERE?
JRST CFSMP1 ;NO
;FOUND A CHAIN TO START ON
CFSMP2: HLRZ T1,HSHROT(Q2) ;SEE IF USER OR MONITOR
MOVE T4,AC4 ;GET MATCH TYPES
TLNN T4,-1 ;WANT A FILTER?
JRST CFSMP5 ;NO. ALL OF THEM THEN
SKIPG T4 ;MONITOR?
JRST [ JUMPE T1,CFSMP4 ;YES. IS IT?
JRST CFSMP5] ;YEP
JUMPN T1,CFSMP4 ;NO.
CFSMP5: TRNE T4,-1 ;ANY MATCH?
JRST CFSMP3 ;YEP
JN HSHCNT,(Q2),CFSMP4 ;NO. MUST BE ZERO
CFSMP3: MOVE T1,AC1 ;GET AND MASK
AND T1,HSHCOD(Q2) ;DO AND
CAME T1,AC2 ;IS THIS IT?
JRST CFSMP4 ;NO. DON'T USE IT
;FOUND A MATCH
MOVE T1,Q2 ;COPY BLOCK
MOVE Q2,HSHLNK(Q2) ;DO COPY NOW IN CASE IT IS REMOVED
CALL @AC3 ;DO THE CALL
RET ;All done.
SKIPA
;WALK THE CHAIN
CFSMP4: MOVE Q2,HSHLNK(Q2) ;NEXT ONE
JUMPN Q2,CFSMP2
;HERE WHEN CHAIN IS DONE
CFSMP1: SOJLE Q3,R ;If seen them all, done
AOJA Q1,CFSMP0 ;DO THEM ALL
SUBTTL Support Routines -- CFSRSE (Remove stale entries)
;Maintenance routine called periodically to remove stale entries
;from the hash table.
;This routine scans the resources now held locally and removes
;any unused ones that have been dormant for a "long time". Currently,
;a "long time" is two minutes.
;OFN "access tokens" are never considered stale!
CFSRSE: MOVE T1,IRJAV ;GET LOAD AVG.
CAILE T1,^D10
MOVEI T1,^D10
IMULI T1,^D15000 ;PURGE BASED ON LAOD AVG.
MOVEI T2,SKDCNT ;Max number to release this pass
CFSRSX: SAVEAC <P1,P2> ;GET WORK REGS
MOVE P1,TODCLK ;GET NOW
SUB P1,T1 ;AGE CUTOFF
SKIPG P2,T2 ;COPY COUNT
MOVX P2,<377777,,0> ;GET A BIG NUMBER
SETZB T1,T2 ;NO MASK, MATCH ALL
XMOVEI T3,CFSRS0 ;WHERE TO GO
SETZM T4 ;ONLY UNUSED ONES PLEASE
CFSLOK ;Lock up the lock
CALL CFSMAP ;DO IT
CALLRET CFSFAL ;And done
;Routine called when an entry is located
CFSRS0: JN <HSHUGD,HSHKPH,HSHWVT>,(T1),RSKP ;If voting, or forced here, keep it
IFN DEBUG,< ;If debugging
TMNE HSHCNT,(T1) ;A debugging check!!!!
BUG.(HLT,CFSMPB,CFSSRV,SOFT,<CFSSRV - CFSMAP returned in-use entry>,,<
Cause: CFSMAP has returned a resource block that is already in use. This
bug is a debugging check.
>)
> ;IFN DEBUG
TMNN HSHLKF,(T1) ;Locked?
CAMGE P1,HSHTIM(T1) ;TOO OLD?
IFSKP.
CALL CFSRMX ;YES, REMOVE IT
SOJLE P2,R ;IF HIT LIMIT, ALL DONE
ENDIF.
RETSKP ;AND DONE
SUBTTL Support Routines -- CFSSPC (Obtain request block space)
;Routine to acquire a request block.
;Returns:
; +1/ no space
; +2 /success. T1/ block address
CFSSPC: PIOFF
SKIPN T1,CFSPCQ ;A PACKET HERE?
IFSKP. ;If so
MOVE T2,0(T1) ;Get the link
MOVEM T2,CFSPCQ ;Pop the stack
PION
AOS CFGTSH ;Count this event
XMOVEI T2,SHTADD
SETZM HSHPST(T1)
SETZM HSHOKV(T1) ;No clla-back for voting
MOVEM T2,HSHRET(T1)
SETZM HSFLAG(T1) ;And the flags
RETSKP ;AND SUCCESS
ENDIF.
PION ;Nothing here.
CALL SPCCOL ;Collect some
SKIPE CFSPCQ ;Any appear?
JRST CFSSPC ;Yep. Go get it
MOVEI T1,HSHSIZ ;Size we need
CALL CFCARV ;Get one please
CALL SHTADD ;Add it
JRST CFSSPC ;And try again
;Entry for a long block
CFSSPL: PIOFF
SKIPN T1,CFSPQL ;Any packets here?
IFSKP. ;If so
AOS CFGTLG ;Count this event
MOVE T2,0(T1) ;Pop it
MOVEM T2,CFSPQL ;And update the list
PION
XMOVEI T2,LNGADD
SETZM HSHPST(T1)
SETZM HSHOKV(T1) ;No clla-back for voting
MOVEM T2,HSHRET(T1)
MOVX T2,HSHLOS ;Say it is long
MOVEM T2,HSFLAG(T1) ; and clear other flags
RETSKP ;AND SUCCESS
ENDIF.
PION
CALL SPCCOL ;Collect some
SKIPE CFSPQL ;Any appear?
JRST CFSSPL ;Yep. Go get it
MOVEI T1,HSHDRI+HSHSIZ ;Size needed
CALL CFCARV ;Get one
CALL LNGADD ;Put it in
JRST CFSSPL ;And continue
;Coroutine to add a short block to the CFSPCQ queue
SHTADD: PIOFF
EXCH T1,CFSPCQ ;Make it the head.
MOVEM T1,@CFSPCQ ;And link old queu back in
PION
RET ;Done
;Coroutine to add a long block to the CFSPQL queue
LNGADD: PIOFF
EXCH T1,CFSPQL ;Make it the head
MOVEM T1,@CFSPQL ;Link old queue back in
PION
RET
SUBTTL Support Routines -- CFCARV (Carve a block from page pool)
;Routine to "carve" another block from the page pool
; T1/ Size Needed
;Returns: +1 always.
; T1/ address of block
CFCARV: NOSKED
DO.
MOVE T2,CFNXSZ ;Get size remaining in pool
SUB T2,T1 ;Compute remainder
IFL. T2 ;If not enough
PUSH P,T1 ;Save size needed
MOVE T1,CFNXPG ;Get current address
ADD T1,CFNXSZ ;Increment to the next page
CALL MLKMA ;Create and lock it
POP P,T1 ;Recover size
MOVEI T2,PGSIZ ;Increment of size
ADDM T2,CFNXSZ ;Add it
LOOP.
ENDIF.
ENDDO.
MOVEM T2,CFNXSZ ;Store new size
EXCH T1,CFNXPG ;Get address
ADDM T1,CFNXPG ;And increment by new count
OKSKED
RET ;And done
;Routine to collect some space when a queue is empty. Used by above routines
SPCCOL: MOVEI T1,CFSCTM ;Time
MOVEI T2,SKDCNT ;# to collect
CALLRET CFSRSX ;Do it
SUBTTL Support Routines -- CFSSBB (Place OFN in SDB)
;Routine called when the bit table for a structure is opened and
;the OFN is about to be placed in the SDB.
; T1/ OFN
; T2/ STR #
;Returns: +1 always.
; Preserves all temps
CFSSBB::
IFE CFSSCA,<RET> ;If no SCA, nothing to do
IFN CFSSCA,< ;If SCA
SAVET ;Save args
MOVE T3,T2 ;STR #
ADD T3,CFSSTR ;The entry in the STR table
SETZM 0(T3) ;No transactions yet
ADD T1,CFSOFN ;Find the OFN in the OFN table
CFSLOK
SKIPN T1,0(T1) ;Get it
IFSKP.
SETONE HSHBTF,(T1) ;Note this is a BT
SETZM HSHOP1(T1) ;No data here as yet
SETZM HSHOPT(T1)
ENDIF.
CALLRET CFSFAL ;And done
> ;IFN CFSSCA
SUBTTL Support Routines -- CFSWUP (General wait routine)
;General purpose wait routine. Used to select kind of wait to use
; T1/ scheduler test word
; T2/ Block address, if appropriate
CFSWUP: MOVE CX,FORKX ;Get fork handle
STOR T2,FKST2,(CX) ;Save block address
SKIPN NSKED ;NOW NOSKED?
IFSKP.
RDISMS ;IF SO, USE SPECIAL TEST
NOSKED
ELSE.
HDISMS
ENDIF.
RET ;AND DONE
SUBTTL Support Routines -- CFSRSV (Restart vote)
IFN CFSSCA,< ;Only need this with SCA present
;Routine to set "restart vote" when a node leaves the CFS net.
;This scans the active connections setting the proer bit.
;Call either CFSLOK or from interrupt level without being locked
CFSRSV: SAVET
SETZB T1,T2 ;MATCH ALL
XMOVEI T3,CFSRVC
MOVEI T4,-1
CALLRET CFSMAP ;DO IT
;The coroutine for above.
CFSRVC: JE HSHWVT,(T1),RSKP ;IF NOT WAITING, ALL DONE
SETONE HSHVRS,(T1) ;MAKE IT RESTART
RETSKP ;AND DONE
> ;IFN CFSSCA
SUBTTL Support Routines -- CFTADC (Get CFS time and date)
;Routine to return CFS TAD if known.
; CALL CFTADC
;Returns: +1 unknown
; +2 T1/ TAD
CFTADC::SKIPN T1,CFTADL ;have one?
RET ;No
SETZM CFTADL ;Clear it
RETSKP ;Yes
SUBTTL Support Routines -- SNDTIM (Send date and time to new node)
;Send date and time to newly on-line host
;Called from various places in CFSSRV
; T1/ Local host index
;Sends date and time if it can
;Clobbers T1-T4
IFN CFSSCA,< ;If SCA support
SNDTIM: ACVAR<W1,W2>
MOVE W1,T1
CALL LGTAD ;Do we have TAD?
CAMN T1,[-1] ;Have it?
RET ;No. DOn't bother doing the rest
MOVE W2,T1 ;Save it
CALL GVOTE1 ;Get a buffer
RET ;None
MOVEI T2,.CFTAD ;Get function
STOR T2,CFCOD,(T1)
MOVEM W2,CFROT(T1) ;Stash the TAD
MOVEI T2,0(W1) ;Host number
CALL SCASND ;Send it off
IFNSK. ;If failed
PIOFF
CALL CFSWDN ;Return the buffer
PION
ENDIF.
RET ;And done
ENDAV.
> ;IFN CFSSCA
SUBTTL Support Routines -- BRDTIM (Send date and time at startup)
;Routine called from MEXEC after date and time is typed in to send
;date and time to any processors that are "inferior" to us.
BRDTIM::
IFE CFSSCA,<RET> ;If no SCA support, nothing to do
IFN CFSSCA,< ;If SCA support...
SAVEQ ;Get some work regs
CFSLOK ;keep things stable for a bit
MOVSI Q1,-HSTSIZ ;Set to loop over the host table
MOVE Q2,MYPORT ;Get our serial number
DO.
SKIPLE CFSHST(Q1) ;Is this one possible around?
SKIPL CFHSTS(Q1) ;yes. Still?
IFSKP. ;If it is here
CAMG Q2,CFSHNM(Q1) ;Are we a bigger wheel?
ANSKP. ;If so
MOVEI T1,0(Q1) ;Get host index
CALL SNDTIM ;Send it the time
ENDIF.
AOBJN Q1,TOP. ;Do all hosts
ENDDO.
CALLRET CFSFAL ;And done
> ;IFN CFSSCA
SUBTTL Support Routines -- CFTADB (Broadcast date and time via STAD)
;Routine to broadcast date and time. Called from STAD JSYS
CFTADB::
IFN CFSSCA,<
CALL LGTAD ;Get local date and time
BLCAL. (CFSBRD,<T1,[0],[.CFTAD],[0]>) ;Do the sends
> ;IFN CFSSCA
RET ;And done
SUBTTL Support Routines -- CFSPRT (Return local port number)
;Routine to return the local port ID to whoever needs it.
; CALL CFSPRT
;Returns: +1
; T1/ ID
CFSPRT::
IFE CFSSCA,<CALLRET RETZ> ;If no SCA, return a zero
IFN CFSSCA,< ;If SCA is present
CALL SC.PRT ;Ask SCA for the amswer
SETZM T1 ;If no port, trouble!!!
RET
> ;IFN CFSSCA
SUBTTL Support Routines -- CFCNCK (Check for CFS connection to node)
;Routine used during CI joining to check if we have a
;CFS connection to a specified node.
;
;Accepts: T1/ node number
;
;Returns: +1: No CFS connection
; +2: CFS connection exists
CFCNCK: SKIPN CFSHCT ;Get count of hosts
RET ;No connections yet
MOVEM T1,T4 ;Save node number
MOVSI T3,-HSTSIZ ;Size of host table
DO.
SKIPN T1,CFSHST(T3) ;Get connect ID to host for this offset
IFSKP. ;A valid one did exist
CALL SC.NOD ;(T1/T1,T2) Get node number for this CID
SKIPL T2 ;A valid CID?
IFNSK. ;Yes, node number is returned
CAMN T4,T2 ;Is this the CID for the desired node?
RETSKP ;Yes, return success
ENDIF.
ENDIF.
AOBJN T3,TOP. ;Try next host table entry
ENDDO.
RET ;Node not found - return failure
SUBTTL Resource manager -- CFSGET (Acquire a resource)
;ROUTINE TO ACQUIRE A RESOURCE
; T1/ POINTER TO REQUEST BLOCK
; T2/ 0=) return if failed
; 1=) retry until successful
;Returns:
; +1 failed.
; T2=-1 An error occurred in which this system knows about
; the resource already and there is a conflict on
; this system. No vote has been sent out.
; T2>0 This system did not know about the requested resource
; so a vote was sent out to ask for permission to it.
; A system told us NO and the first reason for the NO
; (found in HSHDRC) is returned.
;
; +2 succeeeded.
; T1=0 =) Block is now owned by CFS server. Block
; returned to free pool owner. We linked
; the block passed in.
; T1<>0=) Block is returned as part of operation.
; We found a queued resource block and used it.
; Block passed in must be returned by caller.
;entry to figure out out if this is local or not.
;Same as above, but T3/ STR #
CFSGTT: MOVE T3,STRTAB(T3)
TMNE STEXL,(T3) ;Shared or exclusive?
JRST CFSGTL ;Don't need to vote. We have it exclusively.
JRST CFSGET ;Do need to vote.
;CFSGET is main entry point for resource manager. Call CFSGTL is
;resource is known to be exclusive to this processor.
;Entry for local lock only (caller must verify higher-level interlock)
CFSGTL::SETZRO <HSHYES,HSHWVT>,(T1)
TDZA T3,T3 ;Entry type is local
CFSGET::MOVEI T3,1 ;Entry type is remote (have to vote)
SAVEQ
STKVAR <EFLAG,RTYFLG,NSFLAG> ;HOLD RETRY FLAG HERE
MOVEM T3,EFLAG ;Save entry flag
MOVE Q1,T1 ;SAVE BLOCK ADDRESS
MOVEM T2,RTYFLG ;SAVE FLAG
MOVE T3,FORKX ;FORK HANDLE
STOR T3,HSHFRK,(Q1) ;Store it
; ..
;Here to start getting the resource.
;Also enter here from CFSGTX if retry was specified and wait is up.
CFSGT2: CFSLOK ;PROTECT DATABASE
DMOVE T1,HSHROT(Q1) ;GET ARGS.
CALL HSHLOK ;SEE IT WE KNOW ABOUT THIS ALREADY
JRST CFSGT0 ;DON'T KNOW ABOUT IT YET
;Here if we already have it. Check if access is legit.
;At this point:
; T1/ Address of queued resource block
; Q1/ Address of new resource block
CAMN T1,Q1 ;ARE WE ONE AND THE SAME?
JRST CFSG00 ;YES. ASSUME WE ARE VOTER THEN
JN <HSHWVT>,(T1),CFSGTX ;IF VOTING, FAIL
;Not waiting. Therefore we own it.
LOAD T3,HSHTYP,(Q1) ;GET REQUEST TYPE
LOAD T2,HSHTYP,(T1) ;GET TYPE WE OWN
CAIN T2,0(T3) ;ARE THEY THE SAME
JRST CFSGOD ;YES. IT MIGHT SUCCEED THEN
JN HSHCNT,(T1),CFSGTX ;NOT THE SAME. IF IN USE, FAIL
CALL CFSRMV ;NOT IN USE. WE MIGHT BE ABLE TO GET IT
JRST CFSGT1 ;NOW VOTE ON IT
;Request and owner type match. Make sure we can seize it
CFSGOD: TMNE HSHCNT,(T1) ;Unclaimed?
IFNSK. ;If not
CAIE T3,.HTOEX ;DO we want exclusive access?
ANSKP. ;If so
JE HSHLCL,(T1),CFSGTX ;If not local exclusive, lose
ENDIF.
MOVE T3,FORKX ;Get fork handle
;Accesses match and we can have it.
STOR T3,HSHFRK,(T1) ;New owner of this block
INCR HSHCNT,(T1) ;DO IT
MOVE T2,TODCLK ;GET NOW
MOVEM T2,HSHTIM(T1) ;STAMP IT
MOVE T1,Q1 ;DON'T NEED THE BLOCK ANYMORE
CALLRET CFSRSK ;RETURN GOOD
; ..
;Can't honor the request just now.
CFSGTX: SKIPN RTYFLG ;WANT TO RETRY?
IFNSK. ;If not
MOVE T1,Q1
CALL @HSHRET(T1) ;Release the block
SETOM T2 ;Conflict on this system. No reason code.
CALLRET CFSFAL ;And done
ENDIF.
;Here if caller specified retry until successful.
;Wait for a bit, and try again.
;At this point:
; T1/ Address of queued resource block of owner or voter (zero if none)
; Q1/ Address of new resource block
IFN. T1 ;IF THERE IS A LOCK NOW
TMNN HSHLOS,(T1) ;LONG BLOCK?
ANSKP. ; If so
MOVE T2,FORKX
IDIVI T2,44
MOVE T3,BITS(T3)
ADD T2,T1
IORM T3,HSHBTT(T2) ;SET WAITING BIT IN ORIGINAL BLOCK
ENDIF.
SKIPN T1,HSHWTM(Q1) ;Any wait time given?
MOVEI T1,^D1000 ;If not, use 1 sec
CAIGE T1,^D20 ;A reasonable time?
MOVEI T1,^D20 ;No. So make it so
ADD T1,TODCLK ;Compute wakeup time
MOVEM T1,HSHTIM(Q1) ;SAVE IT FOR LATER
SETZRO HSHVRS,(Q1) ;NEED THIS
CFSULK
MOVE T2,Q1 ;Save block address
MOVEI T1,CFSRWT
CALL CFSWUP ;DO A WAIT
SETZRO <HSHRTY,HSHVRS>,(Q1) ;NO RETRY NOW
JRST CFSGT2 ;TRY AGAIN
;Sheduler test for above
CFSRWT: LOAD T1,FKST2,(Q3)
DMOVE T1,HSHROT(T1) ;GET HASH VALUES
CALL HSHLOK ;LOOK IT UP
JRST 1(4)
JN HSHLSG,(T1),0(4) ;IF STILL BEING RELEASED, WAIT
OPSTR <CAMN T1,>,FKST2,(Q3) ;ARE THE TWO BLOCKS THE SAME?
JRST [ MOVE T2,HSHTIM(T1) ;GET AWAKE TIME
TMNN <HSHVRS,HSHRTY>,(T1) ;IF ANY RESTART CONDITIONS
CAMG T2,TODCLK ;TIME UP YET?
JRST 1(4) ;YEP
JRST 0(4)] ;NOPE
LOAD T2,FKST2,(Q3) ;GET BLOCK WE ARE WAITING FOR
JN HSHWVT,(T1),0(4) ;IF NOT THE SAME, AND VOTING, GIVE UP
TMNN HSHCNT,(T1) ;ANY USERS?
JRST 1(4) ;NO
LOAD T3,HSHTYP,(T2)
CAIN T3,.HTOEX ;TRYING FOR EXCLUSIVE USE?
JRST 0(4) ;YES. MUST WAIT SOME MORE THEN
OPSTR <CAME T3,>,HSHTYP,(T1) ;DO THEY NOW MATCH?
JRST 0(4) ;NO. WAIT SOME MORE
JRST 1(4) ;YES. TRY TO GET IT
;Here if we don't have the request queued. Must ask for it.
;Enter CFSGT1 when we have found a queued block on the system which was not
;in use and the access was not the same as what we desire. So, we have
;removed it. Now we will use the new block we passed into CFSGET.
CFSGT1: DMOVE T1,HSHROT(Q1) ;LOOK IT UP AGAIN
CALL HSHLOK ;We should not find it again
SKIPA
JRST CFSGTX ;Old block should have been removed!!
;First make an entry so we can remember we are doing this.
; T1/ POINTER TO PLACE TO MAKE AN ENTRY
CFSGT0: MOVEM Q1,HSHLNK(T1) ;ENQUEUE IT
MOVEM T1,HSHBKP(Q1) ;And point back as well
SETZM HSHLNK(Q1) ;And not next for this one
;Here to actually vote for the resource in an attempt to obtain it.
;No vote is required for a local exclusive resource (EFLAG = 0).
CFSG00: LOAD T1,HSHTYP,(Q1) ;TYPE WE ARE VOTING ON
SKIPE EFLAG ;Remote or local?
CALL VOTEW ;Remote, VOTE AND WAIT
JN HSHYES,(Q1),CFSGT3 ;IF FAILED, NOTIFY HIM
MOVE T2,TODCLK ;GET CLOCK
MOVEM T2,HSHTIM(Q1) ;STAMP IT
SETZRO HSHWVT,(Q1) ;NOT VOTING ANY MORE
INCR HSHCNT,(Q1) ;SEIZE IT
SETZM T1 ;NEED THIS BLOCK
CALLRET CFSRSK ;AND RETURN GOOD
;HERE IF VOTE FAILED.
;If retry specified, leave the vote packet in the hash table, with
;HSHWVT and HSHYES set. This is done for two reasons:
; 1. So that the resource freed message can find it and
; wake up the waiting fork
; 2. So that other requestors can detect that a vote
; has failed so that they will not start their own
; vote. Although this is not strictly necessary,
; it does minimize overhead in the monitor and on the CI.
;Note that leaving HSHWVT and HSHYES set will cause the vote processor
;to allow accesses to this resource since we have already been told "no".
;If "no retry", unlink the packet and release it. Return the reason for
;the failed vote (found in HSHDRC) in T2.
CFSGT3: MOVE T1,Q1 ;Copy pointer
SKIPN RTYFLG ;SHALL WE TRY, TRY AGAIN?
IFNSK. ;If not
LOAD Q1,HSHDRC,(T1) ;Get the reason for the NO
CALL HSHULN ;Unlink it
CALL @HSHRET(T1) ;release it
MOVE T2,Q1 ;Move reason code to T2
CALLRET CFSFAL ;AND DONE
ENDIF.
SETZM T1
JRST CFSGTX ;FAIL
ENDSV.
;Common routine to routine good
CFSRSK: CFSULK
RETSKP ;AND DONE
SUBTTL Resource manager -- CFSRMV (Remove entry from hash table)
;ROUTINE TO REMOVE AN ENTRY FROM THE HASH TABLE
; T1/ ENTRY
;CFSRMV just removes the entry
;CFSRMX also posts removal
;RETURNS: +1 always
; If CFSRMX is called:
; T1/ 0 if resource unconditionally available
; T2= 0 =) not removed even though available
; -1 if resource being released but not yet available.
; In this case, the resource has not been released.
;Must be called with CFS interlock
CFSRMX: TDZA T2,T2 ;REMEMBER TO POST
CFSRMV: SETOM T2 ;DON'T POST
;**;[7247] Change 1 line at CFSRMV:+1 DML 19-Feb-86
SKIPLE HSHPST(T1) ;[7247] Want posting?
SKIPE T2 ;YES. SHOULD WE HONOR IT?
IFSKP.
INCR HSHCNT,(T1) ;MARK IN USE FOR NOW
CALL @HSHPST(T1) ;DO POST
IFSKP.
JUMPE T1,RETO ;If delay release, say so.
SETZRO <HSHCNT,HSHTYP>,(T1) ; Clean these up
SETZM T2 ;Say it is still in the table though
CALLRET RETZ ;And done
ENDIF.
ENDIF.
;**;[7247] Add 2 lines after CFSRMV:+12 DML 19-Feb-86
TMNE HSHTAM,(T1) ;[7247] Is this a cached block?
SOS CFACCT ;[7247] Yes, decrement currently cached count
CALL HSHULN ;Unlink it
CALL @HSHRET(T1) ;FREE THE BLOCK
MOVEI T2,1 ;Removed.
CALLRET RETZ
;Companion routine to unlink an entry from the hash table
; T1/ pointer to entry to remove
;Returns: +1 always
; preserves T1
HSHULN: MOVE T2,HSHLNK(T1) ;Get forward pointer
MOVE T3,HSHBKP(T1) ;Get back pointer
MOVEM T2,HSHLNK(T3) ;Link previous to next
SKIPE T2 ;Was there a next?
MOVEM T3,HSHBKP(T2) ;Yes. Give it a new previous pointer
RET ;And done
SUBTTL Resource manager -- CFSNDO (Undeclare a resource)
;Routine to undeclare a resource.
; T1/ ROOT CODE
; T2/ QAULIFIER
;Returns:
; +1 /couldn't
; +2 done
CFSNDS: TDZA T3,T3 ;Make fairness test
CFSNDO::SETOM T3 ;No count
ASUBR<AC1,AC2,AC3>
CFSLOK
CALL HSHLOK ;LOOK IT UP
JRST [CALLRET CFSFAL]
LOAD T3,HSHCNT,(T1)
SOJL T3,[CALLRET CFSFAL]
STOR T3,HSHCNT,(T1) ;NEW COUNT
JUMPG T3,[CALLRET CFSRSK] ;IF STILL OWNED, GO ON
;RESOURCE NOW UNDECLARED. SEE IF ANYONE WAITING
SAVEQ ;SOME WORK REGS
TMNN HSHLOS,(T1) ;LONG BLOCK?
JRST CFSND3 ;IF NOT, MOVE ON
MOVE Q1,T1 ;BLOCK
ADDI Q1,HSHBTT ;GET TO THE BIT TABLE
MOVSI Q2,-<NFKS+^D35>/^D36 ;WORDS IN BIT TABLE
;Loop over bit table looking for a fork to wake up
CFSND1: SKIPN T2,0(Q1) ;ANYTHING HERE?
JRST CFSND2 ;NOPE
JFFO T2,.+1 ;GET BIT NUMBER
MOVE T2,BITS(T3) ;GET BIT NUMBER
ANDCAM T2,0(Q1) ;TURN IT OFF
MOVEI T1,0(Q2) ;GET WORD NUMBER
IMULI T1,^D36
ADDI T1,0(T3) ;FORK NUMBER
CALL UNBLKF ;UNBLOCK IT
CALLRET CFSRSK ;AND DONE
CFSND2: ADDI Q1,1 ;NEXT BIT TABLE WORD
AOBJN Q2,CFSND1 ;DO NEXT WORD
; ..
;Here if no local fork waiting. See if another host is waiting
CFSND3: SKIPE T3,HSHNBT(T1) ;ANYTING HERE?
IFNSK. ;If so
SKIPN AC3 ;Want to leave a record of this?
IFNSK. ;If so
SETONE HSHRFF,(T1) ;So do it
ENDIF.
CALL CFNOHS ;Tell them
ENDIF.
CALLRET CFSRSK ;And done
SUBTTL Resource manager -- CFSOHS (Notify rejected hosts after undeclare)
;Routine to notify other hosts who were rejected for a resource.
;This is called whenever a resource is undeclared and one or more
;bits is set in HSHNBT
; T1/ hash packet
;Returns: +1 always
; call with interlock set, please
CFNOHS: SAVEAC <P1> ;Where to save packet
IFN CFSSCA,< ;Only if SCA
MOVEM P,CFSSVP ;Save incoming stack
MOVE P,CFSSTK ;Get local stack
MOVE P1,T1
DO.
SKIPN T3,HSHNBT(P1) ;Any body here?
EXIT.
CALL GVOTE1 ;GET A VOTE BUFFER
EXIT.
JFFO T3,.+1 ;GET HOST NUMBER WAITING
MOVE T3,BITS(T4) ;GET THE CORRESPONDING BIT
ANDCAM T3,HSHNBT(P1) ;TURN IT OFF
MOVEI T3,.CFRFR
STOR T3,CFCOD,(T1) ;CODE
DMOVE T2,HSHROT(P1) ;GET RESOURCE
DMOVEM T2,CFROT(T1) ;STASH IT
MOVE T2,T4 ;HOST NUMBER
CALL SCASND
IFNSK. ;If failed
PIOFF
CALL CFSWDN ;Return the buffer
PION
ENDIF.
LOOP.
ENDDO.
MOVE P,CFSSVP ;Restore original stack
> ;IFN CFSSCA
RET ;And done
;Pseudo routine to return failure.
CFSFAL: CFSULK
RETBAD() ;COULDN'T
SUBTTL Resource manager -- CFSUGD (Upgrade or downgrade a resource lock)
;Routine to upgrade (or downgrade) a resource lock.
; T1/ root code
; T2/ qualifier
; T3/ force voting,,new access
; Call with CFS interlock set!
;Returns (interlock cleared)
; +1 not currently held, or can't upgrade
; T2=-1 An error occurred in which this system could not
; find the resource to upgrade or a vote was in
; progress on this resource and we can't upgrade.
; T2>0 This system attempted to upgrade the access of the
; resource by voting for the new access. This vote
; request failed. The first reason we were told NO
; (found in HSHDRC) is returned.
;
; +2 did it. Share count incremented
;This routine is used to "seize" a resource without requiring
;the deallocation of resources. The intended use is for file
;access resources that are either "shared", "exclusive" or
;"unowned".
CFSUGZ: SETO T4, ;Force all votes
JRST CFSUG2 ;And enter
CFSUGA::TDZA T4,T4 ;Force vote
CFSUGD::MOVEI T4,1
CFSUG2: SAVEQ
DMOVE Q2,T3 ;Save incoming args
CALL HSHLOK ;LOOK UP THE REQUEST
JRST CFSUGF ;Can't find the resource!
;FOUND IT.
JN <HSHWVT>,(T1),CFSUGF ;A vote is pending on this resource - fail
INCR HSHCNT,(T1) ;Freeze it here
MOVE Q1,T1 ;COPY POINTER
JUMPL Q3,CFSUG1 ;If all force, go to it
OPSTR <CAME Q2,>,HSHTYP,(T1) ;ALREADY AT THIS TYPE?
JRST CFSUG0 ;NO
CALLRET CFSRSK ;YES, SUCCESS
;Not at this level
CFSUG0: LOAD T2,HSHTYP,(Q1) ;GET TYPE OF CURRENT RESOURCE
CAIE T2,.HTOEX ;ARE WE THE ONLY OWNER?
JRST CFSUG1 ;NO
STOR Q2,HSHTYP,(Q1) ;Stash new access
CALLRET CFSRSK ;And succeed
;HERE IF WE MAY NOT BE THE ONLY OWNER. FREEZE CURRENT RESOURCE AND
;TRY TO GET EXCLUSIVE ACCESS FOR THE CHANGE
CFSUG1: SETONE HSHUGD,(Q1) ;NOTE UPGRADE VOTE
IFLE. Q3 ;If forcing
SETONE HSHAVT,(Q1) ;Say to force
ENDIF.
MOVE T1,Q2 ;Copy desired type for VOTEr
CALL VOTEWS ;DO IT.
SETZRO <HSHAVT,HSHUGD,HSHWVT>,(Q1) ;NOT WAITING ANYMORE
JN HSHYES,(Q1),[
TMNN HSHCNT,(Q1) ;Any count?
CALL CFNCNT ;No!
DECR HSHCNT,(Q1) ;If can't upgrade...
LOAD T2,HSHDRC,(Q1) ;...get reason for NO...
CALLRET CFSFAL] ;...and fail
STOR Q2,HSHTYP,(Q1) ;SET IT
CALLRET CFSRSK ;And succeed
CFSUGF: SETOM T2 ;We could not find the resource or
CALLRET CFSFAL ;...vote in progress on it. Fail - no reason.
SUBTTL The voter -- VOTEW (Start vote and wait for results)
;ROUTINE TO START VOTE AND WAIT FOR RESULTS.
; T1/ TYPE WE ARE VOTING ON
; Q1/ REQUEST TO VOTE ON
;Returns +1 always. Result of vote indicated by HSHYES(Q1)
;This routine sends out requests to all other CFS processors
;and waits for the tallies. Tallies are processed as
;in-coming CFS requests and are therefore handled by the
;scheduler.
;VOTEW does a "regular vote".
;VOTEWS does a "seize" vote
VOTEWS: TDZA T2,T2 ;REMEMBER SEIZE
VOTEW: MOVEI T2,1 ;REMEMBER REGULAR VOTE
IFN CFSSCA,< ;if SCA is present
SAVEP5 ;Work regs
MOVE P2,T2 ;Save type
SETONE HSHWVT,(Q1) ;MARK VOTING
; SETZRO HSHODA,(Q1) ;No optional data yet
STOR T1,HSHVTP,(Q1) ;Store vote type
NOSKED
CFSULK
VOTRST: SKIPN CFSCMC ;Any connects outstanding?
IFSKP. ;If so
MOVEI T1,DISET ;Wait for equal
HRLI T1,CFSCMC ; of this work
CALL CFSWUP ;Do it
ENDIF.
DO.
SKIPE T1,DLYLOK ;A delay in effect?
IFNSK. ;If so
SUB T1,TODCLK ;Get relative time
IFG. T1 ;If we still need to wait...
CALL SETBKT ;Compute wait time
HRRI T1,CFRCNW ;Wait
CALL CFSWUP ;Do it
MOVE T1,TODCLK ;Get now
CAMGE T1,DLYLOK ;Really time to wake up?
LOOP. ;No
ENDIF.
SETZM DLYLOK ;Yes
CALL CLRDLY
ENDIF.
ENDDO.
MOVEM P,CFSSVP ;Save stack pointer
MOVE P,CFSSTK ;Get new stack
AOS T1,VOTNUM ;GET A VOTE DIALOGUE
STOR T1,HSHUNQ,(Q1) ;Set this now
SETZRO <HSHVRS,HSHYES>,(Q1) ;ASSUME NO NO'S
SETZRO HSHRTY,(Q1) ;And now resends yet either
SETZRO HSHDLY,(Q1) ;No delays yet either
SKIPN P3,CFSHCT ;GET HOST COUNT OF OTHER HOSTS
IFNSK. ;If nobody out there...
MOVE P,CFSSVP ;Restore original stack
CFSLOK ;Lock up the data base
OKSKED
RET ;And return now
ENDIF.
SETZRO HSHVCT,(Q1) ;VOTE IS AT ZERO
SETZRO HSHDRC,(Q1) ;No denial reason code yet
SETZM HSHWTM(Q1) ;No wait time yet
SETZM P1 ;Nothing done yet
MOVSI P4,-HSTSIZ ;Loop over entire data base
; ..
;TOP OF VOTING LOOP. FOR EACH OTHER CFS PROCESSOR, SEND REQUEST.
;THE VOTING BUFFERS ARE PRELLOCATED AT SYSTEM START-UP. VOTE
;BUFFERS ARE ALLOCATED DIRECTLY FROM THE QUEUE AND ARE RETURNED
;TO THE QUEUE BY SCA. IF THE QUEUE IS EXHAUSTED, THE VOTE
;WILL BE DELAYED UNTIL SOME ARE FREED (NOT EXPECTED TO BE LONG)
VOTE1: TMNE HSHYES,(Q1) ;ALREADY VETOED?
IFNSK.
MOVE P,CFSSVP ;Restore stack
CFSLOK ;YES.
OKSKED
RET
ENDIF.
SKIPLE CFSHST(P4) ;THIS HOST UP?
SKIPL P5,CFHSTS(P4) ;maybe. CTS?
JRST VOTEW0 ;NO
TRNE P5,-1 ;Is this a "reduced" CFS?
IFSKP. ;If so.
TMNE HSHAVT,(Q1) ;Vote anyway?
ANSKP. ;If not
INCR HSHVCT,(Q1) ;Say it approved
AOJA P1,VOTEW0 ;Account for it and go on
ENDIF.
CALL GVOTE ;GET A VOTE BUFFER
NOP
; ..
; ..
;BUILD VOTE REQUEST IN THIS BUFFER. IT WILL BE SENT TO HOST (P4)
;A vote message is as follows:
; word 0= vote opcode,,vote dialogue
; word 1= root code
; word 2= qualifier
; word 3= access required
LOAD T2,HSHUNQ,(Q1) ;Get code
STOR T2,CFUNQ,(T1) ;STORE VOTING NUMBER
MOVEI T2,.CFVOT ;WE ARE VOTING
; SKIPN P2 ;VOTING OR SEIZING?
; MOVEI T2,.CFCEZ ;SEIZE IT
STOR T2,CFCOD,(T1) ;STORE IT
DMOVE T2,HSHROT(Q1) ;GET ROOT AND QUALIFIER
DMOVEM T2,CFROT(T1) ;STORE IT IN VOTER
LOAD T2,HSHVTP,(Q1) ;GET REQUEST TYPE
TRNN P5,-1 ;Full vote?
MOVEI T2,.HTOEX ;No. Must always be exclusive for these
MOVEM T2,CFTYP(T1)
HRRZ T2,P4 ;HOST NUMBER
TMNE HSVUC,(Q1) ;Vote to include HSHCOD?
IFNSK. ;If so
SETONE CFVUC,(T1) ;Set it
MOVE T3,HSHCOD(Q1) ;Get the code
MOVEM T3,CFDAT(T1) ;Send it off
ENDIF.
CALL SCASND
IFNSK. ;If failed
PIOFF
CALL CFSWDN ;Enqueue the buffer
PION
MOVE P,CFSSVP ;Restore stack
JRST VOTRST ;Do it again
ENDIF.
ADDI P1,1 ;Did one
VOTEW0: CAIGE P1,0(P3) ;Found them all yet?
AOBJN P4,VOTE1 ;DO THEM ALL!
MOVE P,CFSSVP ;Restore stack
; ..
;VOTES ALL SENT OFF. WAIT FOR ALL REPLIES
CAIGE P1,0(P3) ;Found all of them (or more)?
JRST VOTRST ;No. Start over
CALL UPDTCK ;UPDATE TOD CLOCK
DO.
TMNE HSHVRS,(Q1) ;NEED TO RESTART?
JRST VOTRST ;yes
TMNE HSHYES,(Q1) ;Someone veto the request?
IFNSK. ;If so...
CFSLOK
OKSKED
RET
ENDIF.
LOAD T2,HSHVCT,(Q1) ;GET COUNT OF RETURNS
CAIN T2,0(P3) ;NO. ALL IN?
EXIT. ;YES.
REPEAT 0,< ;Don't do stall
CALL GETMST ;GET CURRENT TIME
SUB T1,TODCLK ;COMPUTE TIME IN THE LOOP
CAIGE T1,MAXVWT ;WAITED TOO LONG?
LOOP. ;NO
> ;Repeat 0
;Here when we have waited a long time for the votes. Dismiss and
;try again later.
MOVE T2,Q1 ;Block address
MOVEI T1,VOTSWT ;WAIT ROUTINE
CSKED ;Be critical for the rest of this
OKSKED
CALL CFSWUP ;WAIT FOR IT
NOSKED
ECSKED
LOOP.
ENDDO.
; ..
;Votes are all in, and no nay-sayers
TMNN HSHDLY,(Q1)
IFNSK.
CFSLOK
OKSKED
RET
ENDIF.
;At least one respondent wants time to release the resource. Wait
MOVE T1,TODCLK ;Get now
ADDI T1,^D5000 ;When to retry
;The retry time is simply a precaution
;against the other node being low on resources.
MOVEM T1,HSHTIM(Q1)
MOVE T2,Q1 ;Packet address
MOVEI T1,VOTDWT ;WAIT ROUTINE
SETONE HSHDWT,(Q1) ;Note this
CSKED ;Be critical for the rest of this
OKSKED
CALL CFSWUP ;WAIT FOR IT
SETZRO HSHDWT,(Q1)
TMNN HSHVRS,(Q1) ;RESTART OR SUCCESS?
IFNSK.
CFSLOK
ECSKED
RET
ENDIF.
NOSKED
ECSKED
JRST VOTRST ;DO IT AGAIN
;Scheuler tests for above.
VOTDWT: LOAD T1,FKST2,(Q3)
TMNE HSHVRS,(T1)
JRST 1(4) ;Awake to retry
TMNN HSHDLY,(T1)
JRST 1(4)
REPEAT 1,<JRST 0(4)>
REPEAT 0,<
MOVE T2,HSHTIM(T1) ;Time to retry?
CAML T2,TODCLK ;Still want to wait?
JRST 0(4) ;Yes
SETONE HSHVRS,(T1) ;No. restart the vote
JRST 1(4)
> ;REPEAT 0
VOTSWT: LOAD T1,FKST2,(Q3)
TMNE HSHVRS,(T1) ;NEED TO RESTART?
JRST 1(4) ;YES. AWAKE THEN
LOAD T2,HSHVCT,(T1) ;GET COUNT OF VOTERS
TMNN HSHYES,(T1) ;NO IN YET?
CAMN T2,CFSHCT ; NO. ALL VOTED IN?
JRST 1(4) ;YES.
JRST 0(4) ;NO
CFRCNW: SKIPG DLYLOK ;Still in delay?
JRST 1(4) ;No. Awake now
JRST BLOCKT ;Yes. Check on time
SUBTTL The voter -- GVOTE (Get a vote buffer)
;Routine to get a vote buffer
; Returns +1 on failure
; +2 success
GVOTE1: TDZA T1,T1 ;NO WAIT
GVOTE: SETOM T1 ;WAIT
ASUBR <WFLAG>
DO.
PIOFF
SKIPN T1,VOTQ ;GET ONE
IFNSK.
PION
SKIPN WFLAG
RETBAD() ;IF NO WAIT, ALL DONE
MOVEI T1,VBWAIT
CALL CFSWUP ;WAIT FOR SOME
LOOP.
ENDIF.
ENDDO.
MOVE T2,(T1)
MOVEM T2,VOTQ ;DEQUEUE THIS ONE
PION
SETZM SCALEN(T1) ;Clear the first word
RETSKP ;AND DONE
;SCHEDULER TEST TO WAIT FOR VOTE BUFFERS
VBWAIT: SKIPE VOTQ ;ANY HERE?
JRST 1(4) ;YEP
JRST 0(4) ;NOPE
> ;IFN CFSSCA
IFE CFSSCA,< ;If no SCA
RET ;No vote
> ;IFE CFSSCA
SUBTTL Periodic check -- CFSCHK (Scheduler poller)
;Scheduler poller
;Must either be INSKED or NOSKED
CFSCHK::SKIPE SCAILK ;OK to do this now?
RET ;No. Try again next time
SKIPE SCAFL1 ;Is KLIPA off-line?
IFNSK. ;If so
SETZ T1,0 ;either path
CALL CIONLT ;is it sound yet?
IFNSK. ;If not
MOVX T1,^D1000 ;Come back in a sec
MOVEM T1,CFSTIM ;To check it again
ELSE.
CALL PRTONL ;Set dual-port access
ENDIF.
ELSE.
MOVX T1,^D5000 ;Back in five seconds, please
MOVEM T1,CFSTIM ;Store it
ENDIF.
SOSLE CFSTTM ;Time for full test?
RET ;No
MOVX T1,TIMSE0 ;Ten minutes from now
MOVEM T1,CFSTTM ;Set it
;CALLRET CFSCH1 ;Do a pass
;Worker routine to do the scheduler background tasks.
CFSCH1: AOS SCAILK ;Interlock it to prevent out-of-order messages
MOVEM P,CFSSVP ;Save incoming stack
MOVE P,CFSSTK ;Get a BETTER stack
CALL SCAPOL ;Check on the message spooler
MOVE P,CFSSVP ;Recover original stack
PIOFF ;Prevent races
TMNN SCWKP ;Anything here?
SKIPE SCAQ ;Anything here now?
CALL SKDRUN ;Yes, come back soon
SETZM SCAILK ;And release the interlock
PION ;Allow interruptions again
REPEAT 0,<
SOSLE PRGCNT ;time to scan hash table?
RET ;No
MOVEI T1,^D600 ;Do again in one minute
MOVEM T1,PRGCNT
CALLRET CFSRSE ;And do it
> ;REPEAT 0
RET
;Routine to make the scheduler stuff run ASAP
SKDRUN: SETZM CFSTIM ;Make next 100ms tick come to us
SETZM CFSTTM ;And make sure we do all of our stuff
RET
SUBTTL Periodic check -- SCAPOL (Process incoming SCA messages)
;SCAPOL - routine to process incoming SCA messages
;Called periodically either by unlocking the CFS interlock or by
;the scheduler. Scheduler calls are intended for processing requeued
;requests.
;No arguments.
SCAPOL::SAVEQ ;GET SOME WORK REGS
IFN CFSSCA,< ;Do we have SCA?
SETZM Q2 ;NO REQUEUE NODE YET
TMNN SCRSV ;RESTART VOTE QUEUED?
IFSKP.
SETZRO SCRSV ;YEP
CALL CFSRSV ;DO RESTART
ENDIF.
TMNN SCDDP ;Need DDMP to run?
IFSKP.
SETZRO SCDDP ;All done with this
AOS DDCFSF ;yes.
ENDIF.
TMNN SCDIS ;A pending disconnect?
IFSKP. ;If so
SETZRO SCDIS ;Clear it
PIOFF
MOVSI Q1,-HSTSIZ ;Scan hosts
DO.
SKIPLE T1,CFHSTS(Q1) ;This one active?
SKIPG CFHSTS(Q1) ;Yes. Is it pending for disconnect?
IFSKP.
SETZM CFSHST(Q1) ;Yes
SETZM CFHSTS(Q1) ;Yepper
ENDIF.
AOBJN Q1,TOP. ;Do them all
ENDDO.
PION
ENDIF.
SKIPN SCAQ ;Anything to do?
RET ;No.
SAVET ;Yes. Save regs
DO.
SKIPN Q1,SCAQ ;ANY STUFF HERE?
RET
CAMN Q1,Q2 ;IS THIS THE END?
RET ;YES. DON'T SCAN REQUEUED NODES
PIOFF
MOVE T2,0(Q1) ;GET FORWARD LINK
MOVEM T2,SCAQ ;DEQUEUE IT
IFE. T2 ;IF EMPTY
XMOVEI T2,SCAQ
MOVEM T2,SCTAIL ;INIT TAIL WHEN EMPTY
ENDIF.
PION
MOVE T1,Q1 ;Get pointer to message
CALL SCMSG ;Do a message
IFNSK.
CALL SCAENQ ;ENQUEUE IT FOR RETRY
SKIPN Q2
MOVE Q2,Q1 ;COPY REQUEUED ADDRESS
ENDIF.
LOOP.
ENDDO.
> ;IFN CFSSCA
IFE CFSSCA,<RET> ;If not SCA interface, return now
SUBTTL Call from SCA
;Call-back routine from SCS. Here when something about a connection
;changes.
; T1/ code
; T2/ connection i.d.
; T3/ callback related data if used
; T4/ callback related data if used
IFN CFSSCA,<
CFSSTS: CAILE T1,CFMSFX ;KNOWN FUNCTION?
IFSKP.
EXCH T1,T2 ;Connect ID in T1
CALL @CFFCTB(T2) ;DO IT
ENDIF.
RET ;AND DONE
;Function table for above
CFFCTB: IFIW!R ;.SSDGR - Datagram received
IFIW!SCAIN ;.SSMGR - Message received
IFIW!SCABRK ;.SSPBC - Port broke connection
IFIW!LSNUP ;.SSCTL - Connect to listen
IFIW!CFSCPS ;.SSCRA - Connect response available
IFIW!CFSWDN ;.SSMSC - Message/datagram send complete
IFIW!R ;.SSDDG - Datagram dropped
IFIW!R ;.SSLCL - Little credit left
IFIW!CFSNDU ;.SSNCO - Node came online
IFIW!CFSOKS ;.SSOSD - OK to send data
IFIW!SCABRK ;.SSRID - Remote initiated disconnect
IFIW!SCACRA ;.SSCIA - Credit is available
IFIW!R ;.SSDMA - DMA complete
CFMSFX==.-CFFCTB-1
SUBTTL Call from SCA -- Message Received -- SCAIN (Receive message from SCA)
;Interrupt level routine to receive an incoming SCA packet
; T1/ connect i.d.
; T3/ packet address
; T4/ return address
SCAIN: EXCH T1,T3 ;Swap CID and packet address
LOAD T3,SID,T3 ;GET HOST INDEX
AOS CFRECV(T3) ;Got one
;**;[7211] Add 1 line at SCAIN+3 CEG 18-Dec-85
AOS CFSRCV ;[7211] ADD TO TOTAL RECEIVED
MOVEM T3,.MHSCI(T1) ;STASH IT
MOVEM T4,.MHDCI(T1) ;Save buffer return address
SKIPN SCAILK ;Need to enqueue?
SKIPE SCAQ ;?
IFSKP. ;If not
CALL SCMSG ;Do a message now
SKIPA ;Need to enqeue it
RET ;And done
ENDIF.
CALLRET SCAENQ ;ENQUEUE IT NOW
SUBTTL Call from SCA -- Message Received -- SCMSG (Process a single received message)
;Routine to process a single received message
; T1/ pointer to the message
;Returns: +1 need to requeue. T1/ message pointer
; +2 success. Message already returned
SCMSG: SAVEAC <Q1>
MOVE Q1,T1
LOAD T2,CFCOD,(Q1) ;GET OPCODE
CAILE T2,.CFMAX ;KNOW HOW TO DO THIS?
JRST CFSFRE ;NO. FREE IT AND GO ON
CALL @[ IFIW!CFSRTV ;Vote
IFIW!CFSRVT ;Reply to vote
IFIW!CFSRFR ;Resource freeze
IFIW!CFSRTV ;Seize
IFIW!CFSOFC ;OFN change
IFIW!CFSEFC ;End of file
IFIW!CFTADA ;Time and date
IFIW!CFCEAS]-1(T2); Shutdown
IFNSK.
MOVE T1,Q1 ;Return pointer
RETBAD()
ENDIF.
JUMPE T1,RSKP ;If want to keep it, done
MOVE T1,Q1 ;Else, get address for return
CFSFRE: CALL SCARET ;RETURN SCA BUFFER
RETSKP ;And done
SUBTTL Call from SCA -- Message Received -- CFSRTV (Vote or seize)
;Vote processor. This code is called whenever a request to vote
;Arrives:
; Q1/ The request packet
;Called from the scheduler
;
;Uses:
; T1/ Resource block address
; T2/ Our current access to the resource
; T3/ The requested access in the vote packet
; P1/ Resource block address
; P2/ Delay time if failing
; P3/ Non-zero if want to release the resource
; P4/ Reason code for returning a NO to the vote
; Q2/ Reply type to the vote request
;
;Returns:
; +1 Please reqeue
; +2 done
CFSRTV: SAVEAC <P1,P2,P3,P4,Q2>
SETZB P3,P2 ;No data yet
SETZM P4 ;No reason for NO yet either
DMOVE T1,CFROT(Q1) ;GET CODES
CALL HSHLOK ;LOOK IT UP
IFNSK. ;If not here
SETZM P1 ;Indicate so
JRST CFSRV2 ;And OKAy it
ENDIF.
MOVE P1,T1 ;Save pointer
;**;[7247] Add 9 lines after CFSRTV:+9 DML 19-Feb-86
TMNN HSHTAM,(T1) ;[7247] Is this a cached block?
IFSKP. ;[7247] Yes
MOVE T1,HSHCOD(T1) ;[7247] Get the OFN
MOVX T2,OFNLAC ;[7247] Get bit indicating loss of access
IORM T2,SPTH(T1) ;[7247] Set it
AOS CFACUT ;[7247] Count this event
SETZM P1 ;[7247] Do not release block
JRST CFSRV2 ;[7247] Give an immediate YES answer
ENDIF. ;[7247]
MOVE T4,HSFLAG(T1) ;Get the flags
TXNN T4,HSHDWT ;Are we in a commit?
IFSKP. ;Yes, he loses
MOVX P4,.CDDWT ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
;Found the request. Look it over.
TMNE CFVUC,(Q1) ;Vote to include HSHCOD?
IFNSK. ;If so
MOVE T2,CFDAT(Q1) ;Get required value
CAMN T2,HSHCOD(T1) ;match?
ANSKP. ;They do not, he loses
MOVX P4,.CDVUC ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
LOAD T2,HSHTYP,(T1) ;Get our type
MOVE T3,CFTYP(Q1) ;Get his requested access
TXNN T4,HSHWVT ;Are we voting?
JRST CFSRT0 ;NO
;We are also voting on this. Decide which one can win
TXNN T4,HSHYES ;Did we lose already?
IFSKP. ;If so
TXNN T4,HSHUGD ;Upgrading?
JRST CFSRV2 ; No, he wins
JUMPE T2,CFSRV2 ;If we've only a place-holder, succeed
CAIE T2,.HTOEX ;Do we have it exclusively?
IFSKP. ;Yes, he loses
MOVX P4,.CDYUX ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
CAIN T2,0(T3) ;Do they agree?
JRST CFSRV2 ;Yes. Approve then
MOVX P4,.CDYUN ;No, get reason code
JRST CFSRV3 ;He loses
ENDIF.
JE HSHDLY,(T1),CFSTV1 ;If we do not have a commit, continue
MOVX P4,.CDVDL ;Otherwise, we have a commit. Get reason.
JRST CFSRV3 ;He loses
CFSTV1: LOAD T4,HSHVTP,(T1) ;Get our vote request
CAIE T3,.HTOEX ;He want exclusive?
CAIE T3,0(T4) ;No. Do they agree?
SKIPA T4,.MHSCI(Q1) ;No. One of us has to lose
JRST CFSRV2 ;Yes. Allow it then
MOVE T4,CFSHNM(T4) ;Get his serial number
CAMLE T4,MYPORT ;Is he the bigger wheel?
IFSKP. ;No, we are. He loses
MOVX P4,.CDVLN ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
SETONE HSHYES,(T1) ;Yes, he is bigger. We lose
JN HSHDRC,(T1),CFSTV2 ;If there is already a reason, don't destroy
MOVX T4,.CDVLN ;Get reason for our loss
STOR T4,HSHDRC,(T1) ;Store it
CFSTV2: TMNN HSHUGD,(T1) ;Are we upgrading?
JRST CFSRV2 ;No, he wins
JUMPE T2,CFSRV2 ;If a place-holder, he wins
MOVEI P2,^D50 ;If he loses, try again soon.
CAIE T3,.HTOEX ;He wants exclusive?
IFSKP. ;Yes, he loses too
MOVX P4,.CDVUX ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
CAIN T2,0(T3) ;No. Are they compatible?
JRST CFSRV2 ;Yes, he wins
MOVX P4,.CDVUN ;No, he loses. Get reason code
JRST CFSRV3 ;He loses
;We own this. See if he can share it
CFSRT0: IFE. T2 ;If this is a place-holder
JN HSHKPH,(T1),CFSRV2 ; And keeping, allow it directly
JRST CFSRV5 ;Else, try to remove it as a stale entry
ENDIF.
CAIE T3,.HTOEX ;Does he want exclusive
CAIN T2,.HTOEX ;DO WE OWN IT EXCLUSIVELY?
JRST CFSRT1 ;YES. CHECK IF WE CAN GIVE IT UP
;neither is exclusive. See if either is "promiscuous
CAIE T2,.HTOPM
CAIN T3,.HTOPM ;Do checks
JRST CFSRV2 ;Yes. allow it then
CAIE T2,0(T3) ;NO. SEE IF COMPATIBLE
JRST CFSRT1 ;CHECK IF WE CAN GIVE IT UP
JRST CFSRV2 ;OKAY IT
;Here if we aren't using it
CFSRT1: JE HSHCNT,(T1),CFSRT2 ;If not in use, continue
MOVX P4,.CDOCT ;It is in use. Get reason code.
JRST CFSRV3 ;He loses.
CFSRT2: SKIPE T2,HSHFCT(T1) ;Apply fairness?
CAMG T2,TODCLK ;OK to release it?
IFSKP. ;If not
SUB T2,TODCLK ;Compute difference
MOVE P2,T2 ;Data to send back (time to try again)
MOVX P4,.CDOFC ;Get reason code
JRST CFSRV3 ;Not okay
ENDIF.
;We can give it up. Here by falling through or from CFSRT0
CFSRV5: STOR T3,HSHVTP,(T1) ;Save requested access
MOVE T2,.MHSCI(Q1) ;GET I.D.
STOR T2,HSHRHN,(T1) ;STASH IN PACKET
LOAD T2,CFUNQ,(Q1) ;GET VOTE CODE
STOR T2,HSHVVL,(T1)
AOJA P3,CFSRV2 ;Approve and do release
REPEAT 0,<
CALL CFSRMX ;REMOVE ENTRY
SKIPE Q2,T1 ;Copy type, and test if available
IFSKP. ;If available
IFN. T2 ;And it was removed
MOVEI P1,0 ;No saved entry
ENDIF.
ENDIF.
JRST CFSRV4
> ;REPEAT 0
;At this point:
; P2/ Delay time if failing
; P3/ non-zero if want to release the resource
; P1/ resource address, if any
; Q1/ Request packet from other system
; P4/ Reason code for saying NO
; Q2 will be used to indicate reply type
; 0 -- OK
; 1 -- No
; -1 -- delayed yes
;Here to reply
CFSRV3: IFE. P2 ;Set bit only if not sending data
MOVE T2,.MHSCI(Q1) ;GET HOST NUMBER
MOVE T2,BITS(T2) ;GET BIT FOR THIS HOST
IORM T2,HSHNBT(T1) ;STORE INTO THE PACKET
ENDIF.
SKIPA Q2,[1] ;FAIL!
CFSRV2: MOVEI Q2,0 ;SUCCESS
CFSRV4: CALL GVOTE1 ;GET A BUFFER
RETBAD() ;FAILED. REQUEST A REQUEUE
IFE. Q2 ;If allowing it
SKIPN T2,P1 ;Any request here?
ANSKP. ;If so
SKIPE T3,HSHOKV(P1) ;Yes. Want to know about this?
CALL 0(T3) ;Yes. So tell someone (may change Q2)
IFG. P3 ;Want to try to release it?
EXCH T1,P1
;The following call may return -1 in T1, which changes a "yes" vote
;to "will be released, but not yet"
CALL CFSRMX ;(T1/T1,T2) And try to remove it
MOVE Q2,T1 ;Save type of release
MOVE T1,P1 ;Get back vote packet
ENDIF.
ENDIF.
IFG. Q2 ;If failing
SKIPG P2 ;And have someting to send
ANSKP.
MOVEM P2,CFDAT(T1) ;Stash it
SETONE CFODA,(T1) ;And say so
ENDIF.
MOVEI T2,.CFREP ;WE ARE REPLYING
STOR T2,CFCOD,(T1)
LOAD T2,CFUNQ,(Q1)
STOR T2,CFUNQ,(T1) ;COPY CODE
DMOVE T2,CFROT(Q1)
DMOVEM T2,CFROT(T1) ;MOVE LOCK ID
MOVEM Q2,CFTYP(T1) ;THE VOTE
STOR P4,CFDRC,(T1) ;Store the reason for saying NO, if any
MOVE T2,.MHSCI(Q1)
CALL SCASND ;SEND IT
IFNSK.
PIOFF
CALL CFSWDN ;Return the buffer
PION
ENDIF.
MOVE T1,Q1 ;ENSURE NON-ZERO
RETSKP ;AND DONE
SUBTTL Call from SCA -- Message Received -- CFSRVT (Reply to vote)
;Routine to process returned vote.
; Q1/ packet
;Called from the scheduler or at PI level
CFSRVT: DMOVE T1,CFROT(Q1) ;GET VALUES
CALL HSHLOK ;LOOK IT UP
RETSKP
;Found a node
JE HSHWVT,(T1),RSKP ;IF NOT VOTING, DONE
LOAD T2,CFUNQ,(Q1) ;GET UNIQUE CODE
OPSTR <CAME T2,>,HSHUNQ,(T1) ;MATCH?
JRST RSKP ;NO. SKIP IT THEN
INCR HSHVCT,(T1) ;YES. ANOTHER COUNTY HEARD FROM
TMNE CFODA,(Q1) ;Providing optional data?
IFNSK. ;If so
DO.
SKIPG CFTYP(Q1) ;If a fail vote
IFSKP.
MOVE T2,CFDAT(Q1) ;Get the time stamp
MOVEM T2,HSHWTM(T1) ;Send it back
EXIT.
ENDIF.
SKIPE T2,HSHCDA(T1) ;Want to be notified?
IFNSK. ;If so
CALL 0(T2) ;Do so
EXIT. ;If +1, don't use it
ENDIF.
DMOVE T2,CFDAT(Q1) ;Get it
DMOVEM T2,HSHOPT(T1) ;Store it in the packet
SETONE HSHODA,(T1) ;Say we have some
ENDDO.
ENDIF.
AOS PSKD1 ;MAKE SURE THE SCHEDULER NOTICES THIS
MOVE T2,CFTYP(Q1)
JUMPE T2,RSKP ;IF OK, ALL DONE
IFL. T2 ;IF YES, BUT DELAY
MOVE T3,.MHSCI(Q1)
MOVE T3,BITS+^D18(T3)
LOAD T4,HSHDLY,(T1)
AOSE T2 ;OK WITH DELAY?
IFSKP.
IORM T3,T4 ;YES MARK IT
ELSE.
ANDCAM T3,T4 ;ELSE, UNMARK IT
DECR HSHVCT,(T1) ;Discount vote if this
ENDIF.
STOR T4,HSHDLY,(T1)
ELSE.
SETONE HSHYES,(T1) ;NAY. INDICATE SO
JN HSHDRC,(T1),RSKP ;If there is already a reason, don't destroy
LOAD T2,CFDRC,(Q1) ;Get reason for NO
STOR T2,HSHDRC,(T1) ;Store it
ENDIF.
RETSKP ;AND DONE
SUBTTL Call from SCA -- Message Received -- CFSRFR (Resource freed)
;Routine called when a resource is freed. If anyone is waiting, awake him.
;This routine is used to process an incoming message indicating
;that a resource is now free. The sending node provided this information
;because we requested this resource and were denied. We may or may
;not still require the resource.
;The sender sent this message from CFNOHS!
; T1/ Block address
CFSRFR: DMOVE T1,CFROT(Q1) ;GET RESOURCE ID
CALL HSHLOK ;LOOK IT UP
JRST RSKP
SETONE HSHRTY,(T1) ;AWAKE
AOS PSKD1 ;GET THE SCHEDULER AWAKE TOO
RETSKP ;AND DONE
SUBTTL Call from SCA -- Message Received -- CFSOFC (OFN change)
;Here when a "broadcast OFN change is received.
; Q1/ message block address
CFSOFC: DMOVE T1,CFROT(Q1) ;Get stuff
CALL HSHLOK ;Look it up
JRST RSKP ;Not known here
;found the block
MOVE T2,HSHCOD(T1) ;Get the OFN
;**;[7247] Add 14 lines after CFSOFC:+6 DML 19-Feb-86
TMNN HSHTAM,(T1) ;[7247] Is this a cached block?
IFSKP. ;[7247] Yes
MOVX T1,OFNLAC ;[7247] Get "lost access" bit
TDNN T1,SPTH(T2) ;[7247] It had better be set!
BUG. (HLT,CFSOAC,CFSSRV,SOFT,<CFSSRV - Invalid access to cached OFN>,,<
Cause: CFS has received a message from a remote system that an OFN
has changed and needs to be verified again. But CFS has found
that the OFN is cached and the OFNLAC bit is not set. This
should not happen since this bit should be set when the other
system was granted access.
>) ;[7247] It's not!
RETSKP ;[7247] Ok, just return
ENDIF. ;[7247]
IFN DEBUG,< ;If debugging
MOVE T3,HSFLAG(T1) ;Get flags
TXNN T3,HSHTYP ;A place holder?
IFSKP. ;No.
TXNE T3,HSHWVT ;Better be voting then
TXNE T3,HSHUGD ;And not upgrading
ANNSK. ;If not both...
BUG. (HLT,CFSOFB,CFSSRV,SOFT,<CFSSRV - OFN owned at CFSOFC>,,<
Cause: CFS has received a message from a remote system that an OFN
has changed and needs to be verified again. But CFS has found
that it owns the OFN. It should never have received such a
message.
>)
ENDIF.
> ;IFN DEBUG
JE SPTCDO,(T2),RSKP ;If not yet opened, ignore it
SETONE SPTSFD,(T2) ;Set "reverify" bit
RETSKP ;And done
SUBTTL Call from SCA -- Message Received -- CFSEFC (EOF received)
;Here when broadcast EOF is received.
; Q1/ Block address
CFSEFC: DMOVE T1,CFROT(Q1) ;Get IDs
CALL HSHLOK ;Look it up
JRST RSKP ;We odon't have this file
CALL CFADAR ;Decide if we should use it
JRST RSKP ;No
SETONE HSHODA,(T1) ;Yes.
DMOVE T2,CFDAT(Q1) ;Get it
DMOVEM T2,HSHOPT(T1) ;Copy it
RETSKP ;And done
SUBTTL Call from SCA -- Message Received -- CFTADA (Time and date arrived)
;Here when TAD arrives
CFTADA: MOVE T1,CFROT(Q1) ;Get it
MOVEM T1,CFTADL ;Store it for perusal
AOS JB0FLG ;Get it noticed
RETSKP ;And done
SUBTTL Call from SCA -- Message Received -- CFCEAS (Cease)
COMMENT *
When a system tells its users "System going down in ........" and the shutdown
time is less than one hour away, we check to see if we have any disks onlined
via the MSCP server. If so, we broadcast the shutdown time to the other
systems in the cluster; the same goes for "Shutdown canceled" and
"Timesharing is over". This allows the other systems to see if they have any
structures mounted via the MSCP server on the system which is doing the
broadcasting. If a system finds such mounted structures, it sends to OPR and
the CTY a message stating the remote system's shutdown status and a list of the
structures effected.
Routine CFCBRD is called from MEXEC's shutdown processing to do the broadcast.
Routine CFCEAS processes the incoming message by placing the data (node number,
shutdown time, and node name) in a resident free space block and linking it in
a chain of blocks pointed to by location CCHEAD.
CHKR finds the queued blocks and calls routine CHKCLC. The interlock between
the CHKR routine and the interrupt level code is an EXCH instruction on
location CCHEAD. The data is retrieved from the block, effected structures are
found, and QUEUE% is used to pass the information to OPRs and the CTY.
*
;CFCEAS - PROCESSES CEASE MESSAGE FROM A REMOTE SYSTEM
; Q1/ ADDRESS OF PACKET
; CALL CFCEAS ;(Q1/T1)
; RETURN +2
CFCEAS: SAVEP
DMOVE P1,CFDAT(Q1) ;Get node number and cease time
DMOVE P3,CFROT(Q1) ;Get both words of node name
MOVEI T1,CCLEN ;GET LENGTH OF CLUSTER CEASE INFO BLOCK
HRLI T1,.RESP1 ;PRIORITY 1
MOVE T2,[RS%SE0+.RESGP] ;FROM THE GENERAL POOL
CALL ASGRES ;(T1,T2/T1) GET THE SPACE
IFNSK.
BUG. (INF,CFCCML,CFSSRV,SOFT,<CFSSRV - Cluster cease message lost>,,<
Cause: Another system sent a "cluster cease" that could not be queued
because there was no available resident free space.
>)
JRST CFCEAX ;TOO BAD, BUT NOT CRTITICAL
ENDIF.
SKIPE T2,CCHEAD ;GET HEAD OF QUEUED BLOCKS
IFSKP.
MOVEM T1,CCHEAD ;NONE THERE, MAKE THIS ONE FIRST
ELSE.
CFCEA1: SKIPN T3,CCNXT(T2) ;GET NEXT BLOCK
IFSKP.
MOVE T2,T3 ;WE HAVE ONE
JRST CFCEA1 ;KEEP GOING
ENDIF.
MOVEM T1,CCNXT(T2) ;ADD THIS ONE TO THE END
ENDIF.
DMOVEM P1,CCNOD(T1) ;PUT NODE NUMBER AND TIME IN BLOCK
DMOVEM P3,CCNAM1(T1) ;PUT NODE NAME IN BLOCK
CFCEAX: MOVE T1,Q1 ;INSURE T1 IS NON-ZERO SO BUFFER IS RETURNED
RETSKP
;CHKCLC - CALLED BY CHKR TO SEE IF THERE ARE ANY QUEUED CLUSTER CEASE BLOCKS
;WAITING TO BE PROCESSED
; CALL CHKCLC ;(/)
; RETURN +1
; LOCAL AC USE:
; Q1,Q2 - EXTEND
; Q3 - STRING TERMINATOR
; P1 - FREE SPACE BLOCK
; P2 - KDB
; P3 - UDB
; P4 - SIXBIT STRUCTURE NAME
; P5 - "WE FOUND AT LEAST ONE STRUCTURE" FLAG
SWAPCD
SLEN==^D14 ;WORDS TO HOLD STRUCTURE NAMES
HLEN==^D25 ;WORDS TO HOLD HEADER TEXT
CHKCLC::SETZ T1, ;THIS IS THE INTERLOCK
EXCH T1,CCHEAD ; WITH THE INTERRUPT LEVEL CODE
JUMPE T1,RTN ;IF NO QUEUED BLOCKS, QUIT
SAVEPQ
STKVAR <<SNAMS,SLEN>,<MSG,SLEN+HLEN>>
CHKCL4: SETZ P5, ;START WITH NO STRUCTURES FOUND
MOVE P1,T1 ;PRESERVE BLOCK ADDRESS
MOVE T1,CCNOD(P1) ;GET NODE NUMBER
MOVEI Q1,SNAMS ;MAKE BP
HRLI Q1,(<POINT 7,>) ; TO STRUCTURE NAME SPACE
MOVEI Q3," " ;LOAD "SPACE"
ADD T1,CHNTAB+7 ;GET NODE'S
MOVE P2,CDBUDB(T1) ; KDB
CHKCL1: SKIPN P3,KDBUDB(P2) ;GET NEXT UDB
JRST CHKCL2 ;DONE
MOVX T1,US.TPD ;THREE-PORTED
TDNE T1,UDBSTS(P3) ; HERE?
JRST CHKCL3 ;YES, THEN NO ONE IS USING IT
SKIPGE T1,UDBSTR(P3) ;NO, PART OF STRUCTURE?
JRST CHKCL3 ;NO, THEN IT'S NOT MOUNTED (NOT EVEN MOUNTR)
HLRZ T2,T1 ;YES, GET LOGICAL UNIT OF STRUCTURE
JUMPN T2,CHKCL3 ;IF NOT 0, MOVE ON (ONLY IDENTIFY IT ONCE!)
SETO P5, ;FOUND A STRUCTURE MOUNTED THROUGH A SERVER
HRRZ T1,UDBSTR(P3) ;GET STRUCTURE NUMBER
CALL GNAME ;(T1/T1) GET STRUCTURE NAME
MOVE P4,T1 ;PUT IT SOMEWHERE
MOVEI T1,6 ;GET MAX CHAR. COUNT OF STR NAME
MOVEI T2,P4 ;MAKE BP
HRLI T2,(<POINT 6,>) ; TO IT
SETZB T3,Q2 ;SINGLE WORD BYTE POINTERS
MOVE T4,T1 ;GET CHAR. COUNT AGAIN
EXTEND T1,[MOVSO 40] ;CREATE STR NAME IN ACSII
JFCL
IDPB Q3,Q1 ;PUT IN SPACE
CHKCL3: AOJA P2,CHKCL1 ;GO DO NEXT UDB
;...
;...
CHKCL2: SETZ Q3,
IDPB Q3,Q1 ;TIE OFF STRUCTURE NAMES
HRROI T1,MSG ;YES, GET BP TO MESSAGE
HRROI T2,[ASCIZ/
/]
SETZ T3,
SOUT ;WAKE UP THE OPERATOR
HRROI T2,CCNAM1(P1)
SOUT ;NODE NAME
SKIPG CCTIM(P1) ;CEASE SCHEDULED?
IFSKP.
;Cease scheduled
HRROI T2,[ASCIZ/ is going down at /]
SOUT
MOVE T2,CCTIM(P1) ;GET TIME
ODTIM ;PUT IT IN MESSAGE
HRROI T2,[ASCIZ/. /]
SOUT
HRROI T2,CHKMS1 ;ASSUME STRUCTURES FOUND
SKIPN P5 ;WERE THERE ANY?
HRROI T2,CHKMS2 ;NO, GET DIFFERENT MESSAGE
ELSE.
SKIPE CCTIM(P1) ;SHUTDOWN CANCELED?
IFSKP.
;Shutdown canceled
SKIPN P5 ;ANY STRUCTURES FOUND?
JRST CHKCL5 ;NO
HRROI T2,[ASCIZ/ has canceled its shutdown. It is no longer
necessary to dismount the following structures:
/]
ELSE.
;Timesharing is over
HRROI T2,[ASCIZ/ has ceased timesharing. /]
SOUT
HRROI T2,CHKMS1 ;ASSUME STRUCTURES FOUND
SKIPN P5 ;WERE THERE ANY?
HRROI T2,CHKMS2 ;NO, GET DIFFERENT MESSAGE
ENDIF.
ENDIF.
SOUT ;CREATE HEADER
SKIPN P5 ;ANY STRUCTURES FOUND?
IFSKP.
HRROI T2,SNAMS ;YES, GET BEGINNING OF STRUCTURE NAMES
SOUT ;MOVE THEM TO END OF MESSAGE
ENDIF.
MOVEI T2,MSG ;GET BEGINNING ADDR OF MESSAGE
MOVEI T3,.QBSYS ;TYPE IS "SYSTEM MESSAGE"
CALL WROPR0 ;(T1,T2,T3/) WRITE-TO-OPR
;...
;...
CHKCL5: MOVE P2,CCNXT(P1) ;GET NEXT QUEUED BLOCK
MOVE T1,P1 ;POSITION BLOCK ADDR
CALL RELRES ;(T1/) RELEASE THIS BLOCK
SKIPE T1,P2 ;IS THERE ANOTHER BLOCK?
JRST CHKCL4 ;YES
RET
ENDSV.
CHKMS1: ASCIZ/Before that system
is shutdown, this system should dismount the following
structures:
/
CHKMS2: ASCIZ/No structure
dismounting is needed on this system.
/
RESCD
SUBTTL Call from SCA -- SCABRK (Node went away)
;Here when a connection is broken for any reason
; T1/ connection i.d. or -1 for extra callback
SCABR0: AOS CFSSKC ;Make the scheduler do the check
ISB SCDCHN ;And make it notice
SCABRK: SKIPGE T3,T1 ;Is this an extraneous callback?
RET ;Yes, just return
LOAD T1,SID,T1 ;GET HOST INDEX
SKIPN CFSHST(T1) ;This node active in some way?
IFSKP.
SKIPL T2,CFHSTS(T1) ;If active, is it up (i.e. counted)?
IFSKP. ;If so...
SOS CFSHCT ;ONE LESS
TRNE T2,-1 ;A full or reduced?
SOS CFSHCM ;Full.
CALL MXCIND ;(/T2) Get the max number of nodes ever on CI
IMUL T2,DLYTIM ;Multiply by delay per node
ADD T2,NDSTTM ;Add allowable time for reloading the KLIPA
ADD T2,TODCLK ;Compute time the delay is over
IFN DEBUG,<
; SKIPE DLYFLG ;Doing delay stuff?
> ;IFN DEBUG
MOVEM T2,DLYLOK ;And lock voting for a bit
CALL PHYNOL ;Declare the disk's offline
MOVE T2,CFSHNM(T1) ;Get the serial number
CALL PUTOLD ;And install it now
SKIPE SCAILK ;OK TO DO THIS NOW?
IFSKP.
SETZM CFSHST(T1) ;Not in use now
CALL CFSRSV ;YES, RESTART VOTE
ELSE.
SETONE <SCRSV,SCDIS> ;NO. SAY WE NEED IT LATER
MOVX T2,1B0 ;Get the sign bit
ANDCAM T2,CFHSTS(T1) ;Mark this entry
ENDIF.
ELSE. ;If not counted
SOS CFSCMC ;One less connection being done
SETZM CFSHST(T1) ;And this one is no longer active
ENDIF.
PIOFF
DO. ;Return queued send buffers
SKIPN T3,CFSSMQ(T1) ;Anything here?
EXIT. ;No. All done
MOVE T2,0(T3) ;Get next
MOVEM T2,CFSSMQ(T1)
CALL CFSWDN ;Return the buffer
LOOP. ;Do them all
ENDDO.
PION
ENDIF.
RET
SUBTTL Call from SCA -- LSNUP (Connect to listen)
;Here when listen circuit has a sucker.
;Called at interrupt level or with CFS interlock set
; T1/ Connect I.D.
; T3/ Pointer to serial number
LSNUP: SAVEQ
LOAD Q1,SID,T1 ;GET HOST INDEX
HRRZ T2,OPDTYP(T3) ;Get net number
;here if we know about this. See if connector is trying to
;connect to us (or we know about it).
DMOVE Q2,OPDNAM(T3) ;Get its name
HLLZS Q3 ;Get rid of excess
LSH Q1,1 ;Get index
DMOVEM Q2,CFNNAM(Q1) ;Stash the name
LSH Q1,-1
MOVE Q2,T1 ;SAVE CID
MOVE T1,OPDSER(T3) ;GET SERIAL NUMBER
HLRE Q3,OPDTYP(T3) ;Get type of node
XOR T2,MYPOR1 ;Compare net numbers
TRNE T2,-1 ;Same?
SETZM Q3 ;No. Treat as a reduced node then
MOVEM T1,CFSHNM(Q1) ;AND PORT NUMBER HERE
MOVEI T3,HSTSIZ ;SIZE OF HOST TABLE
CAMG T1,MYPORT ;HIGHER PRIORITY THAN I?
IFNSK.
DO.
SKIPLE CFSHST(T3) ;ACTIVE?
CAME T1,CFSHNM(T3) ;IS THIS ALREADY CONNECTED?
IFSKP.
SKIPL CFHSTS(T3) ;Make sure is fully active
ANSKP.
BLCAL. (SC.REJ,<CFSHST(Q1),[0]>)
NOP
SETZM CFSHST(Q1) ;THIS SLOT NOW AVAILABLE
JRST LSNUP1 ;GO START A NEW LISTENER
RET ;DONE
ENDIF.
SOJGE T3,TOP.
ENDDO.
ENDIF.
;Here if we should accept
MOVE T1,CFSHNM(Q1) ;Get the serial number
CALL CHKOL0 ;see if we know about this one yet
STOR T1,ONFLG,MYPOR3 ;Store old/new flag byte
HRRM Q3,CFHSTS(Q1) ;Remember the type
AOS CFSCMC ;Note we are doing this
BLCAL.(SC.ACC,<Q2,<.,MYPORT>,[BUFSCT],[0]>); ACCEPT THE OVERTURE
IFNSK.
MOVE T3,T1 ;Move error code
MOVE T1,Q2 ;Get connect ID
CALL SC.NOD ;(T1/T1,T2) Get node number
BUG. (HLT,CFACCF,CFSSRV,SOFT,<CFSSRV - SC.ACC failed>,<<T2,NODE>,<T1,CID>,<T3,ERR>>,<
Cause: The call to SC.ACC failed.
Data: NODE - Node Number
CID - Connect ID
ERR - Error returned by SC.ACC
>)
ENDIF.
MOVEM Q2,CFSHST(Q1) ;NOW STORE CID
;NOTE: CFSHCT is incremented during the CFSOKS call-back
LSNUP1: CALL CFSLSN ;GET A NEW LISTENER
NOP
RET ;AND DONE
SUBTTL Call from SCA -- Connect response available -- CFSCPS (Connect response available)
;Here on reply to connect request
; T1/ CID
; T3/ Reply code
; T4/ Pointer to serial number
;We tried to connect to another node, and now a response is available.
;If it has accepted, we may already have a connection open to it.
;If that is true, the open connection was initiated by the other node,
;and the following algorithm applies:
;If we have the lower serial number, close this one.
;If they have the lower serial number, close the existing one.
CFSCPS: SAVEAC<P1,P2>
LOAD T2,SID,T1 ;Get local ID
SKIPE CFSHST(T2) ;This waiting?
SKIPL CFSHNM(T2) ;?
RET ;No. Ignore it then
;Found the waiting entry. See if it was accepted
SOS CFSCMC ;No more of this
MOVEM T1,CFSHST(T2) ;Store CID
IFE. T3 ;If rejected
SETZM CFSHST(T2) ;We are no longer waiting
RET ;And done
ENDIF.
;It was accepted. Make sure we are not connect another way
DMOVE P1,OPDNAM(T4) ;get its name
HLLZS P2 ;Get rid of excess
LSH T2,1 ;Get to index
DMOVEM P1,CFNNAM(T2) ;Stash its name
LSH T2,-1
LOAD P2,ONFLG,OPDNEW(T4) ;Get old/new byte
HLRE P1,OPDTYP(T4) ;Get type of connector
HRRZ T3,OPDTYP(T4) ;Get network nubmer
XOR T3,MYPOR1 ;Compare with our number
TRNE T3,-1 ;Same as us?
SETZM P1 ;No. Treat it as "reduced"
MOVE T4,OPDSER(T4) ;Get other node's serial number
CALL CFSCPX ;(T4/)See if we need to disconnect
RET ;Disconnected our initiator. Quit now
;..
;Here when we want to let this connection proceed. We may have disconnected
;an old connection.
;..
SKIPE SCAFL1 ;OK to allow this?
CALL CFSDIE ;No.
MOVEM T4,CFSHNM(T2) ;OK to store this now
HRROM P1,CFHSTS(T2) ;Set status
SETZM CFSENT(T2)
SETZM CFRECV(T2)
XMOVEI T3,CFSSMQ(T2) ;Get head of send queue
MOVEM T3,CFSSQT(T2) ;Link tail to head
SETZM 0(T3) ;Clear head
MOVE T1,CFSHNM(T2) ;Get its serial number
SKIPE P2 ;If he thinks it is new
CAMG T1,MYPORT ;Or I'm a big wheel
IFSKP. ;If not
EXCH P2,T2 ;Save index, get OLD/NEW arg
CALL CHKOLD ;Check it we've been here before
IFSKP.
MOVE T1,CFSHST(P2) ;Get connect ID
CALL SC.NOD ;(T1/T1,T2) Get node number
BUG. (HLT,CFRECN,CFSSRV,SOFT,<CFSSRV - Illegal reconnect>,<<T2,NODE>,<T1,CID>>,<
Cause: The VC between this system and another has been continued illegally.
Data: NODE - Number that has re-established a connection
CID - Connect ID
>)
ENDIF.
EXCH T2,P2 ;Swap index and OLD/NEW arg
ENDIF.
MOVE T1,CFSHNM(T2) ;recover serial number
CALL CHKDLY ;Check if we are whole again!
AOS CFSHCT ;Another node in the list
MOVE T1,T2 ;Pass local node number
CALL ONLINE ;Do a message
SETONE SCCNC
TRNE P1,-1 ;IS this reduced
IFNSK. ;If not
AOS T3,CFSHCM ;One more full voter on-line
;**;[7152] Remove 2 lines at CFSCPS+75 CEG 15-Oct-85
ENDIF.
MOVEI T1,0(T2) ;Copy host index
CALL SNDTIM ;Send it the TAD
SKIPE SCAILK ;Data base locked?
IFSKP. ;If not
CALL CFSRSV ;Restart votes (called without the lock)
ELSE. ;If so
SETONE SCRSV ;Note we need to do this ASAP
CALL SKDRUN ;Make the scheduler run ASAP
ENDIF.
RET ;And done
SUBTTL Call from SCA -- Connect response available -- CFSCPX (Disconnect duplicate connection)
;CFSCPX - Disconnect if there's a duplicate connection to this node
;Accepts:
; T4/ serial number of the other node
; CALL CFSCPX
;Returns +1: disconnected our initiator (the one that caused this call)
; +2: OK to proceed with this connection
;Preserves the temporary AC's except T3.
;Note: this was written to fix a bug in CFSCPS. It is not general-purpose.
;Calling it from anywhere else might be a mistake
CFSCPX: MOVSI T3,-HSTSIZ ;Scan table for a match
SAVET
DO.
CAME T4,CFSHNM(T3) ;Here?
IFSKP. ;If so, we have a conflict. Must do away with one
SKIPE CFSHST(T3) ;Really in use?
SKIPL CFHSTS(T3) ;?
ANSKP. ; If so...
MOVEI T1,0(T2) ;Assume we will zap our connection
CAMG T4,MYPORT ;Will we?
MOVEI T1,0(T3) ;No zap other side's initiator
PUSH P,T1
BLCAL. (SC.DIS,<CFSHST(T1),[0]>)
NOP
POP P,T1
IFN DEBUG,<
CALL OFLINE ;(T1) REPORT THE DISCONNECTION
>
SETZM CFSHST(T1) ;Clear entry
SKIPL T3,CFHSTS(T1) ;Which connection did we kill?
RET ;Our initiator. Don't continue connecting, then.
;Here when we disconnected the other side's initiator (the old connection).
;Need to decrement the host count and let the current connection continue.
SOS CFSHCT ;Indicate one fewer connections
TRNE T3,-1 ;Full or reduced?
SOS CFSHCM ;It was full
RETSKP ;Let the caller proceed
ENDIF.
AOBJN T3,TOP. ;Scan them all
ENDDO.
RETSKP
SUBTTL Call from SCA -- CFSWDN (Write completed)
;Here to put a packet on the vote queue
; T3/ Buffer address
CFSWDN:
IFN DEBUG,< ;Only for debugging...
LOAD CX,CFGWD,(T3) ;Check if special word is here
CAME CX,[252525] ;Is it?
BUG.(HLT,CFGARD,CFSSRV,SOFT,<CFSSRV - Vote packet address is bad>,,<
Cause: A bad vote packet address has been given to CFSWDN.
>)
> ;IFN DEBUG
EXCH T3,VOTQ ;PUT IT ON TOP
MOVEM T3,@VOTQ ;AND QUEUE REST OF QUEUE TO IT
RET ;DONE
> ;IFN CFSSCA
IFE CFSSCA,< ;If not SCA
CFSWDN==R ;Null routine
> ;IFE CFSSCA
SUBTTL Call from SCA -- CFSNDU (Node up)
;Node up
; T1/ SBI
IFN CFSSCA,<
CFSNDU: SKIPE SCAFL1 ;Are ports off?
CALL DEDKLP ;Yes. We are in trouble
CALL CFSCTH ;Try to connect to it
NOP
RET ;And done
SUBTTL Call from SCA -- CFSOKS (Ok to send)
;Here when a listener is really ready to send
; T1/ CID
CFSOKS: SAVEQ
LOAD Q1,SID,T1 ;get ID
SKIPLE CFSHST(Q1) ;Do we agree?
SKIPGE CFHSTS(Q1) ;Still?
RET ;No
SOS CFSCMC ;Discount this now
;yes. we must do soemthing about this
;Check for a conflict
MOVSI T2,-HSTSIZ
MOVE T3,CFSHNM(Q1) ;Get name
DO.
CAME T3,CFSHNM(T2) ;This one match?
IFSKP. ;if so.
SKIPE CFSHST(T2) ;Make sure is active
SKIPL CFHSTS(T2) ;""
ANSKP.
MOVEI Q2,0(Q1) ;Assume we will close his
CAML T3,MYPORT ;Will we?
MOVEI Q2,0(T2) ;No. Close ours
BLCAL. (SC.DIS,<CFSHST(Q2),[0]>)
NOP
IFN DEBUG,<
MOVE T1,Q2 ;GET LOCAL NODE INDEX
CALL OFLINE ;(T1) REPORT THE DISCONNECTION
>
SETZM CFSHST(Q2)
SKIPL T3,CFHSTS(Q2) ;Was it me or him?
RET ;Me. All done then
SOS CFSHCT ;Him. One less active node
TRNE T3,-1 ;Full or reduced?
SOS CFSHCM ;Full
EXIT.
ENDIF. ;And proceed with the connection
AOBJN T2,TOP.
ENDDO.
SKIPE SCAFL1 ;OK to allow this?
CALL CFSDIE ;No.
XMOVEI T3,CFSSMQ(Q1) ;Get address of head
MOVEM T3,CFSSQT(Q1) ;Link head to tail
SETZM 0(T3) ;Clear head
AOS CFSHCT ;Another one active
MOVE T1,Q1 ;Pass local node number
CALL ONLINE
SETONE SCCNC
HRROS T3,CFHSTS(Q1) ;Mark it active
SETZM CFSENT(Q1)
SETZM CFRECV(Q1)
TRNE T3,-1 ;Full or reduced?
IFNSK. ;If full
AOS T3,CFSHCM ;One more full voter
;**;[7152] Remove 2 lines at CFSOKS+53 CEG 15-Oct-85
ENDIF.
MOVEI T1,0(Q1) ;Copy the index
CALL SNDTIM ;Send it TAD
SKIPE SCAILK ;Data base locked?
IFSKP. ;If not
CALL CFSRSV ;Restart votes (called without the lock)
ELSE. ;If so
SETONE SCRSV ;Note we need to do this ASAP
CALL SKDRUN ;Make the scheduler run
ENDIF.
RET ;And done
SUBTTL Call from SCA -- SCACRA (Credit available)
;Credit arrived.
; T1/ CID
SCACRA: LOAD T1,SID,T1 ;Get local port
SETONE STCRA,(T1) ;Say it arrived
CALLRET SSENDQ ;Process the queue
SUBTTL Sending Messages -- SCAENQ (Enqueue a SCA message)
;ROUTINE TO ENQUEUE AN SCA MESSAGE
; T1/ MESSAGE TO ENQUEUE
;RETURNS:
; +1 ALWAYS
SCAENQ: PIOFF
MOVEM T1,@SCTAIL ;LINK INTO QUEUE
MOVEM T1,SCTAIL
SETZM 0(T1) ;NO FORWARD LINK
PION
RET ;DONE
> ;IFN CFSSCA
SUBTTL Sending Messages -- SCASND (Send a message)
;Routine to send a message.
; T1/ Buffer address
; T2/ host number
;Returns: +1/ failed. T3/ buffer address
; +2 success
IFE CFSSCA,<
SCASND: BUG.(HLT,CFSSMC,CFSSRV,SOFT,<CFSSRV - Tried to send a message>,,<
Cause: CFSSRV tried to send an SCA message and that option is not
supported in this version of TOPS-20>
)
> ;IFE CFSSCA
IFN CFSSCA,<
SCASND: ASUBR <SCBUFF,SCHOST>
SKIPE CFSHST(T2) ;Is this on-line?
SKIPL CFHSTS(T2) ;And up?
IFNSK. ;If not
MOVE T3,T1 ;Return message buffer in T3
RETBAD() ;And tell caller
ENDIF.
PIOFF
SKIPE CFSSMQ(T2) ;A queue?
IFNSK. ;If so
CALL SENDQ ;Queue it up
PION
RETSKP ;And done
ENDIF.
AOS CFSENT(T2) ;Sent one
;**;[7211] Add 1 line at SCASND+15 CEG 18-Dec-85
AOS CFSSND ;[7211] ADD TO TOTAL SENT
PION
DO.
SETZRO STCRA,(T2) ;Say we are about to send
BLCAL. (SC.SMG,<CFSHST(T2),[F.RTB+F.SPM],[VOTSZB],T1,[CFSPRI],[0],[0]>)
IFNSK.
CAIN T1,SCSNEC ;NOT ENOUGH CREDIT?
IFNSK. ;If so...
MOVE T1,SCBUFF ;YES.
MOVE T2,SCHOST ;RESTORE ARGS
PIOFF
TMNE STCRA,(T2) ;Did credit arrive while we weren't looking?
IFNSK. ;If so
PION
LOOP.
ENDIF.
CALL SENDQ ;Queue it up
PION
ELSE.
MOVE T3,SCBUFF ;Reuturn buffer address in T3
RETBAD() ;Didn't send it
ENDIF.
ENDIF.
ENDDO.
RETSKP ;AND DONE
ENDAS.
SUBTTL Sending Messages -- SENDQ (Maintain send queue)
;Routines to maintain the "send queue"
;Routine to enqueue a send message
; T1/ Address of message
; T2/ local port number
;Returns:
; +1 always
;CALL PIOFF!!!
;messages are queued when an attempt to send them fails due to lack
;of credit.
SENDQ: MOVEM T1,@CFSSQT(T2) ;Put it on
SETZM 0(T1)
MOVEM T1,CFSSQT(T2)
RET ;And done
;Routine to send message from send queue until exhausted or failed
; T1/ Local port
;Returns: +1 always
SSENDQ: SAVEAC <Q1,Q2>
MOVE Q1,T1 ;Copy port
DO.
SKIPN Q2,CFSSMQ(Q1) ;Any more to do?
RET ;No
; PIOFF
MOVE T2,0(Q2) ;Unlink it
MOVEM T2,CFSSMQ(Q1) ;New head
IFE. T2 ;If now empty
XMOVEI T2,CFSSMQ(Q1)
MOVEM T2,CFSSQT(Q1) ;Init it
ENDIF.
; PION
BLCAL. (SC.SMG,<CFSHST(Q1),[F.RTB+F.SPM],[VOTSZB],Q2,[CFSPRI],[0],[0]>)
IFNSK. ;If failed
; PIOFF
MOVE T1,CFSSMQ(Q1) ;Get new head
MOVEM T1,0(Q2) ;Make this one the new head
MOVEM Q2,CFSSMQ(Q1) ;
SKIPN T1 ;Was it empty?
MOVEM Q2,CFSSQT(Q1) ;yes.
; PION
RET ;And done
ENDIF.
LOOP. ;Do them all
ENDDO.
SUBTTL Queuing Message Buffers -- SCARET (Queue packet as message buffer)
;Still IFN CFSSCA
;Routine to return a packet as a message buffer
; T1/ address of buffer
SCARET: MOVE T2,.MHSCI(T1) ;Get local index
SKIPE CFSHST(T2) ;Is this slot in use?
SKIPL CFHSTS(T2) ;Still?
IFNSK. ;If not
MOVE T2,.MHDCI(T1) ;Get return address
CALLRET 0(T2) ;Return it
ENDIF.
BLCAL. (SC.RMG,<CFSHST(T2),[1],T1>)
NOP ;JUST IN CASE
RET
SUBTTL Declare a listener -- CFSLSN (Declare CFS listener)
;Routine to declare a CFS listener.
;Returns:
; +1 failed
; T1=0 if no more host slots
; T1<>0 if some SCA error
;Call with CFS interlock set, please
CFSLSN: SAVEQ
PIOFF
MOVSI T1,-HSTSIZ ;SIZE OF HOST TABLE
DO. ;LOOP TO FIND FREE SLOT
SKIPE CFSHST(T1) ;FOUND ONE?
IFSKP. ;IF SO
SETOM CFSHST(T1) ;MARK WE ARE LISTENING ON THIS PORT
SETZM CFHSTS(T1) ;INIT status
PION
HRRZ Q1,T1 ;GET INDEX
BLCAL. (SC.LIS,<<.,LISNAM>,<.,LISNAM>,[-1],<.,CFSSTS>,Q1,[SCRDIT],[RCRDIT]>)
IFNSK.
SETZM CFSHST(Q1) ;AN ERROR. NO LONGER LISTENING
BUG. (HLT,CFLISF,CFSSRV,SOFT,<CFSSRV - SC.LIS failed>,<<T1,ERR>>,<
Cause: The call to SC.LIS failed.
Data: ERR - Error code returned by SC.LIS
>)
RET ;BAD
ENDIF.
MOVEM T1,CFSHNM(Q1) ;STASH I.D. HERE FOR NOW
RETSKP ;AND SUCCEED
ENDIF.
AOBJN T1,TOP. ;TRY THE NEXT
PION
ENDDO. ;END OF LOOP ON CFSHST
CALLRET RETZ ;NONE TO BE FOUND
SUBTTL Connection Management -- CHKOLD (Manage connect serial number)
;Routine to manage the connect serial number data base. CFS keeps track
;of all systems it has ever been connected to so it may prevent illegal
;reconnects.
; CALL CHKOLD
;T1/ Serial number to check
;T2/ Old/ New flag
;Returns: +1 we've never been connected
; +2 we have been
CHKOLD: SAVEP ;Get some work regs
CAIE T2,OF%OLD ;Does it think we are old?
TDZA T2,T2 ;No
MOVX T2,1B0
MOVSI P1,-HSTSIZ ;Size of the table
MOVE P2,OLDTAB ;The address of the table
DO. ;Scan it
SKIPE P3,0(P2) ;Look at this one
TDZ P3,T2 ;Do operation of delay bit
CAME P3,T1 ;Is it the one?
SKIPA
RETSKP ;Yep
ADDI P2,1 ;Next slot
AOBJN P1,TOP. ;Look at them all
ENDDO.
RET ;And say it's new
SUBTTL Connection Management -- CHKOL0 (Generate old/new bit)
;Routine to generate old/new bit
; CALL CHKOL0
; T1/ serial number to look for
;Returns: +1 T1/ old/new bit
CHKOL0: SAVEAC<Q1>
MOVEI T2,HSTSIZ
MOVE T3,OLDTAB
MOVE T4,T1 ;Copy serial number
DO.
SKIPN Q1,0(T3) ;Get next
IFSKP. ;If here
TXZ Q1,1B0 ;Ignore this for now
CAME Q1,T4 ;Is it the one we want
ANSKP. ;If so
SKIPL 0(T3) ;Delay or old?
SKIPA T1,[OF%OLD] ;Old
MOVX T1,OF%DLY ;Delayed
RET
ENDIF.
ADDI T3,1 ;Next
SOJG T2,TOP.
ENDDO.
MOVX T1,OF%NEW
RET
SUBTTL Connection Management -- PUTOLD (Install serial number)
;Routine to install a serial number.
; T2/ the number to install
;Returns: +1 always
PUTOLD: SAVEP ;Get some work regs
MOVSI P1,-HSTSIZ ;Size of the table
MOVE P2,OLDTAB ;The address of the table
DO. ;Scan it
SKIPN P4,0(P2) ;Look at this one
IFSKP. ;If occupied
TXZ P4,1B0 ;Turn off delay bit
CAMN T2,P4 ;Is it what we want?
IFNSK. ;If so
MOVE P3,P2 ;Save the index
EXIT. ;And reinstall it
ENDIF.
ELSE. ;If empty
MOVE P3,P2 ;Save the slot
ENDIF.
ADDI P2,1 ;Next slot
AOBJN P1,TOP. ;Look at them all
ENDDO.
IFN DEBUG,<
; SKIPE DLYFLG ;Only do it if flag is set
> ;IFN DEBUG
TXO T2,1B0 ;Say this is under delay
MOVEM T2,0(P3) ;It is new. Store it
RET ;And say it's new
SUBTTL Connection Management -- CLRDLY (Clear delay bit in OLDTAB entries)
;Routine to clear delay bit in OLD table entries
CLRDLY: MOVEI T1,HSTSIZ ;The size
MOVE T2,OLDTAB ;The table
MOVX T3,1B0 ;The bit to clear
DO.
ANDCAM T3,0(T2) ;Clear it
ADDI T2,1 ;Next entry
SOJG T1,TOP. ;Do them all
ENDDO.
RET
SUBTTL Connection Management -- CHKDLY (Check for delayed entries)
;Routine to check if any delayed entries are still in OLDTAB
; CALL CHKDLY
; T1/ Entry to remove
;Returns: +1 Always. DLYLOK cleared if none left
;All regs preserved
CHKDLY: SAVET
SAVEAC <Q1>
MOVEI Q1,HSTSIZ ;Size of the table
MOVE T2,OLDTAB
SETZM T4 ;Assume none here
DO.
SKIPGE T3,0(T2) ;Delay?
IFNSK. ;If so
TXZ T3,1B0 ;Turn off bit
CAME T3,T1 ;Is it the one we want?
AOSA T4 ;No. Say not clear yet
SETZM 0(T2) ;Yes. Clear it
ENDIF.
ADDI T2,1 ;Next entry
SOJG Q1,TOP. ;Check it all out
SKIPN T4 ;Found any?
SETZM DLYLOK ;No, all clear!
ENDDO.
RET
> ;IFN CFSSCA
SUBTTL Directory lock resource manager -- CFSLDR (Lock directory)
;Directory lock support routines. These routines are used by
;DIRECT to lock and maintain directory lock.
; T1/ Structure number
; T2/ directory number on structure
;Returns:
; +1 always
CFSLDR::STKVAR<STRA,<ARGS,2>> ;WHERE TO SAVE ARGS
MOVEM T1,STRA ;Save structure number
CALL GNAME ;Get str name
TXO T2,DRBASE
DMOVEM T1,ARGS
CSKED
CFSLOK
CALL HSHLOK ;SEE IF WE HAVE IT YET
JRST CFSDLN ;NOPE.
JN <HSHWVT,HSHCNT>,(T1),CFSDLN ;If in use or voting, do vote
INCR HSHCNT,(T1) ;NOT IN USE. GRAB IT
MOVE T3,FORKX
STOR T3,HSHFRK,(T1) ;Store new owner
MOVE T3,TODCLK ;GET NOW
MOVEM T3,HSHTIM(T1) ;STORE NOW
CALLRET CFSFAL ;SUCCEED
;Here if we can't seize it
CFSDLN: CFSULK
CFSDL0: CALL CFSSPL ;GET A REQUEST BLOCK
IFNSK. ;If can't
CALL CFSDM0 ;Release some
JRST CFSDL0 ;And try again
ENDIF.
;..
;Fill in the request block to ask for the resource
DMOVE T2,ARGS
DMOVEM T2,HSHROT(T1) ;STORE LOCK VALUES
MOVEI T2,.HTOEX ;NEED EXL
STOR T2,HSHTYP,(T1) ;STORE IT
MOVX T2,DRBASE
MOVEM T2,HSHCOD(T1) ;THE UNIQUE CODE FOR THIS
MOVE T3,TODCLK ;Now
ADDI T3,DIRTIM ;Keep it for a bit
MOVEM T3,HSHFCT(T1) ;Stash it
MOVE T3,STRA ;Get original str number
CALL CFSGTT
CALL ILLGET
SKIPE T1 ;SUCCEEDED
CALL @HSHRET(T1) ;DIDN'T NEED OUR BLOCK
RET ;AND DONE
;No space to request the thing.
CFSDM0: CALLRET SBLOCK ;Use standard routine
SUBTTL Directory lock resource manager -- CFSRDR (Unlock directory)
;Routine to unlock a directory.
; T1/ Structure number
; T2/ directory number
;Returns:
; +1 did a resched
; +2 no resched
CFSRDR::CALL GNAME
TXO T2,DRBASE
SETZM T3
CALL CFSNDO ;RELEASE IT
IFNSK. ;If can't
BUG.(CHK,DIRDNL,CFSSRV,SOFT,<CFSSRV - Directory not locked>,,<
Cause: CFSRDR was called to unlock a directory, but the directory is not
locked.
>)
RET ;Wasn't locked!
ENDIF.
ECSKED
RET ;AND DONE
SUBTTL Directory lock resource manager -- CFSDAU (Acquire allocation entry)
;Directory allocation support routines. These routines create and
;maintain resources representing the allocation of directories.
;
;Acquire allocation entry
; T1/ Str # or resource node address
; T2/ Dir # or 0
; T3/ Flags,,Operation
; .CFAGT==:0 ;Get and lock current allocation
; .CFAST==:1 ;Store allocation
; .CFARL==:2 ;Release allocation table
; .CFARM==:3 ;remove entry
; .CFAUP==:4 ;Undo hold bit
; .CFAFD==:5 ; Find it
; T4/ Current allocation or -1 if none to set
; Returned allocation in T1
;return resource address in T2 is called without this
; T3/ transaction number if new block allocated
CFSDAU::ASUBR <STRN0,DIRN,ACCESS,ALLC>
HRRZS T3
CAILE T3,.CFAFD ;Still?
BUG.(HLT,CFBAFN,CFSSRV,SOFT,<CFSSRV - Bad function to CFSDAU>,,<
Cause: CFSDAU was called with an invalid function.
Action: Find the caller in the dump and try to determine why it passed a
bad function code to CFSDAU.
>)
SAVEQ ;Work regs
JRST @[IFIW!CFAGET ;Lock allocation entry and get value
IFIW!CFASTO ;Store new value and unlock
IFIW!CFAULK ;Unlock table
IFIW!CFAREM ;Remove entry
IFIW!CFAUPB ;Undo hold bit
IFIW!CFAFND](T3) ;Find
SUBTTL Directory lock resource manager -- CFAFND/CFAGET (Find/Get allocation table)
;Lock allocation table
CFAFND: TDZA T4,T4
CFAGET: MOVEI T4,1
SAVEAC<P1,P2>
MOVE P2,T4
SETZM P1
CFAG00: MOVEI Q3,.HTOEX ;Assume exclusive
TMNN CF%HLD,ACCESS ;Need it held?
MOVEI Q3,.HTOAD ;No. Share it then
CALL GETDBK
IFNSK. ;If not here...
SKIPE T2,P2 ;If finding...
AOJA P1,CFSDAO ;Go to it if not
CALLRET CFSFAL ;Fail otherwise
ENDIF.
IFNDEF CFSDUM,< ;Only if we are a real CFS node
TMNN CF%PRM,ACCESS ;Want it held?
IFSKP.
SETONE HSHKPH,(T1) ;Hold it here
ENDIF.
TMNE <HSHTWF,HSHWVT,HSHUGD>,(T1) ;Anybody else doing this?
IFNSK. ;If so
MOVE T2,T1 ;Copy address
MOVEI T1,CFGVOT ;Wait for a bit
CFSULK
CALL CFSWUP ;""
AOJA P1,CFAG00
ENDIF.
LOAD T2,HSHTYP,(T1) ;Get the type
CAMGE T2,Q3 ;Is it all set for us?
IFNSK. ;If not
;Here when the access is not correct
SETONE HSHTWF,(T1) ;Prevent tampering from others
MOVEI T3,0(Q3) ;Get access desired
MOVE Q1,T1 ;Save block address
DMOVE T1,HSHROT(T1) ;Get lookup stuff
AOS P1
CALL CFSUGD ;Do the upgrade
IFNSK.
SETZRO HSHTWF,(Q1) ;No longer need this
MOVEI T1,CFSRWT ;Wait a bit
MOVE T2,Q1 ;The block
SKIPN T3,HSHWTM(Q1) ;Got a wait time?
MOVEI T3,^D500 ;No invent one
ADD T3,TODCLK ;When to retry
MOVEM T3,HSHTIM(Q1)
CALL CFSWUP ;Wait a bit
DMOVE T1,Q1
JRST CFAG00 ;And do it again
ENDIF.
CFSLOK
SETZRO HSHTWF,(Q1) ;Not blocked anymore
MOVE T1,Q1
ELSE.
INCR HSHCNT,(T1) ;Yes.
ENDIF.
TMNE CF%HLD,ACCESS ;Want it held?
IFSKP. ;If not
DECR HSHCNT,(T1) ;So don't
ENDIF.
> ;IFNDEF CFSDUM
MOVE T2,FORKX ;Fork
STOR T2,HSHFRK,(T1)
MOVE T2,T1 ;Resource address
MOVE T3,HSHOP1(T1) ;Get resource count as well
MOVE T1,HSHOPT(T1) ;Get last value of allocation
CFSULK
JUMPE P1,RSKP ;If no resched, say so
RET ;And done, with a resched
;Here if we must vote
CFSDAO: CALL CFSSPC ;Get some space
IFNSK. ;If failed
CALL CFSDM0 ;Standard recovery
JRST CFAG00 ;Try again
ENDIF.
DMOVEM Q1,HSHROT(T1) ;Store indentifier
STOR Q3,HSHTYP,(T1) ;Store type needed
TMNN CF%PRM,ACCESS ;Want it held?
IFSKP.
SETONE HSHKPH,(T1) ;Keep this
ENDIF.
SETZM HSHOPT(T1) ;No optional data yet
SETZM HSHOP1(T1) ;No transaction number yet
XMOVEI T2,CFAVOK ;When we are to approve a vote
MOVEM T2,HSHOKV(T1) ;Call us here
XMOVEI T2,CFADAR ;When we get some optional data
MOVEM T2,HSHCDA(T1) ;Call us here
XMOVEI T2,CFARMV ;Disallow allocations
MOVEM T2,HSHPST(T1) ;Don't allow release
MOVE T3,STRN0 ;Get structure number
CALL CFSGTT
CALL ILLGET
SKIPE T1 ;Did we use this?
CALL @HSHRET(T1) ;No. Return it then
CFSLOK ;Lock it
DMOVE T1,Q1
CALL HSHLOK ;Find the entry
BUG.(HLT,CFSNAF,CFSSRV,SOFT,<Allocation entry not found>,,<
Cause: An allocation entry has just been created and CFSSRV can't find
it in the hash table.
>)
TMNE CF%HLD,ACCESS ;Want it held?
IFSKP. ;if not
DECR HSHCNT,(T1) ;Get rid of it
ENDIF.
SKIPE T3,HSHOP1(T1) ;Anything in here?
IFNSK. ;If so
MOVE T2,T1 ;Get resource address
MOVE T1,HSHOPT(T1) ;Get it
ELSE. ;If not
MOVE T2,ALLC ;Get new value
MOVEM T2,HSHOPT(T1) ;Stash
TMNN CF%NUL,ACCESS ;Is the value valid?
AOS HSHOP1(T1) ;Say we've been here
EXCH T1,T2
ENDIF.
CALLRET CFSFAL ;And done (we did a resched if we got here)
SUBTTL Directory lock resource manager -- CFASTO (Store new allocation value)
;CFSDAU continued.
;CFASTO - Store new value
CFASTO: CALL GETDBK ;Get block address
CFABUG: BUG.(HLT,CFANAE,CFSSRV,SOFT,<CFSSRV - No allocation entry>,,<
Cause: The caller wanted to update a directory allocation entry, and
no such entry could be found
>)
MOVE T2,ALLC ;Get the value
MOVEM T2,HSHOPT(T1) ;Stash it
AOS HSHOP1(T1) ;And make this transaction current
CFSULK ;Unlock it
DMOVE T1,Q1
; CALLRET CFAULK ;And release it
SUBTTL Directory lock resource manager -- CFAULK (Unlock allocation entry)
;Unlock allocation entry
CFAULK: CALL GETDBK ;Get block address
CALL CFABUG
CFSULK
DMOVE T1,HSHROT(T1)
CALLRET CFSNDO ;Do it
SUBTTL Directory lock resource manager -- CFAREM (Remove allocation entry)
;Remove entry
CFAREM: CALL GETDBK ;Find the block
CALL CFABUG ;Bad!
LOAD T2,HSHCNT,(T1) ;Get current share count
SOSG T2 ;Should we do it?
IFSKP. ;If not
STOR T2,HSHCNT,(T1) ;Store new value
ELSE.
CALL CFSRMV ;remove the entry
ENDIF.
CALLRET CFSRSK ;And done
SUBTTL Directory lock resource manager -- CFAUPB (Undo keep here bit)
;Undo "keep here" bit
CFAUPB: CALL GETDBK ;Find it
CALL CFABUG ;Oops
SETZRO HSHKPH,(T1) ;Clear this
CFSULK
DMOVE T1,HSHROT(T1) ;Get lookup values
CALL CFSNDO
NOP
RET
SUBTTL Directory lock resource manager -- CFAVOK (Vote to be approved)
IFNDEF CFSDUM,< ;If doing CFS for real
;CFAULK stuff continued.
; Interrupt level support routines
;CFAVOK - Called when vote is to be approved
; T1/ vote packet
; T2/ hash packet
CFAVOK: DMOVE T3,HSHOPT(T2) ;Yes, get the stuff
DMOVEM T3,CFDAT(T1) ;Store it
SETONE CFODA,(T1) ;Say we put something here
RET ;And done
SUBTTL Directory lock resource manager -- CFADAR (Optional data present)
;Here when optional data arrives on a vote
; T1/ Hash packet
; Q1/ Vote pakcet
CFADAR: SKIPE T2,CFDT1(Q1) ;has he anything to say?
CAMG T2,HSHOP1(T1) ;A later transaction?
RET ;No
RETSKP ;yes.
SUBTTL Directory lock resource manager -- CFARMV (Voter remove entry)
;here when entry is to be removed by voter
CFARMV: JE HSHKPH,(T1),R ;If not holding, remove it
SETZRO HSHTYP,(T1) ;If holding, turn it into a place-holder
RETSKP ;And allow access
> ;IFNDEF CFSDUM
IFDEF CFSDUM,< ;If not doing CFS for real
CFADAR:
CFARMV:
CFAVOK: RET ;Dummies
> ;IFDEF CFSDUM
SUBTTL Directory lock resource manager -- GETDBK (Find resource block)
;CFSDAU continued
;Utility to find resource block
;Args in ASUBR on the stack
;Returns: +1 not found. Q1, Q2 with names
; +2 T1/ block. CFS lock locked
GETDBK: CFSLOK ;Lock it up
MOVE T1,STRN0 ;Get str number
SKIPN T2,DIRN ;Name or address
RETSKP ;Address
CALL GNAME ;Get its name
MOVE T2,DIRN ;Get directory number
TXO T2,DRBAS0
DMOVE Q1,T1 ;Save names
CALL HSHLOK
JRST CFSFAL ;Not there
RETSKP ;Found it
ENDAS.
SUBTTL File open resource manager -- CFSGFA (Acquire file opening locks)
;Routine to acquire file locks on "first opening".
;Called from GETCFL in PAGUTL.
;
; T1/ STR #
; T2/ XB address
; T3/ Access type - either: .CFOPT - Open thawed (full sharing)
; .CFOPF - Open frozen
; .CFOPR - Restricted
; .CFOPP - Promiscuous (unrestricted)
; .CFOLE - DUD
IFNDEF CFSDUM,< ;If CFS
CFSGFA::SAVEQ
STKVAR <ACCESS>
MOVE T3,[.HTOAD ;Full sharing
.HTOSH ;Read-only sharing
.HTOEX ;Exclusive
.HTOPM ;Promiscuous
1B0!.HTOEX](T3) ;Local exclusive
DMOVE Q1,T1 ;COPY ARGS
MOVEM T3,ACCESS
CALL GNAME
CFSLOK
CALL HSHLOK ;Look 'er up
IFSKP. ;If here
MOVE Q3,T1 ;Save block address
DMOVE T1,HSHROT(T1) ;Get root and qualifier
MOVE T3,ACCESS ;new access
CALL CFSUGD ;Change it
RETBAD() ;No way
; DECR HSHCNT,(Q3) ;Discount extra sharer
RETSKP ;Made it
ENDIF.
CFSULK
CALL CFSSPC ;GET SOME SPACE
IFNSK.
MOVEI T1,^D30000 ;PICK UP STALE RESOURCES
MOVEI T2,10 ;JUST DO SOME
CALL CFSRSX ;FREE UP SOME
CALL CFSSPC ;TRY AGAIN
RETBAD() ;NOPE
ENDIF.
MOVE Q3,T1 ;COPY BLOCK
MOVE T2,ACCESS ;Desired access
STOR T2,HSHTYP,(T1) ;Stash it
IFL. T2 ;If want local exclusive
SETONE HSHLCL,(T1) ;Set it
ENDIF.
MOVEM Q2,HSHQAL(T1)
MOVE T2,Q1 ;STR #
CALL GNAME2
MOVEM T2,HSHROT(T1)
MOVE T3,Q1 ;Copy structure #
CALLRET CFSFCA ;DO COMMON ACQUISITION CODE
> ;IFNDEF CFSDUM
SUBTTL File open resource manager -- CFSFFL (Release file locks)
;Release file locks
;T1/ STR #
;T2/ XB address
;Returns: +1 always
IFNDEF CFSDUM,<
CFSFFL::CALL GNAME
CALL CFSNDO ;FREE IT
NOP
RET
> ;IFNDEF CFSDUM
SUBTTL File open resource manager -- CFSURA (Downgrade to promiscuous)
;Routine to "downgrade" file lock from whatever to promiscuous.
;Called when RELOFN (in PAGEM) detects all "real" openings
;are closed
; T1/ OFN
;Returns: +1 always
IFNDEF CFSDUM,<
CFSURA::SAVET
SAVEAC<Q1>
LOAD T2,STGADR,SPTH(T1) ;Get XB address
LOAD T1,STRX,(T1)
CALL GNAME
CFSLOK
CALL HSHLOK ;Look it up
IFNSK. ;This shouldn't happen
CFSULK
RET
ENDIF.
MOVE Q1,T1
DMOVE T1,HSHROT(T1) ;Get codes
MOVEI T3,.HTOPM ;New mode
CALL CFSUGD ;Do it
CALL CFNCNT
DECR HSHCNT,(Q1)
RET ;And done
> ;IFNDEF CFSDUM
;Versions of above for non-CFS
IFDEF CFSDUM,<
CFSGFA::RETSKP
CFSURA::RET
> ;IFDEF CFSDUM
SUBTTL Frozen writer resource manager -- CFSGWL (Get write access)
;Routine used by PAGEM to acquire the "write access" lock for a fil.
;This "lock" represents the writer for a frozen file.
; T1/ STR #
; T2/ XB address
;Returns:
; +1 failed. Lock owned elsewhere
; +2 success
CFSGWL::
IFDEF CFSDUM,< ;If not a real CFS
RETSKP ;Done
> ;IFDEF CFSDUM
IFNDEF CFSDUM,< ;If real
SAVEQ
DMOVE Q1,T1
CALL CFSSPC ;GET A BLOCK
IFNSK.
SETZM T1
MOVEI T2,10 ;JUST DO SOME
CALL CFSRSX ;FAILED. FREE UP SPACE THEN
CALL CFSSPC ;TRY AGAIN
RETBAD() ;FAILED. NO SPACE
ENDIF.
MOVE T2,Q1 ;STR #
CALL GNAME2
MOVEM T2,HSHROT(T1) ;Stroe it
TXO Q2,FILEWL ;MARK WRITE LOCK WANTED
MOVEM Q2,HSHQAL(T1) ;Store the qualifier
MOVEI T2,.HTOEX ;EXCLUSIVE
STOR T2,HSHTYP,(T1)
MOVE T3,Q1 ;Copy str #
;CALLRET CFSFCA
;Pseudo-routine to acquire a file resource
CFSFCA: SETZM T2 ;NO RETRY
CALL CFSGTT
RETBAD() ; It didn't
SKIPE T1 ;NEED TO RETURN THE BLOCK?
CALL @HSHRET(T1) ;YES
RETSKP ;AND DONE
> ;IFNDEF CFSDUM
SUBTTL Frozen writer resource manager -- CFSFWL (Free write access)
;Free CFS file write lock
;T1/ STR #
;T2/ XB address
;Returns:
; +1 always
IFNDEF CFSDUM,<
CFSFWL::TXO T2,FILEWL ;UNQ
CALL GNAME
CALL CFSNDO ;RELEASE IT
NOP
RET
> ;IFNDEF CFSDUM
;Versions of above for non-CFS
IFDEF CFSDUM,<
CFSFFL::
CFSFWL::RET
> ;IFDEF CFSDUM
;LOCAL ROUTINE TO CLEAN UP RESOURCES AND WAIT A LITTLE BIT
SBLOCK: SETZM T1 ;Desparation. Get a bunch
MOVEI T2,CLCCNT ;Count to collect
CALL CFSRSX
MOVE T1,TODCLK
ANDI T1,377777
ADDI T1,^D300 ;SHORT SLEEP
MOVSS T1
HRRI T1,BLOCKW ;THE TEST
CALL CFSWUP ;WAIT
RET ;AND DONE
SUBTTL BAT block resource manager -- CFGBBS (Set BAT block lock)
;Routines to get and release BAT block locks.
;Get lock
; T1/ Structure number
; Returns: +1 always
IFNDEF CFSDUM,< ;If CFS
CFGBBS::ASUBR<STRNO>
CFGBB0: CALL CFSSPC ;GET SOME SPACE
IFNSK.
CALL SBLOCK ;WAIT A BIT
JRST CFGBB0 ;TRY AGAIN
ENDIF.
MOVE T2,STRNO
SETOM HSHQAL(T1) ;BAT BLOCK CODE
CALL GNAME2
MOVEM T2,HSHROT(T1)
MOVEI T2,.HTOEX ;NEED EXCLUSIVE ACCESS
STOR T2,HSHTYP,(T1) ;STASH IT
MOVE T3,STRNO
MOVE T3,STRTAB(T3)
LOAD T3,STEXL,(T3)
CALL @[ IFIW!CFSGET
IFIW!CFSGTL](T3)
CALL ILLGET
SKIPE T1 ;WANT IT RELEASED?
CALL @HSHRET(T1) ;YES
RET ;DONE
ENDAS.
SUBTTL BAT block resource manager -- CFFBBS (Release BAT block lock)
;Release BAT block lock
; T1/ Str number
; Returns: +1 always
CFFBBS::CALL GNAME
SETOM T2
CALL CFSNDO
NOP ;Who cares?
RET ;And done
> ;IFNDEF CFSDUM
;Versions of above for non-CFS
IFDEF CFSDUM,<
CFFBBS::
CFGBBS::RET
> ;IFDEF CFSDUM
SUBTTL File access token resource manager -- CFSGWT (Get write token value)
;Routines to manage the "write token".
;Fetch current value of token
; T1/ OFN
;Returns:
; +1 not here or in use. T1=0= not here. If here, T2/ 0 or 1
; +2 T1/ 0 or 1
;Called NOSKED!!!
CFSGWT::LOAD T2,STGADR,SPTH(T1) ;GET XB
TXO T2,FILEWT
LOAD T1,STRX,(T1)
CALL GNAME
CFSLOK
CALL HSHLOK ;LOOK 'ER UP
JRST [ CFSULK
JRST RETZ]
MOVE T2,TODCLK ;GET NOW
MOVEM T2,HSHTIM(T1) ;STAMP IT
LOAD T2,HSHCNT,(T1)
LOAD T1,HSHTYP,(T1) ;GET TYPE
JUMPE T1,[ CFSULK ;If a place-holder
JRST RETZ] ; Treat as if not here
CAIE T1,.HTOEX ;EXCLUSIVE?
TDZA T1,T1 ;No.
MOVEI T1,1 ;Yes
CFSULK
IFG. T2
MOVE T2,T1 ;GET ACCESS TYPE
JRST RETO ;AND DONE
ENDIF.
RETSKP ;AND DONE
SUBTTL File access token resource manager -- CFSAWP/CFSAWT (Acquire write token)
;Routine to acquire the proper "write token".
; T1/ OFN
; T2/ type needed
; 0=) shared, <>0=) exclusive
;Returns: +1 always
;Called NOSKED
;CFSAWP - reserve to this processor
;CFSAWT - don't reserve to this processor
CFSAWP::TDZA T3,T3 ;LEAVE IT LOCKED
CFSAWT::MOVEI T3,1 ;UNLOCK WHEN DONE
TMNE OFNDMO,SPTH(T1)
RET ;If dismounted, let it go
;**;[7247] Add 11 lines after CFSAWT::+2 DML 19-Feb-86
CAIGE T1,NOFN ;[7247] Is the OFN in range?
TLNE T1,-1 ;[7247] And is it positioned correctly?
BUG.(HLT,CFSION,CFSSRV,SOFT,<CFSSRV - Invalid OFN number>,,<
Cause: CFSAWT or CFSAWP has been called with an invalid OFN number.
These routines expect the OFN number to be in the right half
of T1 and to be in the expected range of values.
Action: Find the caller in the dump and try to determine why it
passed a bad OFN number.
>) ;[7247] No, report error
SAVEP5 ;REGS
STKVAR <WTFLAG,LKFLAG>
MOVEM T3,LKFLAG ;Save the flag
SKIPE T2 ;Check what kind we need
SKIPA T2,[.HTOEX] ;Exclusive
MOVEI T2,.HTOAD ;Full read-share
DMOVE P1,T1 ;SAVE OFN and access type
IFNDEF CFSDUM,< ;If a real CFS monitor, do this as well
CFSAWL:
DO.
LOAD T1,STRX,(P1) ;GET STR NAME
CFSLOK
TMNE SPTFO,(P1) ;Being forced out?
SKIPGE DDPFRK ;Is this not DDMP
IFSKP. ;If so
MOVS T1,P1 ;Get OFN
HRRI T1,WTFOD ;wait here a bit
CFSULK
CALL CFSWUP ;Wait here
LOOP. ;Try again
ENDIF.
ENDDO.
MOVE T2,CFSOFN ;Get OFN table address
ADDI T2,0(P1) ;See if we know about this one yet
;**;[7247] Replace 5 lines with 6 at CFSAWL:+16 DML 19-Feb-86
SKIPN T1,0(T2) ;[7247] Do we?
JRST CFSAW1 ;[7247] Go on if not around
;[7247] Continue here if the block already exists or is cached and being reused
CFSAWH: ;[7247]
IFN DEBUG,<
HRRZ T2,P1 ;Isolate OFN
CAME T2,HSHCOD(T1) ;Quick check for consistency
BUG.(HLT,CFSBTP,CFSSRV,SOFT,<CFSSRV - Bad token packet>,,<
Cause: CFSAWT has been called to acquire an access token for an OFN.
The OFN access token already exists on this system and the
block address is in CFSOFN. But the OFN recorded in the
block does not match the one passed into CFSAWT.
>)
> ;IFN DEBUG
;**;[7247] Change 1 line at CFSAWH:+11 DML 19-Feb-86
SKIPG HSHPST(T1) ;[7247] This one in use and good?
IFNSK. ;If not
XMOVEI T2,CFSDWT ;Where to do it
MOVEM T2,HSHPST(T1) ;Fix it up (make it a usable block)
ENDIF.
MOVE P5,T1 ;Save pointer
INCR HSHLKF,(P5) ;Lock it
CFSUGX: TMNE <HSHTWF,HSHUGD,HSHWVT>,(P5) ;Waiting for it somewhere else?
IFNSK.
CFSULK
MOVEI T1,CFGVOT ;And wait for vote to complete
SETOM WTFLAG ;We didn't set HSHTWF
JRST CFSUGW ;And wait a bit
ENDIF.
LOAD T3,HSHTYP,(P5) ;Get type we now hold
LOAD T1,STRX,(P1) ;Get STR #
MOVE T1,STRTAB(T1) ;Get SDB
TMNE STEXL,(T1) ;Is this exclusive?
IFNSK. ;If so
MOVEI T3,.HTOEX ;Upgrade it now to the maximum
STOR T3,HSHTYP,(P5) ;And store it
ENDIF.
CAIN T3,.HTOEX ;Do we hold exclusive rights?
IFNSK. ;If so
REPEAT 0,< ;Not using anti-hog device now
TMNN HSHRFF,(P5) ;Someone waiting?
IFSKP. ;If so
MOVE T1,HSHTIM(P5) ;Get last transition time
ADDI T1,MAXHLT ;Get constraint
CAML T1,TODCLK ;Held it too long?
IFSKP. ;If so
SETONE HSHTWF,(P5) ;lock it
SETZM WTFLAG ;Say we did it
MOVEI T1,CFSRWT ;Just stall a bit
CFSULK
JRST CFSUGW ;Do it
ENDIF.
ENDIF.
> ;REPEAT 0
DECR HSHLKF,(P5)
MOVEI P2,0(T3) ;Copy type
SKIPE LKFLAG ;Check the lock flag
JRST RTYPE ;All set. Finish up
INCR HSHCNT,(P5) ;If hold do it
JRST RTYPE ;And set the state
ENDIF.
;Found the entry. See if we can upgrade it
SETONE HSHTWF,(P5) ;Set flag to prevent others from getting in
SETZM WTFLAG
DMOVE T1,HSHROT(P5) ;CODES
MOVEI T3,0(P2) ;MUST WANT EXCLUSIVE
LOAD T4,HSHTYP,(P5) ;Save state we have it in now
CALL CFSUGD ;Must call with the interlock set!!!
IFSKP.
CFSLOK
SETZRO <HSHRFF,HSHTWF>,(P5)
MOVE T1,TODCLK ;Get now
ADDI T1,WRTTIM ;fairness time
SKIPN P4 ;Update only if we just seized it
MOVEM T1,HSHFCT(P5)
DECR HSHLKF,(P5)
SKIPN LKFLAG ;Want to hold?
IFSKP. ;If not
TMNN HSHCNT,(P5) ;Any count?
CALL CFNCNT ;No!
DECR HSHCNT,(P5) ; release the hold
ENDIF.
TMNN HSHCNT,(P5) ;is it still locked here?
SKIPN HSHNBT(P5) ;If no, anyone to notify?
IFSKP. ;If so
MOVE T1,P5 ;Copy address
CALL CFNOHS ;Notify anyone rejected in the interim
ENDIF.
TMNE HSHODA,(P5) ;Any optional data?
IFNSK. ;If so,
MOVE T2,HSHOPT(P5) ;Get it
; SKIPE HSHOP1(P5) ;Store only if from the owner
MOVEM T2,OFNLEN(P1) ;Update length information
SETZRO HSHODA,(P5) ;And no longer valid
ENDIF.
JRST RTYPE ;And go set the state
ENDIF.
SETZRO HSHTWF,(P5) ;Clear it now
SETOM WTFLAG ;And say we didn't set it
MOVEI T1,CFSRWT ;Do this one if here
SKIPE T2,HSHWTM(P5) ;gave us a time to wait?
IFNSK. ;If so
CAIGE T2,^D20 ;Wait at least this long
MOVEI T2,^D20 ;""
SKIPA
ENDIF.
; ..
;Here when couldn't upgrade an entry
CFSUGW: MOVEI T2,^D500 ;Wait a long time if here (we should be
; notified via the "undo" when to try again
ADD T2,TODCLK ;Wait time
MOVEM T2,HSHTIM(P5)
MOVE T2,P5 ;Block address
CALL CFSWUP ;Do the wait
CFSLOK ;Lock 'er up
SKIPN WTFLAG ;Did we set the wait flag?
IFNSK. ;If so
SETZRO HSHTWF,(P5)
ENDIF.
;**;[7247] Change 1 line at CFSUGW:+11 DML 19-Feb-86
SKIPLE HSHPST(P5) ;[7247] Has it been released or uncached?
IFNSK. ;If not
SETZRO <HSHRTY,HSHVRS>,(P5)
DECR HSHLKF,(P5) ;No longer need this lock
CFSULK ;Don't need this now
JRST CFSAWL ;And go to the top
ENDIF.
LOAD T1,HSHLKF,(P5) ;Get lock value
SOSE T1 ;Are we the last?
IFNSK. ;If not
STOR T1,HSHLKF,(P5) ;Replace it
JRST CFSFAL
ENDIF.
MOVE T1,HSHCOD(P5) ;Get the OFN
ADD T1,CFSOFN ;Point to OFN table entry
SETZM 0(T1) ;Clear it
;**;[7247] Replace 2 lines with 25 at CFGVOT:-6 DML 19-Feb-86
;[7247] Here when a call was made to CFSUWT or CFSUNC while block was locked
SKIPL HSHPST(P5) ;[7247] Was a token uncache attempted?
IFSKP. ;[7247] Yes
SETZRO HSHTAM,(P5) ;[7247] Uncache just in case it was set
SOS CFACCT ;[7247] Decrement currently cached count
MOVE T1,P5 ;[7247] Get resource block address
CALL CFSRMV ;[7247] (T1/T1,T2)Remove it
CALLRET CFSFAL ;[7247] And return
ENDIF. ;[7247]
;[7247] Here when a call was made to CFSCWT while block was locked
SUB T1,CFSOFN ;[7247] Get OFN back again
TMNN OFNDMO,SPTH(T1) ;[7247] Is it dismounted?
IFSKP. ;[7247] Yes, destroy token
MOVE T1,P5 ;[7247] Get resource block address
CALL CFSRMV ;[7247] (T1/T1,T2)Remove it
ELSE. ;[7247] Not dismounted, cache it
SETZRO <HSHCNT>,(P5) ;[7247] Clear the count but KEEP bit stays set
SETONE HSHTAM,(P5) ;[7247] Set the cache bit
SETZM HSHPST(P5) ;[7247] No more post address
AOS CFACCT ;[7247] Increment the number we currently have
ENDIF. ;[7247]
CALLRET CFSFAL
;test for above
CFGVOT: LOAD T1,FKST2,(Q3)
TMNE <HSHTWF,HSHWVT,HSHUGD>,(T1) ;Still waiting
JRST 0(4) ;Yepper
JRST 1(4) ;No. Try now
;Here to add an entry. Should happen only once in a while
CFSAW1:
LOAD T1,STRX,(P1) ;Get STR #
LOAD T2,STGADR,SPTH(P1) ;Get XB address
IFN DEBUG,< ;Make sure all is OK
SKIPN T2 ;Is it?
BUG. (HLT,CFNLTK,CFSSRV,SOFT,<CFSSRV - Null disk address given to CFSAWT>,,<
Cause: A call was made to create an OFN access token but SPTH for the
OFN is not set up.
>)
> ;IFN DEBUG
TXO T2,FILEWT ;Set token bit
CALL GNAME ;Get the name of the structure
DMOVE P3,T1 ;Save these for later
;**;[7247] Add 27 lines after CFSAW1:+13 DML 19-Feb-86
CALL HSHLOK ;[7247] (T1,T2/T1,T2) Look for the token
IFSKP. ;[7247] Found so this one better be cached
TMNN HSHTAM,(T1) ;[7247] Is it?
BUG.(HLT,CFSTCM,CFSSRV,SOFT,<CFSSRV - Access token cached but not marked>,,<
Cause: A cached access token is being requested. As expected, it
is in the hash table and not in CFSOFN. But HSHTAM is not
set as expected.
>) ;[7247] No, report error
CAME P1,HSHCOD(T1) ;[7247] Is this the same OFN?
BUG.(HLT,CFAOFM,CFSSRV,SOFT,<CFSSRV - OFN mismatch in cached token>,,<
Cause: A cached access token has been found for a certain OFN
but the OFN stored in the hash block does not agree.
>) ;[7247] No, report error
MOVE T2,CFSOFN ;[7247] Get OFN table address
ADDI T2,0(P1) ;[7247] Offset into table for this OFN
MOVEM T1,0(T2) ;[7247] Store token block address in table
SETZRO HSHTAM,(T1) ;[7247] Not cached anymore
SETONE HSHKPH,(T1) ;[7247] No purging this entry
XMOVEI T2,CFSDWT ;[7247] Get correct post address
MOVEM T2,HSHPST(T1) ;[7247] Fix it up (make it a usable block)
SOS CFACCT ;[7247] One less token currently cached
AOS CFACTO ;[7247] One more cache hit
JRST CFSAWH ;[7247] Continue at "found" code
ENDIF. ;[7247]
CFSULK ;[7247] Free CFS lock
DO.
CALL CFSSPC ;GET SOME SPACE
IFSKP. <EXIT.>
CALL CFSDM0 ;Clean up and pause
LOOP.
ENDDO.
DMOVEM P3,HSHROT(T1) ;SAVE CODES
STOR P2,HSHTYP,(T1) ;STASH IT
SETONE HSHKPH,(T1) ;No purging this entry
HRRZM P1,HSHCOD(T1) ;SAVE OFN AS CODE
XMOVEI T2,CFSDWT
MOVE P5,T1 ;Save block address (to get optional data)
MOVEM T2,HSHPST(T1) ;WHERE TO GO WHEN RELEASED
XMOVEI T2,CFSOVT ;Where to go when vote is approved
MOVEM T2,HSHOKV(T1) ;Store it
XMOVEI T2,CFSDAR ;Data arrived
MOVEM T2,HSHCDA(T1) ;Stash it as well
SETZM HSHOP1(T1) ;No transaction number yet
MOVE T3,CFSOFN ;The OFN table
ADDI T3,0(P1) ;Point to this entry
MOVEM T1,0(T3) ;Stash it for others to see
LOAD T3,STRX,(P1) ;Get STR #
MOVE T3,STRTAB(T3) ;Get SDB
LOAD T3,STEXL,(T3) ;Get shared/exclusive bit
CALL @[ IFIW!CFSGET
IFIW!CFSGTL](T3)
CALL ILLGET
MOVE T2,TODCLK ;Get now
ADDI T2,WRTTIM ;"Fairness" time
MOVEM T2,HSHFCT(P5) ;Stash it
TMNE HSHODA,(P5) ;Any optional data?
IFNSK. ;If so,
MOVE T2,HSHOPT(P5) ;Get it
MOVEM T2,OFNLEN(P1) ;Update length information
SETZRO HSHODA,(P5) ;And no longer valid
ELSE.
MOVE T2,OFNLEN(P1) ;Get our value
MOVEM T2,HSHOPT(P5) ;Stash it
AOS HSHOP1(P5) ;And init transaction number
ENDIF.
SKIPE T1
CALL @HSHRET(T1) ;?????
SKIPN LKFLAG ;Hold or no?
IFSKP. ;If no
DMOVE T1,P3 ;CODES
CALL CFSNDO ;RELEASE IT
NOP
ENDIF.
CFSLOK
; ..
> ;IFNDEF CFSDUM
;Here when WT is seized. Set status in SPT
RTYPE: MOVEI P2,0(P2) ;GET ACCESS TYPE
CAIE P2,.HTOEX ;EXCLUSIVE?
SKIPA T1,[.SPSRD] ;NO
MOVEI T1,.SPSWR ;YES
STOR T1,SPTST,(P1)
JRST CFSFAL ;Done
ENDSV.
SUBTTL File access token resource manager -- CFSDWT (Write token revoked)
;HSHPST callback routine
;Here when write token is revoked
;Must queue requesu for background fork to invalidate pages
CFSDWT:
IFNDEF CFSDUM,< ;Only if a full CFS
JE HSHTYP,(T1),RSKP ;If a place-holder, allow it now
MOVE T2,HSHCOD(T1) ;GET OFN
SETONE SPTFR,(T2) ;SAY WE NEED IT FORCED OUT
LOAD T3,HSHTYP,(T1) ;Get the type we own
CAIE T3,.HTOEX ;Exclusive?
IFSKP. ;If so
LOAD T3,HSHVTP,(T1) ;Get type requested
CAIN T3,.HTOEX ;Not exclusive?
ANSKP. ;If so
SETZRO SPTSR,(T2) ;Say so
ENDIF.
AOS DDCFSF ;Get DDMP awake
IDIVI T2,^D36 ;Get the bit for this OFN
MOVE T3,BITS(T3) ;Get the proper bit
IORM T3,OFNCFS(T2) ;Set the bit for DDMP
; SETONE SCDDP ;Make sure
SETZM T1 ;Indicate wait
> ;IFNDEF CFSDUM
RETSKP ;AND DONE
SUBTTL File access token resource manager -- CFSOVT (Approve sharing of OFN resource)
;Here when we will approve the sharing of an OFN resource.
; T1/ vote packet
; T2/ hash packet
;Called from CFSRTV
;Returns: +1 with vote packet updated
;HSHOKV callback
CFSOVT:
IFN CFSSCA,<
SKIPN HSHOP1(T2) ;Anything here?
IFSKP. ;If so
DMOVE T3,HSHOPT(T2) ;Get opt data
DMOVEM T3,CFDAT(T1) ;Yes. Store in vote packet
SETONE CFODA,(T1) ;And say so
ELSE.
SETZM CFDT1(T1)
ENDIF.
TMNE HSHBTF,(T2) ;Is this a bit table OFN?
CALL SNDFRC ;Send the STR free count
> ;IFN CFSSCA
RET ;And done
SUBTTL File access token resource manager -- CFSGOC (Get count of resource sharers)
;Routine to get count of resource sharers.
; T1/ OFN
;Returns: +1 not here
; +2 T1/ count
CFSGOC::
IFNDEF CFSDUM,< ;If CFS
ADD T1,CFSOFN ;Point to entry in table
SKIPN T1,0(T1) ;Here?
IFSKP. ;If so
LOAD T1,HSHCNT,(T1) ;Get count
RETSKP ;Found it
ENDIF.
> ;IFNDEF CFSDUM
RET ;Not here
SUBTTL File access token resource manager -- CFSDAR (Optional data for access token)
;Here when optional data arrives for an access token
; T1/ HSH node
; Q1/ vote packet
;Returns: +1 forget the data
; +2 store it
IFN CFSSCA,<
CFSDAR: TMNN HSHBTF,(T1) ;Is this for a bit table?
IFSKP. ;If so
SKIPN T2,CFDST1(Q1) ;Any STR data?
ANSKP. ;If so
MOVE T3,HSHCOD(T1) ;Get the OFN
LOAD T3,STRX,(T3) ;Get STR #
MOVE T4,T3
ADD T4,CFSSTR ;Get local transaction count
CAMG T2,0(T4) ;Is the new one greater?
ANSKP. ;If so
MOVEM T2,0(T4) ;Update our transaction number
MOVE T4,CFDST0(Q1) ;Get free count
CALL STOFRC ;Store it (T3,T4)
ENDIF.
CALLRET CFADAR ;And done
> ;IFN CFSSCA
SUBTTL File access token resource manager -- CFSFWT (Free write token)
;Routine to free up write token resource
; T1/ The OFN
;Returns:
; +1 always
;**;[7247] Rewrite portions of routine CFSFWT DML 19-Feb-86
CFSFWT::
STKVAR <TROOT,TQAL,TOFN>;[7247]
CFSLOK ;[7247] Lock up the CFS database
IFNDEF CFSDUM,<
MOVEM T1,TOFN ;[7247] Save the OFN
LOAD T2,STGADR,SPTH(T1)
TXO T2,FILEWT
LOAD T1,STRX,(T1)
CALL GNAME
MOVEM T1,TROOT ;[7247] Save the root...
MOVEM T2,TQAL ;[7247] ...and qualifier
CALL CFSNDS ;Free it
NOP
DO. ;[7247]
MOVE T1,TROOT ;[7247] Get root...
MOVE T2,TQAL ;[7247] ...and qualifier
CALL HSHLOK ;[7247] (T1,T2/T1,T2) Find the resource block
IFNSK. ;[7247] Not found
MOVE T2,TOFN ;[7247] Get the OFN again
TMNE OFNCSH,(T2) ;[7247] Is this OFN cached?
BUG.(HLT,CFWTNF,CFSSRV,SOFT,<CFSSRV - Cached OFN not found when freed>,,<
Cause: CFSFWT was called to free the file access token for an OFN and the
OFN is cached. But the call to HSHLOK did not find the resource
block for the file access token. One should be there.
>) ;[7247] Yes so it should be in hash table!
JRST CFSFAL ;[7247] Return success and unlock CFS database
ENDIF. ;[7247]
;[7247] Now we must check to see if the token should be recached or removed.
;[7247] First, the share count must be checked to see if the token is
;[7247] eligible for removal. If the count is 1, and SPTFR is set, then this
;[7247] really is the last sharer of the token. This is because CFSRMX does
;[7247] an INCR of HSHCNT. In this case, CFSFDF is called to notify the other
;[7247] side and then the token is recached or removed. If the share count is
;[7247] 0, then the token is also eligible. Otherwise, no action is taken.
LOAD T2,HSHCNT,(T1) ;[7247] Get number of sharers
SKIPN T2 ;[7247] Are we the last one?
EXIT. ;[7247] Yes, continue below
CAIE T2,1 ;[7247] Is the share count 1?
JRST CFSFAL ;[7247] No, just return now
MOVE T2,TOFN ;[7247] Get the OFN again
TMNN OFNCSH,(T2) ;[7247] Is this OFN cached?
JRST CFSFAL ;[7247] No, just return
TMNN SPTFR,(T2) ;[7247] Someone waiting for us?
JRST CFSFAL ;[7247] No, just return
;[7247] At this point, OFN is cached, share count is 1, and SPTFR is set
MOVE T3,T2 ;[7247] Copy OFN
IDIVI T3,^D36 ;[7247] Compute the word it is in
MOVE T4,BITS(T4) ;[7247] Get the bit
ANDCAM T4,OFNCFS(T3) ;[7247] Zap the bit
MOVE T1,T2 ;[7247] Get back OFN
SETONE SPTFO,(T1) ;[7247] Lock out others
CFSULK ;[7247] Unlock CFS database for a moment
CALL CFSFDF ;[7247] Tell the other system they have it
NOP ;[7247]
CFSLOK ;[7247] Lock up everything again
MOVE T1,TOFN ;[7247] Get the OFN again
SETZRO SPTFO,(T1) ;[7247] Clear the lock
LOOP. ;[7247] Check everything again
ENDDO. ;[7247]
SKIPL HSHPST(T1) ;[7247] Was a token uncache attempted?
IFSKP. ;[7247] Yes
SETZRO HSHTAM,(T1) ;[7247] Uncache just in case it was set
SOS CFACCT ;[7247] Decrement currently cached count
CALL CFSRMV ;[7247] (T1/T1,T2)Remove it
CALLRET CFSFAL ;[7247] And return
ENDIF. ;[7247]
MOVE T2,TOFN ;[7247] Get the OFN again
TMNN OFNCSH,(T2) ;[7247] Is this OFN cached?
IFSKP. ;[7247] Yes - recache the file access token then
ADD T2,CFSOFN ;[7247] Point to OFN table entry
SETZM 0(T2) ;[7247] Clear entry in OFN table
TMNE HSHTAM,(T1) ;[7247] Already cached?
ANSKP. ;[7247] No so re-cache it now
SETZRO <HSHCNT>,(T1);[7247] Clear the count but KEEP bit stays set
SETONE HSHTAM,(T1) ;[7247] Set the cache bit
SETZM HSHPST(T1) ;[7247] No more post address either
AOS CFACCT ;[7247] Increment the count of cached tokens
ENDIF. ;[7247]
> ;IFNDEF CFSDUM
JRST CFSFAL ;[7247] Return success and unlock CFS database
ENDSV. ;[7247]
SUBTTL File access token resource manager -- CFSUWT/CFSCWT (Release/Cache access token)
;[7247] CFSCWT:
;[7247] Routine called when a file is closed to cache the access token
;[7247]
;[7247] CFSUWT:
;[7247] Routine called by INVOFN when a structure is dismounted to destroy
;[7247] the file access token.
;[7247]
;[7247] Both routines expect the following:
; T1/ STR #
; T2/ XB address
;Returns: +1 always
;**;[7247] Replace 4 lines with 12 at CFSUWT::+0 DML 19-Feb-86
IFDEF CFSDUM,< ;[7247]
CFSCWT:: ;[7247]
CFSUWT:: RET ;[7247]
> ;[7247]
IFNDEF CFSDUM,< ;[7247]
CFSCWT::ASUBR <STRN0,XB> ;[7247]
SAVEAC <Q1> ;[7247]
SETZ Q1, ;[7247] Cache the file access token
JRST CFSUW0 ;[7247]
CFSUWT::ASUBR <STRN0,XB> ;[7247]
SAVEAC <Q1> ;[7247]
SETO Q1, ;[7247] Destroy the file access token
CFSUW0: TXO T2,FILEWT ;Access token
CALL GNAME
CFSLOK
CALL HSHLOK ;Look it up
JRST CFSFAL ;Not here
;**;[7247] Add 2 lines after CFSUW0:+4 DML 19-Feb-86
TMNE HSHTAM,(T1) ;[7247] Is this a cached token?
JRST CFSFAL ;[7247] Yes, so don't need to release it
MOVE T2,HSHCOD(T1) ;Get the OFN
TMNE SPTFR,(T2) ;Someone waiting for us?
IFNSK. ;If so
CFSULK
MOVE T3,T2 ;Copy
IDIVI T3,^D36 ;Compute the word it is in
MOVE T4,BITS(T4) ;Get the bit
ANDCAM T4,OFNCFS(T3) ;Zap the bit
MOVE T1,T2
CALL CFSFDF ;Try now
NOP
MOVE T1,STRN0
MOVE T2,XB
JRST CFSUW0 ;And do it again
ENDIF.
PUSH P,T1 ;Save packet
CALL CFNOHS ;Notify any others
POP P,T1
TMNE HSHLKF,(T1) ;Now interlocked?
IFNSK. ;If so
;**;[7247] Replace 2 lines with 3 at CFSUW0:+24 DML 19-Feb-86
SETZRO <HSHTYP,HSHCNT>,(T1) ;[7247] Clear type and count but not KEEP
SKIPL HSHPST(T1) ;[7247] Has an uncache been attemped already?
MOVEM Q1,HSHPST(T1) ;[7247] No, so set release flag in post address
JRST CFSFAL ;And give it up
ENDIF.
MOVE T3,HSHCOD(T1) ;Get OFN again
ADD T3,CFSOFN ;Point to entry in table
SKIPN 0(T3) ;Is one here?
BUG.(HLT,CFSNOT,CFSSRV,SOFT,<CFSSRV - OFN token table and hash table disagree>,,<
Cause: CFSSRV is trying to remove a file access token and has found the
token in the hash table but not in the OFN token table. This indicates
that one of the data bases is incorrect.
>)
SETZM 0(T3) ;Clear entry in OFN table
;**;[7247] Replace 1 line with 13 at CFSNFO::-7 DML 19-Feb-86
SKIPL Q1 ;[7247] Want to cache the token?
IFSKP. ;[7247]
CALL CFSRMV ;[7247] (T1/T1,T2)No, remove it
ELSE. ;[7247] Yes
;[7247] Now cache the token
SETZRO <HSHCNT>,(T1) ;[7247] Clear the count but KEEP bit stays set
SETONE HSHTAM,(T1) ;[7247] Set the cache bit
SKIPL HSHPST(T1) ;[7247] Has an uncache been attemped already?
SETZM HSHPST(T1) ;[7247] No, so clear post address
AOS CFACCT ;[7247] Increment the number we currently have
ENDIF. ;[7247]
JRST CFSFAL ;And done
ENDAS.
> ;IFNDEF CFSDUM
;Here when DDMP failed to do the flush
; T1/ the OFN
CFSNFO::SETONE SCDDP ;Try again
CALLRET SKDRUN ;Make the scheduler run
;Debugging routine called from DASOFN
;This is called when an OFN is being released to see if the file
;access token has been deleted. If not, we will BUGHLT.
; T1/ OFN
CFSCON::
IFDEF CFSDUM,<RET>
IFNDEF CFSDUM,<
SAVEAC<T1> ;Save the OFN
MOVE T2,CFSOFN ;See if it is in the OFN table
ADDI T2,0(T1)
SKIPE 0(T2) ;Is it?
IFSKP. ;If not
LOAD T2,STGADR,SPTH(T1) ;Get XB address
TXO T2,FILEWT
LOAD T1,STRX,(T1) ;Get structure number
CALL GNAME ;Get name
CFSLOK ;Lock it up
;**;[7247] Replace 12 lines with 17 at CFSCON::+15 DML 19-Feb-86
CALL HSHLOK ;[7247] Look it up
IFSKP. ;[7247] It is here!
TMNN HSHTAM,(T1) ;[7247] Is it cached?
CFSCND: BUG.(HLT,CFSTND,CFSSRV,SOFT,<CFSSRV - Access token not deleted>,,<
Cause: CFSCON was called to verify that an access token has been deleted
before an OFN is released. This BUGHLT indicates that the token has
not been deleted or cached.
>) ;[7247] Found but not cached - error!
ENDIF. ;[7247]
CFSULK ;[7247] All is ok - free the lock
RET ;[7247] And done
ENDIF. ;[7247]
TMNN OFNCSH,(T1) ;[7247] Not deleted - is this OFN cached?
JRST CFSCND ;[7247] No - error!
RET ;[7247] Yes, so it is ok
> ;IFNDEF CFSDUM
SUBTTL File access token resource manager -- CFSUNC (Uncache token)
;**;[7247] Add routine CFSUNC DML 19-Feb-86
;[7247] Routine called when an OFN is being deleted and the access token
;[7247] should be uncached. This is called from DASOFN.
;[7247]
;[7247] Accepts:
;[7247] T1/ OFN
;[7247]
;[7247] Returns: +1 always with T1 preserved
CFSUNC::TMNE OFNDMO,SPTH(T1) ;[7247]
RET ;[7247] If dismounted, let it go
SAVEAC <T1> ;[7247] Save OFN
STKVAR <UCOFN> ;[7247] Location to hold OFN to uncache
MOVEM T1,UCOFN ;[7247] Save OFN to uncache
LOAD T2,STGADR,SPTH(T1) ;[7247] Get XB address
TXO T2,FILEWT ;[7247] Set token bit
LOAD T1,STRX,(T1) ;[7247] Get structure number
CALL GNAME ;[7247] (T1/T1) Get the name of the structure
CFSLOK ;[7247] Lock up the CFS database
CALL HSHLOK ;[7247] (T1,T2/T1,T2) Look for token
BUG.(HLT,CFCTNF,CFSSRV,SOFT,<CFSSRV - Could not find cached token while uncaching>,,<
Cause: CFSUNC has been called to uncache the token for a certain OFN.
The file access token should have been cached and in the hash
table but it was not found.
>) ;[7247] Not found - error!!
TMNE HSHLKF,(T1) ;[7247] Now interlocked?
IFNSK. ;[7247] If so
SETZRO <HSHTYP,HSHCNT>,(T1) ;[7247] Clear status bits but not KEEP
SETOM HSHPST(T1) ;[7247] Set to indicate that uncache attempted
JRST CFSFAL ;[7247] Return
ENDIF. ;[7247]
TMNN HSHTAM,(T1) ;[7247] Is it cached?
BUG.(HLT,CFSUCN,CFSSRV,SOFT,<CFSSRV - Uncaching non-cached token>,,<
Cause: CFSUNC has been called to uncache the token for a certain OFN.
We found the access token for the OFN but it is not cached.
>) ;[7247] No, error
MOVE T2,HSHCOD(T1) ;[7247] Get the OFN described by this token
CAME T2,UCOFN ;[7247] Does it match the one to be uncached?
BUG.(HLT,CFSUCM,CFSSRV,SOFT,<CFSSRV - Uncaching mismatch>,,<
Cause: CFSUNC has been called to uncache the token for a certain OFN.
We found the access token for the OFN but the OFN stored in the
resource block does not match the one we should be uncaching.
>) ;[7247] No - error
SETZRO HSHTAM,(T1) ;[7247] Uncache just in case it was set
SOS CFACCT ;[7247] Decrement currently cached count
CALL CFSRMV ;[7247] (T1/T1,T2) Remove entry
JRST CFSFAL ;[7247] Unlock the database and return
ENDSV. ;[7247]
SUBTTL File access token resource manager -- CFSBOW (Broadcast OFN update)
;Broadcasting routines
;CFS broadcasts information about certain events. Any braodcast
;other than a vote is done using CFSBRD.
;Here when PAGEM is about to update an OFN
;This event is broadcast so that if this system crashes before
;it can pass on access to the file, the next user will know to
;validate the XB before using it. Note this technique also elimiates
;the need for an optional data item on the access token reply to
;indicate that the OFN needs validating!
; T1/ OFN
IFNDEF CFSDUM,< ;Only need this for full CFS
CFSBOW::SKIPN CFSHCT ;Anybody out there?
RET ;No
LOAD T2,STGADR,SPTH(T1) ;Get XB address
LOAD T1,STRX,(T1) ;Get structure number
TSTRMT ;Is it a shared structure?
RET ;No. All done then
TXO T2,FILEWT
CALL GNAME ;Get the name
;Now send message to each node that is up
BLCAL. (CFSBRD,<T1,T2,[.CFBOW],[0]>) ;Do the braodcast
RET ;And done
SUBTTL File access token resource manager -- CFSBEF (Broadcast EOF)
;CFSBRD routines, continued
;Routine to broadcast EOF pointer on a file close or CHFDB%.
;This is broadcast so that the OFNLEN entries on other systems will
;be correct over a crash of this system. Since the FDB will be updated
;on the close, it is essential that sharers of this file have the
;correct EOF value.
;
;Accepts: T1/ OFN to do
;
;This routine does not expect to be called from interrupt level so
;it will protect itself via CFSLOK and CFSULK.
;
;This routine is called from DSKCLZ upon a CLOSF% of a file that has
;a window page setup and is open for write. In this case, the FDB
;will be updated with the correct length and CFSBEF will be called to
;broadcast it to the other systems in the cluster. This covers the case
;of sequential I/O EOF being broadcast.
;
;This routine is also called from CHFDB% after the FDB has been written
;to disk. The file must be open at the time of the CHFDB%. The broadcast
;is done in this case because any entry can be written into the FDB with
;CHFDB% without having the disk get updated (CF%NUD). So, the .FBSIZ
;field could have been written with CF%NUD. Therefore, in order to insure
;that the file size is broadcast, CFSBEF must be called whenever the
;directory is updated to disk from CHFDB% regardless of which specific field
;of the FDB was changed. This covers the case of random (PMAP%) I/O being
;broadcast since CHFDB% is the method by which the EOF is to be updated.
CFSBEF::SAVEAC<P1,P2> ;Get some regs
SKIPN P1,OFNLEN(T1) ;Get EOF pointer
RET ;None here
LOAD P2,SPTST,(T1) ;Get state
CAIE P2,.SPSWR ;Are we the owner?
RET ;No, don't broadcast anything
CFSLOK ;Yes, lock CFS database
MOVE T2,T1 ;Get the OFN
ADD T2,CFSOFN ;Point to entry in table
SKIPN T2,0(T2) ;Here?
BUG.(HLT,CFSBNO,CFSSRV,SOFT,<CFSSRV - Broadcast of unknown OFN>,,<
Cause: CFSBEF was called to broadcast the EOF pointer for an OFN. This
OFN does not have an entry in the CFSOFN table.
>) ;Report error
MOVEM P1,HSHOPT(T2) ;Store broadcast value
AOS P2,HSHOP1(T2) ;Bump the transaction number
CFSULK ;Unlock CFS database
LOAD T2,STGADR,SPTH(T1) ;Get XB address
TXO T2,FILEWT ;Make token ID
LOAD T1,STRX,(T1)
TSTRMT ;Here?
RET ;Yes. Don't do anymore
CALL GNAME ;Get the name
BLCAL. (CFSBRD,<T1,T2,[.CFBEF],<.,CFSBF0>>) ;do it
RET ;And done
;Coroutine of above
CFSBF0: DMOVEM P1,CFDAT(T1) ;Stash the data
RET
SUBTTL File access token resource manager -- CFSBRD (Main broadcast routine)
;Still IFNDEF CFSDUM and still CFSBRD routines
;Routine to do a broadcast. Called by various routines to send a CI
;broadcast. Since the CI is a point-to-point bus, the broadcasr must
;be simulated by a number of point-to-point messages. The broadcast,
;therefore, is slow but since it uses virtual circuits, it is reliable.
CFSBRD: BLSUB. (<ROT,QAL,OPR,CB>) ;Lots of args!!!
SAVEQ ;Get some work ACS
MOVSI Q3,-HSTSIZ
MOVE Q1,ROT ;Get root code
MOVE Q2,QAL ;Get qualifier code
AOS CFBRDS ;Send a broadcast
CFSLOK ;Preserve the configuration
DO. ;Scan them all
SKIPLE CFSHST(Q3) ;This one up?
SKIPL T2,CFHSTS(Q3) ;Still?
IFSKP. ;If so
TRNN T2,-1 ;Is it real or dummy?
ANSKP. ;If real
CALL GVOTE ;Get a packet
NOP
DMOVEM Q1,CFROT(T1) ;Stash it
MOVE T2,OPR ;Get operator
STOR T2,CFCOD,(T1) ;And stash it
HRRZ T2,Q3 ;Host number
SKIPE T3,CB ;Want to look at it first?
CALL 0(T3) ;Yes. Give it a chance then
CALL SCASND ;Send it off
IFNSK. ;If failed
PIOFF
CALL CFSWDN ;Return the packet
PION
ENDIF.
ENDIF.
AOBJN Q3,TOP. ;Do all hosts
ENDDO.
CALLRET CFSFAL ;And done
ENDBS.
> ;IFN CFSDUM
;non-CFS dummies
IFDEF CFSDUM,<
CFSBOW::
CFSBEF::RET
> ;IFDEF CFSDUM
SUBTTL File access token resource manager -- CFSFOD (DDMP force out done)
;Here after DDMP has forced pages out.
; T1/ OFN
;Returns: +1 didn't do it
; +2 OK
IFDEF CFSDUM,<
CFSFOD::BUG.(HLT,CFSDDD,CFSSRV,SOFT,<CFSFOD called incorrectly>,,<
Cause: CFSFOD has been called by DDMP to indicate that a force out is
complete. However, as this is not a real CFS monitor, DDMP should
never have been requested to do this.
>)
> ;IFDEF CFSDUM
IFNDEF CFSDUM,< ;If real CFS
CFSFDF: TDZA T2,T2 ;Entry to force it out
CFSFOD::MOVEI T2,1 ;Normal entry from PAGEM
SAVEQ
MOVE Q2,T1 ;SAVE OFN
;**;[7247] Replace 9 lines with 15 at CFSFOD::+3 DML 19-Feb-86
MOVE Q1,T2 ;[7247] Save entry flag
CFSLOK ;[7247] Lock up CFS database
LOAD T1,STRX,(Q2) ;[7247] Get STR #
LOAD T2,STGADR,SPTH(Q2) ;[7247] Get XB address
SKIPN T2 ;[7247] Is it still here?
JRST CFSFO1 ;[7247] No, all done
TXO T2,FILEWT ;[7247] Set token bit
CALL GNAME ;[7247] Get the name of the structure
CALL HSHLOK ;[7247] (T1,T2/T1,T2) Look for the token
IFNSK. ;[7247] If not here
CFSFO1: SETZRO <SPTST,SPTFR>,(Q2) ;[7247] No longer have it
JRST CFSRSK ;[7247] And done
ENDIF. ;[7247]
LOAD Q3,HSHCNT,(T1) ;[7247] Get share count
IFN. Q1 ;[7247] If normal entry
CAILE Q3,2 ;correct number of sharers?
JRST CFSFAL
ENDIF.
MOVE Q1,T1
LOAD Q3,HSHVVL,(T1) ;GET VOTE CODE
CFSULK
CALL GVOTE1 ;GET A VOTE PACKET
JRST .-1 ;It will get one soon
TMNE HSHODA,(Q1) ;Any data laying here?
SKIPA T2,HSHOPT(Q1) ;Get it
MOVE T2,OFNLEN(Q2) ;Else. Get word from SPT data base
IFN. T2 ;If something is here
MOVEM T2,HSHOPT(Q1) ;In case
MOVEM T2,CFDAT(T1) ;Store it
SETONE CFODA,(T1) ;Say we are doing it
LOAD T2,HSHTYP,(Q1) ;Get type we are giving up
MOVE T3,HSHOP1(Q1) ;Get transaction number
CAIN T2,.HTOEX ;Were we the writer?
AOS T3,HSHOP1(Q1) ;yes. Bump transaction number
MOVEM T3,CFDT1(T1) ;Indicate who we are
ELSE.
SETZM CFDT1(T1) ;No data!
ENDIF.
TMNN HSHBTF,(Q1) ;Is this a bit table?
IFSKP. ;If so
MOVE T2,Q1 ;Get hash packet
CALL SNDFRC ;Send the STR free count
ENDIF.
STOR Q3,CFUNQ,(T1) ;STORE CODE
DMOVE T2,HSHROT(Q1)
DMOVEM T2,CFROT(T1)
MOVEI T2,.CFREP
STOR T2,CFCOD,(T1)
MOVX T2,<-2>
MOVEM T2,CFTYP(T1)
MOVE Q3,T1 ;Save pointer to message
SETZRO HSHRFF,(Q1)
TMNN SPTSR,(Q2) ;Exclusive?
IFNSK. ;If not
DMOVE T1,[.HTOAD ;Share it
.SPSRD]
ELSE.
SETZB T1,T2
ENDIF.
STOR T1,HSHTYP,(Q1) ;new type
STOR T2,SPTST,(Q2) ;New OFN access
;**;[7247] Add 6 lines after SNDFRC:-20 DML 19-Feb-86
TMNN OFNCSH,(Q2) ;[7247] Is the OFN cached?
IFSKP. ;[7247] Yes
MOVX T1,OFNLAC ;[7247] Get bit indicating loss of access
IORM T1,SPTH(Q2) ;[7247] Set it
AOS CFACUT ;[7247] Count this event
ENDIF. ;[7247]
LOAD T2,HSHRHN,(Q1) ;GET HOST INDEX NOW BEFORE RELEASING THE RESOURCE
SETZRO SPTFR,(Q2) ;No longer doing this
TMNN HSHCNT,(Q1) ;Any count?
CALL CFNCNT ;No
DECR HSHCNT,(Q1) ;One less unit of count
MOVE T1,Q3 ;recover message pointer
CALL SCASND ;SEND OFF VOTE
IFNSK.
PIOFF
CALL CFSWDN ;Return the buffer
PION
ENDIF.
RETSKP ;And done
;Routine to fill in STR free count in reply message
; T1/ Message to send
; T2/ hash packet
;Returns: +1 always
SNDFRC: MOVE T3,HSHCOD(T2) ;Get the OFN
LOAD T3,STRX,(T3) ;Get STR #
CALL GETFRC ;Get the current free count
MOVEM T4,CFDST0(T1) ;Save it
ADD T3,CFSSTR ;Find STR trnasaction entry
LOAD T4,HSHTYP,(T2) ;Get type we now own
CAIN T4,.HTOEX ;Exclusive?
AOSA T3,0(T3) ;Yep
MOVE T3,0(T3) ;No
MOVEM T3,CFDST1(T1) ;Save this
SETONE CFODA,(T1) ;Say we sent something
RET ;And done
> ;IFNDEF CFSDUM
SUBTTL Structure resource manager -- CFSSMT (Acquire structure resource)
;Routines to handle structures. Structure resources control the
;use of aliases as well as specify if structures are sharable.
;Acquire structure resource.
; T1/ Structure number
; T2/ type of access
; 0=) shared
; <>0=) exclusive
;Returns:
; +1 failed. Can't mount it this way
; +2 OK
;CFSSMT accomplishes two things:
; 1. It insures that the alias for this structure is
; not already in use for another structure
; 2. It insures that the name being given to this structure
; is the same as the name used by any other CFS systems.
;These guarantees are sufficient to allow the alias to be used as
;the CFS root name for this structure
CFSSMT::SAVEAC<Q1,Q2,Q3,P1>
STKVAR <SDBADR,STRNM>
IFN CFSSCA,< ;Only if SCA is present
MOVEM T1,STRNM ;Save the structure number
SKIPL MYPOR1 ;Are we a dummy?
SKIPA ;Yes, force exclusive then
SKIPE T2 ;Share or exclusive?
SKIPA Q2,[.HTOEX] ;Exclusive
MOVEI Q2,.HTOAD ;Read-share
MOVE Q3,T1
CALL GNAME
EXCH Q3,T1 ;Save name
MOVE T1,STRTAB(T1) ;Get SDB address
MOVEM T1,SDBADR
MOVE T1,SDBUDB(T1) ;Get first unit
MOVE P1,UDBDSH(T1) ;Get the high-order bits
TXO P1,STRCTK ;Make it unique!
MOVE Q1,UDBDSN(T1) ;Get DSN
;..
;CFSSMT continued
;At this point
; Q1/ DSN, unswapped
; Q2/ desired access
; Q3/ Alias
; P1/ high-order serial number bits
CALL CFMNAM ;First register the name
IFNSK. ;Can't
CAIN T2,.CDVUC ;Fail due to unmatch serial number?
RETBAD(MSTX45) ;Yes, return correct error
CALLRET CFMDER ;(T2,Q2) No - analyze error
ENDIF.
TLNN Q1,-1 ;See if need to swap DSN
MOVSS Q1 ;We do
CALL CFMDSN ;Now register the DSN
IFSKP. <RETSKP> ;If made it, done
MOVEM T2,Q1 ;Save denial reason code from CFMDSN
MOVE T1,STRNM ;Get the structure number
CALL CFSSDM ;Undo the mount
MOVE T2,Q1 ;Get denial reason code
CAIN T2,.CDVUC ;Fail due to unmatch alias name?
RETBAD(MSTX49) ;Yes, return correct error
CALLRET CFMDER ;(T2,Q2) No - analyze error
SUBTTL Structure resource manager -- CFMNAM (Register structure name)
;Subroutine of above to register the name
; Q1/ DSN, unswapped
; Q2/ desired access
; Q3/ Alias
; P1/ high-order serial number bits
;
;Returns: +1 Failed to mount structure
; T2 contains the denial reason code
; +2 Success
CFMNAM: DO.
CALL CFSSPC ;Get a block
IFNSK. ;if none
CALL SBLOCK ;Wait here
LOOP. ;And do it again
ENDIF.
ENDDO.
MOVEM Q3,HSHROT(T1) ;Stash name
MOVX T3,STRCTN ;Bits for this
MOVEM T3,HSHQAL(T1) ;Stash it
MOVEI T2,.HTOAD ;Full share this one
STOR T2,HSHTYP,(T1) ;Store requested access
MOVE T2,Q1 ;Get low-order DSN word
XOR T2,P1 ;Make a hash of the two words
; We do this to try to improve the precision
; of the test. However, the REAL protection
; of DSN is provided in the other resource!
MOVEM T2,HSHCOD(T1) ;Save code as well
SETONE <HSHAVT,HSVUC>,(T1) ;Vote must include the code; always vote
SETZM T2 ;No auto retry
CALL CFSGET ;Try it out
RETBAD() ;No luck! Return reason for NO in T2
SKIPE T1 ;Need the block?
CALL @HSHRET(T1) ;No
RETSKP ;Done
SUBTTL Structure resource manager -- CFMDSN (Register drive serial number)
;Another subroutine of above. Register DSN
; Q1/ DSN
; Q2/ desired access
; Q3/ Alias
; P1/ high-order serial number bits
;
;Returns: +1 Failed to register drive serial number
; T2 contains the denial reason code
; +2 Success
CFMDSN: DO.
CALL CFSSPC ;Get a block
IFNSK. ;if none
CALL SBLOCK ;Wait here
LOOP. ;And do it again
ENDIF.
ENDDO.
MOVEM Q1,HSHROT(T1) ;Stash DSN
MOVEM P1,HSHQAL(T1) ;Stash high-order bits as the qualifier
STOR Q2,HSHTYP,(T1) ;Store requested access
MOVEM Q3,HSHCOD(T1) ;Save code as well
SETONE <HSHAVT,HSVUC>,(T1) ;Vote must include the code; always vote
SETZM T2 ;No auto retry
CALL CFSGET ;Try it out
RETBAD() ;No luck! Return reason for NO in T2
SKIPE T1 ;Need the block?
CALL @HSHRET(T1) ;No
CAIN Q2,.HTOEX ;Got it exclusive?
IFNSK. ;If so
MOVE T1,SDBADR ;Get address of SDB
SETONE STEXL,(T1) ;Set exclusive bit
ENDIF.
> ;IFN CFSSCA
RETSKP ;And done
ENDSV.
SUBTTL Structure resource manager -- CFSSUG (Upgrade or downgrade mount)
;Routine to upgrade or downgrade a CFS mount resource.
; T1/ Structure number
; T2/ New access needed
; Same as for CFSSMT
;
;Returns: +1 Can't do it
; +2 Done
CFSSUG::
IFN CFSSCA,< ;Only if SCA is present
SAVEQ ;Get some work regs
SKIPL MYPOR1 ;Are we a real node?
RETBAD(MSTX46) ;No. Can't do this function then
SKIPE T2 ;Share or exclusive?
SKIPA Q1,[.HTOEX] ;Exclusive
MOVEI Q1,.HTOAD ;Share
MOVE T1,STRTAB(T1) ;Get SDB
MOVE T1,SDBUDB(T1) ;Get SDB address
MOVE T2,UDBDSH(T1) ;Get the high-order bits
MOVE T1,UDBDSN(T1) ;Get DSN
TLNN T1,-1
MOVSS T1
TXO T2,STRCTK
CFSLOK
CALL HSHLOK ;Look it up
BUG.(HLT,CFSSUF,CFSSRV,SOFT,<CFSSUG - Could not find entry to upgrade>,,<
Cause: A request was made to change the mount type of a structure, and the
CFS data base has no record of the structure being mounted.
>)
LOAD T2,HSHTYP,(T1) ;Get current type
CAMN T2,Q1 ;The same?
JRST CFSRSK ;Yes. Done.
MOVE Q2,T1 ;Save entry
DMOVE T1,HSHROT(T1) ;Get codes
MOVE T3,Q1 ;Access
CALL CFSUGA ;Do it
IFNSK.
MOVE Q2,Q1 ;Can't upgrade - get desired access
CALLRET CFMDER ;(T2,Q2) Return appropriate error
ENDIF.
DECR HSHCNT,(Q2) ;Don't need this
> ;IFN CFSSCA
RETSKP ;And done
SUBTTL Structure resource manager -- CFMDER (Mount/Dismount error)
; This routine is used by CFSSMT and CFSSUG upon failure.
; It will convert the denial reason code (returned from the failed vote)
; into a meaningful TOPS-20 error code and RETBAD with it.
;
; Expects: T2/ Denial reason code
; Q2/ Desired access
;**;[7330] Replace 2 lines with 4 at CFMDER: DML 16-Jun-86
CFMDER: SKIPN T2 ;[7330] Did we receive an expected error code?
JRST CFMDE1 ;[7330] No - invalid error code
SKIPG T2 ;[7330] Did the mount fail on this system?
RETBAD(MSTX50) ;[7330] Yes, so say so
CAIE T2,.CDOCT ;Fail because it is owned on another system?
RETBAD(MSTX44) ;No, not a special error worth calling out.
CAIE Q2,.HTOEX ;Did we want exclusive?
RETBAD(MSTX47) ;No. Failed because another system had .HTOEX
RETBAD(MSTX48) ;Yes. Failed because another system had .HTOAD
;**;[7330] Change BUGHLT text at CFMDE1: DML 16-Jun-86
CFMDE1: BUG. (HLT,CFSTUC,CFSSRV,SOFT,<CFSSRV - Unexpected error encountered during structure operation>,<<T2,CODE>>,<
Cause: A structure mount or dismount failed and generated an unexpected or
illegal error code of zero. This should never happen.
Data: CODE - Bogus error code
>) ;[7330]
SUBTTL Structure resource manager -- CFSSDM (Release mount resource)
;Routine to undo the MOUNT entry
; T1/ STRUCTURE number
;Returns: +1 always
CFSSDM::
IFE CFSSCA,<RET>
IFN CFSSCA,< ;Only if SCA is present
SAVEAC <Q1,Q2,Q3,P1> ;Get some regs to work with
MOVE Q3,T1 ;Save STR number
CALL GNAME
EXCH T1,Q3 ;Save name, get str num back
MOVE T1,STRTAB(T1) ;Get SDB
MOVE T1,SDBUDB(T1) ;Get UDB of first unit
MOVE Q1,UDBDSN(T1) ;Get serial number
MOVE P1,UDBDSH(T1) ;Get the high-order bits
TXO P1,STRCTK
TLNN Q1,-1 ;Something in the LH?
MOVSS Q1 ;No
;Now have:
; Q1/ DSN
; Q3/ name
; P1/ high-order DSN bits
CFSLOK ;Lock up the data base
MOVE T1,Q3 ;Copy the name
MOVX T2,STRCTN ;Get proper qualifier
CALL HSHLOK ;Look 'er up
SKIPA ;If not here, forget it
CALL CFSRMV ;Remove it
MOVE T1,Q1 ;Get DSN
MOVE T2,P1 ;Get qualifier
CALL HSHLOK ;Look it up
SKIPA
CALL CFSRMV ;And remove it
CALLRET CFSFAL ;And done
> ;IFN CFSSCA
SUBTTL Structure resource manager -- STRVER (Structure verify)
;Routine called during "CI joining" to reverify any structure resource.
;This is done in the event one or more nodes have been off of the CI
;and mounted structures without benefit of the voting operation.
;The reverification simply votes on the current state of the structure
;mount resources.
STRVER:
IFE CFSSCA,<RET> ;NOTHING TO DO FOR NON-CFS SYSTEMS
IFN CFSSCA,<
SAVEP ;Get some regs to use
MOVSI P1,-STRN ;Scan the table
DO.
SKIPN P2,STRTAB(P1) ;Anybody here?
IFSKP. ;If so
MOVEI T1,0(P1) ;Get STR number
CALL GNAME ;Get its name
MOVX T2,STRCTN ;Look up resource
CALL HSHLOK
ANSKP. ;If we have it registered...
CALL STRVVT ;Do vote
MOVE P2,SDBUDB(P2) ;Get UDB address
MOVE T2,UDBDSH(P2) ;Get high order serial number
MOVE T1,UDBDSN(P2) ;Get low order
TXO T2,STRCTK ;Make it unique
TLNN T1,-1
MOVSS T1 ;Get DSN in right order
CALL HSHLOK ;Look this up too
ANSKP. ;If here
CALL STRVVT ;Do vote
ENDIF. ;Done with that one
AOBJN P1,TOP. ;Do all entries
ENDDO.
RET ;Done
;Local routine of STRVER to do upgrading.
; T1/ resource block
; uses P3 (temp of STRVER)
STRVVT: MOVE P3,T1 ;Save block
DMOVE T1,HSHROT(T1) ;Get name
LOAD T3,HSHTYP,(P3) ;Get current access
CFSLOK
CALL CFSUGZ ;do it
BUG.(HLT,CFSVFL,CFSSRV,SOFT,<CFSSRV - Structure verify failed>,,<
Cause: CFS could not verify an existing structure resource during
the join operation. This probably means there is a structure
naming conflict.
>)
DECR HSHCNT,(P3) ;Don't need this count
RET ;Done
> ;IFN CFSSCA
;job 0 routine called from CHKR for stuff
CFSJ0:: JE SCVER,,R ;If no bit set, all done
SETZRO SCVER ;no longer needed
CALLRET STRVER ;Do it
SUBTTL File enqueue resource manager -- CFSENQ (Get ENQ resource)
;Routines to obtain and release ENQ lock on a file. This code is
;the ENQ "detector" that prevents two or more CFS nodes from using
;ENQ on the same file!
;Get ENQ resource.
; T1/ OFN
;Returns:
; +1 failed. Another node has it
; +2 SUCCESS.
IFDEF CFSDUM,< ;If a reduced CFS
CFSENQ::RETSKP ;Succeed
> ;IFDEF CFSDUM
IFNDEF CFSDUM,<
CFSENQ::SAVEQ
;**;[7348] Add 2 lines after CFSENQ::+0 DML 1-Aug-86
STKVAR <OFNENQ> ;[7348]
MOVEM T1,OFNENQ ;[7348] Save the OFN
LOAD Q3,STRX,(T1)
CALL ENQSET ;Set up args
JRST RSKP ;Local. All set
;**;[7348] Remove 1 line at CFSENQ:+4 DML 1-Aug-86
DMOVE Q1,T1
DO.
CALL CFSSPC ;Get some space
IFNSK. ;If failed
CALL SBLOCK ;Wait a bit
LOOP.
ENDIF.
ENDDO.
DMOVEM Q1,HSHROT(T1) ;Stash it
MOVEI T2,.HTOEX ;Exclusive please
STOR T2,HSHTYP,(T1) ;Ask for it
SETONE HSHLCL,(T1) ;But it is local exclusive
SETZM T2 ;No retry
MOVE T3,STRTAB(Q3) ;Get SDB
LOAD T3,STEXL,(T3) ;Get shared/exclusive indicator
CALL @[ IFIW!CFSGET
IFIW!CFSGTL](T3)
RETBAD() ;Nope. Someone else has it
SKIPE T1
CALL @HSHRET(T1) ;If didn't need it
;**;[7348] Replace 1 line with 17 at CFSDEQ::-8 DML 1-Aug-86
CFSLOK ;[7348] Lock the database
DMOVE T1,Q1 ;[7348] Get root and qualifier
CALL HSHLOK ;[7348] (T1,T2/T1,T2)Find the entry
BUG.(HLT,CFEQHF,CFSSRV,SOFT,<ENQ token not found>,,<
Cause: An ENQ token was just created and one already existed so the block
which was passed has been released. Now, we are attempting to find
the original block and this has failed.
Action: Look in CFS free space to try to find the remains of the original
block. Try to determine how the block could have been released even
though this routine acquired it.
>) ;[7348] Error!
MOVE T2,OFNENQ ;[7348] Get the OFN for this ENQ
MOVEM T2,HSHCOD(T1) ;[7348] Put it in the token
JRST CFSRSK ;[7348] Unlock database and return success
ENDSV. ;[7348] End of STKVAR
> ;IFNDEF CFSDUM
SUBTTL File enqueue resource manager -- CFSDEQ (Release ENQ resource)
;Release ENQ resource
; T1/ OFN
;Returns: +1 always
IFDEF CFSDUM,<
CFSDEQ::RET
> ;IFDEF CFSDUM
IFNDEF CFSDUM,< ;If real CFS
CFSDEQ::CALL ENQSET ;Get args
RET ;Local structure
CALL CFSNDO ;undo it
NOP ;??
RET ;And done
;Utility to set up args for ENQ/DEQ stuff
; T1/ OFN
;**;[7315] Replace 3 lines with 26 at ENQSET: DML 4-Jun-86
ENQSET: STKVAR <SAVOFN> ;[7315] A place to save the OFN
TMNN OFNDMO,SPTH(T1) ;[7315] Is this OFN dismounted?
IFSKP. ;[7315] Yes
MOVEM T1,SAVOFN ;[7315] Save this for later
HRLZS T1 ;[7315] Form OFN,,0 for call
CALL OFNJFD ;[7315] (T1/T1)Convert OFN into JFN
BUG.(HLT,CFEQSF,CFSSRV,SOFT,<CFSSRV - Could not convert OFN to JFN>,,<
Cause: ENQSET was called to set up the root and qualifier for the ENQ token
for a certain OFN. This OFN was dismounted so the routine must look
in the JFN block for the structure name because the STRTAB entry is
zero. However, the conversion from OFN to JFN failed.
Action: Investigate the dump to try to determine why the call to OFNJFN failed.
>) ;[7315] Error!
HLRZS T1 ;[7315] Position the JFN correctly
IMULI T1,MLJFN ;[7315] Convert into internal offset
LOAD T1,FLDSB,(T1) ;[7315] Get the pointer to the device string
CALL ASCSIX ;[7315] (T1/T1,T2)Convert to sixbit
NOP ;[7315] This should not fail!
MOVE T2,SAVOFN ;[7315] Get back saved OFN
LOAD T2,STGADR,SPTH(T2) ;[7315] Get XB address
ELSE. ;[7315] OFN is not dismounted
LOAD T2,STGADR,SPTH(T1) ;[7315] Get XB address
LOAD T1,STRX,(T1) ;[7315] Get structure number
CALL GNAME ;[7315] (T1/T1)Get the structure name
ENDIF. ;[7315]
TXO T2,FILEEQ ;Ask for this resource
RETSKP ;And done
;**;[7315] Add 1 line after ENQSET:+5 DML 4-JUN-86
ENDSV. ;[7315]
> ;IFNDEF CFSDUM
SUBTTL Global Job Number Routines -- JBAVAL (Manage job bit table)
;Routines to manage job bit table.
;First, routine to make a job available
; T1/ Job to make available
;Returns: +1
; clobbers all temps
JBAVAL::
SKIPN T1 ;Job 0 is not reserved, so
RET ;Just return
MOVE T4,T1 ;Copy ti
IDIVI T1,^D36 ;Compute word and bit offset
MOVE T2,BITS(T2) ;Get the bit
IORM T2,JOBMBT(T1) ;Make it available
ADJBP T4,GLBPTR ;Point to entry in translation table
MOVEI T3,0 ;Get a zero
DPB T3,T4 ;Clear the entry
RET ;Done
SUBTTL Global Job Number Routines -- JBGET1 (Get global job number for local job)
;Get a free job global for a local job.
; T1/ Local job number
;Returns: +1 none available
; +2 T1/ number
JBGET1::
SKIPN T1 ;Local Job 0 is always Global Job 0
RETSKP ;So just return
MOVE T4,T1 ;Save argument
MOVSI T1,-JBWDS ;Scan the table
DO.
SKIPN T2,JOBMBT(T1) ;Anything here?
IFSKP. ;If so
JFFO T2,.+1 ;Find the first
MOVE T2,BITS(T3) ;Get the bit
ANDCAM T2,JOBMBT(T1) ;Clear it
MOVEI T1,0(T1)
IMULI T1,^D36 ;Compute jobs ahead of this one
ADDI T1,(T3) ;Add in the bit
MOVEI T2,(T1) ;Copy it
ADJBP T2,GLBPTR ;Point to entry in translation table
DPB T4,T2 ;Store local job number
RETSKP ;And done
ENDIF.
AOBJN T1,TOP. ;Look over them all
ENDDO.
RET ;None here
SUBTTL Global Job Number Routines -- GL2LCL (Return local job number)
;Routine to return the local job number for a global job number.
; T1/ Global job number
;Returns: +1 not a local job. T1/ Error code
; +2 T1/ local job number
;
;Note: This routine is also called by Non-CFS monitors, since they
; depend upon it to check the range of the job number supplied.
GL2LCL::
SKIPN T1 ;Job 0 always returns 0
RETSKP ;
SKIPL T1 ;Must be positive
CAILE T1,MXGLBS ;And must be within range
RETBAD(GTJIX3) ;invalid
IFG. T1
ADJBP T1,GLBPTR ;Point to entry
LDB T1,T1 ;Get the value
SKIPE T1 ;SKIP if it's zero
CAILE T1,NJOBS ;SKIP if it's below the max.
RETBAD(GTJIX4) ;Illegal job number
ENDIF.
RETSKP ;Else, return the local job number
SUBTTL Global Job Number Routines -- LCL2GL (Return global job number)
;Routine to return the Global Job number, given the local job number.
;Search the Global job number table serially, comparing each entry to
;the desired local job number. This routine can be very slow, and not
;recommended unless absolutely necessary.
;
; T1/ Local Job number
;Returns: +1 No Global job assigned to this local index
; T1/ Error code
; +2 T1/ Global Job number
;
LCL2GL::
SKIPN T1 ;Local Job 0 is always Global Job 0
RETSKP ;So return good
CAIL T1,1 ;Check for legal local index
CAILE T1,NJOBS ;Like so
IFNSK. ;If that didn't skip, job index is bad
BUG.(CHK,CFSILJ,CFSSRV,SOFT,<CFSSRV - Illegal Local Job Number>,,<
Cause: LCL2GL as been called to convert a local job number to a global
index, but the local job number is invalid.
Action: If this problem persists, change the CHK to a HLT and determine why
the caller is passing a bad job number.
>)
RETBAD(GTJIX3) ;Return error code for invalid job index
ENDIF.
SAVEP ;Save P registers.
MOVE P1,T1 ;Save requested local job number
MOVSI P4,-MXGLBS ;Build counter
MOVE P3,GLBPTR ;Get pointer to start of table
DO. ;Loop through the table
MOVEI T1,1(P4) ;Get Current Global Job number in T1
ILDB P2,P3 ;Get a table entry
CAIN P2,(P1) ;Does it match requested number?
RETSKP ;Yes. Simply return
AOBJN P4,TOP. ;No, bump counter, and continue loop
ENDDO. ;end of loop, job not found
RETBAD(GTJIX4) ;Return 'No such job'.
SUBTTL Global Job Number Routines -- CFGTJB (Get jobs at system startup)
;Job bit table routines, continued
;Routine to get some jobs. Called at system start up to
;allocate the proper number of job packets and mark the JOBMBT table
CFGTJB::
SAVEQ ;Get some work regs
MOVSI Q1,-MXPKTS ;Max,,packet we are on
MOVEI Q2,LCLPKT ;Number we need
DO. ;Loop
CALL CFSSPC ;Get some space
CALL CFSERR
MOVX T2,CFJBAS ;Assign job numbers
MOVEM T2,HSHROT(T1) ;Store root code
MOVX T2,.HTOEX ;Need exclusive
STOR T2,HSHTYP,(T1) ;Stash it
HRRZM Q1,HSHQAL(T1) ;Store slot needed
SETZM T2 ;No retry
CALL CFSGET ;Get it
IFSKP. ;If we got this one
MOVEI Q3,0(Q1) ;Get slot
IMULI Q3,JBPCKT ;Jobs in a slot
HRLI Q3,-JBPCKT
DO.
HRRI T1,1(Q3) ;Get job number
CALL JBAVAL ;Make it available
AOBJN Q3,TOP. ;Do them all
ENDDO.
SOJLE Q2,R ;If all done, return
ENDIF.
AOBJN Q1,TOP. ;Try next slot
ENDDO.
RET ;Done
SUBTTL Miscellaneous Interfaces -- FILRST (Reset all files at startup)
;Routine called at system start-up to reset all file states to unowned.
;This is used so that we can mount PS: after reading it.
FILRST::
REPEAT 0,< ;Don't need this while PS: are not shared
SAVEAC <P1> ;Get a work reg
IFNDEF CFSDUM,< ;Only if real CFS
;
; NOTE: IT MIGHT BE USEFUL TO ONLY SEARCH THE OFNS POINTED TO BY THE HASH
; TABLE BUT THIS CODE IS DONE VERY INFREQUENTLY SO IT DOESN'T REALLY
; MATTER NOW. TAM 28-JAN-85
;
MOVEI P1,1 ;Start with first OFN
SETOM DDPFRK ;Pretend we are DDMP
DO. ;Loop over them all
SKIPN SPTH(P1) ;This one in use?
IFSKP. ;If so.
SETONE SPTFR,(P1) ;Say we need it flushed
CALL DDOCFS ;Do it
ANNSK. ;But if it failed
MOVEI T1,1 ;Do a short dismiss
DISMS ;""
JRST TOP.
ENDIF.
CAIGE P1,NOFN ;All done?
AOJA P1,TOP. ;No. DO them all
ENDDO. ;All done
SETZM DDPFRK ;No longer DDMP
> ;IFNDEF CFSDUM
> ;REPEAT 0
RET ;""
SUBTTL Miscellaneous Interfaces -- CFSERR (Illegal configuration)
;Here when an illegal CFS confiugration occurs
CFSERR: BUG.(HLT,CFSICN,CFSSRV,SOFT,<CFSSRV - Illegal configuration>,,<
Cause: This system has detected an illegal configuration. There may be
too many nodes in the network. The caller of this routine should
be examined for more details.
>)
SUBTTL Miscellaneous Interfaces -- CFRDSN (Read drive serial number)
;Routine called from PHYSIO when a pack that is part of a mounted
;structure is moved to a new drive. The events that cause this are:
;1) operator reassignment (moving the pack), or 2) shadow-set failure.
;This routine handles the case of a pack being moved to a previously
;unused drive; it is called so that the CFS resource may be "renamed".
;It does not handle the case of two packs swapped between their drives.
;This unsupported case seems useless and is very hard to support without
;serious races.
;ACCEPTS: T1/ new UDB
; T2/ previous UDB for this
;RETURNS: +1
CFRDSN::
IFE CFSSCA,<RET> ;If no SCA, done
IFN CFSSCA,< ;If an SCA
EA.ENT ;Need to be extended
SAVEAC <Q1,Q2> ;Save some work registers
STKVAR <NUDB,OUDB>
SETOM Q1 ;Indicate we entered at CFRDSN
MOVEM T1,NUDB ;Save the arguments
MOVEM T2,OUDB
JRST CFDSN1 ;Continue at common code
SUBTTL Miscellaneous Interfaces -- CFSDSN (Swap drive serial number)
;Routine called from PHYSIO when the drive serial number of a unit
;changes. This can happen when the HDA of a DSA disk (RA60/RA81) is
;changed while the system is still running.
;
;PHYSIO will provide the address of the UDB (with the new serial number
;stored in it) and the old drive serial number. This routine will proceed
;to unlink the old resource blocks, adjust the DSN, and link this new block
;into its appropriate place in the hash table. Conceptually, the old blocks
;are removed and replaced by the new ones. But in effect, the old blocks
;are never actually destroyed, just updated and relinked.
;
;This routine only handles the case of a drive being assigned a new DSN and
;this new DSN does not already have a CFS resource which describes it. If
;a CFS resource exists for the new DSN, and it is for a different structure
;name, then a CFSRNM BUGHLT will result. This case is not only unsupported
;but clearly illegal.
;
;Expects: T1/ high-order word of old DSN
; T2/ low-order word of old DSN
; P3/ UDB updated with new drive serial number
;Returns: +1 always
CFSDSN::
IFE CFSSCA,<RET> ;If no SCA, done
IFN CFSSCA,< ;If an SCA
EA.ENT ;Need to be extended
SAVEAC <Q1,Q2> ;Save some work registers
STKVAR <NUDB,HDSN,LDSN>
SETZM Q1 ;Indicate we entered at CFSDSN
MOVEM P3,NUDB ;Save arguments
MOVEM T1,HDSN
MOVEM T2,LDSN
; JRST CFDSN1 ;Continue at common code
;..
;This is common code used by both CFRDSN and CFSDSN.
;..
CFDSN1: MOVE T1,NUDB ;Get new UDB
MOVE T3,UDBSTR(T1) ;Get structure "back pointer"
TLNE T3,-1 ;Is this the first unit?
RET ;No. All done then
;This is the first unit of a structure. Rename the CFS resource.
MOVE T2,UDBDSH(T1) ;Get high-order bits for new DSN from new UDB
MOVE T1,UDBDSN(T1) ;Get low-order bits
TXO T2,STRCTK ;Prepare to look up resource based on new DSN
TLNN T1,-1
MOVSS T1
CALL HSHLOK ;(T1,T2/T1,T2) See if it is around
IFSKP. ;If so, this could be bad
MOVE T2,NUDB ;Recover the UDB
HRRZ T2,UDBSTR(T2) ;Get SDB pointer
CALL GNAME2 ;(T2/T2) Get name of this structure
CAMN T2,HSHCOD(T1) ;Same as the resources name?
RET ;Yes. Nothing to do then.
;If we are here, it is likely the system will crash with a CFSRNM BUGHLT.
;The most likely reason for the crash is the unsupported case of two packs
;swapped between their drives. This could also indicate another unsupported
;case where a drive is given a new HDA (and thus a new drive serial number)
;and this DSN is already described by a CFS resource for structure of a
;different name.
ENDIF.
SKIPL Q1 ;Did we move the pack to a new drive?
IFSKP. ;Yes
MOVE T2,OUDB ;Recover the old UDB address
MOVE T1,UDBDSN(T2) ;Get DSN
MOVE T2,UDBDSH(T2) ;Get the high-order bits
ELSE. ;No, drive received a new serial number
MOVE T1,LDSN ;Get the low-order bits of the old DSN
MOVE T2,HDSN ;Get the high-order bits of the old DSN
ENDIF.
TLNN T1,-1 ;Anything in the LH?
MOVSS T1 ;No
TXO T2,STRCTK ;Qualifier
CALL HSHLOK ;(T1,T2/T1,T2) Look 'er up
RET ;Not here. Nothing more to do
;Found the entry. Dequeue it and rename it.
CALL HSHULN ;(T1) Remove it
MOVE T3,NUDB ;Get new UDB
DMOVE T3,UDBDSH(T3) ;Get the new DSN
TLNN T4,-1 ;LH OK?
MOVSS T4 ;No.
MOVEM T4,HSHROT(T1) ;New name
TXO T3,STRCTK ;Form high-order DSN as qualifier
MOVEM T3,HSHQAL(T1)
MOVEM T1,Q2 ;Save pointer to resource block
DMOVE T1,HSHROT(T1) ;Get name
CALL HSHLOK ;(T1,T2/T1,T2) Look up new name
SKIPA T2,Q2 ;If not here, good, so get packet address
BUG.(HLT,CFSRNM,CFSSRV,SOFT,<CFRDSN - Could not rename DSN entry>,,<
Cause: A pack of a mounted structure has been moved to a new unit and
the new CFS mount resource already exists for the new drive.
Or, a drive on which there is a pack of a mounted structure has
been given a new drive serial number and the new CFS mount
resource already exists for the new drive.
This indicates either the CFS data base is wrong, or PHYSIO's
data base is wrong.
>)
MOVEM T2,HSHLNK(T1) ;Enqueue it
MOVEM T1,HSHBKP(T2) ;And point backwards as well
SETZM HSHLNK(T2) ;Clear our link
MOVE T1,HSHCOD(T2) ;Get the STRUCTURE name
MOVX T2,STRCTN ;Look up the name
CALL HSHLOK ;(T1,T2/T1,T2) Do it
IFSKP. ;We should have found the resource!!
MOVE T2,NUDB ;Get the new UDB
MOVE T3,UDBDSN(T2) ;Get the low order DSN
MOVE T4,UDBDSH(T2) ;Get the high order DSN
TXO T4,STRCTK ;Make high order word unique
XOR T3,T4 ;Make the hash code
MOVEM T3,HSHCOD(T1) ;Stash in the packet as the code
ENDIF.
RET ;And done
ENDSV.
> ;IFN CFSSCA
SUBTTL Miscellaneous Interfaces -- CFCBRD (Broadcast system cease)
;CFCBRD - Cease broadcast, called by MEXEC during the shutdown sequence.
;This routine broadcasts cease, cease canceled, and timesharing is over
;so other systems can take action with regards to structures being accessed
;through the MSCP server.
; CALL CFCBRD ;(/)
; RETURN +1: No other systems out there
; +2: Sent the message
;
;USES: T1,T2/ ASCIZ OF OUR NODE NAME
;******
;FOR A MORE COMPLETE DESCRIPTION OF THE "CLUSTER CEASE" PROCESSING, SEE THE
;LARGE COMMENT PRECEDING ROUTINE CFCEAS.
;******
CFCBRD::
IFDEF CFSDUM,<RET> ;If reduced CFS, just return
IFNDEF CFSDUM,< ;Full CFS so do routine
SKIPN CFSHCT ;Anybody else out there?
RET ;No, nothing else to do
DMOVE T1,OURNAM ;Get our node name
BLCAL. (CFSBRD,<T1,T2,[.CFSHT],<.,CFSHCO>>) ;Do the broadcast
RETSKP ;Done
;Coroutine of above. Used to stash the node number and shutdown time.
CFSHCO: SAVEAC <T1,T2> ;Do not trash anything
MOVE T2,T1 ;Save vote packet
CALL CFSPRT ;(/T1) Get our local port number
MOVEM T1,CFDAT(T2) ;Store it in the vote packet
MOVE T1,HSYST1 ;GET CEASE TIME
MOVEM T1,CFDT1(T2) ;Store time in the vote packet
;It is placed in the transaction number word
RET ;Return
> ;End of IFNDEF CFSDUM
;Random stuff
;here if CFSGET does anything unexpected
ILLGET: BUG.(HLT,CFSIGT,CFSSRV,SOFT,<CFSSRV - Illegal return from CFSGET>,,<
Cause: A call to CFSGET, CFSGTT or CFSGTL returns +1 even though a
wait-until-successful was requested.
>)
;Routine to crash if someone tries to connect after we've been dead for
;sometime. This routine is called whenever we get connected another
;CFS SYSAP and we had previously been off of the CI for some time.
;We have to crash in that case because the two systems may be out
;of synch wrt the shared structures and may permanently interlock
;one another against referencing those structures.
CFSDIE: BUG. (HLT,CFSKPD,CFSSRV,HARD,<CFSSRV - The KLIPA failed>,,<
Cause: The KLIPA hardware or the CI has failed and CFS cannot continue.
>)
CFNCNT: BUG. (HLT,CFZCNT,CFSSRV,SOFT,<CFSSRV - Zero HSHCNT before decrement>,,<
Cause: A routine wants to decrement the resource share count but the
count is already zero.
>)
ONLINE: SAVET
MOVE T3,CFSHNM(T1) ;Get serial number
LSH T3,-4 ;right-justify it
MOVE T1,CFSHST(T1) ;Get CID
CALL SC.NOD ;Get node number
IFN DEBUG,<
BUG. (INF,CFCONN,CFSSRV,SOFT,<CFSSRV - CFS connection>,<<T2,NODE>,<T1,CID>,<T3,SERNUM>>,<
Cause: A CFS connection has been received from another node on the CI-20.
Data: NODE - Number of connecting node
CID - Connect ID
SERNUM - Serial number of remote node
>)
> ;IFN DEBUG
CALLRET PYCON ;INFORM PHYSIO OF ONLINE
IFN DEBUG,<
OFLINE: SAVET
MOVE T3,CFSHNM(T1) ;Get serial number
LSH T3,-4 ;right-justify it
MOVE T1,CFSHST(T1) ;Get CID
CALL SC.NOD ;Get node number
BUG. (INF,CFDISC,CFSSRV,SOFT,<CFSSRV - CFS disconnect>,<<T2,NODE>,<T1,CID>,<T3,SERNUM>>,<
Cause: A CFS disconnect request has been received from a remote node on
the CI-20.
Data: NODE - Remote node number
CID - Connect ID
SERNUM - Serial number of remote node
>)
RET
> ;IFN DEBUG
;PHYNOL
;
; T3/ CONNECT ID OF NODE GOING OFFLINE
;
PHYNOL: SAVET ;Save everything just in case
MOVE T1,T3 ;Get the connect ID
CALL SC.NOD ;Get the node number
CALLRET PYCOFF ;And declare offline
SUBTTL DIAG% JSYS Support -- CFDIAG (Code for Set CI Unavailable)
;Routine called from DIAG code when the CI is placed off-line. This
;routine closes all of the CFS connections.
CFDIAG::
IFE CFSSCA,<RET> ;If nothing to do, don't do anything
IFN CFSSCA,< ;If we might have something to do
SAVEQ
CFSLOK ;Lock everything up
MOVSI Q1,-HSTSIZ ;Scan the table
DO.
SKIPE CFSHST(Q1) ;Anybody here?
SKIPL CFHSTS(Q1) ;Yes, and opened?
IFSKP. ;If this is opened
BLCAL. (SC.DIS,<CFSHST(Q1),[0]>) ;Close it
IFNSK.
MOVE T3,T1 ;Save error code
MOVE T1,CFSHST(Q1) ;Get connect ID
CALL SC.NOD ;(T1/T1,T2) Get node number
BUG.(CHK,CFCCLZ,CFSSRV,SOFT,<CFSSRV - Can't close CFS connection>,<<T2,NODE>,<T1,CID>,<T3,ERROR>>,<
Cause: A "set CI offline" has been requested and SCA refuses to close
a CFS connection. The call to SC.DIS to disconnect from the remote
node failed. This may result in a CFRECN BUGHLT when the CI is put
on-line.
Data: NODE - node number of remote
CID - connect ID
ERROR - error code returned by SCA
>)
ELSE.
MOVE T3,CFSHST(Q1) ;Get the connect ID
CALL PHYNOL ;Declare the disk's offline
SETZM CFSHST(Q1) ;It is closed
MOVE T1,CFHSTS(Q1)
SETZM CFHSTS(Q1)
SOS CFSHCT ;One less of this
TRNE T1,-1 ;Full?
SOS CFSHCM ;Yes
ENDIF.
HRRZ Q2,Q1 ;GET POSITION
ADD Q2,OLDTAB ; IN OLD CONNECTIONS TABLE
MOVE T1,CFSHNM(Q1) ;GET REMOTE SYSTEM'S SERIAL NUMBER
MOVEM T1,(Q2) ;SAVE IT
ENDIF.
AOBJN Q1,TOP. ;Do all of the table
ENDDO.
CALLRET CFSFAL ;And done
> ;IFN CFSSCA
SUBTTL CNFIG% JSYS Support -- CFCIN (Return CFS information)
IFN CFSSCA,<
; CNFIG% JSYS SUPPORT ROUTINES FOR CFS
; THEY ALSO USE CNFIG% SUPPORT ROUTINES IN JSYSA.MAC
; THE FOLLOWING CONVENTIONS ARE USED FOR PRESERVED REGISTERS
;
; Q1/ MONITOR BLOCK ADDRESS (ESTABLISHED IN THESE ROUTINES)
; Q2/ USER BLOCK ADDRESS
; Q3/ WORDS PROCESSED,,WORDS SUPPLIED
CFCIN:: TRVAR <<CFCINB,.CFCLN>>
XMOVEI Q1,CFCINB ;Q1 POINTS TO MONITOR BLOCK
MOVEI T1,.CFCLN
CALL CFLNDO ;PROCESS .CFLEN
MOVE T1,CFSHCT ;NUMBER OF OTHER CFS HOSTS UP
ADDI T1,1
MOVEM T1,.CFNCN(Q1) ;NUMBER OF CFS NODES
SETZM T2
LOAD T1,SCCNC ;GOT CONNECTED FLAG
SKIPE T1
TXO T2,CF%CFR ;NONZERO MEANS WE DID
MOVEM T2,.CFCDO(Q1) ;DYNAMIC SOFTWARE OPTIONS
CALL CFRET ;RETURN STUFF TO USER
RETSKP
ENDTV.
SUBTTL CNFIG% JSYS Support -- CFCSE (Return serial numbers of CFS nodes)
;RETURN SERIAL NUMBERS OF OTHER HOSTS UP
CFCSE:: TRVAR <<CFCSEB,MAXNDS+2>> ;MAX NUMBER OF OTHER HOSTS + OURS + .CFLEN
XMOVEI Q1,CFCSEB ;ADDRESS OF MONITOR BLOCK
MOVE T1,CFSHCT ;NUMBER OF OTHER HOSTS CURRENTLY UP
ADDI T1,2 ;PLUS US PLUS .CFLEN
CALL CFLND2
XMOVEI P1,.CFCS1(Q1) ; P1/ PLACE TO STORE SERIAL NUMBERS
SETZM 0(P1) ;INITIALIZE TO ZEROS
MOVE T1,APRSER ;APR SERIAL NUMBER IN RIGHT HALF
STOR T1,CF%HSN,0(P1) ;STORE AWAY OUR SERIAL NUMBER
CALL SC.PRT ;GET OUR CI NODE NUMBER
ERJMP .+1 ;IGNORE ERRORS
STOR T1,CF%CIN,0(P1) ;STASH IT
ADDI P1,1
; HERE IS OUR MAIN LOOP TO GET THE SERIAL NUMBERS AND STASH THEM
MOVEI P2,CFSHST ; P2/ PRESENCE TABLE
MOVEI P3,CFHSTS ; P3/ ACTIVENESS TABLE
MOVEI P4,CFSHNM ; P4/ SERIAL NUMBER TABLE
MOVEI P5,HSTSIZ ; P5/ LOOP
DO.
SKIPLE 0(P2) ;ANYTHING HERE?
SKIPL 0(P3) ;ANYTHING ACTIVE?
IFSKP.
SETZM 0(P1) ;INITIALIZE TO ZEROS
MOVE T1,0(P4) ;GET SERIAL NUMBER
LSH T1,-4 ;NORMALIZE
STOR T1,CF%HSN,0(P1) ;STASH IT
MOVE T1,0(P2) ;Get connect ID
CALL SC.NOD ;(T1/T1,T2) Get CI node number
STOR T2,CF%CIN,0(P1) ;Save CI node number
ADDI P1,1 ;BUMP STASH POINTER
ENDIF.
ADDI P2,1 ;BUMP ALL LOOP VARIABLES
ADDI P3,1
ADDI P4,1
SOJG P5,TOP. ;END WHEN WHOLE TABLE SEARCHED
ENDDO.
CALL CFRET ;RETURN STUFF TO USER SPACE
RETSKP
ENDTV.
SUBTTL CNFIG% JSYS Support -- CFCND (Return list of node names)
CFCND:: TRVAR <<CFCNDB,MAXNDS*3+4>>
XMOVEI Q1,CFCNDB
MOVE T1,CFSHCT ;NUMBER OF OTHER HOSTS CURRENTLY UP
IMULI T1,3
ADDI T1,4 ;MAX WORDS RETURNABLE
CALL CFLND2
MOVE T1,CFSHCT
ADDI T1,1
STOR T1,CF%NND,.CFNND(Q1) ; SET NUMBER OF NODES
XMOVEI P1,.CFBP1(Q1) ; P1/ PLACE TO STORE BYTE POINTERS
XMOVEI P2,.CFBP1+1(Q1)
ADD P2,CFSHCT ; P2/ PLACE TO STORE HOST NAMES
MOVEI T3,.CFBP1+1(Q2)
ADD T3,CFSHCT ; T3/ RUNNING ADDRESS FOR BYTE POINTERS
HRR T1,T3
HRLI T1,(POINT 7,)
MOVEM T1,0(P1) ; STORE B.P. FOR OUR NAME
ADDI P1,1 ; BUMP POINTER
ADDI T3,2
DMOVE T1,OURNAM
DMOVEM T1,0(P2)
ADDI P2,2 ; BUMP POINTER
; HERE IS OUR MAIN LOOP TO GET THE NAMES AND STATES AND STASH THEM
MOVEI P3,CFSHST ; P3/ PRESENCE TABLE
MOVEI P4,CFHSTS ; P4/ ACTIVENESS TABLE
MOVEI P5,CFNNAM ; P5/ HOST NAME TABLE
MOVEI T4,HSTSIZ ; T4/ LOOP
DO.
SKIPLE 0(P3) ;ANYTHING HERE?
SKIPL 0(P4) ;ANYTHING ACTIVE?
IFSKP.
HRR T1,T3
HRLI T1,(POINT 7,)
MOVEM T1,0(P1) ; STORE B.P. FOR OUR NAME
ADDI P1,1 ; BUMP POINTER
ADDI T3,2
CALL ASC8T7 ; COPY 0,1(P5) TO 0,1(P2) AND CONVERT
ADDI P2,2 ; BUMP POINTER
ENDIF.
ADDI P3,1
ADDI P4,1
ADDI P5,2
SOJG T4,TOP.
ENDDO.
CALL CFRET
RETSKP
ENDTV.
; THE FOLLOWING CONVERTS 0,1(P5) FROM 8 TO 7 BIT ASCII
; AND STORES THE RESULT IN 0,1(P2)
ASC8T7::SAVET
HRLI T1,(<POINT 8,0>)
HRRI T1,0(P5) ; BYTE POINTER TO SOURCE
HRLI T2,(<POINT 7,0>)
HRRI T2,0(P2) ; BYTE POINTER TO DESTINATION
SETZM 1(P2) ; ZERO DESTINATION NOT TOUCHED
MOVEI T3,8 ; COUNT, 8 BYTES
LOP8T7: ILDB T4,T1 ; THIS IS OUR COPY LOOP
IDPB T4,T2
SOJG T3,LOP8T7
RET
> ;IFN CFSSCA
TNXEND
SUBTTL End of CFSSRV
END