1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 
 13 grab_aste: procedure (segptr, a_len, rcode) returns (ptr);
 14 
 15 /*  This  procedure  is  responsible for forcibly activating segments.  The I/O
 16 Buffer  Manager  uses  the  _io entries, which also clean up the segment w.r.t.
 17 cache  control.   The  directory containing the segment must not be locked when
 18 grab_aste is called.
 19 
 20 Bernard Greenberg,   May 10, 1974
 21 
 22 */
 23 /* 5/8/75 by BSG for NSS */
 24 /* 4/26/77 by BSG for aste.ddnp */
 25 /* 12/1/78 by BSG for not crashing on activate errors */
 26 /* 1/82 BIM for dir write lock to get exclusive lock */
 27 
 28 dcl       (segptr,                                /* pointer to segment.   KST-recognized segment number */
 29            a_astep) pointer;                      /* argument astep of segment  on release calls. */
 30 
 31 dcl       (rcode,                                 /* return error code */
 32            code,                                  /* code from called routines */
 33            word) fixed bin (35);                  /* used for touching  seg */
 34 
 35 dcl       do_io bit (1);                          /* flag for _io entry */
 36 dcl       prewithdraw bit (1);                    /* flag for page prewithdrawing */
 37 dcl       segno fixed bin (17);                   /* segno for syserr calls */
 38 dcl       dp ptr;                                 /* ptr to dir */
 39 
 40 dcl       (null, baseno, ptr, fixed) builtin;
 41 
 42 dcl       based_word (0:262143) fixed bin (35) based;
 43 dcl       (len, a_len) fixed bin (18);
 44 dcl       pno fixed bin;                                    /* Page number when prewithdrawing seg */
 45 
 46 dcl       error_table_$dirseg fixed bin (35)  ext;
 47 
 48 dcl       sum$getbranch entry (ptr, bit (36) aligned,  ptr, fixed bin (35)),
 49           lock$unlock_ast entry,
 50           activate entry (ptr, fixed bin (35)) returns (ptr),
 51           lock$dir_unlock entry (ptr),
 52           setfaults$cache entry (ptr, bit (1) aligned),
 53           syserr entry options (variable),
 54           syserr$error_code entry options (variable);
 55 
 56 /*^L*/
 57 %include dir_entry;
 58 %include aste;
 59 /*^L*/
 60 
 61 
 62           do_io = "0"b;                                     /* set flag for no  cache  business */
 63           prewithdraw = "0"b;
 64           go to grab_join;
 65 
 66 grab_aste_io: entry (segptr, a_len, rcode) returns (ptr);
 67 
 68           do_io = "1"b;                                     /* set cache flags flag */
 69           prewithdraw = "0"b;
 70           go to grab_join;
 71 
 72 prewithdraw: entry (segptr, a_len, rcode) returns (ptr);
 73 
 74           do_io = "0"b;
 75           prewithdraw = "1"b;
 76 
 77 grab_join:
 78           segno = fixed (baseno (segptr), 17);              /* get segment number forr syserr calls */
 79 
 80           len = divide (a_len + 1023, 1024, 17, 0);         /* len = NUMBER OF PAGES in request */
 81 
 82 
 83           call sum$getbranch (segptr, (36)"1"b /* WRITE */, ep, code);          /* access  entry, and lock dir. Root and
 84                                                               mylock are not acceptable */
 85 
 86 /* The point of locking the directory is so that nobody else can try to activate the
 87           segment while we try. Boundfaults and segfaults in this state are acceptable. */
 88 
 89           if code ^= 0 then do;                             /* no errors are acceptable */
 90                rcode = code;                                /* pass the buck */
 91                return (null());
 92           end;
 93           dp = ptr (ep, 0);                                 /* get dir ptr for unlock call */
 94           if ep -> entry.dirsw then do;                     /* we do not take kindly to ehs'ing dirs */
 95                call lock$dir_unlock (dp);
 96                rcode = error_table_$dirseg;                 /* operation not allowed for dirs */
 97                return (null());
 98           end;
 99 
100           astep = activate (ep, code);                      /* Force to be active. Must have
101                                                                large enough ASTE. */
102 
103           if astep = null then do;                          /* Could be disk offline, etc. */
104                call lock$dir_unlock (dp);
105                rcode = code;
106                return (null ());
107           end;
108 
109           if astep -> aste.ehs then
110                     call syserr (1, "grab_aste: Attempt to re-use seg ^o", segno);
111 
112           astep -> aste.ddnp = "1"b;                        /* Don't deposit null pages- this protects
113                                                                against deactivation, but boundsfaults go thru,
114                                                                and segment moves reproduce the withdrawals! */
115 
116           call lock$unlock_ast;                             /* Unlock AST to allow segmoves and boundsfaults */
117 
118           if prewithdraw then pno = 1;
119           else pno = len;                                   /* Get prewithdraw range */
120 
121           do pno = pno to len by 1;                         /* Touch all pages */
122                word = segptr -> based_word ((pno - 1) * 1024);        /* Cause allocation */
123                                                             /* aste.ddnp prevents against deallocation */
124           end;
125 
126           astep = activate (ep, code);
127           if astep = null then call syserr$error_code (1, code, "grab_aste: failed to reactivate ^p", ep);
128 
129           astep -> aste.ddnp = prewithdraw;                 /* Conditionally turn off ddnp */
130 
131           astep -> aste.ehs = "1"b;                         /* set entry hold active */
132 
133           if do_io then do;                                 /* if used for i/o, must disencache  */
134                astep -> aste.any_access_on = "0"b;          /* put in non-encached state */
135                astep -> aste.write_access_on,
136                astep -> aste.inhibit_cache = "1"b;          /* and make sure it stays there. */
137                call setfaults$cache (astep, "0"b);          /* take it out of current caches */
138           end;
139 
140           call lock$unlock_ast;
141           call lock$dir_unlock (dp);    /* unlock dir, now that ehs is on */
142           rcode = 0;                                        /* all is ok */
143 
144           return (astep);                                   /* return ast entry  ptr */
145 
146 /*^L*/
147 release_io:         entry (a_astep);                        /* entry to un-disencache and de-ehs */
148           do_io  = "1"b;
149           prewithdraw = "0"b;
150           go to release_join;
151 
152 release_prewithdraw: entry (a_astep);                       /* Release nondepositable segments as ssch */
153 
154           prewithdraw = "1"b;
155           do_io = "0"b;
156           go to release_join;
157 
158 release:  entry (a_astep);
159           do_io = "0"b;
160           prewithdraw = "0"b;
161 
162 release_join:
163           astep = a_astep;                                  /* copy arg */
164           if ^astep -> aste.ehs then
165                call syserr (1, "grab_aste: Unprotected segment:  astep = ^p", astep);
166                                                             /* must have ehs on */
167           astep -> aste.ehs = "0"b;                         /* turn off ehs */
168           if do_io then astep -> aste.inhibit_cache = "0"b; /* resume standard cache control */
169           if prewithdraw then astep -> aste.ddnp = "0"b;
170           return;
171 ^L
172 /* BEGIN MESSAGE DOCUMENTATION
173 
174    Message:
175    grab_aste: Attempt to reuse segno SSS
176 
177    S: $crash
178 
179    T: $run
180 
181    M: A call has been made to force active a segment already forced active.
182    This indicates an inconsistency in the programming of the supervisor.
183    $err
184 
185    A: $recover
186    $notify
187 
188    Message:
189    grab_aste: failed to reactivate PPPP ERRORMESSAGE
190 
191    S: $crash
192 
193    T: $run
194 
195    M: $err
196 
197    A: $recover
198    $notify
199 
200    Message:
201    grab_aste: Unprotected segment: astep = AAA
202 
203    S: $crash
204 
205    T: $run
206 
207    M: An attempt was made to release from forced activity a segment (whose
208    AST entry is at AAA) which was not even in a state of forced activity.
209    $err
210 
211    A: $inform
212    $recover
213 
214    END MESSAGE DOCUMENTATION */
215 
216 end;