Deck FSETABL

0 Modifications

Listing Sections

Source

Seq #  *Modification Id* Act 
----------------------------+
00001  M01S00001.fsetabl +++|PROC FSETABL;
00002  M01S00002.fsetabl +++|  BEGIN
00003  M01S00003.fsetabl +++|
00004  M01S00004.fsetabl +++|
00005  M01S00005.fsetabl +++|#
00006  M01S00006.fsetabl +++|***       FSETABL - COMPILE THE *COMFTAB* COMMON BLOCK.
00007  M01S00007.fsetabl +++|*
00008  M01S00008.fsetabl +++|*         FSETABL IS THE ONLY COMPILATION IN SINGLE THAT USES
00009  M01S00009.fsetabl +++|*         CONTROL PRESET WITH THE COMFTAB COMMON BLOCK.  IN THE MULTI-
00010  M01S00010.fsetabl +++|*         USER SUBSYSTEM, THE SMFEX MONITOR WILL DO THIS JOB.
00011  M01S00011.fsetabl +++|#
00012  M01S00012.fsetabl +++|
00013  M01S00013.fsetabl +++|  DEF LISTCON #1#;
00014  M01S00014.fsetabl +++|
00015  M01S00015.fsetabl +++|CONTROL PRESET;              # UNIVERSL DECLARES #
00016  M01S00016.fsetabl +++|
00017  M01S00017.fsetabl +++|*IFCALL SINGLE,COMFSGL
00018  M01S00018.fsetabl +++|*IFCALL ONLY,COMFONL
00019  M01S00019.fsetabl +++|*IFCALL MULTI,COMFMLT
00020  M01S00020.fsetabl +++|*CALL COMFFSE
00021  M01S00021.fsetabl +++|
00022  M01S00022.fsetabl +++|
00023  M01S00023.fsetabl +++|*CALL COMFTAB
00024  M01S00024.fsetabl +++|
00025  M01S00025.fsetabl +++|
00026  M01S00026.fsetabl +++|  END TERM
00027  M01S00014.fsetabl +++|FSEWORK
Line S49517 Modification History
M01 (Yanked) (Updated by) @004290
M02 (Yanked) (Updated by) @021714
M03 (Yanked) (Updated by) @053587
M04 (Yanked) (Updated by) @033731
M05 (Yanked) (Updated by) @053646
M06 (Yanked) (Updated by) @053652
M07 (Yanked) (Updated by) @049964
M08 (Yanked) (Added by) @012497
M09 (Yanked) (Updated by) @021420
M10 (Yanked) (Updated by) @020744
M11 (Yanked) (Added by) @017361
Seq #  *Modification Id* Act 
----------------------------+
00028  M11S49517.@017361 +++|6
00029  M01S00001.@000001 +++|*         COPYRIGHT CONTROL DATA SYSTEMS INC.  1992.
00030  M01S00009.fsetabl +++|#
00031  M01S00010.fsetabl +++|
00032  M01S00011.fsetabl +++|  DEF LISTCON #0#;
00033  M01S00012.fsetabl +++|
00034  M01S00013.fsetabl +++|CONTROL EJECT;                         # UNIVERSAL DEFINITIONS       #
00035  M01S00014.fsetabl +++|
00036  M01S00015.fsetabl +++|*IFCALL SINGLE,COMFSGL
00037  M01S00016.fsetabl +++|*IFCALL ONLY,COMFONL
00038  M01S00017.fsetabl +++|*IFCALL MULTI,COMFMLT
00039  M01S00018.fsetabl +++|*CALL COMFFSE
00040  M01S00019.fsetabl +++|
00041  M01S00020.fsetabl +++|
00042  M01S00021.fsetabl +++|  CONTROL IFEQ MULTI,1;
00043  M01S00022.fsetabl +++|    DEF RECALL(AA) #SMFRCL(AA)#;
00044  M01S00023.fsetabl +++|    DEF DELAY      #SMFDLY#;
00045  M01S00024.fsetabl +++|    XREF PROC SMFRCL;
00046  M01S00025.fsetabl +++|    XREF PROC SMFDLY;
00047  M01S00026.fsetabl +++|  CONTROL FI;
00048  M01S00027.fsetabl +++|  CONTROL IFEQ SINGLE,1;
00049  M01S00028.fsetabl +++|    XREF PROC RECALL;
00050  M01S00029.fsetabl +++|    DEF DELAY      #RECALL(0)#;
00051  M01S00030.fsetabl +++|  CONTROL FI;
00052  M01S00031.fsetabl +++|
00053  M01S00032.fsetabl +++|  XREF                       # SYSTEM PROCS      #
00054  M01S00033.fsetabl +++|    BEGIN
00055  M01S00034.fsetabl +++|    PROC WRITE;
00056  M01S00035.fsetabl +++|    PROC REWRITE;
00057  M01S00036.fsetabl +++|    PROC RPHR;
00058  M01S00037.fsetabl +++|    PROC RPHRLS;
00059  M01S00038.fsetabl +++|    PROC SKIPEI;
00060  M01S00039.fsetabl +++|    PROC REWIND;
00061  M01S00040.fsetabl +++|    PROC READ;
00062  M01S00041.fsetabl +++|    PROC WRITER;
00063  M01S00042.fsetabl +++|    PROC WRITEW;
00064  M01S00043.fsetabl +++|    PROC REWRITR;
00065  M01S00044.fsetabl +++|    CONTROL IFEQ SINGLE,1;
00066  M01S00045.fsetabl +++|      PROC EVICT;
00067  M01S00046.fsetabl +++|    CONTROL FI;
00068  M01S00047.fsetabl +++|    END
00069  M01S00048.fsetabl +++|
00070  M01S00049.fsetabl +++|  XREF                       # COMPASS PROCS     #
00071  M01S00050.fsetabl +++|    BEGIN
00072  M01S00051.fsetabl +++|    PROC MOVEWD;
00073  M01S00052.fsetabl +++|    PROC EXCHWD;
00074  M01S00053.fsetabl +++|    FUNC MOVELN;
00075  M01S00054.fsetabl +++|    FUNC LINESZ;
00076  M01S00055.fsetabl +++|    END
00077  M01S00056.fsetabl +++|
00078  M01S00057.fsetabl +++|  XREF
00079  M01S00058.fsetabl +++|    BEGIN
00080  M01S00059.fsetabl +++|*CALL COMFXSB
00081  M01S00060.fsetabl +++|    END
00082  M01S00061.fsetabl +++|
00083  M01S00062.fsetabl +++|  XDEF
00084  M01S00063.fsetabl +++|    BEGIN
00085  M01S00064.fsetabl +++|*CALL COMFXWK
00086  M01S00065.fsetabl +++|    END
00087  M01S00066.fsetabl +++|
00088  M01S00067.fsetabl +++|                             # COMMON DATA       #
00089  M01S00068.fsetabl +++|
00090  M01S00069.fsetabl +++|CONTROL IFEQ MULTI,1;
00091  M01S00070.fsetabl +++|  XREF ARRAY RENTSTK [1:MAXREENT];     # SUBROUTINE STACK  #
00092  M01S00071.fsetabl +++|    BEGIN
00093  M01S00072.fsetabl +++|    ITEM RSTK;
00094  M01S00073.fsetabl +++|    END
00095  M01S00074.fsetabl +++|  XREF ITEM RSTKPTR;
00096  M01S00075.fsetabl +++|  XREF PROC WIOSTAT;
00097  M01S00076.fsetabl +++|CONTROL FI;
00098  M01S00077.fsetabl +++|
00099  M01S00078.fsetabl +++|*CALL COMFDS1
00100  M01S00079.fsetabl +++|*CALL COMFVD2
00101  M01S00080.fsetabl +++|*CALL COMFDS2
00102  M01S00081.fsetabl +++|PAGE
00103  M01S00082.fsetabl +++|
00104  M01S00083.fsetabl +++|
00105  M01S00084.fsetabl +++|PROC INITFET(BUFF,LEN);      # INITIALIZE FET    #
00106  M01S00085.fsetabl +++|  BEGIN
00107  M01S00086.fsetabl +++|#
00108  M01S00087.fsetabl +++|**        INITFET - INITIALIZE FILE ENVIRONMENT TABLE.
00109  M01S00088.fsetabl +++|*
00110  M01S00089.fsetabl +++|*         INITFET IS SPECIALIZED FOR THE WORKFILE MANAGER.  THE FET
00111  M01S00090.fsetabl +++|*         IS ASSUMED TO BE MAPPED BY THE BASED ARRAY "FET". THE
00112  M01S00091.fsetabl +++|*         LENGTH OF THE FET IS ASSUMED TO BE AT LEAST SEVEN WORDS,
00113  M01S00092.fsetabl +++|*         AND RANDOM I/O FLAGS WILL BE SET.
00114  M01S00093.fsetabl +++|*
00115  M01S00094.fsetabl +++|*         ENTRY  BUFF - THE ARRAY PROVIDED AS A BUFFER.
00116  M01S00095.fsetabl +++|*                LEN - INTEGER LENGTH OF BUFFER.
00117  M01S00096.fsetabl +++|*
00118  M01S00097.fsetabl +++|*         EXIT   FET - INITIALIZED FOR RANDOM I/O.
00119  M01S00098.fsetabl +++|*                QUARTER - INITIALIZED AS APPROX LEN/4.
00120  M01S00099.fsetabl +++|#
00121  M01S00100.fsetabl +++|  ARRAY BUFF;;
00122  M01S00101.fsetabl +++|  ITEM LEN;
00123  M01S00102.fsetabl +++|  QUARTER=(LEN+O"300")/4;
00124  M01S00103.fsetabl +++|  FETNAM = WORKNAM;
00125  M01S00104.fsetabl +++|  FETCOD = 0;
00126  M01S00105.fsetabl +++|  FETDUN = TRUE;
00127  M01S00106.fsetabl +++|  FETR = TRUE;
00128  M01S00107.fsetabl +++|  FETW = FALSE;
00129  M01S00108.fsetabl +++|  FETOUT = LOC(BUFF); FETLIM = LOC(BUFF) + LEN;
00130  M01S00109.fsetabl +++|  FETL = 2;
00131  M01S00110.fsetabl +++|  FETFIR = LOC(BUFF); FETIN = LOC(BUFF);
00132  M01S00111.fsetabl +++|  END
00133  M01S00112.fsetabl +++|
00134  M01S00113.fsetabl +++|
00135  M01S00114.fsetabl +++|FUNC BUFAVAIL I;
00136  M01S00115.fsetabl +++|  BEGIN
00137  M01S00116.fsetabl +++|#
00138  M01S00117.fsetabl +++|**        BUFAVAIL - FUNCTION TO COMPUTE BUFFER FREE SPACE.
00139  M01S00118.fsetabl +++|*
00140  M01S00119.fsetabl +++|*         BUFAVAIL COMPUTES THE SPACE AVAILABLE IN THE CIRCULAR
00141  M01S00120.fsetabl +++|*         BUFFER ASSIGNED TO THE FET MAPPED BY THE BASED ARRAY
00142  M01S00121.fsetabl +++|*         "FET".
00143  M01S00122.fsetabl +++|*
00144  M01S00123.fsetabl +++|*         ENTRY  FET - FET.
00145  M01S00124.fsetabl +++|*
00146  M01S00125.fsetabl +++|*         EXIT   BUFAVAIL - WORDS OF SPACE STILL AVAILABLE FOR DATA.
00147  M01S00126.fsetabl +++|#
00148  M01S00127.fsetabl +++|  IF FETIN LS FETOUT THEN BUFAVAIL=FETOUT-FETIN;
00149  M01S00128.fsetabl +++|  ELSE BUFAVAIL=(FETLIM-FETFIR)-(FETIN-FETOUT);
00150  M01S00129.fsetabl +++|  END
00151  M01S00130.fsetabl +++|
00152  M01S00131.fsetabl +++|
00153  M01S00132.fsetabl +++|FUNC BUFUSAGE I;
00154  M01S00133.fsetabl +++|  BEGIN
00155  M01S00134.fsetabl +++|#
00156  M01S00135.fsetabl +++|**        BUFUSAGE - FUNCTION TO COMPUTE BUFFER UTILIZATION.
00157  M01S00136.fsetabl +++|*
00158  M01S00137.fsetabl +++|*         BUFUSAGE IS THE COUTERPART TO BUFAVAIL, COMPUTING THE
00159  M01S00138.fsetabl +++|*         NUMBER OF WORDS ALREADY USED IN THE CIRCULAR BUFFER
00160  M01S00139.fsetabl +++|*         ASSIGNED TO THE FET MAPPED BY BASED ARRAY "FET".
00161  M01S00140.fsetabl +++|*
00162  M01S00141.fsetabl +++|*         ENTRY  FET - FET.
00163  M01S00142.fsetabl +++|*
00164  M01S00143.fsetabl +++|*         EXIT   BUFUSAGE - RESULT.
00165  M01S00144.fsetabl +++|#
00166  M01S00145.fsetabl +++|  IF FETIN GQ FETOUT THEN BUFUSAGE=FETIN-FETOUT;
00167  M01S00146.fsetabl +++|  ELSE BUFUSAGE=(FETLIM-FETFIR)-(FETOUT-FETIN);
00168  M01S00147.fsetabl +++|  END
00169  M01S00148.fsetabl +++|
00170  M01S00149.fsetabl +++|
00171  M01S00150.fsetabl +++|FUNC LSTUSAGE I;
00172  M01S00151.fsetabl +++|  BEGIN
00173  M01S00152.fsetabl +++|#
00174  M01S00153.fsetabl +++|**        LSTUSAGE - COMPUTE UTILIZATION OF READ LIST.
00175  M01S00154.fsetabl +++|*
00176  M01S00155.fsetabl +++|*         LSTUSAGE COMPUTES THE NUMBER OF WORDS USED IN THE READ
00177  M01S00156.fsetabl +++|*         LIST.
00178  M01S00157.fsetabl +++|*
00179  M01S00158.fsetabl +++|*         ENTRY  RDIN, RDOUT - BOUNDS FOR PORTION OF LIST USED.
00180  M01S00159.fsetabl +++|*                LSTSIZE - SIZE OF LIST.
00181  M01S00160.fsetabl +++|*
00182  M01S00161.fsetabl +++|*         EXIT   LSTUSAGE - RESULT.
00183  M01S00162.fsetabl +++|#
00184  M01S00163.fsetabl +++|  LSTUSAGE=RDIN-RDOUT;
00185  M01S00164.fsetabl +++|  IF RDIN LS RDOUT THEN LSTUSAGE=LSTSIZE-1-RDOUT+RDIN;
00186  M01S00165.fsetabl +++|  END
00187  M01S00166.fsetabl +++|
00188  M01S00167.fsetabl +++|
00189  M01S00168.fsetabl +++|FUNC LSTAVAIL I;
00190  M01S00169.fsetabl +++|  BEGIN
00191  M01S00170.fsetabl +++|#
00192  M01S00171.fsetabl +++|**        LSTAVAIL - COMPUTE SPACE AVAILABLE IN READ LIST.
00193  M01S00172.fsetabl +++|*
00194  M01S00173.fsetabl +++|*         LSTAVAIL COMPUTES THE NUMBER OF WORDS AVAILABLE FOR USE
00195  M01S00174.fsetabl +++|*         IN THE RANDOM READ LIST.
00196  M01S00175.fsetabl +++|*
00197  M01S00176.fsetabl +++|*         ENTRY - RDIN, RDOUT, LSTSIZE - CONTROL READ LIST.
00198  M01S00177.fsetabl +++|*
00199  M01S00178.fsetabl +++|*         EXIT   LSTAVAIL - RESULT.
00200  M01S00179.fsetabl +++|*
00201  M01S00180.fsetabl +++|*         CALLS  LSTUSAGE.
00202  M01S00181.fsetabl +++|#
00203  M01S00182.fsetabl +++|  LSTAVAIL=LSTSIZE-1-LSTUSAGE;
00204  M01S00183.fsetabl +++|  END
00205  M01S00184.fsetabl +++|
00206  M01S00185.fsetabl +++|
00207  M01S00186.fsetabl +++|PROC RDWBUF(LENGTH);
00208  M01S00187.fsetabl +++|  BEGIN
00209  M01S00188.fsetabl +++|#
00210  M01S00189.fsetabl +++|**        RDWBUF - READ WORDS FROM BUFFER WITH NO I/O.
00211  M01S00190.fsetabl +++|*
00212  M01S00191.fsetabl +++|*         RDWBUF FUNCTIONS AS A SPECIALIZED READW MACRO.  A STANDARD
00213  M01S00192.fsetabl +++|*         FET IS ASSUMED AND THE DATA TRANSFER WORKING BUFFER IS
00214  M01S00193.fsetabl +++|*         ASSUMED TO BE MAPPED BY A STANDARD BASED ARRAY.  MOST
00215  M01S00194.fsetabl +++|*         IMPORTANT, THIS ROUTINE IS GUARANTEED TO NEVER CALL CIO.
00216  M01S00195.fsetabl +++|*         THE CALLER IS RESPONSIBLE TO ASSURE THAT THE CIRCULAR
00217  M01S00196.fsetabl +++|*         BUFFER HAS ENOUGH DATA TO SATISFY THE REQUEST.
00218  M01S00197.fsetabl +++|*
00219  M01S00198.fsetabl +++|*         ENTRY  LENGTH - AMMOUNT OF DATA NEEDED.
00220  M01S00199.fsetabl +++|*                FET - FET AND CIRCULAR BUFFER HAVE ENOUGH DATA.
00221  M01S00200.fsetabl +++|*                TOO - MAPPED TO USER'S WORKING BUFFER.
00222  M01S00201.fsetabl +++|*
00223  M01S00202.fsetabl +++|*         EXIT   FET - INDICATES DATA TRANSFERRED.
00224  M01S00203.fsetabl +++|*                TOO - DATA IS TRANSFERRED.
00225  M01S00204.fsetabl +++|*
00226  M01S00205.fsetabl +++|*         CALLS  MOVEWD, TRAGIC, BUFUSAGE.
00227  M01S00206.fsetabl +++|*
00228  M01S00207.fsetabl +++|*         USES   FROM.
00229  M01S00208.fsetabl +++|#
00230  M01S00209.fsetabl +++|  ITEM LENGTH, X1;
00231  M01S00210.fsetabl +++|  IF BUFUSAGE LS LENGTH OR LENGTH LS 0 THEN
00232  M01S00211.fsetabl +++|    BEGIN
00233  M01S00212.fsetabl +++|    TRAGIC(" WORKFILE BUFFER EMPTY ON READ.$");
00234  M01S00213.fsetabl +++|    END
00235  M01S00214.fsetabl +++|  P<FROM>=FETOUT;
00236  M01S00215.fsetabl +++|  IF FETIN GR FETOUT OR FETLIM-FETOUT GR LENGTH THEN
00237  M01S00216.fsetabl +++|    BEGIN
00238  M01S00217.fsetabl +++|    MOVEWD(LENGTH,FROM,TOO);
00239  M01S00218.fsetabl +++|    FETOUT=FETOUT+LENGTH;
00240  M01S00219.fsetabl +++|    END
00241  M01S00220.fsetabl +++|  ELSE
00242  M01S00221.fsetabl +++|    BEGIN
00243  M01S00222.fsetabl +++|    X1=FETLIM-FETOUT;
00244  M01S00223.fsetabl +++|    MOVEWD(X1,FROM,TOO);
00245  M01S00224.fsetabl +++|    P<TOO>=LOC(TOO)+X1;
00246  M01S00225.fsetabl +++|    X1=LENGTH-X1;
00247  M01S00226.fsetabl +++|    P<FROM>=FETFIR;
00248  M01S00227.fsetabl +++|    MOVEWD(X1,FROM,TOO);
00249  M01S00228.fsetabl +++|    FETOUT=FETFIR+X1;
00250  M01S00229.fsetabl +++|    END
00251  M01S00230.fsetabl +++|  END
00252  M01S00231.fsetabl +++|
00253  M01S00232.fsetabl +++|
00254  M01S00233.fsetabl +++|PROC WTWBUF(LENGTH);
00255  M01S00234.fsetabl +++|  BEGIN
00256  M01S00235.fsetabl +++|#
00257  M01S00236.fsetabl +++|**        WTWBUF - WRITE WORDS TO BUFFER WTH NO I/O.
00258  M01S00237.fsetabl +++|*
00259  M01S00238.fsetabl +++|*         WTWBUF PERFORMS THE ROLE OF THE WRITEW MACRO, BUT IS
00260  M01S00239.fsetabl +++|*         SPECIALIZED TO USE AN ASSUMED FET AND WORKING BUFFER, AND
00261  M01S00240.fsetabl +++|*         IS GUARANTEED TO NEVER PERFORM ANY CIO CALLS.  THE CALLER
00262  M01S00241.fsetabl +++|*         IS RESPONSIBLE TO ASSURE THE CIRCULAR BUFFER HAS ROOM TO
00263  M01S00242.fsetabl +++|*         ACCEPT THE DATA.
00264  M01S00243.fsetabl +++|*
00265  M01S00244.fsetabl +++|*         ENTRY  LENGTH - NUMBER OF WORDS.
00266  M01S00245.fsetabl +++|*                FET - THE CIRCULAR BUFFER HAS ROOM.
00267  M01S00246.fsetabl +++|*                FROM - MAPPED ONTO WORKING BUFFER.
00268  M01S00247.fsetabl +++|*
00269  M01S00248.fsetabl +++|*         EXIT   FET - THE CIRCULAR BUFFER HAS DATA.
00270  M01S00249.fsetabl +++|*
00271  M01S00250.fsetabl +++|*         CALLS  BUFAVAIL, TRAGIC, MOVEWD.
00272  M01S00251.fsetabl +++|*
00273  M01S00252.fsetabl +++|*         USES   TOO.
00274  M01S00253.fsetabl +++|#
00275  M01S00254.fsetabl +++|  ITEM LENGTH, X1;
00276  M01S00255.fsetabl +++|  IF BUFAVAIL LS LENGTH OR LENGTH LS 0 THEN
00277  M01S00256.fsetabl +++|    BEGIN
00278  M01S00257.fsetabl +++|    TRAGIC(" WORKFILE BUFFER FULL ON WRITE.$");
00279  M01S00258.fsetabl +++|    END
00280  M01S00259.fsetabl +++|  P<TOO>=FETIN;
00281  M01S00260.fsetabl +++|  IF FETOUT GR FETIN OR FETLIM-FETIN GR LENGTH THEN
00282  M01S00261.fsetabl +++|    BEGIN
00283  M01S00262.fsetabl +++|    MOVEWD(LENGTH,FROM,TOO);
00284  M01S00263.fsetabl +++|    FETIN=FETIN+LENGTH;
00285  M01S00264.fsetabl +++|    END
00286  M01S00265.fsetabl +++|  ELSE
00287  M01S00266.fsetabl +++|    BEGIN
00288  M01S00267.fsetabl +++|    X1=FETLIM-FETIN;
00289  M01S00268.fsetabl +++|    MOVEWD(X1,FROM,TOO);
00290  M01S00269.fsetabl +++|    P<FROM>=LOC(FROM)+X1;
00291  M01S00270.fsetabl +++|    X1=LENGTH-X1;
00292  M01S00271.fsetabl +++|    P<TOO>=FETFIR;
00293  M01S00272.fsetabl +++|    MOVEWD(X1,FROM,TOO);
00294  M01S00273.fsetabl +++|    FETIN=FETFIR+X1;
00295  M01S00274.fsetabl +++|    END
00296  M01S00275.fsetabl +++|  END
00297  M01S00276.fsetabl +++|
00298  M01S00277.fsetabl +++|PROC WAIT;
00299  M01S00278.fsetabl +++|  IOBEGIN(WAIT)
00300  M01S00279.fsetabl +++|#
00301  M01S00280.fsetabl +++|**        WAIT - WAIT (RECALL) FOR I/O TO FINISH.
00302  M01S00281.fsetabl +++|*
00303  M01S00282.fsetabl +++|*         WAIT DELAYS THIS TASK UNTIL THE FET IS FOUND TO INDICATE
00304  M01S00283.fsetabl +++|*         COMPLETION OF A PREVIOUS I/O OPERATION.  WAIT IS A NO-OP
00305  M01S00284.fsetabl +++|*         IF THE FET ALREADY INDICATES COMPLETION.
00306  M01S00285.fsetabl +++|*
00307  M01S00286.fsetabl +++|*         ENTRY  FETDUN - SHOWS WHETHER DELAYS REALLY NEEDED.
00308  M01S00287.fsetabl +++|*
00309  M01S00288.fsetabl +++|*         EXIT   FETDUN - TRUE.
00310  M01S00289.fsetabl +++|*
00311  M01S00290.fsetabl +++|*         CALLS  RECALL.
00312  M01S00291.fsetabl +++|#
00313  M01S00292.fsetabl +++|  IF NOT FETDUN THEN
00314  M01S00293.fsetabl +++|    BEGIN
00315  M01S00294.fsetabl +++|    RECALL(FET);
00316  M01S00295.fsetabl +++|    END
00317  M01S00296.fsetabl +++|  IOEND
00318  M01S00297.fsetabl +++|
00319  M01S00298.fsetabl +++|
00320  M01S00299.fsetabl +++|PROC DISOWNCACHE(PARM);
00321  M01S00300.fsetabl +++|  BEGIN
00322  M01S00301.fsetabl +++|#
00323  M01S00302.fsetabl +++|**        DISOWNCACHE - RELEASE CACHE FRAME FROM OWNERSHIP.
00324  M01S00303.fsetabl +++|*
00325  M01S00304.fsetabl +++|*         DISOWNCACHE IS USED TO RELEASE A PAGE FROM OWNERSHIP BY
00326  M01S00305.fsetabl +++|*         A LEVEL OF THE TREE STRUCTURE.  RELEASE OF A PAGE MAKES
00327  M01S00306.fsetabl +++|*         IT ELIGIBLE TO BE FLUSHED OUT OF MEMORY (AND POSSIBLY
00328  M01S00307.fsetabl +++|*         REWRITTEN BACK TO DISK) ANYTIME THE FLUSHCACHE ROUTINE
00329  M01S00308.fsetabl +++|*         IS NEEDED.  DISOWNCACHE ALSO SETS THE AGE FOR THE PAGE
00330  M01S00309.fsetabl +++|*         SO THAT FLUSHCACHE CAN DO ANY REWRITES IN THE MANDATORY
00331  M01S00310.fsetabl +++|*         ORDER OF RELEASE.  THE GLOBAL AGE COUNTER IS INCREMENTED.
00332  M01S00311.fsetabl +++|*
00333  M01S00312.fsetabl +++|*         ENTRY  PARM - TREE LEVEL.
00334  M01S00313.fsetabl +++|*                CACHEOWNED[PARM] - TRUE FOR NON-TRIVIAL OPERATON.
00335  M01S00314.fsetabl +++|*                AGECOUNT - HIGHEST AGE YET ASSIGNED TO ANY PAGE.
00336  M01S00315.fsetabl +++|*
00337  M01S00316.fsetabl +++|*         EXIT   AGECOUNT - INCREMENTED.
00338  M01S00317.fsetabl +++|*                CACHEOWNED[PARM] - FALSE.
00339  M01S00318.fsetabl +++|*                CACHEAGE[PARM] - SETUP.
00340  M01S00319.fsetabl +++|#
00341  M01S00320.fsetabl +++|  ITEM PARM;
00342  M01S00321.fsetabl +++|  IF PARM LS 0 OR NOT CACHEOWNED[PARM] THEN RETURN;
00343  M01S00322.fsetabl +++|  CACHEOWNED[PARM]=FALSE;
00344  M01S00323.fsetabl +++|  AGECOUNT=AGECOUNT+1;
00345  M01S00324.fsetabl +++|  CACHEAGE[PARM]=AGECOUNT;
00346  M01S00325.fsetabl +++|  END                         # OF DISOWNCACHE        #
00347  M01S00326.fsetabl +++|
00348  M01S00327.fsetabl +++|
00349  M01S00328.fsetabl +++|FUNC COUNTCACHE;
00350  M01S00329.fsetabl +++|  BEGIN
00351  M01S00330.fsetabl +++|#
00352  M01S00331.fsetabl +++|**        COUNTCACHE - DETERMINE HOW MANY CACHE FRAMES ARE NOT USED.
00353  M01S00332.fsetabl +++|*
00354  M01S00333.fsetabl +++|*         COUNTCACHE TELLS THE CALLER HOW MANY CACHE FRAMES ARE
00355  M01S00334.fsetabl +++|*         NEITHER OWNED BY ANY TREE LEVEL NOR CONTAIN DATA, WHICH
00356  M01S00335.fsetabl +++|*         HAS BEEN ALTERED IN THE CACHE BUT NOT YET ON DISK.
00357  M01S00336.fsetabl +++|*
00358  M01S00337.fsetabl +++|*         ENTRY  CACHEOWNED[ALL] - SETUP.
00359  M01S00338.fsetabl +++|*                CACHEDIRTY[ALL] - SETUP.
00360  M01S00339.fsetabl +++|*
00361  M01S00340.fsetabl +++|*         EXIT   COUNTCACHE - RESULT.
00362  M01S00341.fsetabl +++|#
00363  M01S00342.fsetabl +++|  ITEM I, J;
00364  M01S00343.fsetabl +++|  J=0;
00365  M01S00344.fsetabl +++|  FOR I=0 STEP 1 UNTIL MAXCACHE DO IF NOT
00366  M01S00345.fsetabl +++|    (CACHEDIRTY[I] OR CACHEOWNED[I]) THEN J=J+1;
00367  M01S00346.fsetabl +++|  COUNTCACHE=J;
00368  M01S00347.fsetabl +++|  END                         # OF COUNTCACHE     #
00369  M01S00348.fsetabl +++|
00370  M01S00349.fsetabl +++|
00371  M01S00350.fsetabl +++|PROC SEARCHCACHE(M);
00372  M01S00351.fsetabl +++|  BEGIN
00373  M01S00352.fsetabl +++|#
00374  M01S00353.fsetabl +++|**        SEARCHCACHE - DETERMINE BEST CACHEFRAME TO TAKE OVER.
00375  M01S00354.fsetabl +++|*
00376  M01S00355.fsetabl +++|*         SEARCHCACHE TESTS ALL CACHE FRAMES FOR THOSE WHICH ARE
00377  M01S00356.fsetabl +++|*         AVAILABLE TO BE CLAIMED AND USED FOR DIFFERENT DATA THAN
00378  M01S00357.fsetabl +++|*         PRESENTLY IN MEMORY.  THE OLDEST AVAILABLE FRAME IS
00379  M01S00358.fsetabl +++|*         CONSIDERED THE BEST CANDIDATE FOR RECYCLE.  A FRAME
00380  M01S00359.fsetabl +++|*         IS AVAILABLE IF IT IS NEITHER CURRENTLY OWNED BY ANY TREE
00381  M01S00360.fsetabl +++|*         LEVEL NOR CONTAINS DATA ALTERED IN MEMORY BUT NOT ON DISK.
00382  M01S00361.fsetabl +++|*
00383  M01S00362.fsetabl +++|*         ENTRY  CACHEOWNED[ALL] - SETUP.
00384  M01S00363.fsetabl +++|*                CACHEDIRTY[ALL] - SETUP.
00385  M01S00364.fsetabl +++|*                CACHEAGE[ALL] - SETUP FOR UNOWNED, UNDIRTY FRAMES.
00386  M01S00365.fsetabl +++|*
00387  M01S00366.fsetabl +++|*         EXIT   M - CHOSEN FRAME.
00388  M01S00367.fsetabl +++|*
00389  M01S00368.fsetabl +++|*         CALLS  TRAGIC.
00390  M01S00369.fsetabl +++|#
00391  M01S00370.fsetabl +++|  ITEM K,L,M;
00392  M01S00371.fsetabl +++|  M=-1;
00393  M01S00372.fsetabl +++|  K=999999999;
00394  M01S00373.fsetabl +++|  FOR L=0 STEP 1 UNTIL MAXCACHE DO
00395  M01S00374.fsetabl +++|    BEGIN
00396  M01S00375.fsetabl +++|    IF CACHEAGE[L] LS K AND
00397  M01S00376.fsetabl +++|      NOT (CACHEDIRTY[L] OR CACHEOWNED[L]) THEN
00398  M01S00377.fsetabl +++|      BEGIN               # SEARCH OLDEST AVAIL PAGE    #
00399  M01S00378.fsetabl +++|      M=L;
00400  M01S00379.fsetabl +++|      K=CACHEAGE[L];
00401  M01S00380.fsetabl +++|      END
00402  M01S00381.fsetabl +++|    END
00403  M01S00382.fsetabl +++|  IF M LS 0 THEN TRAGIC(" ALL WORKFILE BUFFERS ARE FULL.$");
00404  M01S00383.fsetabl +++|  END                         # OF SEARCHCACHE     #
00405  M01S00384.fsetabl +++|
00406  M01S00385.fsetabl +++|
00407  M01S00386.fsetabl +++|PROC ALLOCCACHE;
00408  M01S00387.fsetabl +++|  BEGIN
00409  M01S00388.fsetabl +++|#
00410  M01S00389.fsetabl +++|**        ALLOCCACHE - LAY CLAIM TO A CACHE FRAME.
00411  M01S00390.fsetabl +++|*
00412  M01S00391.fsetabl +++|*         ALLOCCACHE IS CALLED TO CLAIM A FRAME OF MEMORY IN THE
00413  M01S00392.fsetabl +++|*         DISK CACHE, AND ATTACH IT TO A PARTICULAR TREE LEVEL.
00414  M01S00393.fsetabl +++|*         THE DISK ADDRESS OF THE DISK DATA IS SAVED IN THE HEADER
00415  M01S00394.fsetabl +++|*         WORD OF THE CACHE FRAME, SO IT CAN BE MATCHED FOR
00416  M01S00395.fsetabl +++|*         PURPOSES OF AVOIDING DISK READS.
00417  M01S00396.fsetabl +++|*
00418  M01S00397.fsetabl +++|*         ENTRY  PL - CURRENT TREE LEVEL.
00419  M01S00398.fsetabl +++|*                PADA[PL] - DISK ADDRESS ASSIGNED FOR REAL DATA.
00420  M01S00399.fsetabl +++|*
00421  M01S00400.fsetabl +++|*         EXIT   PACACHE[PL] - WHICH CACHE FRAME WAS SELECTED.
00422  M01S00401.fsetabl +++|*                BFDA[PL] - DISK ADDRESS IS STORED IN CACHE FRAME.
00423  M01S00402.fsetabl +++|*
00424  M01S00403.fsetabl +++|*         CALLS  SEARCHCACHE.
00425  M01S00404.fsetabl +++|#
00426  M01S00405.fsetabl +++|  ITEM TMP1;
00427  M01S00406.fsetabl +++|  SEARCHCACHE(TMP1);
00428  M01S00407.fsetabl +++|  PACACHE[PL]=TMP1;
00429  M01S00408.fsetabl +++|  CACHEOWNED[TMP1]=TRUE;
00430  M01S00409.fsetabl +++|  BFDA[TMP1]=PADA[PL];
00431  M01S00410.fsetabl +++|  END                         # OF ALLOCCACHE     #
00432  M01S00411.fsetabl +++|
00433  M01S00412.fsetabl +++|
00434  M01S00413.fsetabl +++|PROC RECLAIMCACHE;
00435  M01S00414.fsetabl +++|  BEGIN
00436  M01S00415.fsetabl +++|#
00437  M01S00416.fsetabl +++|**        RECLAIMCACHE - IDENTIFY CACHE FRAME WRONGLY RELEASED.
00438  M01S00417.fsetabl +++|*
00439  M01S00418.fsetabl +++|*         RECLAIMCACHE IS USED TO MATCH A TREE LEVEL TO A CACHE
00440  M01S00419.fsetabl +++|*         FRAME WHICH CONTAINS THE VIRTUAL DISK SECTOR FOR THE
00441  M01S00420.fsetabl +++|*         TREE LEVEL, AND REESTABLISH OWNERSHIP.  THIS IS DONE
00442  M01S00421.fsetabl +++|*         BECAUSE THERE ARE SITUATIONS WHERE A PAGE MUST BE
00443  M01S00422.fsetabl +++|*         TEMPORARILY RELEASED FROM OWNERSHIP SO IT CAN BE WRITTEN
00444  M01S00423.fsetabl +++|*         TO DISK, BUT FORFEITURE OF OWNERSHIP IS NOT INTENDED
00445  M01S00424.fsetabl +++|*         FOR ANY OTHER REASON.  RECLAIMCACHE CAN BE CALLED AFTER
00446  M01S00425.fsetabl +++|*         A SEQUENCE OF DISOWNCACHE AND FLUSHCACHE, AND THE TREE
00447  M01S00426.fsetabl +++|*         LEVELS ARE THEN AS THEY WERE BUT DATA ALTERATIONS ARE
00448  M01S00427.fsetabl +++|*         UP TO DATE ON DISK.  REMEMBER THAT THE ORDER IN WHICH PAGES
00449  M01S00428.fsetabl +++|*         CAN BE UPDATED TO DISK DEPENDS ON THE TREE HIERARCHY, SO
00450  M01S00429.fsetabl +++|*         IT IS SOMETIMES NECESSARY TO GO THRU THIS SEQUENCE WITH ONE
00451  M01S00430.fsetabl +++|*         TREE LEVEL IN ORDER TO ACHIEVE THE ACTUAL PURPOSE OF
00452  M01S00431.fsetabl +++|*         WRITING A DIFFERENCE TREE LEVEL TO DISK.
00453  M01S00432.fsetabl +++|*
00454  M01S00433.fsetabl +++|*         ENTRY  PL - CURRENT TREE LEVEL.
00455  M01S00434.fsetabl +++|*                PALVL - DEEPEST VALID TREE LEVEL.
00456  M01S00435.fsetabl +++|*                CACHEOWNED[ALL], PACACHE[ALL], BFDA[ALL] - SETUP.
00457  M01S00436.fsetabl +++|*
00458  M01S00437.fsetabl +++|*         EXIT   CACHEOWNED[PL THRU PALVL] - TRUE.
00459  M01S00438.fsetabl +++|*
00460  M01S00439.fsetabl +++|*         CALLS  TRAGIC.
00461  M01S00440.fsetabl +++|*
00462  M01S00441.fsetabl +++|*         USES   TPL.
00463  M01S00442.fsetabl +++|#
00464  M01S00443.fsetabl +++|  FOR TPL=PL STEP 1 UNTIL PALVL DO
00465  M01S00444.fsetabl +++|    BEGIN
00466  M01S00445.fsetabl +++|    IF CACHEOWNED[PACACHE[TPL]] THEN TEST TPL;
00467  M01S00446.fsetabl +++|    IF BFDA[PACACHE[TPL]] NQ PADA[TPL] THEN
00468  M01S00447.fsetabl +++|      BEGIN
00469  M01S00448.fsetabl +++|      TRAGIC(" WORKFILE BUFFER CONTAINS WRONG TEXT.$");
00470  M01S00449.fsetabl +++|      END
00471  M01S00450.fsetabl +++|    CACHEOWNED[PACACHE[TPL]]=TRUE;
00472  M01S00451.fsetabl +++|    END
00473  M01S00452.fsetabl +++|  END                         # OF RECLAIMCACHE   #
00474  M01S00453.fsetabl +++|PAGE
00475  M01S00454.fsetabl +++|PROC MOVEIO;
00476  M01S00455.fsetabl +++|  BEGIN
00477  M01S00456.fsetabl +++|#
00478  M01S00457.fsetabl +++|**        MOVEIO - INITIATE ANY CIO CALLS AS NEEDED.
00479  M01S00458.fsetabl +++|*
00480  M01S00459.fsetabl +++|*         MOVEIO IS CALLED ANY TIME CIO CALLS ARE KNOWN TO BE
00481  M01S00460.fsetabl +++|*         NECESSARY, AND CAN ALSO BE CALLED ANY TIME CIO CALLS MIGHT
00482  M01S00461.fsetabl +++|*         BE DESIRABLE.  MOVEIO BECOMES A NO-OP IF A CIO CALL IS
00483  M01S00462.fsetabl +++|*         ALREADY IN PROGRESS, OR IF NO CIO CALL IS NEEDED.  THE
00484  M01S00463.fsetabl +++|*         CALLER IS RESPONSIBLE TO PREPARE THE FET AND CIRCULAR
00485  M01S00464.fsetabl +++|*         BUFFER IN ALL WAYS EXCEPT THE CHOICE OF CIO FUNCTION CODE.
00486  M01S00465.fsetabl +++|*
00487  M01S00466.fsetabl +++|*         WRITES ARE INITIATED WHEN THE IOWRITE FLAG HAS BEEN
00488  M01S00467.fsetabl +++|*         PREPARED TO INDICATE THAT WRITES ARE NEEDED, THE FET IS NOT
00489  M01S00468.fsetabl +++|*         PREVIOUSLY INTERLOCKED, AND THE CIRCULAR BUFFER CONTAINS
00490  M01S00469.fsetabl +++|*         SOME DATA.  READS ARE INITIATED WHEN THE IOREAD FLAG HAS
00491  M01S00470.fsetabl +++|*         BEEN PREPARED TO INDICATE THAT READS ARE NEEDED, THE FET IS
00492  M01S00471.fsetabl +++|*         NOT PREVIOUSLY INTERLOCKED, AND THE RDIN/RDOUT POINTERS
00493  M01S00472.fsetabl +++|*         INDICATE THERE IS A NON-TRIVIAL LIST OF PRUS STILL AWAITING
00494  M01S00473.fsetabl +++|*         READS.
00495  M01S00474.fsetabl +++|*
00496  M01S00475.fsetabl +++|*         MOVEIO ALSO PERFORMS THE FUNCTION OF RECOGNIZING THAT ALL
00497  M01S00476.fsetabl +++|*         DESIRED I/O HAS BEEN COMPLETED, SUCH AS ALL WRITEABLE DATA
00498  M01S00477.fsetabl +++|*         REMOVED FROM CIRCULAR BUFFER OR ALL READABLE PRUS REMOVED
00499  M01S00478.fsetabl +++|*         FROM READ LIST.  UNDER THESE CONDITIONS, MOVEIO CLEARS THE
00500  M01S00479.fsetabl +++|*         IOXXXX FLAGS SO THAT NO FURTHER DESIRE FOR CIO CALLS WILL
00501  M01S00480.fsetabl +++|*         BE INDICATED, UNTIL AND UNLESS SOMEONE TURNS THE FLAGS ON
00502  M01S00481.fsetabl +++|*         AGAIN.
00503  M01S00482.fsetabl +++|*
00504  M01S00483.fsetabl +++|*         IN THE CASES WHERE THE CIRCULAR BUFFER CONTAINS DATA TO BE
00505  M01S00484.fsetabl +++|*         WRITTEN, THE ACTUAL CIO FUNCTION CODE IS CHOSEN FROM FOUR
00506  M01S00485.fsetabl +++|*         POSSIBILITIES BASED ON EXTENSION/ALTERATION OF THE FILE AND
00507  M01S00486.fsetabl +++|*         NEED OR NON-NEED FOR END-OF-RECORD TO BE WRITTEN.  WHEN THE
00508  M01S00487.fsetabl +++|*         DISK IS TO BE READ, THE FUNCTION CODE IS ALWAYS "RPHRLS",
00509  M01S00488.fsetabl +++|*         AKA "READ PRUS RANDOMLY BY LIST".
00510  M01S00489.fsetabl +++|*
00511  M01S00490.fsetabl +++|*         NOTE THAT MOVEIO NEVER WAITS FOR ANY CIO TO COMPLETE, THUS
00512  M01S00491.fsetabl +++|*         MOVEIO IS NOT A REENTRANT ROUTINE.
00513  M01S00492.fsetabl +++|*
00514  M01S00493.fsetabl +++|*         ENTRY  FETDUN - WHETHER ANY PREVIOUS I/O IS DONE.
00515  M01S00494.fsetabl +++|*                IOACT - WHETHER I/O SHOULD BE DONE SOMETIME SOON.
00516  M01S00495.fsetabl +++|*                IOWRITE - WHETHER I/O NEEDED IS A WRITE.
00517  M01S00496.fsetabl +++|*                IOREAD - WHETHER I/O NEEDED IS A READ.
00518  M01S00497.fsetabl +++|*                IOAPEND - WHETHER WRITE IS TO EXTEND FILE OR ALTER.
00519  M01S00498.fsetabl +++|*                IOWRTEOR - WHETHER WRITE IS TO PRODUCE EOR.
00520  M01S00499.fsetabl +++|*                FETIN, FETOUT - INDICATE WHETHER UNWRITTEN DATA IS
00521  M01S00500.fsetabl +++|*                    STILL IN THE BUFFER.
00522  M01S00501.fsetabl +++|*                RDIN, RDOUT - INDICATE WHETHER THERE ARE PRUS
00523  M01S00502.fsetabl +++|*                    IDENTIFIED IN READ LIST AS DESIRABLE TO READ,
00524  M01S00503.fsetabl +++|*                    BUT NOT YET READ IN.
00525  M01S00504.fsetabl +++|*                FETLA, FETLAW - CURRENT POSITION IN READ LIST.
00526  M01S00505.fsetabl +++|*                RDLIST[ALL] - SETUP.
00527  M01S00506.fsetabl +++|*                CIOCOUNT - ACCOUNTING ACCUMULATOR.
00528  M01S00507.fsetabl +++|*                MAXDA, LASTDA - USED TO DETERMINE VALIDITY OF
00529  M01S00508.fsetabl +++|*                    WRITE PARAMETERS, WHEN CONSISTENCY CHECKING
00530  M01S00509.fsetabl +++|*                    IS ENABLED IN THE SOURCE CODE.
00531  M01S00510.fsetabl +++|*                FETCRI - USED WITH MAXDA AND LASTDA FOR VALIDITY.
00532  M01S00511.fsetabl +++|*
00533  M01S00512.fsetabl +++|*         EXIT   FETDUN - FALSE IF A CIO CALL STARTED UP.
00534  M01S00513.fsetabl +++|*                CIOCOUNT - INCREMENTED IF CIO CALLED.
00535  M01S00514.fsetabl +++|*                IOACT, IOREAD, IOWRITE, IOAPEND - CLEARED IF AND
00536  M01S00515.fsetabl +++|*                    ONLY IF ALL MOVEIO DETERMINES THAT ALL
00537  M01S00516.fsetabl +++|*                    PREVIOUSLY REQUESTED I/O HAS COMPLETED.
00538  M01S00517.fsetabl +++|*
00539  M01S00518.fsetabl +++|*         CALLS  WRITE, REWRITE, WRITER, REWRITR, RPHRLS, TRAGIC.
00540  M01S00519.fsetabl +++|#
00541  M01S00520.fsetabl +++|  ITEM I;
00542  M01S00521.fsetabl +++|  SWITCH CALLWRITE WRTFUNC,RWRTFUNC,WRTRFUNC,RWRTRFUNC;
00543  M01S00522.fsetabl +++|
00544  M01S00523.fsetabl +++|  IF IOACT AND FETDUN THEN
00545  M01S00524.fsetabl +++|   BEGIN
00546  M01S00525.fsetabl +++|
00547  M01S00526.fsetabl +++|    IF IOWRITE AND FETIN NQ FETOUT THEN          # WRITE NOT DONE    #
00548  M01S00527.fsetabl +++|      BEGIN
00549  M01S00528.fsetabl +++|      CIOCOUNT = CIOCOUNT + 1;
00550  M01S00529.fsetabl +++|
00551  M01S00530.fsetabl +++|      I=1;
00552  M01S00531.fsetabl +++|      IF IOAPEND THEN I=0;
00553  M01S00532.fsetabl +++|      IF IOWRTEOR THEN I=I+2;
00554  M01S00533.fsetabl +++|      IOWRTEOR=FALSE;
00555  M01S00534.fsetabl +++|      GOTO CALLWRITE[I];
00556  M01S00535.fsetabl +++|
00557  M01S00536.fsetabl +++|WRTFUNC:
00558  M01S00537.fsetabl +++|      WRITE(FET,0);
00559  M01S00538.fsetabl +++|      RETURN;
00560  M01S00539.fsetabl +++|
00561  M01S00540.fsetabl +++|RWRTFUNC:
00562  M01S00001.@000000 +++|      FETEP = TRUE;                  # SET ERROR PROCESSING BIT       #
00563  M01S00541.fsetabl +++|      REWRITE(FET,0);
00564  M01S00002.@000000 +++|      FETEP = FALSE;                 # CLEAR ERROR PROCESSING BIT     #
00565  M01S00003.@000000 +++|      IF FETAT EQ O"22" THEN
00566  M01S00004.@000000 +++|        BEGIN                        # IF FATAL ERROR                 #
00567  M01S00005.@000000 +++|        TRAGIC(" WORKFILE BUFFER EMPTY ON REWRITE.$");
00568  M01S00006.@000000 +++|        END
00569  M01S00542.fsetabl +++|      RETURN;
00570  M01S00543.fsetabl +++|
00571  M01S00544.fsetabl +++|WRTRFUNC:
00572  M01S00545.fsetabl +++|      WRITER(FET,0);
00573  M01S00546.fsetabl +++|      RETURN;
00574  M01S00547.fsetabl +++|
00575  M01S00548.fsetabl +++|RWRTRFUNC:
00576  M01S00007.@000000 +++|      FETEP = TRUE;                  # SET ERROR PROCESSING BIT       #
00577  M01S00549.fsetabl +++|      REWRITR(FET,0);
00578  M01S00008.@000000 +++|      FETEP = FALSE;                 # CLEAR ERROR PROCESSING BIT     #
00579  M01S00009.@000000 +++|      IF FETAT EQ O"22" THEN
00580  M01S00010.@000000 +++|        BEGIN                        # IF FATAL ERROR                 #
00581  M01S00011.@000000 +++|        TRAGIC(" WORKFILE BUFFER EMPTY ON REWRITER. $");
00582  M01S00012.@000000 +++|        END
00583  M01S00550.fsetabl +++|      RETURN;
00584  M01S00551.fsetabl +++|
00585  M01S00552.fsetabl +++|      END
00586  M01S00553.fsetabl +++|
00587  M01S00554.fsetabl +++|    ELSE IF IOREAD AND RDIN NQ RDOUT THEN        # READ NOT DONE     #
00588  M01S00555.fsetabl +++|      BEGIN
00589  M01S00556.fsetabl +++|      IF FETLA EQ LOC(RDLIST[RDLIM])
00590  M01S00557.fsetabl +++|        THEN FETLAW = LOC(RDLIST[0]);
00591  M01S00558.fsetabl +++|
00592  M01S00559.fsetabl +++|      IF FETLA NQ LOC(RDLIST[RDIN]) THEN
00593  M01S00560.fsetabl +++|        BEGIN
00594  M01S00561.fsetabl +++|        CIOCOUNT = CIOCOUNT + 1;
00595  M01S00562.fsetabl +++|        RPHRLS(FET,0);
00596  M01S00563.fsetabl +++|        END
00597  M01S00564.fsetabl +++|      END
00598  M01S00565.fsetabl +++|
00599  M01S00566.fsetabl +++|    ELSE                               # READ AND WRITE DONE         #
00600  M01S00567.fsetabl +++|      BEGIN
00601  M01S00568.fsetabl +++|
00602  M01S00569.fsetabl +++|      CONTROL IFGQ PARANOIA,5;
00603  M01S00570.fsetabl +++|        IF IOWRITE THEN                # CHECK WRITE CRI   #
00604  M01S00571.fsetabl +++|          BEGIN
00605  M01S00572.fsetabl +++|          IF IOAPEND THEN
00606  M01S00573.fsetabl +++|            BEGIN
00607  M01S00574.fsetabl +++|            IF FETCRI NQ MAXDA+1 THEN
00608  M01S00575.fsetabl +++|              BEGIN
00609  M01S00576.fsetabl +++|              TRAGIC(" FILE SIZE INCORRECT.$");
00610  M01S00577.fsetabl +++|              END
00611  M01S00578.fsetabl +++|            END
00612  M01S00579.fsetabl +++|          ELSE
00613  M01S00580.fsetabl +++|            BEGIN
00614  M01S00581.fsetabl +++|            IF FETCRI NQ LASTDA+1 THEN
00615  M01S00582.fsetabl +++|              BEGIN
00616  M01S00583.fsetabl +++|              TRAGIC(" RANDOM ADDRESS INCORRECT.$");
00617  M01S00584.fsetabl +++|              END
00618  M01S00585.fsetabl +++|            END
00619  M01S00586.fsetabl +++|          END
00620  M01S00587.fsetabl +++|      CONTROL FI;
00621  M01S00588.fsetabl +++|
00622  M01S00589.fsetabl +++|      IOACT = FALSE;
00623  M01S00590.fsetabl +++|      IOWRITE = FALSE; IOAPEND = FALSE;
00624  M01S00591.fsetabl +++|      IOREAD = FALSE;
00625  M01S00592.fsetabl +++|      END
00626  M01S00593.fsetabl +++|
00627  M01S00594.fsetabl +++|    END
00628  M01S00595.fsetabl +++|  END
00629  M01S00596.fsetabl +++|PAGE
00630  M01S00597.fsetabl +++|PROC PAUSEIO;
00631  M01S00598.fsetabl +++|  IOBEGIN(PAUSEIO)
00632  M01S00599.fsetabl +++|#
00633  M01S00600.fsetabl +++|**        PAUSEIO - AWAIT AND/OR ENFORCE CIO COMPLETION.
00634  M01S00601.fsetabl +++|*
00635  M01S00602.fsetabl +++|*         PAUSEIO IS CALLED FOR ONE OF THREE REASONS:  (1) THE CALLER
00636  M01S00603.fsetabl +++|*         HAS STARTED SOME I/O VIA MOVEIO AND NEEDS TO WAIT FOR IT TO
00637  M01S00604.fsetabl +++|*         FINISH, OR (2) THE CALLER NEEDS SOME OLD I/O TO FINISH SO
00638  M01S00605.fsetabl +++|*         THAT THE FET CAN BE USED TO INITIATE NEW DESIRED I/O, OR
00639  M01S00606.fsetabl +++|*         (3) THE CALLER NEEDS SOME OLD I/O TO FINISH, TO FREE THE
00640  M01S00607.fsetabl +++|*         CIRCULAR BUFFER AND READ LIST SO THOSE MEMORY RESOURCES CAN
00641  M01S00608.fsetabl +++|*         BE MANAGED AND POSSIBLY RE-ASSIGNED.
00642  M01S00609.fsetabl +++|*
00643  M01S00610.fsetabl +++|*         PAUSEIO THEREFORE GUARANTEES THAT ANY WRITEABLE DATA IN THE
00644  M01S00611.fsetabl +++|*         CIRCULAR BUFFER REALLY GETS WRITTEN, AND THAT ANY INITIATED
00645  M01S00612.fsetabl +++|*         READS ARE FINISHED WITH THE DATA DISCARDED AND THE CIRCULAR
00646  M01S00613.fsetabl +++|*         BUFFER EMPTY.  PAUSEIO IS ALLOWED TO HANDLE READS WHICH
00647  M01S00614.fsetabl +++|*         HAVE BEEN REQUESTED BUT NOT YET INITIATED BY SIMPLE
00648  M01S00615.fsetabl +++|*         CANCELLATION.  THUS, PAUSEIO IS MEANINGFUL TO THE TYPE 1
00649  M01S00616.fsetabl +++|*         CALLER ONLY FOR THE WRITE DIRECTION - THE READ DIRECTION IS
00650  M01S00617.fsetabl +++|*         A THROWAWAY WHILE THE WRITE DIRECTION HAS ASSURANCE OF
00651  M01S00618.fsetabl +++|*         COMPLETION.
00652  M01S00619.fsetabl +++|*
00653  M01S00620.fsetabl +++|*         SINCE THE TYPE 3 CALLER OFTEN DOES NOT KNOW HOW (OR IS NOT
00654  M01S00621.fsetabl +++|*         ALLOWED) TO DETERMINE IF THE MEMORY RESOURCES ARE ALREADY
00655  M01S00622.fsetabl +++|*         AVAILABLE FOR REASSIGNMENT, PAUSEIO CAN BE CALLED CASUALLY,
00656  M01S00623.fsetabl +++|*         AND WILL NO-OP ITSELF IF THE DESIRED CONDITIONS ARE ALREADY
00657  M01S00624.fsetabl +++|*         TRUE.
00658  M01S00625.fsetabl +++|*
00659  M01S00626.fsetabl +++|*         PAUSEIO ALSO ZEROES OUT FETCHGUIDE.  THIS IS USED TO CONTROL
00660  M01S00627.fsetabl +++|*         THE QUANTITY OF DATA PREFETCHED AS A FUNCTION OF HOW MUCH
00661  M01S00628.fsetabl +++|*         SUCCESS WE HAVE HAD IN UTILIZING PREFETCHED DATA IN RECENT
00662  M01S00629.fsetabl +++|*         HISTORY.  A PAUSEIO CALL IS REGARDED AS AN ADMISSION THAT
00663  M01S00630.fsetabl +++|*         ANY CURRENT PREFETCHING HAS LOST ALL RELEVANCE.
00664  M01S00631.fsetabl +++|*
00665  M01S00632.fsetabl +++|*         ENTRY  IOREAD - WHETHER WE WERE PREVIOUSLY TRYING TO READ
00666  M01S00633.fsetabl +++|*                    SOMETHING WHICH MUST NOW BE THROWN AWAY.
00667  M01S00634.fsetabl +++|*                IOWRITE - WHETHER WE HAD PREVIOUSLY REQUESTED THAT
00668  M01S00635.fsetabl +++|*                    SOMETHING BE WRITTEN, WHICH MUST NOW BE BROUGHT
00669  M01S00636.fsetabl +++|*                    TO FASTEST POSSIBLE COMPLETION.
00670  M01S00637.fsetabl +++|*                RDIN, RDOUT - BRACKET ACTIVE SEGMENT OF READ LIST.
00671  M01S00638.fsetabl +++|*                FETIN, FETOUT - BRACKET CIRCULAR BUFFER DATA.
00672  M01S00639.fsetabl +++|*
00673  M01S00640.fsetabl +++|*         EXIT   IOREAD, IOWRITE, IOACT - GUARANTEED FALSE.
00674  M01S00641.fsetabl +++|*                FET - CIRCULAR BUFFER GUARANTEED EMPTY.
00675  M01S00642.fsetabl +++|*                RDLIST[ALL], RDIN, RDOUT - GUARANTEED EMPTY.
00676  M01S00643.fsetabl +++|*                FETCHGUIDE - ZEROED.
00677  M01S00644.fsetabl +++|*
00678  M01S00645.fsetabl +++|*         CALLS  WAIT, MOVEIO.
00679  M01S00646.fsetabl +++|#
00680  M01S00647.fsetabl +++|  ITEM I, J, K;
00681  M01S00648.fsetabl +++|
00682  M01S00649.fsetabl +++|  FETCHGUIDE=0;
00683  M01S00650.fsetabl +++|
00684  M01S00651.fsetabl +++|  IF IOREAD THEN
00685  M01S00652.fsetabl +++|    BEGIN
00686  M01S00653.fsetabl +++|    WAIT;                    # FOR ACTIVE TRANSFER TO FINISH         #
00687  M01S00654.fsetabl +++|    FOR I = RDIN WHILE I NQ RDOUT DO   # CLEAN OUT READLIST          #
00688  M01S00655.fsetabl +++|      BEGIN
00689  M01S00656.fsetabl +++|      I = I - 1;
00690  M01S00657.fsetabl +++|      IF I LS 0 THEN I = RDLIM - 1;
00691  M01S00658.fsetabl +++|      RDLIST[I] = 0;
00692  M01S00659.fsetabl +++|      END
00693  M01S00660.fsetabl +++|    FETOUT = FETIN;          # ABANDON CIRCULAR BUFFER CONTENT       #
00694  M01S00661.fsetabl +++|    IOACT = FALSE;
00695  M01S00662.fsetabl +++|    IOREAD = FALSE;
00696  M01S00663.fsetabl +++|    END
00697  M01S00664.fsetabl +++|
00698  M01S00665.fsetabl +++|  ELSE IF IOWRITE THEN
00699  M01S00666.fsetabl +++|    BEGIN
00700  M01S00667.fsetabl +++|    WHYLE IOWRITE DO
00701  M01S00668.fsetabl +++|      BEGIN
00702  M01S00669.fsetabl +++|      MOVEIO;
00703  M01S00670.fsetabl +++|      WAIT;
00704  M01S00671.fsetabl +++|      END
00705  M01S00672.fsetabl +++|    END
00706  M01S00673.fsetabl +++|
00707  M01S00674.fsetabl +++|  IOEND
00708  M01S00675.fsetabl +++|PAGE
00709  M01S00676.fsetabl +++|PROC SETREAD((DA));
00710  M01S00677.fsetabl +++|  BEGIN
00711  M01S00678.fsetabl +++|#
00712  M01S00679.fsetabl +++|**        SETREAD - ADD DISK ADDRESS TO READ LIST.
00713  M01S00680.fsetabl +++|*
00714  M01S00681.fsetabl +++|*         SETREAD PERFORMS FET INITIALIZATION AS NEEDED, TO ASSURE
00715  M01S00682.fsetabl +++|*         THAT THE BUFFER AND FET ARE TURNED AROUND TO THE INPUT
00716  M01S00683.fsetabl +++|*         DIRECTION, AND APPENDS THE SPECIFIED DISK ADDRESS ONTO THE
00717  M01S00684.fsetabl +++|*         READ LIST.  THE CALLER IS RESPONSIBLE TO ASSURE THAT
00718  M01S00685.fsetabl +++|*         SETREAD WILL NOT ENCOUNTER A FULL READ LIST.  THE CALLER IS
00719  M01S00686.fsetabl +++|*         ALLOWED TO CALL SETREAD FOR AN ADDRESS ALREADY LISTED, IN
00720  M01S00687.fsetabl +++|*         WHICH CASE SETREAD NO-OPS ITSELF.  THE USER IS REQUIRED TO
00721  M01S00688.fsetabl +++|*         PROVIDE AN IN-BOUNDS DISK ADDRESS, AND TO HAVE USED PAUSEIO
00722  M01S00689.fsetabl +++|*         TO COMPLETE ANY PREVIOUS OUTPUT ACTIVITIES.
00723  M01S00690.fsetabl +++|*
00724  M01S00691.fsetabl +++|*         ENTRY  DA - SECTOR NUMBER FOR DESIRED PRU.
00725  M01S00692.fsetabl +++|*                IOREAD - WHETHER FET ALREADY INITIALIZED FOR INPUT.
00726  M01S00693.fsetabl +++|*                IOWRITE, MAXDA - WHEN CONSISTENCY CHECKING IS ENABLED,
00727  M01S00694.fsetabl +++|*                    THESE ARE USED TO VERIFY VALIDITY.
00728  M01S00695.fsetabl +++|*                RDIN, RDOUT - BRACKET ACTIVE SEGMENT OF READ LIST.
00729  M01S00696.fsetabl +++|*                RDLIST[ALL] - SETUP FOR EXISTING DISK ADDRESSES
00730  M01S00697.fsetabl +++|*                    AND WITH ZEROES IN EXCESS LIST AREAS.
00731  M01S00698.fsetabl +++|*
00732  M01S00699.fsetabl +++|*         EXIT   IOREAD, IOACT - TRUE.
00733  M01S00700.fsetabl +++|*                FET AND CIRCULAR BUFFER - VALID FOR MOVEIO CALL.
00734  M01S00701.fsetabl +++|*                RDIN, RDOUT - UPDATED FOR ENLARGED READ LIST.
00735  M01S00702.fsetabl +++|*                RDLIST[NEW RDIN-1] - DISK ADDRESS STORED HERE.
00736  M01S00703.fsetabl +++|*
00737  M01S00704.fsetabl +++|*         CALLS  TRAGIC, INITFET.
00738  M01S00705.fsetabl +++|#
00739  M01S00706.fsetabl +++|  ITEM DA;
00740  M01S00707.fsetabl +++|  ITEM P;
00741  M01S00708.fsetabl +++|
00742  M01S00709.fsetabl +++|  CONTROL IFGQ PARANOIA,5;
00743  M01S00710.fsetabl +++|    IF DA LQ 0 OR DA GR MAXDA THEN
00744  M01S00711.fsetabl +++|      BEGIN
00745  M01S00712.fsetabl +++|      TRAGIC(" OUT OF BOUNDS PRU ADDRESS ON READ (1).$");
00746  M01S00713.fsetabl +++|      END
00747  M01S00714.fsetabl +++|    IF IOWRITE THEN TRAGIC(" WORKFILE BUFFER FULL ON READ.$");
00748  M01S00715.fsetabl +++|  CONTROL FI;
00749  M01S00716.fsetabl +++|
00750  M01S00717.fsetabl +++|  IF NOT IOREAD THEN
00751  M01S00718.fsetabl +++|    BEGIN
00752  M01S00719.fsetabl +++|    INITFET(DISK,DSKSIZ);
00753  M01S00720.fsetabl +++|
00754  M01S00721.fsetabl +++|    RDIN = 0;
00755  M01S00722.fsetabl +++|    RDOUT = 0;
00756  M01S00723.fsetabl +++|    FETLAW = LOC(RDLIST[0]);
00757  M01S00724.fsetabl +++|
00758  M01S00725.fsetabl +++|    IOACT = TRUE;
00759  M01S00726.fsetabl +++|    IOREAD = TRUE;
00760  M01S00727.fsetabl +++|    END
00761  M01S00728.fsetabl +++|
00762  M01S00729.fsetabl +++|  FOR P = RDOUT WHILE RDLIST[P] NQ DA DO
00763  M01S00730.fsetabl +++|    BEGIN
00764  M01S00731.fsetabl +++|    IF P EQ RDIN THEN
00765  M01S00732.fsetabl +++|      BEGIN
00766  M01S00733.fsetabl +++|      RDLIST[RDIN] = DA;
00767  M01S00734.fsetabl +++|      RDIN = RDIN + 1;
00768  M01S00735.fsetabl +++|      IF RDIN EQ RDLIM THEN RDIN = 0;
00769  M01S00736.fsetabl +++|      CONTROL IFGQ PARANOIA,5;
00770  M01S00737.fsetabl +++|        IF RDIN EQ RDOUT THEN TRAGIC(" RPHRLS LIST BUFFER IS FULL.$");
00771  M01S00738.fsetabl +++|      CONTROL FI;
00772  M01S00739.fsetabl +++|      END
00773  M01S00740.fsetabl +++|
00774  M01S00741.fsetabl +++|    ELSE
00775  M01S00742.fsetabl +++|      BEGIN
00776  M01S00743.fsetabl +++|      P = P + 1;
00777  M01S00744.fsetabl +++|      IF P EQ RDLIM THEN P = 0;
00778  M01S00745.fsetabl +++|      END
00779  M01S00746.fsetabl +++|
00780  M01S00747.fsetabl +++|    END
00781  M01S00748.fsetabl +++|
00782  M01S00749.fsetabl +++|  END
00783  M01S00750.fsetabl +++|PAGE
00784  M01S00751.fsetabl +++|PROC PREFETCH((DD));
00785  M01S00752.fsetabl +++|  BEGIN
00786  M01S00753.fsetabl +++|#
00787  M01S00754.fsetabl +++|**        ARRANGE READ LIST FOR SEVERAL PREFETCHES.
00788  M01S00755.fsetabl +++|*
00789  M01S00756.fsetabl +++|*         PREFETCH SHOULD BE CALLED ONCE PER SECTOR PROCESSED, BY
00790  M01S00757.fsetabl +++|*         THOSE PROCESSES WHICH ACT UPON POTENTIALLY LARGE SERIES OF
00791  M01S00758.fsetabl +++|*         DISK SECTORS IN EITHER THE FORWARD OR BACKWARD LOGICAL
00792  M01S00759.fsetabl +++|*         ORDER OF TEXT IN THE FILE.  THE LOGICAL ORDER CAN BE QUITE
00793  M01S00760.fsetabl +++|*         DIFFERENT FROM THE PHYSICAL ORDER DUE TO THE TREE LINKAGES.
00794  M01S00761.fsetabl +++|*
00795  M01S00762.fsetabl +++|*         PREFETCH DETERMINES SEVERAL DISK ADDRESSES WHOSE NEED IS
00796  M01S00763.fsetabl +++|*         ANTICIPATED ON BEHALF OF THE CALLER, AND USES SETREAD TO
00797  M01S00764.fsetabl +++|*         ARRANGE THAT SUCH SECTORS CAN BE READ IN THE LOGICAL ORDER.
00798  M01S00765.fsetabl +++|*         IT IS THE CALLING PROCESSES RESPONSIBILITY TO OCCASIONALLY
00799  M01S00766.fsetabl +++|*         CALL MOVEIO FOR ACTUAL INITIATION OF CIO.
00800  M01S00767.fsetabl +++|*
00801  M01S00768.fsetabl +++|*         TO MINIMIZE OVERHEAD, PREFETCH CHOOSES A DEPTH OF
00802  M01S00769.fsetabl +++|*         PREFETCHING BASED ON APPARENT RECENT SUCCESS IN UTILIZING
00803  M01S00770.fsetabl +++|*         PREFETCHED DATA, AND SUCCESSIVELY UPDATES THE DEPTH OF
00804  M01S00771.fsetabl +++|*         PREFETCH.  THIS DEPTH INDICATOR MAY BE CLEARED BY PAUSEIO
00805  M01S00772.fsetabl +++|*         IN RECOGNITION OF THE ABANDONMENT OF A READ, OR BY THE
00806  M01S00773.fsetabl +++|*         CALLER WHEN A LOGICAL BREAK IN SEQUENTIAL PROCESSING IS
00807  M01S00774.fsetabl +++|*         KNOWN TO OCCUR.
00808  M01S00775.fsetabl +++|*
00809  M01S00776.fsetabl +++|*         TO MINIMIZE OVERHEAD, PREFETCH ATTEMPTS TO PRODUCE EITHER
00810  M01S00777.fsetabl +++|*         ZERO OR SEVERAL NEW ENTRIES IN THE READ LIST, AND ATTEMPTS
00811  M01S00778.fsetabl +++|*         TO NO-OP ITSELF WHEN IT IS RECOGNIZED THAT ONLY ONE OR A
00812  M01S00779.fsetabl +++|*         FEW ENTRIES COULD BE PRODUCED.  PREFETCH MUST KEEP THE
00813  M01S00780.fsetabl +++|*         DEPTH OF PREFETCHING WITHIN THE LEGAL BOUNDS OF THE SETREAD
00814  M01S00781.fsetabl +++|*         ROUTINE.
00815  M01S00782.fsetabl +++|*
00816  M01S00783.fsetabl +++|*         THE DEPTH OF PREFETCHING IS LIMITED TO THE SMALLEST OF THE
00817  M01S00784.fsetabl +++|*         FOLLOWING FACTORS - (1) THE FETCHGUIDE QUANTITY, WHICH
00818  M01S00785.fsetabl +++|*         REPRESENTS RECENT SUCCESS, (2) THE LEGAL LIMITS IMPOSED BY
00819  M01S00786.fsetabl +++|*         SETREAD, AND (3) ONE AND A HALF TIMES THE SIZE OF THE
00820  M01S00787.fsetabl +++|*         CIRCULAR BUFFER.  PREFETCHING IS SET UP ONLY WHEN THE
00821  M01S00788.fsetabl +++|*         EXISTING QUEUE IS LESS THAN HALF THE DESIRED DEPTH.  FOR
00822  M01S00789.fsetabl +++|*         LARGER QUEUES, IT IS ANTICIPATED THE QUEUE WILL BE SHRUNK
00823  M01S00790.fsetabl +++|*         BACK DOWN AT SOME FUTURE CALL TO PREFETCH, AT WHICH TIME
00824  M01S00791.fsetabl +++|*         A LARGE BATCH OF QUEUE ENTIRES CAN BE PRODUCED.
00825  M01S00792.fsetabl +++|*
00826  M01S00793.fsetabl +++|*         ONCE PREFETCH DECIDES TO SET UP A BATCH OF READ LIST QUEUE
00827  M01S00794.fsetabl +++|*         ENTRIES, IT IDENTIFIES THE SECTORS TO BE READ AS ALL DATA
00828  M01S00795.fsetabl +++|*         (BOTTOM) LEVEL PRUS, POINTED TO BY THE NEXT-TO-BOTTOM
00829  M01S00796.fsetabl +++|*         DIRECTORY, LOGICALLY ADJACENT TO THE CURRENT DATA SECTOR IN
00830  M01S00797.fsetabl +++|*         THE SPECIFIED DIRECTION.  PREFETCH ALSO CAN QUEUE THE NEXT
00831  M01S00798.fsetabl +++|*         LOGICALLY ADJACENT NEXT-TO-BOTTOM DIRECTORY, BY LOOKING
00832  M01S00799.fsetabl +++|*         ANOTHER LEVEL TOWARDS THE ROOT OF THE TREE.
00833  M01S00800.fsetabl +++|*
00834  M01S00801.fsetabl +++|*         ENTRY  FETCHGUIDE - CURRENT GUIDELINE FOR DEPTH.
00835  M01S00802.fsetabl +++|*                RDIN, RDOUT - DESCRIBE CURRENT READ LIST.
00836  M01S00803.fsetabl +++|*                DSKSIZ - CIRCULAR BUFFER SIZE.
00837  M01S00804.fsetabl +++|*                PALVL - DEEPEST TREE LEVEL CURRENTLY VALID.
00838  M01S00805.fsetabl +++|*                PACACHE[ALL] - CACHE FRAMES AT EACH TREE LEVEL.
00839  M01S00806.fsetabl +++|*                BFPRU[ALL] - DISK ADDRESSES FOR EACH FRAME.
00840  M01S00807.fsetabl +++|*                PAFINAL[ALL] - LAST WORDS IN EACH SECTOR OF TREE.
00841  M01S00808.fsetabl +++|*                IOWRITE - WHETHER FET INTERLOCKED FOR OUTPUT.
00842  M01S00809.fsetabl +++|*
00843  M01S00810.fsetabl +++|*         EXIT   RDLIST[ALL], RDIN, RDOUT - UPDATED.
00844  M01S00811.fsetabl +++|*                FETCHGUIDE - INCREMENTED UNLESS DIRECTORY INCLUDED.
00845  M01S00812.fsetabl +++|*
00846  M01S00813.fsetabl +++|*         CALLS  LSTAVAIL, LSTUSAGE, MIN, MAX, SETREAD.
00847  M01S00814.fsetabl +++|*
00848  M01S00815.fsetabl +++|*         USES   P<PRU> WITH RESTORATION.
00849  M01S00816.fsetabl +++|#
00850  M01S00817.fsetabl +++|  ITEM DD,N;
00851  M01S00818.fsetabl +++|  ITEM DSTOP;
00852  M01S00819.fsetabl +++|  ITEM DONE B;
00853  M01S00820.fsetabl +++|  ITEM TMPPRU;
00854  M01S00821.fsetabl +++|  ITEM TMPPL,TMPD;
00855  M01S00822.fsetabl +++|  ITEM I;
00856  M01S00823.fsetabl +++|
00857  M01S00824.fsetabl +++|  IF FETCHGUIDE LS 0 OR IOWRITE THEN RETURN;
00858  M01S00825.fsetabl +++|
00859  M01S00826.fsetabl +++|  FETCHGUIDE=FETCHGUIDE+2;
00860  M01S00827.fsetabl +++|  N=LSTAVAIL;
00861  M01S00828.fsetabl +++|  N=MIN(N-3,3*DSKSIZ/O"200");
00862  M01S00829.fsetabl +++|  N=MIN(N,FETCHGUIDE);
00863  M01S00830.fsetabl +++|
00864  M01S00831.fsetabl +++|  IF LSTUSAGE LQ N/2 THEN
00865  M01S00832.fsetabl +++|    BEGIN
00866  M01S00833.fsetabl +++|    TMPPRU = P<PRU>;
00867  M01S00834.fsetabl +++|
00868  M01S00835.fsetabl +++|    DONE = FALSE;
00869  M01S00836.fsetabl +++|    FOR TMPPL = PALVL-1 STEP -1 WHILE TMPPL GQ 0 AND NOT DONE DO
00870  M01S00837.fsetabl +++|      BEGIN
00871  M01S00838.fsetabl +++|      TMPD = PADISP[TMPPL] + DD;
00872  M01S00839.fsetabl +++|      P<PRU> = LOC(BFPRU[PACACHE[TMPPL]]);
00873  M01S00840.fsetabl +++|
00874  M01S00841.fsetabl +++|      IF DD GR 0 THEN DSTOP = MIN(PAFINAL[TMPPL]+1,TMPD+N);
00875  M01S00842.fsetabl +++|      ELSE DSTOP = MAX(0,TMPD-N);
00876  M01S00843.fsetabl +++|
00877  M01S00844.fsetabl +++|      IF DSTOP EQ TMPD+N*DD THEN DONE = TRUE;
00878  M01S00845.fsetabl +++|      ELSE FETCHGUIDE=-1;
00879  M01S00846.fsetabl +++|      N=1;
00880  M01S00847.fsetabl +++|
00881  M01S00848.fsetabl +++|      FOR TMPD = TMPD STEP DD WHILE TMPD NQ DSTOP DO
00882  M01S00849.fsetabl +++|        BEGIN
00883  M01S00850.fsetabl +++|        FOR I=0 STEP 1 UNTIL MAXCACHE DO
00884  M01S00851.fsetabl +++|          BEGIN
00885  M01S00852.fsetabl +++|          IF BFDA[I] EQ DIRDA[TMPD] THEN TEST TMPD;
00886  M01S00853.fsetabl +++|          END
00887  M01S00854.fsetabl +++|        SETREAD(DIRDA[TMPD]);
00888  M01S00855.fsetabl +++|        END
00889  M01S00856.fsetabl +++|
00890  M01S00857.fsetabl +++|      END
00891  M01S00858.fsetabl +++|
00892  M01S00859.fsetabl +++|    P<PRU> = TMPPRU;
00893  M01S00860.fsetabl +++|    END
00894  M01S00861.fsetabl +++|  END
00895  M01S00862.fsetabl +++|PAGE
00896  M01S00863.fsetabl +++|PROC READPA;
00897  M01S00864.fsetabl +++|  IOBEGIN(READPA)
00898  M01S00865.fsetabl +++|#
00899  M01S00866.fsetabl +++|**        READPA - READ NEXT DEEPER TREE PATH SECTOR.
00900  M01S00867.fsetabl +++|*
00901  M01S00868.fsetabl +++|*         READPA IS USED TO ACCESS THE SECTOR OF DIRECTORY OR DATA
00902  M01S00869.fsetabl +++|*         FOR A SPECIFIED LEVEL OF THE TREE.  THE HIGHER LEVELS OF
00903  M01S00870.fsetabl +++|*         THE TREE MUST ALREADY BE PROPERLY FILLED IN.  ANY RESIDUAL
00904  M01S00871.fsetabl +++|*         SECTOR IN THE CURRENT TREE LEVEL MUST BE PROPERLY RELEASED
00905  M01S00872.fsetabl +++|*         FROM OWNERSHIP, SO THAT READPA WILL NOT NEED TO CONCERN
00906  M01S00873.fsetabl +++|*         ITSELF WITH THE UPDATING OF ALTERED DATA TO DISK.  THE
00907  M01S00874.fsetabl +++|*         CALLER DOES NOT NEED TO SETUP THE FET AND CIRCULAR BUFFER
00908  M01S00875.fsetabl +++|*         FOR INPUT, AND READPA WILL TAKE CARE OF THAT IF NEEDED.
00909  M01S00876.fsetabl +++|*
00910  M01S00877.fsetabl +++|*         WHEN POSSIBLE, READPA WILL ACCESS THE DESIRED DISK SECTOR
00911  M01S00878.fsetabl +++|*         BY SIMPLY IDENTIFYING IT IN CACHE AND CLAIMING OWNERSHIP OF
00912  M01S00879.fsetabl +++|*         THE RIGHT CACHE FRAME.  WHEN THE CACHE DOES NOT PROVIDE THE
00913  M01S00880.fsetabl +++|*         NECESSARY DATA, READPA WILL READ IT FROM DISK.  IF THE FET
00914  M01S00881.fsetabl +++|*         AND CIRCULAR BUFFER ARE PREVIOUSLY INTERLOCKED FOR PENDING
00915  M01S00882.fsetabl +++|*         OUTPUT, READPA WILL ASSURE THAT THE UNFINISHED WRITES GET
00916  M01S00883.fsetabl +++|*         DONE.  IF THE FET IS ALREADY SETUP FOR INPUT BUT HAS THE
00917  M01S00884.fsetabl +++|*         WRONG DISK ADDRESS COMING IN AT THE FRONT OF THE CIRCULAR
00918  M01S00885.fsetabl +++|*         BUFFER, READPA WILL DISCARD SUCH INCORRECT INPUT AND
00919  M01S00886.fsetabl +++|*         REINITIALIZE TO INPUT THE RIGHT DISK ADDRESS.  IF THE FET
00920  M01S00887.fsetabl +++|*         IS ALREADY SET UP FOR INPUT WITH THE RIGHT SECTOR IN OR
00921  M01S00888.fsetabl +++|*         COMING INTO THE CIRCULAR BUFFER, READPA WILL MAKE USE OF
00922  M01S00889.fsetabl +++|*         THAT CIO ACTIVITY.
00923  M01S00890.fsetabl +++|*
00924  M01S00891.fsetabl +++|*         IF READPA READS THE SECTOR FROM DISK, IT CLEANS UP THE
00925  M01S00892.fsetabl +++|*         RANDOM READ LIST AFTERWARDS, ATTEMPTING TO SHUFFLE THE
00926  M01S00893.fsetabl +++|*         ACTIVE SEGMENT OF THE READ LIST TO MAXIMIZE THE REMAINING
00927  M01S00894.fsetabl +++|*         LIST CAPACITY BEFORE WRAPAROUND.  READPA ALSO CHECKS TO SEE
00928  M01S00895.fsetabl +++|*         IF THE BUFFER IS SUFFICIENTLY EMPTY WITH A SUFFICIENTLY
00929  M01S00896.fsetabl +++|*         FULL PREFETCH LIST SO THAT ANTICIPATORY READS SHOULD BE
00930  M01S00897.fsetabl +++|*         STARTED.
00931  M01S00898.fsetabl +++|*
00932  M01S00899.fsetabl +++|*         ENTRY  TEMP - SECTOR NUMBER.
00933  M01S00900.fsetabl +++|*                PL - CURRENT PATH LEVEL.
00934  M01S00901.fsetabl +++|*                PACACHE[ALL] - CACHE FRAMES CURRENTLY OWNED.
00935  M01S00902.fsetabl +++|*                CACHEOWNED[ALL] - SETUP.
00936  M01S00903.fsetabl +++|*                BFDA[ALL] - IDENTIFY SECTOR ADDRESSES EACH FRAME.
00937  M01S00904.fsetabl +++|*                BFHEAD[ALL] - HEADER WORDS FOR EACH CACHED SECTOR.
00938  M01S00905.fsetabl +++|*                ACCTPRU - PRU TRANSFER COUNT.
00939  M01S00906.fsetabl +++|*                IOWRITE - WHETHER FET ALREADY SET FOR WRITES.
00940  M01S00907.fsetabl +++|*                RDIN, RDOUT - READ LIST BRACKETING.
00941  M01S00908.fsetabl +++|*                RDLIST[ALL] - SETUP.
00942  M01S00909.fsetabl +++|*                IOREAD - WHETHER SOME READ ALREADY SCHEDULED.
00943  M01S00910.fsetabl +++|*                FETCHGUIDE - PREFETCH QUANTITY GUIDELINE.
00944  M01S00911.fsetabl +++|*                QUARTER - APPROX ONE FOURTH BUFFER SIZE.
00945  M01S00912.fsetabl +++|*
00946  M01S00913.fsetabl +++|*         EXIT   PACACHE[PL] - INDICATES CACHE FRAME WITH SECTOR.
00947  M01S00914.fsetabl +++|*                CACHEOWNED[PACACHE[PL]] - TRUE.
00948  M01S00915.fsetabl +++|*                ANY OLD CACHE FRAMES MAY HAVE BEEN FLUSHED TO
00949  M01S00916.fsetabl +++|*                    DISK AND/OR REASSIGNED IN MEMORY.
00950  M01S00917.fsetabl +++|*                PAHEAD[PL] - HEADER WORD.
00951  M01S00918.fsetabl +++|*                IOWRITE - FALSE IF NOT CACHE HIT.
00952  M01S00919.fsetabl +++|*                IOREAD - POSSIBLY CHANGED.
00953  M01S00920.fsetabl +++|*                RDOUT - ADVANCED IF DISK READ DONE.
00954  M01S00921.fsetabl +++|*                RDIN - RDIN AND RDOUT POSSIBLY RELOCATED IF READ
00955  M01S00922.fsetabl +++|*                    DONE AND CIO TERMINATED.
00956  M01S00923.fsetabl +++|*                ACCTPRU - INCREMENTED IF NO CACHE HIT.
00957  M01S00924.fsetabl +++|*                FETCHGUIDE - POSSIBLY NEW VALUE.
00958  M01S00925.fsetabl +++|*                ANTICIPATORY CIO POSSIBLY CALLED.
00959  M01S00926.fsetabl +++|*
00960  M01S00927.fsetabl +++|*         CALLS  TRAGIC, COUNTCACHE, FLUSHCACHE, DISOWNCACHE,
00961  M01S00928.fsetabl +++|*                WIOSTAT, PAUSEIO, ALLOCCACHE, SETREAD, MOVEIO,
00962  M01S00929.fsetabl +++|*                DELAY, RECALL, RDWBUF, BUFUSAGE.
00963  M01S00930.fsetabl +++|*
00964  M01S00931.fsetabl +++|*         USES   P<TOO>.
00965  M01S00932.fsetabl +++|#
00966  M01S00933.fsetabl +++|  ITEM X1;
00967  M01S00934.fsetabl +++|
00968  M01S00935.fsetabl +++|  CONTROL IFGQ PARANOIA,5;
00969  M01S00936.fsetabl +++|    IF PADIRTY[PL] THEN TRAGIC(" ALTERED PRU WAS NOT REWRITTEN.$");
00970  M01S00937.fsetabl +++|  CONTROL FI;
00971  M01S00938.fsetabl +++|
00972  M01S00939.fsetabl +++|  IF COUNTCACHE LQ 2 THEN FLUSHCACHE;
00973  M01S00940.fsetabl +++|
00974  M01S00941.fsetabl +++|  # FIRST RELEASE CURRENTLY OWNED SECTOR IF ANY #
00975  M01S00942.fsetabl +++|  DISOWNCACHE(PACACHE[PL]);
00976  M01S00943.fsetabl +++|
00977  M01S00944.fsetabl +++|  FOR X1=0 STEP 1 UNTIL MAXCACHE DO
00978  M01S00945.fsetabl +++|    BEGIN                     # TRY TO FIND IN CACHE        #
00979  M01S00946.fsetabl +++|    IF BFDA[X1] EQ TEMP THEN        # GOT IT  #
00980  M01S00947.fsetabl +++|      BEGIN
00981  M01S00948.fsetabl +++|      CONTROL IFGQ PARANOIA,5;
00982  M01S00949.fsetabl +++|        IF CACHEOWNED[X1] THEN
00983  M01S00950.fsetabl +++|          BEGIN
00984  M01S00951.fsetabl +++|          TRAGIC(" WORKFILE BUFFER ALLOCATED TWICE.$");
00985  M01S00952.fsetabl +++|          END
00986  M01S00953.fsetabl +++|      CONTROL FI;
00987  M01S00954.fsetabl +++|      PACACHE[PL]=X1;
00988  M01S00955.fsetabl +++|      CACHEOWNED[X1]=TRUE;
00989  M01S00956.fsetabl +++|      PAHEAD[PL] = BFHEAD[X1];
00990  M01S00957.fsetabl +++|      CONTROL IFEQ MULTI,1;
00991  M01S00958.fsetabl +++|        WIOSTAT(1);          # ACCUMULATE CACHE HITS #
00992  M01S00959.fsetabl +++|      CONTROL FI;
00993  M01S00960.fsetabl +++|      IORET
00994  M01S00961.fsetabl +++|     END
00995  M01S00962.fsetabl +++|   END
00996  M01S00963.fsetabl +++|
00997  M01S00964.fsetabl +++|  CONTROL IFEQ MULTI,1;
00998  M01S00965.fsetabl +++|    WIOSTAT(2);              # ACCUMULATE SECTORS READ #
00999  M01S00966.fsetabl +++|    ACCTPRU=ACCTPRU+1;
01000  M01S00967.fsetabl +++|  CONTROL FI;
01001  M01S00968.fsetabl +++|
01002  M01S00969.fsetabl +++|  IF IOWRITE THEN            # DO ANY PENDING WRITES       #
01003  M01S00970.fsetabl +++|    BEGIN
01004  M01S00971.fsetabl +++|    PAUSEIO;
01005  M01S00972.fsetabl +++|    CONTROL IFEQ MULTI,1;
01006  M01S00973.fsetabl +++|      WIOSTAT(3);            # ACCUMULATE FLUSHED WRITES #
01007  M01S00974.fsetabl +++|    CONTROL FI;
01008  M01S00975.fsetabl +++|    END
01009  M01S00976.fsetabl +++|
01010  M01S00977.fsetabl +++|  CONTROL IFGQ PARANOIA,5;
01011  M01S00978.fsetabl +++|    IF TEMP LQ 0 OR TEMP GR MAXDA THEN
01012  M01S00979.fsetabl +++|      BEGIN
01013  M01S00980.fsetabl +++|      TRAGIC(" OUT OF BOUNDS PRU ADDRESS ON READ (2).$");
01014  M01S00981.fsetabl +++|      END
01015  M01S00982.fsetabl +++|  CONTROL FI;
01016  M01S00983.fsetabl +++|
01017  M01S00984.fsetabl +++|  PADA[PL] = TEMP;
01018  M01S00985.fsetabl +++|  ALLOCCACHE;
01019  M01S00986.fsetabl +++|
01020  M01S00987.fsetabl +++|  IF IOREAD AND RDLIST[RDOUT] NQ TEMP THEN
01021  M01S00988.fsetabl +++|    BEGIN
01022  M01S00989.fsetabl +++|    PAUSEIO;
01023  M01S00990.fsetabl +++|    CONTROL IFEQ MULTI,1;
01024  M01S00991.fsetabl +++|      WIOSTAT(4);            # ACCUMULATE READ REJECTS #
01025  M01S00992.fsetabl +++|    CONTROL FI;
01026  M01S00993.fsetabl +++|    END
01027  M01S00994.fsetabl +++|
01028  M01S00995.fsetabl +++|  IF NOT IOREAD THEN
01029  M01S00996.fsetabl +++|    BEGIN
01030  M01S00997.fsetabl +++|    SETREAD(TEMP);
01031  M01S00998.fsetabl +++|    FETCHGUIDE=2;
01032  M01S00999.fsetabl +++|    END
01033  M01S01000.fsetabl +++|
01034  M01S01001.fsetabl +++|  WHYLE FETIN EQ FETOUT DO
01035  M01S01002.fsetabl +++|    BEGIN
01036  M01S01003.fsetabl +++|    CONTROL IFEQ MULTI,1;
01037  M01S01004.fsetabl +++|      WIOSTAT(10);           # ACCUMULATE NOT ALREADY IN BUFFER #
01038  M01S01005.fsetabl +++|    CONTROL FI;
01039  M01S01006.fsetabl +++|    MOVEIO;
01040  M01S01007.fsetabl +++|    CONTROL IFEQ MULTI,1;
01041  M01S01008.fsetabl +++|      WAIT;
01042  M01S01009.fsetabl +++|    CONTROL FI;
01043  M01S01010.fsetabl +++|    CONTROL IFEQ SINGLE,1;
01044  M01S01011.fsetabl +++|      IF NOT FETDUN THEN DELAY;
01045  M01S01012.fsetabl +++|    CONTROL FI;
01046  M01S01013.fsetabl +++|    END
01047  M01S01014.fsetabl +++|
01048  M01S01015.fsetabl +++|  P<TOO> = LOC(BFPRU[PACACHE[PL]]);
01049  M01S01016.fsetabl +++|  RDWBUF(O"100");
01050  M01S01017.fsetabl +++|  PAHEAD[PL] = BFHEAD[PACACHE[PL]];
01051  M01S01018.fsetabl +++|
01052  M01S01019.fsetabl +++|  CONTROL IFGQ PARANOIA,5;
01053  M01S01020.fsetabl +++|    IF TEMP NQ RDLIST[RDOUT] THEN
01054  M01S01021.fsetabl +++|      BEGIN
01055  M01S01022.fsetabl +++|      TRAGIC(" RANDOM READ LIST INCORRECT.$");
01056  M01S01023.fsetabl +++|      END
01057  M01S01024.fsetabl +++|    IF PADA[PL] NQ TEMP THEN TRAGIC(" PRU CONTENT INCORRECT.$");
01058  M01S01025.fsetabl +++|    IF PADIRTY[PL] THEN
01059  M01S01026.fsetabl +++|      BEGIN
01060  M01S01027.fsetabl +++|      TRAGIC(" STATUS FLAGS SHOULD HAVE BEEN CLEARED.$");
01061  M01S01028.fsetabl +++|      END
01062  M01S01029.fsetabl +++|  CONTROL FI;
01063  M01S01030.fsetabl +++|
01064  M01S01031.fsetabl +++|  RDLIST[RDOUT] = 0;
01065  M01S01032.fsetabl +++|  IF RDOUT EQ RDLIM-1 THEN RDOUT = 0;
01066  M01S01033.fsetabl +++|  ELSE RDOUT = RDOUT + 1;
01067  M01S01034.fsetabl +++|  IF FETDUN AND RDIN EQ RDOUT THEN
01068  M01S01035.fsetabl +++|    BEGIN
01069  M01S01036.fsetabl +++|    RDIN=0;
01070  M01S01037.fsetabl +++|    RDOUT=0;
01071  M01S01038.fsetabl +++|    FETCHGUIDE=ABS(FETCHGUIDE);
01072  M01S01039.fsetabl +++|    END
01073  M01S01040.fsetabl +++|
01074  M01S01041.fsetabl +++|  IF BUFUSAGE LQ QUARTER THEN MOVEIO;
01075  M01S01042.fsetabl +++|
01076  M01S01043.fsetabl +++|  IOEND
01077  M01S01044.fsetabl +++|PAGE
01078  M01S01045.fsetabl +++|PROC ALLOC;
01079  M01S01046.fsetabl +++|  BEGIN
01080  M01S01047.fsetabl +++|#
01081  M01S01048.fsetabl +++|**        ALLOC - ASSIGN DISK ADDRESS.
01082  M01S01049.fsetabl +++|*
01083  M01S01050.fsetabl +++|*         ALLOC IS CALLED WHEN A NEW SECTOR MUST BE CREATED.  THE
01084  M01S01051.fsetabl +++|*         NEXT PRU OFF THE LOGICAL END OF THE FILE IS CHOSEN.  NOTE
01085  M01S01052.fsetabl +++|*         THAT THE LOGICAL END OF THE FILE REPRESENTS THOSE ADDRESSES
01086  M01S01053.fsetabl +++|*         WHICH HAVE BEEN ALLOCATED.  THE PHYSICAL END OF THE FILE
01087  M01S01054.fsetabl +++|*         REPRESENTS THOSE ADDRESSES ACTUALLY WRITTEN ONTO THE FILE,
01088  M01S01055.fsetabl +++|*         AND CAN BE A SMALLER NUMBER THAN THE LOGICAL END.
01089  M01S01056.fsetabl +++|*
01090  M01S01057.fsetabl +++|*         ENTRY  PL - CURRENT PATH LEVEL.
01091  M01S01058.fsetabl +++|*                DANEXT - ALLOCATION THRESHOLD.
01092  M01S01059.fsetabl +++|*
01093  M01S01060.fsetabl +++|*         EXIT   PADA[PL] - SETUP.
01094  M01S01061.fsetabl +++|*                DANEXT - INCREMENTED.
01095  M01S01062.fsetabl +++|*
01096  M01S01063.fsetabl +++|*         CALLS  TRAGIC.
01097  M01S01064.fsetabl +++|#
01098  M01S01065.fsetabl +++|  CONTROL IFGQ PARANOIA,5;
01099  M01S01066.fsetabl +++|    IF PADIRTY[PL] THEN TRAGIC(" OLD SECTOR MUST BE WRITTEN.$");
01100  M01S01067.fsetabl +++|  CONTROL FI;
01101  M01S01068.fsetabl +++|  PADA[PL] = DANEXT;
01102  M01S01069.fsetabl +++|  DANEXT = DANEXT + 1;
01103  M01S01070.fsetabl +++|  END
01104  M01S01071.fsetabl +++|
01105  M01S01072.fsetabl +++|
01106  M01S01073.fsetabl +++|PROC DEALLOC;
01107  M01S01074.fsetabl +++|  BEGIN
01108  M01S01075.fsetabl +++|#
01109  M01S01076.fsetabl +++|**        DEALLOC - DISCARD DISK SECTOR.
01110  M01S01077.fsetabl +++|*
01111  M01S01078.fsetabl +++|*         DEALLOC IS USED TO DISCARD A DISK SECTOR WHICH CAN NO
01112  M01S01079.fsetabl +++|*         LONGER BE USED.  THIS CAN BE NEEDED WHEN A SECTOR HAS
01113  M01S01080.fsetabl +++|*         OVERFLOWED AND HAS BEEN SPLIT INTO TWO NEW SECTORS.  IF THE
01114  M01S01081.fsetabl +++|*         ROOT SECTOR NEEDS TO BE SPLIT, A COMPLETE NEW TREE LEVEL IS
01115  M01S01082.fsetabl +++|*         CREATED WITH NEW SECTORS, THE ROOT SECTOR IS MODIFIED TO
01116  M01S01083.fsetabl +++|*         BECOME A DIRECTORY FOR THE NEW LEVEL, AND NO DEALLOCATION
01117  M01S01084.fsetabl +++|*         IS NEEDED.  IF A NON-ROOT SECTOR NEEDS TO BE SPLIT EXACTLY
01118  M01S01085.fsetabl +++|*         AT (JUST AFTER) ITS EXISTING LAST FIELD, THEN THAT SECTOR
01119  M01S01086.fsetabl +++|*         IS PRESERVED WITHOUT DEALLOCATION AND A NEW SECTOR IS
01120  M01S01087.fsetabl +++|*         CREATED FOR THE OVERFLOW CONTENT.  BUT IF A NON-ROOT SECTOR
01121  M01S01088.fsetabl +++|*         MUST BE SPLIT SOMEWHERE IN THE MIDDLE OF ITS EXISTING
01122  M01S01089.fsetabl +++|*         CONTENT, IT MUST BE DEALLOCATED AND BE REPLACED BY TWO
01123  M01S01090.fsetabl +++|*         COMPLETELY NEW SECTORS.
01124  M01S01091.fsetabl +++|*
01125  M01S01092.fsetabl +++|*         THE REASON FOR DEALLOCATION IS THAT NOTHING MUST BE ALLOWED
01126  M01S01093.fsetabl +++|*         TO BE POINTED TO UNTIL AND UNLESS IT ALREADY EXISTS, AS
01127  M01S01094.fsetabl +++|*         UPDATED TO DISK ALTHOUGH NOT NECESSARILY AS CACHED IN
01128  M01S01095.fsetabl +++|*         MEMORY.  SINCE A NON-ROOT SECTOR IS POINTED TO BE
01129  M01S01096.fsetabl +++|*         HIGHER-LEVEL DIRECOTRIES, IT CANNOT BE TOTALLY REFORMATTED
01130  M01S01097.fsetabl +++|*         IN PLACE, THEREFORE IT IS LEFT AS IS AND NEW SECTORS
01131  M01S01098.fsetabl +++|*         REPLACE IT.  THE DIRECTORIES WHICH POINT TO THE DISCARDED
01132  M01S01099.fsetabl +++|*         SECTOR WILL EVENTUALLY BE UPDATED THEMSELVES.  UNTIL THEN,
01133  M01S01100.fsetabl +++|*         THOSE HIGHER DIRECTORIES MAY BE OUT OF DATE BUT AT LEAST
01134  M01S01101.fsetabl +++|*         POINT TO A VALID DATA STRUCTURE.
01135  M01S01102.fsetabl +++|*
01136  M01S01103.fsetabl +++|*         ENTRY  PL - CURRENT TREE LEVEL.
01137  M01S01104.fsetabl +++|*
01138  M01S01105.fsetabl +++|*         EXIT   PADA[PL] - CLEARED AWAY.
01139  M01S01106.fsetabl +++|
01140  M01S01107.fsetabl +++|*
01141  M01S01108.fsetabl +++|*         CALLS  TRAGIC.
01142  M01S01109.fsetabl +++|#
01143  M01S01110.fsetabl +++|  CONTROL IFGQ PARANOIA,5;
01144  M01S01111.fsetabl +++|    IF PL EQ 0 OR PADA[PL] EQ 0 THEN
01145  M01S01112.fsetabl +++|      BEGIN
01146  M01S01113.fsetabl +++|      TRAGIC(" SECTOR CANNOT BE DEALLOCATED.$");
01147  M01S01114.fsetabl +++|      END
01148  M01S01115.fsetabl +++|  CONTROL FI;
01149  M01S01116.fsetabl +++|  PADA[PL] = 0;
01150  M01S01117.fsetabl +++|  PADIRTY[PL] = FALSE;
01151  M01S01118.fsetabl +++|  END
01152  M01S01119.fsetabl +++|
01153  M01S01120.fsetabl +++|
01154  M01S01121.fsetabl +++|PROC SETWRITE(PARM);
01155  M01S01122.fsetabl +++|  BEGIN
01156  M01S01123.fsetabl +++|#
01157  M01S01124.fsetabl +++|**        SETWRITE - SCHEDULE EXTENSION/ALTERATION OF FILE.
01158  M01S01125.fsetabl +++|*
01159  M01S01126.fsetabl +++|*         SETWRITE INITIALIZES THE FET FOR OUTPUT.  IT SETS THE IOACT
01160  M01S01127.fsetabl +++|*         FLAG TO INDICATE THAT I/O IS SCHEDULED, SETS IOWRITE TO
01161  M01S01128.fsetabl +++|*         INDICATE THAT THE I/O SHALL BE AN OUTPUT FUNCTION, AND
01162  M01S01129.fsetabl +++|*         SETS OR CLEARS IOAPEND ACCORDING TO WHETHER THE SECTOR TO
01163  M01S01130.fsetabl +++|*         BE WRITTEN IS WITHIN THE CURRENT PHYSICAL BOUNDARIES OF THE
01164  M01S01131.fsetabl +++|*         FILE OR REPRESENTS AN EXTENSION OF PHYSICAL SIZE.
01165  M01S01132.fsetabl +++|*
01166  M01S01133.fsetabl +++|*         ENTRY  PARM - DISK ADDRESS TO BE WRITTEN.
01167  M01S01134.fsetabl +++|*                MAXDA - CURRENT PHYSICAL SIZE OF FILE.
01168  M01S01135.fsetabl +++|*
01169  M01S01136.fsetabl +++|*         EXIT   FET - INITIALIZED WITH EMPTY CIRCULAR BUFFER.
01170  M01S01137.fsetabl +++|*                IOACT - TRUE.
01171  M01S01138.fsetabl +++|*                IOWRITE - TRUE.
01172  M01S01139.fsetabl +++|*                IOAPEND - TRUE OR FALSE BASED ON PARM AND MAXDA.
01173  M01S01140.fsetabl +++|*                LASTDA - SET TO KEEP TRACK OF WHERE WE ARE IN FILE.
01174  M01S01141.fsetabl +++|*                FETRR - SETUP.
01175  M01S01142.fsetabl +++|*
01176  M01S01143.fsetabl +++|*         CALLS  INITFET.
01177  M01S01144.fsetabl +++|#
01178  M01S01145.fsetabl +++|  ITEM PARM;
01179  M01S01146.fsetabl +++|
01180  M01S01147.fsetabl +++|  INITFET(DISK,DSKSIZ);
01181  M01S01148.fsetabl +++|
01182  M01S01149.fsetabl +++|  IOACT = TRUE;
01183  M01S01150.fsetabl +++|  IOWRITE = TRUE;
01184  M01S01151.fsetabl +++|
01185  M01S01152.fsetabl +++|  IF PARM GR MAXDA THEN
01186  M01S01153.fsetabl +++|    BEGIN
01187  M01S01154.fsetabl +++|    IOAPEND = TRUE;
01188  M01S01155.fsetabl +++|    FETRR = LOC(DUMB);
01189  M01S01156.fsetabl +++|    END
01190  M01S01157.fsetabl +++|
01191  M01S01158.fsetabl +++|  ELSE
01192  M01S01159.fsetabl +++|    BEGIN
01193  M01S01160.fsetabl +++|    IOAPEND = FALSE;
01194  M01S01161.fsetabl +++|    FETRR = PARM;
01195  M01S01162.fsetabl +++|    LASTDA = PARM - 1;
01196  M01S01163.fsetabl +++|    END
01197  M01S01164.fsetabl +++|
01198  M01S01165.fsetabl +++|  END
01199  M01S01166.fsetabl +++|PAGE
01200  M01S01167.fsetabl +++|PROC TRYWRITE(PARM,FLAG);
01201  M01S01168.fsetabl +++|  BEGIN
01202  M01S01169.fsetabl +++|#
01203  M01S01170.fsetabl +++|**        TRYWRITE - TRANSMIT SECTOR TO CIRCULAR BUFFER.
01204  M01S01171.fsetabl +++|*
01205  M01S01172.fsetabl +++|*         TRYWRITE ATTEMPTS TO TRANSMIT A SECTOR TO THE CIRCULAR
01206  M01S01173.fsetabl +++|*         BUFFER.  IT MAY FAIL TO DO SO IF THE CIRCULAR BUFFER ALREADY
01207  M01S01174.fsetabl +++|*         CONTAINS SECTORS FOR WHICH THIS SECTOR IS NOT CONTIGUOUS.
01208  M01S01175.fsetabl +++|*         THE CALLER SHOULD CALL PAUSEIO WHEN TRYWRITE FAILS, AND
01209  M01S01176.fsetabl +++|*         THEN CALL THIS ROUTINE AGAIN.  TRYWRITE CANNOT FAIL IF
01210  M01S01177.fsetabl +++|*         PAUSEIO IS USED.
01211  M01S01178.fsetabl +++|*
01212  M01S01179.fsetabl +++|*         ENTRY  P<FROM> - POINTS TO TEXT OF SECTOR.
01213  M01S01180.fsetabl +++|*                PARM - DISK ADDRESS.
01214  M01S01181.fsetabl +++|*                MAXDA - PHYSICAL FILE SIZE.
01215  M01S01182.fsetabl +++|*                LASTDA - MOST RECENT DISK ADDRESS TRANSMITTED.
01216  M01S01183.fsetabl +++|*
01217  M01S01184.fsetabl +++|*
01218  M01S01185.fsetabl +++|*         EXIT   P<FROM> - POSSIBLY DESTROYED.
01219  M01S01186.fsetabl +++|*                MAXDA - INCREMENTED IF FILE EXTENDED.
01220  M01S01187.fsetabl +++|*                LASTDA - INCREMENTED IF CONTIGUOUS EARLIER OUTPUT.
01221  M01S01188.fsetabl +++|*                FET - GUARANTEED SETUP FOR OUTPUT WITH THIS SECTOR
01222  M01S01189.fsetabl +++|*                    OF TEXT IN CIRCULAR BUFFER.  EXISTING FET SETUP
01223  M01S01190.fsetabl +++|*                    AND CIRCULAR BUFFER CONTENT, IF ANY, ARE NOT
01224  M01S01191.fsetabl +++|*                    DISTURBED WITH REGARD TO EARLIER OUTPUT.
01225  M01S01192.fsetabl +++|*                FLAG - TRUE IF THIS SECTOR TRANSMITTED.  FALSE IF
01226  M01S01193.fsetabl +++|*                    UNABLE TO TRANSMIT DUE TO DISCONTIGUITY WITH
01227  M01S01194.fsetabl +++|*                    EARLIER OUTPUT.
01228  M01S01195.fsetabl +++|*                IOACT, IOWRITE - TRUE.
01229  M01S01196.fsetabl +++|*                IOAPEND - SETUP.
01230  M01S01197.fsetabl +++|*
01231  M01S01198.fsetabl +++|*         CALLS  SETWRITE, WTWBUF.
01232  M01S01199.fsetabl +++|#
01233  M01S01200.fsetabl +++|  ITEM PARM, FLAG B, ZERO = 0;         # ZERO IS A CONSTANT          #
01234  M01S01201.fsetabl +++|
01235  M01S01202.fsetabl +++|  FLAG = TRUE;
01236  M01S01203.fsetabl +++|
01237  M01S01204.fsetabl +++|  IF NOT IOWRITE THEN SETWRITE(PARM);
01238  M01S01205.fsetabl +++|
01239  M01S01206.fsetabl +++|  IF IOAPEND THEN
01240  M01S01207.fsetabl +++|    BEGIN
01241  M01S01208.fsetabl +++|
01242  M01S01209.fsetabl +++|    IF MAXDA+1 LS PARM THEN  # ADD PADDING SECTOR          #
01243  M01S01210.fsetabl +++|      BEGIN
01244  M01S01211.fsetabl +++|      MAXDA = MAXDA + 1;
01245  M01S01212.fsetabl +++|      P<FROM>=LOC(ZERO);
01246  M01S01213.fsetabl +++|      WTWBUF(O"100");
01247  M01S01214.fsetabl +++|      END
01248  M01S01215.fsetabl +++|
01249  M01S01216.fsetabl +++|    ELSE IF MAXDA+1 EQ PARM THEN       # ADD REAL SECTOR   #
01250  M01S01217.fsetabl +++|      BEGIN
01251  M01S01218.fsetabl +++|      MAXDA = MAXDA+1;
01252  M01S01219.fsetabl +++|      WTWBUF(O"100");
01253  M01S01220.fsetabl +++|      END
01254  M01S01221.fsetabl +++|
01255  M01S01222.fsetabl +++|    ELSE
01256  M01S01223.fsetabl +++|      BEGIN
01257  M01S01224.fsetabl +++|      FLAG = FALSE;
01258  M01S01225.fsetabl +++|      END
01259  M01S01226.fsetabl +++|    END
01260  M01S01227.fsetabl +++|
01261  M01S01228.fsetabl +++|  ELSE
01262  M01S01229.fsetabl +++|    BEGIN
01263  M01S01230.fsetabl +++|
01264  M01S01231.fsetabl +++|    IF LASTDA+1 EQ PARM AND PARM LQ MAXDA THEN
01265  M01S01232.fsetabl +++|      BEGIN
01266  M01S01233.fsetabl +++|      LASTDA = LASTDA+1;
01267  M01S01234.fsetabl +++|      WTWBUF(O"100");
01268  M01S01235.fsetabl +++|      END
01269  M01S01236.fsetabl +++|
01270  M01S01237.fsetabl +++|    ELSE
01271  M01S01238.fsetabl +++|      BEGIN
01272  M01S01239.fsetabl +++|      FLAG = FALSE;
01273  M01S01240.fsetabl +++|      END
01274  M01S01241.fsetabl +++|    END
01275  M01S01242.fsetabl +++|
01276  M01S01243.fsetabl +++|  END
01277  M01S01244.fsetabl +++|PAGE
01278  M01S01245.fsetabl +++|PROC FLUSHCACHE;
01279  M01S01246.fsetabl +++|  IOBEGIN(FLUSHCACHE)
01280  M01S01247.fsetabl +++|#
01281  M01S01248.fsetabl +++|**        FLUSHCACHE - UPDATE ALTERED CACHE FRAMES TO DISK.
01282  M01S01249.fsetabl +++|*
01283  M01S01250.fsetabl +++|*         FLUSHCACHE IS OBLIGATED TO ASSURE THAT ALL ALTERED, UNOWNED
01284  M01S01251.fsetabl +++|*         CACHE PAGES BECOME UNALTERED IN CACHE.  THIS REQUIRES THAT
01285  M01S01252.fsetabl +++|*         SUCH PAGES BE TRANSMITTED TO THE CIRCULAR BUFFER.  THIS IN
01286  M01S01253.fsetabl +++|*         TURN CAN BE DONE ONLY IN ORDER OF AGE AND IN ADDRESS ORDER.
01287  M01S01254.fsetabl +++|*
01288  M01S01255.fsetabl +++|*         UNALTERED FRAMES DO NOT NEED TO BE UPDATED TO DISK.  OWNED
01289  M01S01256.fsetabl +++|*         FRAMES CANNOT YET BE UPDATED - IN THE AGE-RESTRICTED ORDER
01290  M01S01257.fsetabl +++|*         OF UPDATE, OWNED PAGES CAN BE THOUGHT OF AS HAVING THE
01291  M01S01258.fsetabl +++|*         WORST AGE CATEGORY.
01292  M01S01259.fsetabl +++|*
01293  M01S01260.fsetabl +++|*         EACH SECTOR CAN BE TRANSMITTED TO THE CIRCULAR BUFFER IF
01294  M01S01261.fsetabl +++|*         THE BUFFER AND FET ARE AVAILABLE FOR OUTPUT, AND IF THE
01295  M01S01262.fsetabl +++|*         BUFFER IS EITHER EMPTY OR HAS ONE OR MORE SECTORS ALREADY IN
01296  M01S01263.fsetabl +++|*         IT FOR WHICH THE NEW SECTOR IS CONTIGOUS IN ADDRESS.  IF THE
01297  M01S01264.fsetabl +++|*         FET IS ALREADY CLAIMED FOR INPUT PROCESSING, PAUSEIO CAN BE
01298  M01S01265.fsetabl +++|*         CALLED TO STOP AND DISCARD SUCH INPUT.  FOR SPANNED
01299  M01S01266.fsetabl +++|*         ADDRESSES, WE MUST CALL PAUSEIO.  THIS LOGIC IS PROVIDED BY
01300  M01S01267.fsetabl +++|*         INSPECTING THE FLAG RETURNED BY TRYWRITE, AND CALLING
01301  M01S01268.fsetabl +++|*         TRYWRITE A SECOND TIME WITH PAUSEIO, WHEN TRYWRITE FAILED.
01302  M01S01269.fsetabl +++|*
01303  M01S01270.fsetabl +++|*         BECAUSE THE ALLOCATION OF NEW SECTORS AT THE LOGICAL END OF
01304  M01S01271.fsetabl +++|*         THE FILE CAN RUN SEVERAL UNITS AHEAD OF THE ACTUAL
01305  M01S01272.fsetabl +++|*         EXTENDING OF THE PHYSICAL END OF THE FILE, AND BECAUSE THE
01306  M01S01273.fsetabl +++|*         AGE-DEPENDENT ORDERING MIGHT REQUIRE A HIGH ADDRESS SECTOR
01307  M01S01274.fsetabl +++|*         TO BE WRITTEN BEFORE A LOWER ADDRESS SECTOR MAY BE LEGALLY
01308  M01S01275.fsetabl +++|*         WRITTEN, A SITUATION CAN ARISE WHERE A SECTOR MUST BE
01309  M01S01276.fsetabl +++|*         WRITTEN SEVERAL ADDRESSES BEYOND THE CURRENT PHYSICAL END
01310  M01S01277.fsetabl +++|*         OF FILE.  WHEN THIS OCCURS, FLUSHCACHE RECOGNIZES THE
01311  M01S01278.fsetabl +++|*         SITUATION AND PADS THE PHYSICAL END OUT TO WITHIN ONE
01312  M01S01279.fsetabl +++|*         SECTOR OF THE SECTOR THAT MUST BE NEXT WRITTEN.  THE
01313  M01S01280.fsetabl +++|*         INTERMEDIATE SECTORS THUS GET A DISK IMAGE WHICH IS NOT UP
01314  M01S01281.fsetabl +++|*         TO DATE IN ANY WAY WHATSOEVER.  THIS IS NOT A PROBLEM - THE
01315  M01S01282.fsetabl +++|*         UP TO DATE FRAMES FOR SUCH PADDING WILL EVENTUALLY BE
01316  M01S01283.fsetabl +++|*         RELEASED FOR ACTUAL DISK UPDATE.  THE CONTENT OF PADDING
01317  M01S01284.fsetabl +++|*         SECTORS IS INNOCUOUS, TO FOLLOW THE RULE THAT NOTHING CAN
01318  M01S01285.fsetabl +++|*         BE POINTED TO ON DISK UNTIL THE OBJECT ITSELF IS UP TO DATE
01319  M01S01286.fsetabl +++|*         ON DISK.
01320  M01S01287.fsetabl +++|*
01321  M01S01288.fsetabl +++|*         ENTRY  CACHEDIRTY[ALL] - SETUP.
01322  M01S01289.fsetabl +++|*                CACHEAGE[ALL] - SETUP.
01323  M01S01290.fsetabl +++|*                CACHEOWNED[ALL] - SETUP.
01324  M01S01291.fsetabl +++|*                BFDA[ALL] - SETUP.
01325  M01S01292.fsetabl +++|*                IOREAD - WHETHER OBSOLETE INPUT SCHEDULED.
01326  M01S01293.fsetabl +++|*                IOACT - WHETHER ANY PREVIOUS I/O SCHEDULED.
01327  M01S01294.fsetabl +++|*                FETDUN - FET INTERLOCK.
01328  M01S01295.fsetabl +++|*                IOAPEND - WHETHER A PREVIOUS WRITE EXTENDS.
01329  M01S01296.fsetabl +++|*                QUARTER - APPROX ONE FOURTH BUFFER CAPACITY.
01330  M01S01297.fsetabl +++|*                ACCTPRU - SECTOR TRANSFER ACCUMULATOR.
01331  M01S01298.fsetabl +++|*                MAXDA - FILE PHYSICAL BOUNDARY.
01332  M01S01299.fsetabl +++|*
01333  M01S01300.fsetabl +++|*         EXIT   ALL ALTERED AND UNOWNED CACHE FRAMES OUTPUT TO DISK
01334  M01S01301.fsetabl +++|*                    OR BUFFERED FOR OUTPUT.
01335  M01S01302.fsetabl +++|*                IOREAD - FORCED FALSE IF ANY OUTPUT NEEDED.
01336  M01S01303.fsetabl +++|*                IOACT, IOWRITE, IOAPEND - POSSIBLY TRUE.
01337  M01S01304.fsetabl +++|*                CACHEDIRTY[ALL] - FALSE WHERE CACHEOWNED IS FALSE.
01338  M01S01305.fsetabl +++|*                ACCTPRU - INCREMENTED FOR ANY WORK DONE.
01339  M01S01306.fsetabl +++|*                MAXDA - INCREMENTED IF FILE EXTENDED.
01340  M01S01307.fsetabl +++|*
01341  M01S01308.fsetabl +++|*         CALLS  WIOSTAT, PUSHTEMP, POPTEMP, PAUSEIO, BUFAVAIL,
01342  M01S01309.fsetabl +++|*                MOVEIO, WAIT, DELAY, TRYWRITE, TRAGIC.
01343  M01S01310.fsetabl +++|*
01344  M01S01311.fsetabl +++|*         USES   P<FROM>, TEMP(RESTORED).
01345  M01S01312.fsetabl +++|#
01346  M01S01313.fsetabl +++|  ITEM TMP1, TMP2, BOOL B;
01347  M01S01314.fsetabl +++|  CONTROL IFEQ MULTI,1;
01348  M01S01315.fsetabl +++|    WIOSTAT(5);              # ACCUMULATE CACHE FLUSHES #
01349  M01S01316.fsetabl +++|  CONTROL FI;
01350  M01S01317.fsetabl +++|
01351  M01S01318.fsetabl +++|  PUSHTEMP;
01352  M01S01319.fsetabl +++|
01353  M01S01320.fsetabl +++|FLUSHLOOP:
01354  M01S01321.fsetabl +++|
01355  M01S01322.fsetabl +++|  TMP1=999999999;
01356  M01S01323.fsetabl +++|  TEMP=-1;
01357  M01S01324.fsetabl +++|  FOR TMP2=0 STEP 1 UNTIL MAXCACHE DO
01358  M01S01325.fsetabl +++|    BEGIN                     # SEARCH FOR OLDEST DIRTY     #
01359  M01S01326.fsetabl +++|    IF CACHEDIRTY[TMP2] AND CACHEAGE[TMP2] LS TMP1
01360  M01S01327.fsetabl +++|      AND NOT CACHEOWNED[TMP2] THEN
01361  M01S01328.fsetabl +++|      BEGIN
01362  M01S01329.fsetabl +++|      TEMP=TMP2;
01363  M01S01330.fsetabl +++|      TMP1=CACHEAGE[TMP2];
01364  M01S01331.fsetabl +++|      END
01365  M01S01332.fsetabl +++|    END
01366  M01S01333.fsetabl +++|  IF TEMP LS 0 THEN          # NO MORE FLUSH NEEDED        #
01367  M01S01334.fsetabl +++|    BEGIN
01368  M01S01335.fsetabl +++|    POPTEMP;
01369  M01S01336.fsetabl +++|    IORET
01370  M01S01337.fsetabl +++|    END
01371  M01S01338.fsetabl +++|
01372  M01S01339.fsetabl +++|  CACHEDIRTY[TEMP]=FALSE;
01373  M01S01340.fsetabl +++|  IF BFDA[TEMP] EQ 0 THEN GOTO FLUSHLOOP;
01374  M01S01341.fsetabl +++|
01375  M01S01342.fsetabl +++|  IF IOREAD THEN             # COMPLETE ANY INPUT          #
01376  M01S01343.fsetabl +++|    BEGIN
01377  M01S01344.fsetabl +++|    PAUSEIO;
01378  M01S01345.fsetabl +++|    CONTROL IFEQ MULTI,1;
01379  M01S01346.fsetabl +++|      WIOSTAT(6);            # ACCUMULATE READ REJECTS #
01380  M01S01347.fsetabl +++|    CONTROL FI;
01381  M01S01348.fsetabl +++|    END
01382  M01S01349.fsetabl +++|
01383  M01S01350.fsetabl +++|WRITELOOP:
01384  M01S01351.fsetabl +++|
01385  M01S01352.fsetabl +++|  WHYLE IOACT AND BUFAVAIL LS O"100" DO
01386  M01S01353.fsetabl +++|    BEGIN                     # NEED ROOM IN BUFFER         #
01387  M01S01354.fsetabl +++|    MOVEIO;
01388  M01S01355.fsetabl +++|    CONTROL IFEQ MULTI,1;
01389  M01S01356.fsetabl +++|      WAIT;
01390  M01S01357.fsetabl +++|    CONTROL FI;
01391  M01S01358.fsetabl +++|    CONTROL IFEQ SINGLE,1;
01392  M01S01359.fsetabl +++|      IF NOT FETDUN THEN DELAY;
01393  M01S01360.fsetabl +++|    CONTROL FI;
01394  M01S01361.fsetabl +++|    END
01395  M01S01362.fsetabl +++|
01396  M01S01363.fsetabl +++|  CONTROL IFEQ MULTI,1;
01397  M01S01364.fsetabl +++|    WIOSTAT(7);              # ACCUMULATE SECTORS WRITTEN #
01398  M01S01365.fsetabl +++|    ACCTPRU=ACCTPRU+1;
01399  M01S01366.fsetabl +++|  CONTROL FI;
01400  M01S01367.fsetabl +++|
01401  M01S01368.fsetabl +++|  P<FROM>=LOC(BFPRU[TEMP]);
01402  M01S01369.fsetabl +++|  TRYWRITE(BFDA[TEMP],BOOL);
01403  M01S01370.fsetabl +++|  IF NOT BOOL THEN
01404  M01S01371.fsetabl +++|    BEGIN                     # ONE FAILURE ALLOWED, NOT TWO          #
01405  M01S01372.fsetabl +++|    PAUSEIO;
01406  M01S01373.fsetabl +++|    CONTROL IFEQ MULTI,1;
01407  M01S01374.fsetabl +++|      WIOSTAT(8);            # ACCUMULATE DISCONTIGUOUS WRITES #
01408  M01S01375.fsetabl +++|    CONTROL FI;
01409  M01S01376.fsetabl +++|    P<FROM>=LOC(BFPRU[TEMP]);
01410  M01S01377.fsetabl +++|    TRYWRITE(BFDA[TEMP],BOOL);
01411  M01S01378.fsetabl +++|    IF NOT BOOL THEN TRAGIC(" UNABLE TO WRITE FROM BUFFER.$");
01412  M01S01379.fsetabl +++|    END
01413  M01S01380.fsetabl +++|
01414  M01S01381.fsetabl +++|  # EITHER ADD MORE PADDING FOR THIS FLUSH OR FLUSH ANOTHER #
01415  M01S01382.fsetabl +++|  IF IOAPEND AND MAXDA LS BFDA[TEMP] THEN
01416  M01S01383.fsetabl +++|    BEGIN
01417  M01S01384.fsetabl +++|    CONTROL IFEQ MULTI,1;
01418  M01S01385.fsetabl +++|      WIOSTAT(9);            # ACCUMULATE PADDING SECTORS #
01419  M01S01386.fsetabl +++|    CONTROL FI;
01420  M01S01387.fsetabl +++|    GOTO WRITELOOP;
01421  M01S01388.fsetabl +++|    END
01422  M01S01389.fsetabl +++|  IF BUFAVAIL LQ QUARTER THEN MOVEIO;
01423  M01S01390.fsetabl +++|  GOTO FLUSHLOOP;
01424  M01S01391.fsetabl +++|
01425  M01S01392.fsetabl +++|  IOEND                       # OF FLUSHCACHE       #
01426  M01S01393.fsetabl +++|
01427  M01S01394.fsetabl +++|
01428  M01S01395.fsetabl +++|PROC CLOSEOUT;
01429  M01S01396.fsetabl +++|  IOBEGIN(CLOSEOUT)
01430  M01S01397.fsetabl +++|#
01431  M01S01398.fsetabl +++|**        CLOSEOUT - FINISH UPDATE OF DISK.
01432  M01S01399.fsetabl +++|*
01433  M01S01400.fsetabl +++|*         WORKFILE CLOSEOUT CONDITIONS HAVE BEEN DETECTED.  UNDER
01434  M01S01401.fsetabl +++|*         CLOSEOUT CONDITIONS, WE MUST WRITE NOT ONLY THE ZERO-LEVEL
01435  M01S01402.fsetabl +++|*         SECTOR, BUT ALSO THE DATA SEGMENT (RIGHT AFTER ROOT SECTOR)
01436  M01S01403.fsetabl +++|*         FOLLOWED BY EOR THEN ARRAY SEGMENT THEN A SECOND EOR.
01437  M01S01404.fsetabl +++|*
01438  M01S01405.fsetabl +++|*         THE CLOSEOUT ROUTINE WRITES THE TWO BINARY SEGMENTS, BUT
01439  M01S01406.fsetabl +++|*         REQUIRES THAT THE CALLER FIRST FLUSH ALL TREE STRUCTURE
01440  M01S01407.fsetabl +++|*         SECTORS TO DISK OR AT LEAST TO THE CIRCULAR BUFFER.  THE
01441  M01S01408.fsetabl +++|*         CALLER SHOULD USE THE CLEAN ROUTINE WITH PL=0 TO MEET THAT
01442  M01S01409.fsetabl +++|*         REQUIREMENT.  THE CLOSEOUT ROUTINE DEPENDS ON THE RULE THAT
01443  M01S01410.fsetabl +++|*         THE ROOT SECTOR OF THE TREE STRUCTURE MUST BE THE LAST
01444  M01S01411.fsetabl +++|*         (CHRONOLOGICALLY) TO BE FREED FOR UPDATE TO DISK, AND
01445  M01S01412.fsetabl +++|*         DEPENDS ON THE RULE THAT THE ROOT SECTOR IS AT DISK ADDRESS
01446  M01S01413.fsetabl +++|*         1 AND THEREFORE IS CONTIGUOUS WITH NO PREVIOUSLY RELEASED
01447  M01S01414.fsetabl +++|*         SECTORS.  THUS, CLOSEOUT EXPECTS THAT ALL SECTORS EXCEPT
01448  M01S01415.fsetabl +++|*         THE ROOT HAVE BEEN ACTUALLY WRITTEN TO DISK, AND THE ROOT
01449  M01S01416.fsetabl +++|*         SECTOR IS EXPECTED TO BE SCHEDULED FOR UPDATE BUT STILL IS
01450  M01S01417.fsetabl +++|*         PRESENT IN THE CIRCULAR BUFFER.
01451  M01S01418.fsetabl +++|*
01452  M01S01419.fsetabl +++|*         CLOSEOUT INTERCEPTS THE ISSUANCE OF CIO FUNCTION CODES FOR
01453  M01S01420.fsetabl +++|*         THE UPDATE OF THE ROOT SECTOR, AND AFTER APPENDING THE
01454  M01S01421.fsetabl +++|*         SCALAR DATA SEGMENT ONTO THE ROOT SECTOR IN THE CIRCULAR
01455  M01S01422.fsetabl +++|*         BUFFER, CLOSEOUT CALLS PAUSEIO (AND THUS MOVEIO) SUCH THAT
01456  M01S01423.fsetabl +++|*         ONE WRITE WITH END OF RECORD OCCURS.  THEN CLOSEOUT
01457  M01S01424.fsetabl +++|*         CONSTRUCTS A NEW CIRCULAR BUFFER IMAGE FOR THE ARRAY
01458  M01S01425.fsetabl +++|*         SEGMENT, AND USES PAUSEIO A SECOND TIME TO WRITE ANOTHER
01459  M01S01426.fsetabl +++|*         MULTIPLE SECTOR RECORD.
01460  M01S01427.fsetabl +++|*
01461  M01S01428.fsetabl +++|*         ENTRY  CLEAN HAS BEEN CALLED WITH PL=0.
01462  M01S01429.fsetabl +++|*                IOAPEND - WHETHER FILE PRESENTLY EMPTY.
01463  M01S01430.fsetabl +++|*                LASTDA, MAXDA - LOGICAL AND PHYSICAL FILE SIZES.
01464  M01S01431.fsetabl +++|*                DATALEN, ARRAYLEN - LENGTHS OF BINARY SEGMENTS.
01465  M01S01432.fsetabl +++|*                DATAPRUS, ARRAYPRUS - LENGTHS IN SECTORS.
01466  M01S01433.fsetabl +++|*
01467  M01S01434.fsetabl +++|*         EXIT   FILE COMPLETELY DRAINED TO DISK, FET INACTIVE.
01468  M01S01435.fsetabl +++|*                LASTDA, MAXDA - ONE OF THESE TWO IS INCREMENTED.
01469  M01S01436.fsetabl +++|*
01470  M01S01437.fsetabl +++|*         CALLS  FLUSHCACHE, WTWBUF, PAUSEIO, INITFET.
01471  M01S01438.fsetabl +++|*
01472  M01S01439.fsetabl +++|*         USES   P<FROM>, IOWRITE, IOWRTEOR, IOAPEND, IOACT.
01473  M01S01440.fsetabl +++|#
01474  M01S01441.fsetabl +++|  FLUSHCACHE;        # PUT SECTOR 1 (ROOT PRU) INTO BUFFER   #
01475  M01S01442.fsetabl +++|  IOWRTEOR=TRUE;     # WRITE ROOT PRU PLUS DATA SEGMENT      #
01476  M01S01443.fsetabl +++|  P<FROM>=LOC(DATASTART);
01477  M01S01444.fsetabl +++|  WTWBUF(DATALEN);
01478  M01S01445.fsetabl +++|  IF IOAPEND THEN MAXDA=MAXDA+DATAPRUS;
01479  M01S01446.fsetabl +++|  ELSE LASTDA=LASTDA+DATAPRUS;
01480  M01S01447.fsetabl +++|  PAUSEIO;
01481  M01S01448.fsetabl +++|  INITFET(DISK,DSKSIZ);        # NOW SET UP FOR ARRAYS       #
01482  M01S01449.fsetabl +++|  IOACT=TRUE;
01483  M01S01450.fsetabl +++|  IOWRITE=TRUE;
01484  M01S01451.fsetabl +++|  IF FETCRI GR MAXDA THEN
01485  M01S01452.fsetabl +++|    BEGIN
01486  M01S01453.fsetabl +++|    IOAPEND=TRUE;
01487  M01S01454.fsetabl +++|    FETRR=LOC(DUMB);
01488  M01S01455.fsetabl +++|    MAXDA=MAXDA+ARRAYPRUS;
01489  M01S01456.fsetabl +++|    END
01490  M01S01457.fsetabl +++|  ELSE
01491  M01S01458.fsetabl +++|    BEGIN
01492  M01S01459.fsetabl +++|    IOAPEND=FALSE;
01493  M01S01460.fsetabl +++|    FETRR=FETCRI;
01494  M01S01461.fsetabl +++|    LASTDA=LASTDA+ARRAYPRUS;
01495  M01S01462.fsetabl +++|    END
01496  M01S01463.fsetabl +++|  IOWRTEOR=TRUE;
01497  M01S01464.fsetabl +++|  P<FROM>=LOC(ARRAYSTART);
01498  M01S01465.fsetabl +++|  WTWBUF(ARRAYLEN);
01499  M01S01466.fsetabl +++|  PAUSEIO;
01500  M01S01467.fsetabl +++|  IOEND                       # OF CLOSEOUT       #
01501  M01S01468.fsetabl +++|PAGE
01502  M01S01469.fsetabl +++|PROC CLEAN;
01503  M01S01470.fsetabl +++|  IOBEGIN(CLEAN)
01504  M01S01471.fsetabl +++|#
01505  M01S01472.fsetabl +++|**        CLEAN - DISCONNECT SECTOR FROM LOWEST TREE LEVEL.
01506  M01S01473.fsetabl +++|*
01507  M01S01474.fsetabl +++|*         CLEAN IS CALLED WHENEVER A ROUTINE WISHES TO DISCARD THE
01508  M01S01475.fsetabl +++|*         SECTOR PRESENTLY ASSOCIATED WITH A TREE LEVEL.  THIS CAN BE
01509  M01S01476.fsetabl +++|*         DONE ONLY IN THE REVERSE ORDER OF THE TREE HIERARCHY, IE,
01510  M01S01477.fsetabl +++|*         THE BOTTOM LEVEL FIRST AND THE ROOT LEVEL LAST.  THE EFFECT
01511  M01S01478.fsetabl +++|*         OF CALLING CLEAN IS TO DISCONNECT THE SECTOR FROM THE TREE
01512  M01S01479.fsetabl +++|*         STRUCTURE BY FREEING THE CACHE FRAME FROM OWNERSHIP, FIRST
01513  M01S01480.fsetabl +++|*         DISCONNECTING ANY TREE LEVELS LOWER THAN THE CURRENT LEVEL.
01514  M01S01481.fsetabl +++|*
01515  M01S01482.fsetabl +++|*         IF THE TREE LEVEL WAS PREVIOUSLY FLAGGED AS ALTERED, THE
01516  M01S01483.fsetabl +++|*         FREED CACHE FRAME IS SIMILARLY FLAGGED.  ALL HEADER WORD
01517  M01S01484.fsetabl +++|*         DATA IS COPIED FROM THE TREE CONTROL VECTOR TO THE SECTOR
01518  M01S01485.fsetabl +++|*         IMAGE IN CACHE.
01519  M01S01486.fsetabl +++|*
01520  M01S01487.fsetabl +++|*         ENTRY  PL - LEVEL TO BE FREED.
01521  M01S01488.fsetabl +++|*                PALVL - DEEPEST ACTIVE TREE LEVEL.
01522  M01S01489.fsetabl +++|*                PAHEAD[ALL] - HEADER WORDS IN TREE VECTOR.
01523  M01S01490.fsetabl +++|*                PACACHE[ALL] - SETUP.
01524  M01S01491.fsetabl +++|*                CACHEOWNED[ALL] - SETUP.
01525  M01S01492.fsetabl +++|*                PADIRTY[ALL] - ALTERATION FLAG.
01526  M01S01493.fsetabl +++|*
01527  M01S01494.fsetabl +++|*         EXIT   THIS LEVEL AND ALL DEEPER LEVELS FREED.
01528  M01S01495.fsetabl +++|*                CACHEOWNED[ANY] - FORCED TRUE FOR THOSE FREED.
01529  M01S01496.fsetabl +++|*                CACHEDIRTY[ANY] - FORCED TRUE FOR THOSE FREED
01530  M01S01497.fsetabl +++|*                    WITH PADIRTY TRUE.
01531  M01S01498.fsetabl +++|*                CACHEAGE[ANY] - INITIALIZED FOR THOSE FREED.
01532  M01S01499.fsetabl +++|*
01533  M01S01500.fsetabl +++|*         CALLS  DROPIT(INTERNAL), DISOWNCACHE.
01534  M01S01501.fsetabl +++|*
01535  M01S01502.fsetabl +++|*         USES   TPL.
01536  M01S01503.fsetabl +++|#
01537  M01S01504.fsetabl +++|
01538  M01S01505.fsetabl +++|  PROC DROPIT;
01539  M01S01506.fsetabl +++|    BEGIN
01540  M01S01507.fsetabl +++|    IF CACHEOWNED[PACACHE[TPL]] THEN BFHEAD[PACACHE[TPL]]=PAHEAD[TPL];
01541  M01S01508.fsetabl +++|    DISOWNCACHE(PACACHE[TPL]);
01542  M01S01509.fsetabl +++|    END                       # OF DROPIT         #
01543  M01S01510.fsetabl +++|
01544  M01S01511.fsetabl +++|  # START OF MAIN CODE #
01545  M01S01512.fsetabl +++|
01546  M01S01513.fsetabl +++|  IF PADIRTY[PL] THEN
01547  M01S01514.fsetabl +++|    BEGIN
01548  M01S01515.fsetabl +++|    FOR TPL = PALVL STEP -1 UNTIL PL DO
01549  M01S01516.fsetabl +++|      BEGIN
01550  M01S01517.fsetabl +++|      IF PADIRTY[TPL] THEN
01551  M01S01518.fsetabl +++|        BEGIN
01552  M01S01519.fsetabl +++|        PADIRTY[TPL]=FALSE;
01553  M01S01520.fsetabl +++|        CACHEDIRTY[PACACHE[TPL]]=TRUE;
01554  M01S01521.fsetabl +++|        DROPIT;
01555  M01S01522.fsetabl +++|        END
01556  M01S01523.fsetabl +++|      ELSE DROPIT;
01557  M01S01524.fsetabl +++|      END
01558  M01S01525.fsetabl +++|    END
01559  M01S01526.fsetabl +++|  ELSE
01560  M01S01527.fsetabl +++|    BEGIN
01561  M01S01528.fsetabl +++|    FOR TPL=PALVL STEP -1 UNTIL PL DO DROPIT;
01562  M01S01529.fsetabl +++|    END
01563  M01S01530.fsetabl +++|
01564  M01S01531.fsetabl +++|  IOEND
01565  M01S01532.fsetabl +++|
01566  M01S01533.fsetabl +++|
01567  M01S01534.fsetabl +++|PROC CLEANALL;
01568  M01S01535.fsetabl +++|  IOBEGIN(CLEANALL)
01569  M01S01536.fsetabl +++|#
01570  M01S01537.fsetabl +++|**        CLEANALL - CLEAN ENTIRE TREE STRUCTURE AND DATA SEGEMENTS.
01571  M01S01538.fsetabl +++|*
01572  M01S01539.fsetabl +++|*         CLEANALL IS USED TO INITIATE CLOSEOUT OF THE WORKFILE
01573  M01S01540.fsetabl +++|*         MANAGER.  THE ENTIRE TREE STRUCTURE IS CLEANED WITH ANY
01574  M01S01541.fsetabl +++|*         ALTERED SECTORS WRITTEN TO DISK, AND THE SCALAR AND ARRAY
01575  M01S01542.fsetabl +++|*         DATA SEGMENTS ARE UPDATED.
01576  M01S01543.fsetabl +++|*
01577  M01S01544.fsetabl +++|*         ENTRY  CACHEOWNED[ALL] - SETUP.
01578  M01S01545.fsetabl +++|*                PACACHE[ALL] - SETUP.
01579  M01S01546.fsetabl +++|*                PADIRTY[ALL] - SETUP.
01580  M01S01547.fsetabl +++|*                PAHEAD[ALL] -SETUP.
01581  M01S01548.fsetabl +++|*                PALVL - DEEPEST TREE LEVEL.
01582  M01S01549.fsetabl +++|*
01583  M01S01550.fsetabl +++|*         EXIT   PL - ZERO.
01584  M01S01551.fsetabl +++|*                CACHEDIRTY[ALL] - FALSE.
01585  M01S01552.fsetabl +++|*                FET AND CIRCULAR BUFFER - COMPLETE/EMPTY.
01586  M01S01553.fsetabl +++|*                PADIRTY[ALL] - FALSE.
01587  M01S01554.fsetabl +++|*
01588  M01S01555.fsetabl +++|*         CALLS  CLEAN, CLOSEOUT, RECLAIMCACHE.
01589  M01S01556.fsetabl +++|#
01590  M01S01557.fsetabl +++|  PADIRTY[0]=TRUE;
01591  M01S01558.fsetabl +++|  PL=0;
01592  M01S01559.fsetabl +++|  CLEAN;
01593  M01S01560.fsetabl +++|  CLOSEOUT;
01594  M01S01561.fsetabl +++|  RECLAIMCACHE;
01595  M01S01562.fsetabl +++|  IOEND                       # OF CLEANALL       #
01596  M01S01563.fsetabl +++|PAGE
01597  M01S01564.fsetabl +++|PROC BK;
01598  M01S01565.fsetabl +++|  IOBEGIN(BK)
01599  M01S01566.fsetabl +++|#
01600  M01S01567.fsetabl +++|**        BK - BACK UP ONE LINE.
01601  M01S01568.fsetabl +++|*
01602  M01S01569.fsetabl +++|*         BK IS ORGANIZED INTO THREE OPERATIONAL PHASES.  THE FIRST
01603  M01S01570.fsetabl +++|*         PHASE DETERMINES WHETHER THE CURRENT TREE PATH ALREADY
01604  M01S01571.fsetabl +++|*         CONTAINS THE SECTOR WITH THE DESIRED LINE OF TEXT, AND IF
01605  M01S01572.fsetabl +++|*         NOT, IT CLEANS AWAY AS MANY TREE LEVELS AS NECESSARY, FROM
01606  M01S01573.fsetabl +++|*         THE BOTTOM TOWARDS THE ROOT, UNTIL WE ARE IN A DIRECTORY
01607  M01S01574.fsetabl +++|*         WHOSE SPHERE OF INFLUENCE INCLUDES THE DESIRED LINE.
01608  M01S01575.fsetabl +++|*
01609  M01S01576.fsetabl +++|*         THE SECOND PHASE ASSURES THAT WE HAVE A FULL DEPTH TREE
01610  M01S01577.fsetabl +++|*         STRUCTURE CONTAINING THE RIGHT SECTOR AT THE DATA (BOTTOM)
01611  M01S01578.fsetabl +++|*         LEVEL.  IF THE FIRST PHASE WAS NON-TRIVIAL, THEN THE SECOND
01612  M01S01579.fsetabl +++|*         PHASE WILL ALSO HAVE REAL WORK TO PERFORM, WORKING BACK
01613  M01S01580.fsetabl +++|*         TOWARD DEEP TREE LEVELS, READING IN EACH SECTOR NEEDED.
01614  M01S01581.fsetabl +++|*         THE SECOND PHASE IS A NO-OP IF THE FIRST PHASE WAS A NO-OP
01615  M01S01582.fsetabl +++|*         AND IF THE TREE ALREADY EXISTS ALL THE WAY DOWN TO THE DATA
01616  M01S01583.fsetabl +++|*         LEVEL.  HOWEVER, THE FIRST PHASE COULD HAVE BEEN A NO-OP
01617  M01S01584.fsetabl +++|*         FOR AN INCOMPLETE TREE PATH, IN WHICH CASE THE SECOND PHASE
01618  M01S01585.fsetabl +++|*         MUST DEEPEN THE TREE PATH.
01619  M01S01586.fsetabl +++|*
01620  M01S01587.fsetabl +++|*         THE THIRD PHASE SCANS THE DATA SECTOR TO FIND THE RIGHT
01621  M01S01588.fsetabl +++|*         LINE IMAGE.  THE INTERNAL LINE IMAGE FORMAT USES THE SIGN
01622  M01S01589.fsetabl +++|*         BIT TO INDICATE WORDS WHICH ARE THE LAST WORDS OF LINES.
01623  M01S01590.fsetabl +++|*
01624  M01S01591.fsetabl +++|*         ENTRY  CURRENT - CURRENT LINE.
01625  M01S01592.fsetabl +++|*                PALVL - DEEPEST TREE LEVEL.
01626  M01S01593.fsetabl +++|*                ALL PATH AND CACHE CONTROLS SETUP.
01627  M01S01594.fsetabl +++|*                P<MVLNBUF> - WHERE TO PUT LINE OF TEXT.
01628  M01S01595.fsetabl +++|*                DISP, CURNW - DESCRIBE WORD OFFSET AND LENGTH OF
01629  M01S01596.fsetabl +++|*                    PREVIOUS CURRENT LINE.
01630  M01S01597.fsetabl +++|*
01631  M01S01598.fsetabl +++|*         EXIT   CURRENT - DECREMENTED.
01632  M01S01599.fsetabl +++|*                MVLNBUF - CONTAINS LINE OF TEXT.
01633  M01S01600.fsetabl +++|*                PALVL - NEW VALUE FOR DEEPEST TREE LEVEL.
01634  M01S01601.fsetabl +++|*                ALL PATH CONTROLS - MAY CONTROL DIFFERENT SECTORS
01635  M01S01602.fsetabl +++|*                    FOR DEEPER TREE LEVELS.
01636  M01S01603.fsetabl +++|*                ALL CACHE CONTROLS - MAY CONTROL DIFFERENT SECTORS.
01637  M01S01604.fsetabl +++|*                FET, CIRCULAR BUFFER, READ LIST - MAY CONTROL
01638  M01S01605.fsetabl +++|*                    A PREFETCH OPERATION.
01639  M01S01606.fsetabl +++|*                CURNW - SIZE OF NEW LINE.
01640  M01S01607.fsetabl +++|*                DISP - OFFSET OF NEW LINE.
01641  M01S01608.fsetabl +++|*
01642  M01S01609.fsetabl +++|*         CALLS  TRAGIC, CLEAN, PUSHTEMP, READPA, POPTEMP, PREFETCH,
01643  M01S01610.fsetabl +++|*                MOVELN.
01644  M01S01611.fsetabl +++|*
01645  M01S01612.fsetabl +++|*         USES   TEMP(RESTORED), P<PRU>, PL.
01646  M01S01613.fsetabl +++|#
01647  M01S01614.fsetabl +++|  IF CURRENT LQ 0 THEN TRAGIC(" BAK BEFORE START OF FILE.$");
01648  M01S01615.fsetabl +++|
01649  M01S01616.fsetabl +++|  CURRENT = CURRENT - 1;
01650  M01S01617.fsetabl +++|
01651  M01S01618.fsetabl +++|  FOR PL = PALVL WHILE PAFIRST[PL] GR CURRENT DO
01652  M01S01619.fsetabl +++|    BEGIN
01653  M01S01620.fsetabl +++|    CLEAN;
01654  M01S01621.fsetabl +++|    PL = PL - 1;
01655  M01S01622.fsetabl +++|    END
01656  M01S01623.fsetabl +++|
01657  M01S01624.fsetabl +++|  P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01658  M01S01625.fsetabl +++|
01659  M01S01626.fsetabl +++|  DISP = PADISP[PL] - 1;
01660  M01S01627.fsetabl +++|  CONTROL IFGQ PARANOIA,5;
01661  M01S01628.fsetabl +++|    IF DISP LQ 0 THEN TRAGIC(" DIRECTORY BLOCK POINTER TOO SMALL.$");
01662  M01S01629.fsetabl +++|  CONTROL FI;
01663  M01S01630.fsetabl +++|  PADISP[PL] = DISP;
01664  M01S01631.fsetabl +++|
01665  M01S01632.fsetabl +++|  IF PADIR[PL] THEN
01666  M01S01633.fsetabl +++|    BEGIN
01667  M01S01634.fsetabl +++|    FOR PL = PL WHILE PADIR[PL] DO
01668  M01S01635.fsetabl +++|      BEGIN
01669  M01S01636.fsetabl +++|      PL = PL + 1;
01670  M01S01637.fsetabl +++|      PALVL = PL;
01671  M01S01638.fsetabl +++|
01672  M01S01639.fsetabl +++|      PUSHTEMP;
01673  M01S01640.fsetabl +++|      TEMP=DIRDA[DISP];
01674  M01S01641.fsetabl +++|      READPA;
01675  M01S01642.fsetabl +++|      POPTEMP;
01676  M01S01643.fsetabl +++|
01677  M01S01644.fsetabl +++|      PAFIRST[PL] = CURRENT - DIRNL[DISP] + 1;
01678  M01S01645.fsetabl +++|      PALAST[PL] = CURRENT;
01679  M01S01646.fsetabl +++|
01680  M01S01647.fsetabl +++|      P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01681  M01S01648.fsetabl +++|
01682  M01S01649.fsetabl +++|      DISP = PAFINAL[PL];
01683  M01S01650.fsetabl +++|      PADISP[PL] = DISP;
01684  M01S01651.fsetabl +++|      END
01685  M01S01652.fsetabl +++|
01686  M01S01653.fsetabl +++|    PREFETCH(-1);
01687  M01S01654.fsetabl +++|    END
01688  M01S01655.fsetabl +++|
01689  M01S01656.fsetabl +++|  # NOTE THIS CODE REQUIRES INTERNAL CHARSET USAGE OF SIGN BIT #
01690  M01S01657.fsetabl +++|  FOR DISP = DISP - 1 WHILE DISP NQ 0 AND B<0,1>DATWORD[DISP] EQ 0
01691  M01S01658.fsetabl +++|    DO DISP = DISP - 1;
01692  M01S01659.fsetabl +++|
01693  M01S01660.fsetabl +++|  PADISP[PL] = DISP + 1;
01694  M01S01661.fsetabl +++|  P<FROM> = LOC(BFPRU[PACACHE[PALVL]]) + PADISP[PALVL];
01695  M01S01662.fsetabl +++|  CURNW = MOVELN(FROM,MVLNBUF);
01696  M01S01663.fsetabl +++|
01697  M01S01664.fsetabl +++|  IOEND
01698  M01S01665.fsetabl +++|PAGE
01699  M01S01666.fsetabl +++|PROC FW;
01700  M01S01667.fsetabl +++|  IOBEGIN(FW)
01701  M01S01668.fsetabl +++|#
01702  M01S01669.fsetabl +++|**        FW - ADVANCE ONE LINE.
01703  M01S01670.fsetabl +++|*
01704  M01S01671.fsetabl +++|*         FW IS ORGANIZED INTO THREE OPERATIONAL PHASES.  THE FIRST
01705  M01S01672.fsetabl +++|*         PHASE DETERMINES WHETHER THE CURRENT TREE PATH ALREADY
01706  M01S01673.fsetabl +++|*         CONTAINS THE SECTOR WITH THE DESIRED LINE OF TEXT, AND IF
01707  M01S01674.fsetabl +++|*         NOT, IT CLEANS AWAY AS MANY TREE LEVELS AS NECESSARY, FROM
01708  M01S01675.fsetabl +++|*         THE BOTTOM TOWARDS THE ROOT, UNTIL WE ARE IN A DIRECTORY
01709  M01S01676.fsetabl +++|*         WHOSE SPHERE OF INFLUENCE INCLUDES THE DESIRED LINE.
01710  M01S01677.fsetabl +++|*
01711  M01S01678.fsetabl +++|*         THE SECOND PHASE ASSURES THAT WE HAVE A FULL DEPTH TREE
01712  M01S01679.fsetabl +++|*         STRUCTURE CONTAINING THE RIGHT SECTOR AT THE DATA (BOTTOM)
01713  M01S01680.fsetabl +++|*         LEVEL.  IF THE FIRST PHASE WAS NON-TRIVIAL, THEN THE SECOND
01714  M01S01681.fsetabl +++|*         PHASE WILL ALSO HAVE REAL WORK TO PERFORM, WORKING BACK
01715  M01S01682.fsetabl +++|*         TOWARD DEEP TREE LEVELS, READING IN EACH SECTOR NEEDED.
01716  M01S01683.fsetabl +++|*         THE SECOND PHASE IS A NO-OP IF THE FIRST PHASE WAS A NO-OP
01717  M01S01684.fsetabl +++|*         AND IF THE TREE ALREADY EXISTS ALL THE WAY DOWN TO THE DATA
01718  M01S01685.fsetabl +++|*         LEVEL.  HOWEVER, THE FIRST PHASE COULD HAVE BEEN A NO-OP
01719  M01S01686.fsetabl +++|*         FOR AN INCOMPLETE TREE PATH, IN WHICH CASE THE SECOND PHASE
01720  M01S01687.fsetabl +++|*         MUST DEEPEN THE TREE PATH.
01721  M01S01688.fsetabl +++|*
01722  M01S01689.fsetabl +++|*         THE THIRD PHASE IDENTIFIES THE CORRECT LINE IMAGE WITHIN
01723  M01S01690.fsetabl +++|*         THE DATA SECTOR.  THE MECHANISM USED DEPENDS ON WHETHER THE
01724  M01S01691.fsetabl +++|*         SECOND PHASE WAS ACTUALLY PERFORMED, SINCE FOR A NO-OP THE
01725  M01S01692.fsetabl +++|*         DISP AND CURNW PARAMETERS FOR THE PREVIOUS CURRENT LINE
01726  M01S01693.fsetabl +++|*         PROVIDE ALL INFORMATION REQUIRED TO ADVANCE ONE LINE.
01727  M01S01694.fsetabl +++|*
01728  M01S01695.fsetabl +++|*         ENTRY  CURRENT - CURRENT LINE.
01729  M01S01696.fsetabl +++|*                PALVL - DEEPEST TREE LEVEL.
01730  M01S01697.fsetabl +++|*                ALL PATH AND CACHE CONTROLS SETUP.
01731  M01S01698.fsetabl +++|*                P<MVLNBUF> - WHERE TO PUT LINE OF TEXT.
01732  M01S01699.fsetabl +++|*                DISP, CURNW - DESCRIBE WORD OFFSET AND LENGTH OF
01733  M01S01700.fsetabl +++|*                    PREVIOUS CURRENT LINE.
01734  M01S01701.fsetabl +++|*
01735  M01S01702.fsetabl +++|*         EXIT   CURRENT - INCREMENTED.
01736  M01S01703.fsetabl +++|*                MVLNBUF - CONTAINS LINE OF TEXT.
01737  M01S01704.fsetabl +++|*                PALVL - NEW VALUE FOR DEEPEST TREE LEVEL.
01738  M01S01705.fsetabl +++|*                ALL PATH CONTROLS - MAY CONTROL DIFFERENT SECTORS
01739  M01S01706.fsetabl +++|*                    FOR DEEPER TREE LEVELS.
01740  M01S01707.fsetabl +++|*                ALL CACHE CONTROLS - MAY CONTROL DIFFERENT SECTORS.
01741  M01S01708.fsetabl +++|*                FET, CIRCULAR BUFFER, READ LIST - MAY CONTROL
01742  M01S01709.fsetabl +++|*                    A PREFETCH OPERATION.
01743  M01S01710.fsetabl +++|*                CURNW - SIZE OF NEW LINE.
01744  M01S01711.fsetabl +++|*                DISP - OFFSET OF NEW LINE.
01745  M01S01712.fsetabl +++|*
01746  M01S01713.fsetabl +++|*         CALLS  TRAGIC, CLEAN, PUSHTEMP, READPA, POPTEMP, PREFETCH,
01747  M01S01714.fsetabl +++|*                MOVELN.
01748  M01S01715.fsetabl +++|*
01749  M01S01716.fsetabl +++|*         USES   TEMP(RESTORED), P<PRU>, PL.
01750  M01S01717.fsetabl +++|#
01751  M01S01718.fsetabl +++|
01752  M01S01719.fsetabl +++|  IF CURRENT GQ PALAST[0] THEN TRAGIC(" FWD BEYOND END OF FILE.$");
01753  M01S01720.fsetabl +++|
01754  M01S01721.fsetabl +++|  CURRENT = CURRENT + 1;
01755  M01S01722.fsetabl +++|
01756  M01S01723.fsetabl +++|  FOR PL = PALVL WHILE PALAST[PL] LS CURRENT DO
01757  M01S01724.fsetabl +++|    BEGIN
01758  M01S01725.fsetabl +++|    CLEAN;
01759  M01S01726.fsetabl +++|    PL = PL - 1;
01760  M01S01727.fsetabl +++|    END
01761  M01S01728.fsetabl +++|
01762  M01S01729.fsetabl +++|  P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01763  M01S01730.fsetabl +++|
01764  M01S01731.fsetabl +++|  DISP = PADISP[PL];
01765  M01S01732.fsetabl +++|
01766  M01S01733.fsetabl +++|  IF PADIR[PL] THEN
01767  M01S01734.fsetabl +++|    BEGIN
01768  M01S01735.fsetabl +++|    DISP = DISP + 1;
01769  M01S01736.fsetabl +++|    CONTROL IFGQ PARANOIA,5;
01770  M01S01737.fsetabl +++|      IF DISP GR PAFINAL[PL] THEN
01771  M01S01738.fsetabl +++|        BEGIN
01772  M01S01739.fsetabl +++|        TRAGIC(" DIRECTORY BLOCK POINTER TOO LARGE (1).$");
01773  M01S01740.fsetabl +++|        END
01774  M01S01741.fsetabl +++|    CONTROL FI;
01775  M01S01742.fsetabl +++|    PADISP[PL] = DISP;
01776  M01S01743.fsetabl +++|
01777  M01S01744.fsetabl +++|    FOR PL = PL WHILE PADIR[PL] DO
01778  M01S01745.fsetabl +++|      BEGIN
01779  M01S01746.fsetabl +++|      PL = PL + 1;
01780  M01S01747.fsetabl +++|      PALVL = PL;
01781  M01S01748.fsetabl +++|
01782  M01S01749.fsetabl +++|      PUSHTEMP;
01783  M01S01750.fsetabl +++|      TEMP=DIRDA[DISP];
01784  M01S01751.fsetabl +++|      READPA;
01785  M01S01752.fsetabl +++|      POPTEMP;
01786  M01S01753.fsetabl +++|
01787  M01S01754.fsetabl +++|      PAFIRST[PL] = CURRENT;
01788  M01S01755.fsetabl +++|      PALAST[PL] = CURRENT + DIRNL[DISP] - 1;
01789  M01S01756.fsetabl +++|
01790  M01S01757.fsetabl +++|      P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01791  M01S01758.fsetabl +++|
01792  M01S01759.fsetabl +++|      DISP = 1;
01793  M01S01760.fsetabl +++|      PADISP[PL] = 1;
01794  M01S01761.fsetabl +++|      END
01795  M01S01762.fsetabl +++|
01796  M01S01763.fsetabl +++|    PREFETCH(+1);
01797  M01S01764.fsetabl +++|    END
01798  M01S01765.fsetabl +++|
01799  M01S01766.fsetabl +++|  ELSE PADISP[PL] = DISP + CURNW;
01800  M01S01767.fsetabl +++|
01801  M01S01768.fsetabl +++|  P<FROM> = LOC(BFPRU[PACACHE[PALVL]]) + PADISP[PALVL];
01802  M01S01769.fsetabl +++|  CURNW = MOVELN(FROM,MVLNBUF);
01803  M01S01770.fsetabl +++|
01804  M01S01771.fsetabl +++|  IOEND
01805  M01S01772.fsetabl +++|PAGE
01806  M01S01773.fsetabl +++|PROC POSR;
01807  M01S01774.fsetabl +++|  IOBEGIN(POSR)
01808  M01S01775.fsetabl +++|#
01809  M01S01776.fsetabl +++|**        POSR - POSITION TO A RANDOMLY SELECTED LINE.
01810  M01S01777.fsetabl +++|*
01811  M01S01778.fsetabl +++|*         POSR IS ORGANIZED INTO THREE OPERATIONAL PHASES.  THE FIRST
01812  M01S01779.fsetabl +++|*         PHASE DETERMINES WHETHER THE CURRENT TREE PATH ALREADY
01813  M01S01780.fsetabl +++|*         CONTAINS THE SECTOR WITH THE DESIRED LINE OF TEXT, AND IF
01814  M01S01781.fsetabl +++|*         NOT, IT CLEANS AWAY AS MANY TREE LEVELS AS NECESSARY, FROM
01815  M01S01782.fsetabl +++|*         THE BOTTOM TOWARDS THE ROOT, UNTIL WE ARE IN A DIRECTORY
01816  M01S01783.fsetabl +++|*         WHOSE SPHERE OF INFLUENCE INCLUDES THE DESIRED LINE.
01817  M01S01784.fsetabl +++|*
01818  M01S01785.fsetabl +++|*         THE SECOND PHASE ASSURES THAT WE HAVE A FULL DEPTH TREE
01819  M01S01786.fsetabl +++|*         STRUCTURE CONTAINING THE RIGHT SECTOR AT THE DATA (BOTTOM)
01820  M01S01787.fsetabl +++|*         LEVEL.  IF THE FIRST PHASE WAS NON-TRIVIAL, THEN THE SECOND
01821  M01S01788.fsetabl +++|*         PHASE WILL ALSO HAVE REAL WORK TO PERFORM, WORKING BACK
01822  M01S01789.fsetabl +++|*         TOWARD DEEP TREE LEVELS, READING IN EACH SECTOR NEEDED.
01823  M01S01790.fsetabl +++|*         THE SECOND PHASE IS A NO-OP IF THE FIRST PHASE WAS A NO-OP
01824  M01S01791.fsetabl +++|*         AND IF THE TREE ALREADY EXISTS ALL THE WAY DOWN TO THE DATA
01825  M01S01792.fsetabl +++|*         LEVEL.  HOWEVER, THE FIRST PHASE COULD HAVE BEEN A NO-OP
01826  M01S01793.fsetabl +++|*         FOR AN INCOMPLETE TREE PATH, IN WHICH CASE THE SECOND PHASE
01827  M01S01794.fsetabl +++|*         MUST DEEPEN THE TREE PATH.
01828  M01S01795.fsetabl +++|*
01829  M01S01796.fsetabl +++|*         THE THIRD PHASE SCANS THE DATA SECTOR TO FIND THE RIGHT
01830  M01S01797.fsetabl +++|*         LINE IMAGE.  THE INTERNAL LINE IMAGE FORMAT USES THE SIGN
01831  M01S01798.fsetabl +++|*         BIT TO INDICATE WORDS WHICH ARE THE LAST WORDS OF LINES.
01832  M01S01799.fsetabl +++|*
01833  M01S01800.fsetabl +++|*         ENTRY  NEWCURL - DESIRED LINE.
01834  M01S01801.fsetabl +++|*                PALVL - DEEPEST TREE LEVEL.
01835  M01S01802.fsetabl +++|*                ALL PATH AND CACHE CONTROLS SETUP.
01836  M01S01803.fsetabl +++|*                P<MVLNBUF> - WHERE TO PUT LINE OF TEXT.
01837  M01S01804.fsetabl +++|*                DISP, CURNW - DESCRIBE WORD OFFSET AND LENGTH OF
01838  M01S01805.fsetabl +++|*                    PREVIOUS CURRENT LINE.
01839  M01S01806.fsetabl +++|*
01840  M01S01807.fsetabl +++|*         EXIT   CURRENT - MATCHES NEWCURL.
01841  M01S01808.fsetabl +++|*                MVLNBUF - CONTAINS LINE OF TEXT.
01842  M01S01809.fsetabl +++|*                PALVL - NEW VALUE FOR DEEPEST TREE LEVEL.
01843  M01S01810.fsetabl +++|*                ALL PATH CONTROLS - MAY CONTROL DIFFERENT SECTORS
01844  M01S01811.fsetabl +++|*                    FOR DEEPER TREE LEVELS.
01845  M01S01812.fsetabl +++|*                ALL CACHE CONTROLS - MAY CONTROL DIFFERENT SECTORS.
01846  M01S01813.fsetabl +++|*                FET, CIRCULAR BUFFER, READ LIST - MAY CONTROL
01847  M01S01814.fsetabl +++|*                    A PREFETCH OPERATION.
01848  M01S01815.fsetabl +++|*                CURNW - SIZE OF NEW LINE.
01849  M01S01816.fsetabl +++|*                DISP - OFFSET OF NEW LINE.
01850  M01S01817.fsetabl +++|*
01851  M01S01818.fsetabl +++|*         CALLS  TRAGIC, CLEAN, PUSHTEMP, READPA, POPTEMP, PREFETCH,
01852  M01S01819.fsetabl +++|*                MOVELN.
01853  M01S01820.fsetabl +++|*
01854  M01S01821.fsetabl +++|*         USES   TEMP(RESTORED), P<PRU>, PL.
01855  M01S01822.fsetabl +++|#
01856  M01S01823.fsetabl +++|
01857  M01S01824.fsetabl +++|  IF NEWCURL LS 0 OR NEWCURL GR PALAST[0] THEN
01858  M01S01825.fsetabl +++|    BEGIN
01859  M01S01826.fsetabl +++|    TRAGIC(" LINE NOT FOUND IN FILE.$");
01860  M01S01827.fsetabl +++|    END
01861  M01S01828.fsetabl +++|
01862  M01S01829.fsetabl +++|  PUSHTEMP;
01863  M01S01830.fsetabl +++|
01864  M01S01831.fsetabl +++|  CURRENT = NEWCURL;
01865  M01S01832.fsetabl +++|
01866  M01S01833.fsetabl +++|  FOR PL=PALVL WHILE
01867  M01S01834.fsetabl +++|    NOT(CURRENT GQ PAFIRST[PL] AND CURRENT LQ PALAST[PL]) DO
01868  M01S01835.fsetabl +++|    BEGIN
01869  M01S01836.fsetabl +++|    CLEAN;
01870  M01S01837.fsetabl +++|    PL = PL - 1;
01871  M01S01838.fsetabl +++|    END
01872  M01S01839.fsetabl +++|
01873  M01S01840.fsetabl +++|  P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01874  M01S01841.fsetabl +++|
01875  M01S01842.fsetabl +++|  FOR PL = PL WHILE PADIR[PL] DO
01876  M01S01843.fsetabl +++|    BEGIN
01877  M01S01844.fsetabl +++|    TEMP = PAFIRST[PL];
01878  M01S01845.fsetabl +++|
01879  M01S01846.fsetabl +++|    FOR DISP = 1 WHILE CURRENT GQ TEMP+DIRNL[DISP] DO
01880  M01S01847.fsetabl +++|      BEGIN
01881  M01S01848.fsetabl +++|      TEMP = TEMP + DIRNL[DISP];
01882  M01S01849.fsetabl +++|      DISP = DISP + 1;
01883  M01S01850.fsetabl +++|      END
01884  M01S01851.fsetabl +++|
01885  M01S01852.fsetabl +++|    CONTROL IFGQ PARANOIA,5;
01886  M01S01853.fsetabl +++|      IF DISP GR PAFINAL[PL] THEN
01887  M01S01854.fsetabl +++|        BEGIN
01888  M01S01855.fsetabl +++|        TRAGIC(" DIRECTORY BLOCK POINTER TOO LARGE (2).$");
01889  M01S01856.fsetabl +++|        END
01890  M01S01857.fsetabl +++|    CONTROL FI;
01891  M01S01858.fsetabl +++|    PADISP[PL] = DISP;
01892  M01S01859.fsetabl +++|
01893  M01S01860.fsetabl +++|    PL = PL + 1;
01894  M01S01861.fsetabl +++|    PALVL = PL;
01895  M01S01862.fsetabl +++|
01896  M01S01863.fsetabl +++|    PAFIRST[PL] = TEMP;
01897  M01S01864.fsetabl +++|    PALAST[PL] = TEMP + DIRNL[DISP] - 1;
01898  M01S01865.fsetabl +++|
01899  M01S01866.fsetabl +++|    PUSHTEMP;
01900  M01S01867.fsetabl +++|    TEMP=DIRDA[DISP];
01901  M01S01868.fsetabl +++|    READPA;
01902  M01S01869.fsetabl +++|    POPTEMP;
01903  M01S01870.fsetabl +++|
01904  M01S01871.fsetabl +++|    P<PRU> = LOC(BFPRU[PACACHE[PL]]);
01905  M01S01872.fsetabl +++|
01906  M01S01873.fsetabl +++|    END
01907  M01S01874.fsetabl +++|
01908  M01S01875.fsetabl +++|  TEMP = PAFIRST[PL];
01909  M01S01876.fsetabl +++|
01910  M01S01877.fsetabl +++|  FOR DISP = 1 WHILE CURRENT NQ TEMP DO
01911  M01S01878.fsetabl +++|    BEGIN
01912  M01S01879.fsetabl +++|    # NOTE THIS CODE REQUIRES INTERNAL CHARSET USAGE OF SIGN BIT #
01913  M01S01880.fsetabl +++|    IF B<0,1>DATWORD[DISP] NQ 0 THEN TEMP = TEMP + 1;
01914  M01S01881.fsetabl +++|    DISP = DISP + 1;
01915  M01S01882.fsetabl +++|    END
01916  M01S01883.fsetabl +++|
01917  M01S01884.fsetabl +++|  CONTROL IFGQ PARANOIA,5;
01918  M01S01885.fsetabl +++|    IF DISP GR PAFINAL[PL] THEN
01919  M01S01886.fsetabl +++|      BEGIN
01920  M01S01887.fsetabl +++|      TRAGIC(" DIRECTORY BLOCK POINTER TOO LARGE (3).$");
01921  M01S01888.fsetabl +++|      END
01922  M01S01889.fsetabl +++|  CONTROL FI;
01923  M01S01890.fsetabl +++|
01924  M01S01891.fsetabl +++|  PADISP[PL] = DISP;
01925  M01S01892.fsetabl +++|
01926  M01S01893.fsetabl +++|  P<FROM> = LOC(BFPRU[PACACHE[PALVL]]) + PADISP[PALVL];
01927  M01S01894.fsetabl +++|  CURNW = MOVELN(FROM,MVLNBUF);
01928  M01S01895.fsetabl +++|
01929  M01S01896.fsetabl +++|  POPTEMP;
01930  M01S01897.fsetabl +++|
01931  M01S01898.fsetabl +++|  IOEND
01932  M01S01899.fsetabl +++|PAGE
01933  M01S01900.fsetabl +++|
01934  M01S01901.fsetabl +++|PROC FWD;
01935  M01S01902.fsetabl +++|  IOBEGIN(FWD)
01936  M01S01903.fsetabl +++|#
01937  M01S01904.fsetabl +++|**        FWD - EXTERNAL INTERFACE FOR FORWARD MOVEMENT.
01938  M01S01905.fsetabl +++|*
01939  M01S01906.fsetabl +++|*         FWD INTERFACES TO THE FW ROUTINE TO ADVANCE ONE LINE
01940  M01S01907.fsetabl +++|*         FROM THE CURRENT POSITION.  FWD ALSO CONTROLS THE BASE
01941  M01S01908.fsetabl +++|*         ADDRESS FOR MVLNBUF AND ACCUMULATES STATISTICS.
01942  M01S01909.fsetabl +++|*
01943  M01S01910.fsetabl +++|*         ENTRY  P<LINEBUF> - WHERE TO PUT TEXT OR ZERO FOR INVISIBLE
01944  M01S01911.fsetabl +++|*                    POSITIONING FUNCTION.
01945  M01S01912.fsetabl +++|*                CURRENT - CURRENT LINE.
01946  M01S01913.fsetabl +++|*
01947  M01S01914.fsetabl +++|*         EXIT   CURRENT - INCREMENTED.
01948  M01S01915.fsetabl +++|*                LINEBUF - TEXT MOVE HERE IF BASE ADDRESS NONZERO.
01949  M01S01916.fsetabl +++|*
01950  M01S01917.fsetabl +++|*         CALLS  FW.
01951  M01S01918.fsetabl +++|*
01952  M01S01919.fsetabl +++|*         USES   P<MVLNBUF>.
01953  M01S01920.fsetabl +++|#
01954  M01S01921.fsetabl +++|
01955  M01S01922.fsetabl +++|  CONTROL IFEQ MULTI,1;
01956  M01S01923.fsetabl +++|    WIOSTAT(0);               # ACCUMULATE LINE ACCESES #
01957  M01S01924.fsetabl +++|  CONTROL FI;
01958  M01S01925.fsetabl +++|
01959  M01S01926.fsetabl +++|  P<MVLNBUF>=LOC(LINEBUF);
01960  M01S01927.fsetabl +++|  FW;
01961  M01S01928.fsetabl +++|  P<MVLNBUF>=0;
01962  M01S01929.fsetabl +++|  IOEND
01963  M01S01930.fsetabl +++|
01964  M01S01931.fsetabl +++|PROC BAK;
01965  M01S01932.fsetabl +++|  IOBEGIN(BAK)
01966  M01S01933.fsetabl +++|#
01967  M01S01934.fsetabl +++|**        FWD - EXTERNAL INTERFACE FOR BACKWARD MOVEMENT.
01968  M01S01935.fsetabl +++|*
01969  M01S01936.fsetabl +++|*         BAK INTERFACES TO THE BK ROUTINE TO REGRESS ONE LINE
01970  M01S01937.fsetabl +++|*         FROM THE CURRENT POSITION.  BAK ALSO CONTROLS THE BASE
01971  M01S01938.fsetabl +++|*         ADDRESS FOR MVLNBUF AND ACCUMULATES STATISTICS.
01972  M01S01939.fsetabl +++|*
01973  M01S01940.fsetabl +++|*         ENTRY  P<LINEBUF> - WHERE TO PUT TEXT OR ZERO FOR INVISIBLE
01974  M01S01941.fsetabl +++|*                    POSITIONING FUNCTION.
01975  M01S01942.fsetabl +++|*                CURRENT - CURRENT LINE.
01976  M01S01943.fsetabl +++|*
01977  M01S01944.fsetabl +++|*         EXIT   CURRENT - DECREMENTED.
01978  M01S01945.fsetabl +++|*                LINEBUF - TEXT MOVE HERE IF BASE ADDRESS NONZERO.
01979  M01S01946.fsetabl +++|*
01980  M01S01947.fsetabl +++|*         CALLS  BK.
01981  M01S01948.fsetabl +++|*
01982  M01S01949.fsetabl +++|*         USES   P<MVLNBUF>.
01983  M01S01950.fsetabl +++|#
01984  M01S01951.fsetabl +++|
01985  M01S01952.fsetabl +++|  CONTROL IFEQ MULTI,1;
01986  M01S01953.fsetabl +++|    WIOSTAT(0);               # ACCUMULATE LINE ACCESES #
01987  M01S01954.fsetabl +++|  CONTROL FI;
01988  M01S01955.fsetabl +++|
01989  M01S01956.fsetabl +++|  P<MVLNBUF>=LOC(LINEBUF);
01990  M01S01957.fsetabl +++|  BK;
01991  M01S01958.fsetabl +++|  P<MVLNBUF>=0;
01992  M01S01959.fsetabl +++|  IOEND
01993  M01S01960.fsetabl +++|
01994  M01S01961.fsetabl +++|PROC POS;
01995  M01S01962.fsetabl +++|  IOBEGIN(POS)
01996  M01S01963.fsetabl +++|#
01997  M01S01964.fsetabl +++|**        POS - EXTERNAL INTERFACE FOR RANDOM MOVEMENT.
01998  M01S01965.fsetabl +++|*
01999  M01S01966.fsetabl +++|*         POS INTERFACES TO THE POSR ROUTINE TO GO TO ANY LINE
02000  M01S01967.fsetabl +++|*         FROM THE CURRENT POSITION.  POS ALSO CONTROLS THE BASE
02001  M01S01968.fsetabl +++|*         ADDRESS FOR MVLNBUF AND ACCUMULATES STATISTICS.
02002  M01S01969.fsetabl +++|*
02003  M01S01970.fsetabl +++|*         ENTRY  P<LINEBUF> - WHERE TO PUT TEXT OR ZERO FOR INVISIBLE
02004  M01S01971.fsetabl +++|*                    POSITIONING FUNCTION.
02005  M01S01972.fsetabl +++|*                NEWCURL - DESIRED LINE.
02006  M01S01973.fsetabl +++|*                CURRENT - PREVIOUS CURRENT LINE.
02007  M01S01974.fsetabl +++|*
02008  M01S01975.fsetabl +++|*         EXIT   CURRENT - MATCHES NEWCURL.
02009  M01S01976.fsetabl +++|*                LINEBUF - TEXT MOVE HERE IF BASE ADDRESS NONZERO.
02010  M01S01977.fsetabl +++|*
02011  M01S01978.fsetabl +++|*         CALLS  POSR.
02012  M01S01979.fsetabl +++|*
02013  M01S01980.fsetabl +++|*         USES   P<MVLNBUF>.
02014  M01S01981.fsetabl +++|#
02015  M01S01982.fsetabl +++|
02016  M01S01983.fsetabl +++|  CONTROL IFEQ MULTI,1;
02017  M01S01984.fsetabl +++|    WIOSTAT(0);               # ACCUMULATE LINE ACCESES #
02018  M01S01985.fsetabl +++|  CONTROL FI;
02019  M01S01986.fsetabl +++|
02020  M01S01987.fsetabl +++|  P<MVLNBUF>=LOC(LINEBUF);
02021  M01S01988.fsetabl +++|  IF NEWCURL EQ CURRENT-1 THEN BK;
02022  M01S01989.fsetabl +++|  ELSE IF NEWCURL EQ CURRENT+1 THEN FW;
02023  M01S01990.fsetabl +++|  ELSE IF NEWCURL NQ CURRENT THEN POSR;
02024  M01S01991.fsetabl +++|  ELSE                       # JUST READOUT SAME LINE      #
02025  M01S01992.fsetabl +++|    BEGIN
02026  M01S01993.fsetabl +++|    P<FROM> = LOC(BFPRU[PACACHE[PALVL]]) + PADISP[PALVL];
02027  M01S01994.fsetabl +++|    DUMB = MOVELN(FROM,LINEBUF);
02028  M01S01995.fsetabl +++|    END
02029  M01S01996.fsetabl +++|  P<MVLNBUF>=0;
02030  M01S01997.fsetabl +++|  IOEND                       # OF POS  #
02031  M01S01998.fsetabl +++|PAGE
02032  M01S01999.fsetabl +++|  PROC SPLITTOP;
02033  M01S02000.fsetabl +++|    IOBEGIN(SPLITTOP)
02034  M01S02001.fsetabl +++|#
02035  M01S02002.fsetabl +++|**        SPLITTOP - SPLIT ROOT SECTOR TO MAKE NEW LEVEL.
02036  M01S02003.fsetabl +++|*
02037  M01S02004.fsetabl +++|*         SPLITTOP IS USED WHEN THE ROOT SECTOR OVERFLOWS.  THE ROOT
02038  M01S02005.fsetabl +++|*         SECTOR MUST ALWAYS EXIST AT DISK ADDRESS 1, THUS THE METHOD
02039  M01S02006.fsetabl +++|*         USED TO SPLIT IT IS DIFFERENT FROM THAT USED FOR ANY OTHER
02040  M01S02007.fsetabl +++|*         SECTOR.  THE EXISTING CONTENTS OF THE ROOT SECTOR ARE
02041  M01S02008.fsetabl +++|*         PLACED IN TWO NEW SECTORS, AND THE ROOT SECTOR IS
02042  M01S02009.fsetabl +++|*         RECONSTRUCTED AS A DIRECTORY POINTING TO THESE TWO NEW
02043  M01S02010.fsetabl +++|*         SECTORS.  THUS THE OVERALL TREE STRUCTURE IS DEEPENED BY
02044  M01S02011.fsetabl +++|*         ONE LEVEL.
02045  M01S02012.fsetabl +++|*
02046  M01S02013.fsetabl +++|*         HOWEVER, SPLITTOP DOES NOT PROVIDE ALL THIS ALGORITHM.
02047  M01S02014.fsetabl +++|*         SPLITTOP DOES PRODUCE A NEW TREE LEVEL WITH A REBUILT ROOT,
02048  M01S02015.fsetabl +++|*         BUT STOPS SHORT OF FITTING THE OVERFLOWED TEXT INTO A PAIR
02049  M01S02016.fsetabl +++|*         OF SECTORS.  SPLITTOP PLACES THE PRE-OVERFLOW SECTOR
02050  M01S02017.fsetabl +++|*         CONTENT INTO A SINGLE SECTOR AT THE NEW INTERMEDIATE TREE
02051  M01S02018.fsetabl +++|*         LEVEL, AND ESTABLISHES THIS AS THE CURRENT TREE PATH LEVEL.
02052  M01S02019.fsetabl +++|*         THE CALLER IS THEN RESPONSIBLE TO USE ONE OF THE OTHER
02053  M01S02020.fsetabl +++|*         SECTOR SPLITTING ALGORITHMS TO GET THE TEXT ACTUALLY SPLIT
02054  M01S02021.fsetabl +++|*         INTO TWO SECTORS.  THESE OTHER ALGORITHMS WILL UPDATE THE
02055  M01S02022.fsetabl +++|*         NEW ROOT TO POINT TO THE OVERFLOW SECTOR.
02056  M01S02023.fsetabl +++|*
02057  M01S02024.fsetabl +++|*         ENTRY  PL - MUST EQUAL ZERO.
02058  M01S02025.fsetabl +++|*                PADEPTH[0] - INDICATE HIGH WATER MARK OF TREE DEPTH.
02059  M01S02026.fsetabl +++|*                PALVL - CURRENT DEEPEST TREE LEVEL ON PATH.
02060  M01S02027.fsetabl +++|*                ALL PATH CONTROLS - SETUP.
02061  M01S02028.fsetabl +++|*                CACHE - AT LEAST ONE FRAME MUST BE AVAILABLE TO
02062  M01S02029.fsetabl +++|*                    BE CLAIMED.
02063  M01S02030.fsetabl +++|*
02064  M01S02031.fsetabl +++|*         EXIT   PL - ONE.
02065  M01S02032.fsetabl +++|*                PALVL - INCREMENTED.
02066  M01S02033.fsetabl +++|*                PADEPTH[0] - INCREMENETED.
02067  M01S02034.fsetabl +++|*                ALL PATH CONTROLS - SHUFFLED TO DEEPER LEVELS.
02068  M01S02035.fsetabl +++|*                CACHE - ONE FRAME ALLOCATED FOR NEW LEVEL 0.
02069  M01S02036.fsetabl +++|*                ROOT SECTOR CACHE FRAME - BUILT AS DIRECTORY WITH
02070  M01S02037.fsetabl +++|*                    ONE ENTRY POINTING TO INTERMEDIATE SECTOR.
02071  M01S02038.fsetabl +++|*                PATH LEVEL 1 - BUILT AS INTERMEDIATE TREE LEVEL
02072  M01S02039.fsetabl +++|*                    USING SAME CACHE FRAME AS FORMER ROOT LEVEL,
02073  M01S02040.fsetabl +++|*                    BUT ASSIGNED A NEWLY ALLOCATED DISK ADDRESS.
02074  M01S02041.fsetabl +++|*                    MARKED AS ALTERED SO NEW DISK ADDRESS CAN BE
02075  M01S02042.fsetabl +++|*                    EVENTUALLY WRITTEN TO DISK.
02076  M01S02043.fsetabl +++|*
02077  M01S02044.fsetabl +++|*         CALLS  TRAGIC, ALLOC, ALLOCCACHE, MOVEWD.
02078  M01S02045.fsetabl +++|*
02079  M01S02046.fsetabl +++|*         USES   P<PRU>.
02080  M01S02047.fsetabl +++|#
02081  M01S02048.fsetabl +++|    IF PADEPTH[0] GQ MAXDEPTH THEN TRAGIC(" FILE TOO LARGE.$");
02082  M01S02049.fsetabl +++|    PADEPTH[0] = PADEPTH[0] + 1;
02083  M01S02050.fsetabl +++|
02084  M01S02051.fsetabl +++|    FOR PL =  PALVL STEP -1 UNTIL 0 DO # SLIDE PATH UP     #
02085  M01S02052.fsetabl +++|      BEGIN
02086  M01S02053.fsetabl +++|      PAFIRST[PL+1] = PAFIRST[PL];
02087  M01S02054.fsetabl +++|      PALAST[PL+1] = PALAST[PL];
02088  M01S02055.fsetabl +++|      PADISP[PL+1] = PADISP[PL];
02089  M01S02056.fsetabl +++|      PAHEAD[PL+1] = PAHEAD[PL];
02090  M01S02057.fsetabl +++|      PACACHE[PL+1] = PACACHE[PL];
02091  M01S02058.fsetabl +++|      END
02092  M01S02059.fsetabl +++|
02093  M01S02060.fsetabl +++|    PL = 1;                  # STEP UP PL & PALVL          #
02094  M01S02061.fsetabl +++|    PALVL = PALVL + 1;
02095  M01S02062.fsetabl +++|
02096  M01S02063.fsetabl +++|    PATOP[1] = FALSE;        # FIX UP OLD TOP    #
02097  M01S02064.fsetabl +++|    PADIRTY[1] = FALSE;
02098  M01S02065.fsetabl +++|    PADA[1] = 0;
02099  M01S02066.fsetabl +++|    ALLOC;
02100  M01S02067.fsetabl +++|    ALLOCCACHE;
02101  M01S02068.fsetabl +++|    PADIRTY[1] = TRUE;
02102  M01S02069.fsetabl +++|    P<FROM> = LOC(BFPRU[PACACHE[0]]) + 1;
02103  M01S02070.fsetabl +++|    P<TOO> = LOC(BFPRU[PACACHE[1]]) + 1;
02104  M01S02071.fsetabl +++|    MOVEWD(PAFINAL[0],FROM,TOO);
02105  M01S02072.fsetabl +++|
02106  M01S02073.fsetabl +++|    PADATA[0] = FALSE;       # BUILD NEW TOP     #
02107  M01S02074.fsetabl +++|    PADIR[0] = TRUE;
02108  M01S02075.fsetabl +++|    PADIRTY[0] = TRUE;
02109  M01S02076.fsetabl +++|    PAFINAL[0] = 1;
02110  M01S02077.fsetabl +++|    P<PRU> = LOC(BFPRU[PACACHE[0]]);
Proceed to Part 1