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 dbm_man: proc;
 13 
 14 /* This routine manages the initialization, allocating, freeing, setting and resetting of the
 15    bit maps that control the system dumper. For every mounted volume there exist two bit maps,
 16    each as many bits long(rounded up to nearest word) as there are vtoces on that volume.
 17    The incremental and consolidated dumpers are driven off these bit maps and dump each vtoce and
 18    associated data object whose bit is on */
 19 
 20 /* Coded by D Vinograd Feb 1976
 21    Modified by E.N. Kittlitz Nov 1980 for new dtm/dtu calculation, clock builtin
 22    Modified 03/21/81, W. Olin Sibert, for ADP SDW formats
 23    Modified 03/01/82, J. Bongiovanni, to compute proper size for dbm_seg
 24             and for new PVTE include file
 25 */
 26 
 27 
 28 /****^  HISTORY COMMENTS:
 29   1) change(88-05-27,GWMay), approve(88-05-27,MCR7883),
 30      audit(88-06-14,Beattie), install(88-07-19,MR12.2-1061):
 31      Changed to allow setting of the dumper bit maps values with set_bit.
 32                                                    END HISTORY COMMENTS */
 33 
 34 
 35           idx = divide (1, 0, 17, 0);                       /* should never be called here */
 36 
 37 update_map_from_ast: entry (a_pvtep, a_pvtx);
 38 
 39           pvtep = a_pvtep;
 40           pvtx = a_pvtx;
 41           call lock$lock_ast;
 42           call lock_dbm;
 43           call get_mapp (incr, "1"b);
 44 
 45           do i = 0 to hbound (sst$level, 1);
 46                first = "1"b;
 47                first_fp = sst$level (i).ausedp;
 48                if first_fp ^= "0"b then
 49                     do fp = first_fp repeat (aste.fp)while (fp ^= first_fp | first);
 50                     first = "0"b;
 51                     astep = ptr (addr (sst_seg$), fp);
 52                     if aste.pvtx = pvtx & ^aste.gtus & ^aste.nid & ^aste.per_process & ^aste.hc_sdw then do;
 53                          if ((aste.np ^= "0"b) | (aste.infp ^= "0"b)) then      /* implies 'in use' */
 54                               aste.dtu = substr (bit (fixed (clock (), 52), 36), 1, 36);
 55                          if aste.fms then do;
 56                               aste.fms = "0"b;
 57 again1:                       dump_it (aste.vtocx) = "1"b;
 58                               if dump_it (aste.vtocx) ^= "1"b then do;
 59                                    call syserr (LOG, "dbm_man: csl failure");
 60                                    goto again1;
 61                               end;
 62                          end;
 63                     end;
 64                end;
 65           end;
 66 
 67           call unlock_dbm;
 68           call lock$unlock_ast;
 69           return;
 70 
 71 set_incr: entry (a_pvtx, a_vtocx, a_code);
 72 
 73           type = incr;
 74           switch = "1"b;
 75           a_code = 0;
 76           goto set_common;
 77 
 78 set:      entry (a_pvtx, a_vtocx, a_type, a_switch);
 79 
 80           type = a_type;
 81           switch = a_switch;
 82 
 83 set_common:
 84           call lock_dbm;
 85 
 86           call get_pvte;
 87 
 88           call set_bit (a_vtocx, type, switch);
 89 
 90           call unlock_dbm;
 91 
 92           return;
 93 
 94 get_next_vtocx: entry (a_pvtx, a_vtocx, a_type, a_reset, a_code);
 95 
 96           a_code = 0;
 97           reset = a_reset;
 98           call lock_dbm;
 99 
100           call get_pvte;
101 
102           call get_mapp (a_type, "1"b);
103           do idx = a_vtocx + 1 to pvte.n_vtoce - 1 while (dump_it (idx) = "0"b); end;
104 
105           if idx > pvte.n_vtoce - 1 then do;
106                a_code = error_table_$end_of_info;
107                call unlock_dbm;
108                return;
109           end;
110 
111           pvte.curn_dmpr_vtocx (a_type) = idx;
112 
113           if reset then;
114           else call set_bit (idx, a_type, "0"b);
115           if a_type = incr then                             /* set consolidated bit */
116                call set_bit (idx, cons, "1"b);
117 
118           call unlock_dbm;
119 
120           return;
121 
122 init_map: entry (a_pvtx, a_bmp, a_code);
123 
124           a_code = 0;
125           call lock_dbm;
126 
127           call get_pvte;
128 
129           if pvte.dbmrp (incr) ^= "0"b then
130                call syserr (CRASH, "dbm_man: attempt to initialize already initialized map for PV on ^a_^a^[^a^;^1s^]",
131                     pvte.devname, convert (p99, pvte.logical_area_number), pvte.is_sv, pvte.sv_name);
132 
133           bit_map_len = divide (pvte.n_vtoce + 35, 36, 17, 0) * num_of_maps;
134 
135           on area call syserr (CRASH, "dbm_man: unable to allocate dumper bit map for PV on ^a_^a^[^a^;^1s^]",
136                pvte.devname, convert (p99, pvte.logical_area_number), pvte.is_sv, pvte.sv_name);
137           allocate bit_map in (dbm.area) set (mapp);
138 
139           pvte.dbmrp (incr) = rel (mapp);
140           pvte.dbmrp (cons) = bit (fixed (fixed (rel (mapp), 18) + divide (bit_map_len, 2, 18, 0), 18), 18);
141           mapp -> bit_map = a_bmp -> bit_map;
142 
143           call unlock_dbm;
144           return;
145 
146 update_map: entry (a_pvtx, a_bmp, a_pageno, a_code);
147 
148           free = "0"b;
149           goto free_common;
150 
151 free_map: entry (a_pvtx, a_bmp, a_pageno, a_code);
152 
153           free = "1"b;
154 
155 free_common:
156           a_code = 0;
157           call lock_dbm;
158 
159           call get_pvte;
160 
161           call get_mapp (incr, (^free));
162           if mapp = null () then goto UNLOCK_RETURN;
163 
164           bit_map_len = divide (pvte.n_vtoce + 35, 36, 17, 0) * num_of_maps;
165           if (free & a_pageno = 0) then do;
166                call reset_curn_vtocx (incr);
167                call reset_curn_vtocx (cons);
168           end;
169           cnt1 = min (1024 - bit_map_offset, bit_map_len);
170           if a_pageno = 0 then do;
171                cnt = cnt1;
172                from_ptr = mapp;
173                to_ptr = addrel (a_bmp, bit_map_offset);
174           end;
175           else do;
176                cnt = max (bit_map_len - cnt1, 0);
177                from_ptr = addrel (mapp, cnt1);
178                to_ptr = a_bmp;
179           end;
180           to_ptr -> copy = from_ptr -> copy;
181 
182           if (free & a_pageno = 1) then do;
183                free mapp -> bit_map in (dbm.area);
184                pvte.dbmrp (*) = "0"b;
185           end;
186 
187 UNLOCK_RETURN:
188           call unlock_dbm;
189           return;
190 
191 init:     entry;                                            /* Set up the dbm seg */
192 
193 /* Compute the size of dbm_seg from the number of disk devices configured */
194 
195           dbmp = addr (dbm_seg$);
196           dbm_segno = binary (baseno (addr (dbm_seg$)));
197           sltp = addr (slt$);
198           sltep = addr (slt.seg (dbm_segno));
199 
200           dbm_seg_size = size (area_header) + binary (rel (addr (dbm.area)))
201                + pvt$n_entries * (alloc_blkhdrsz + divide (MAX_VTOCE_PER_PACK + 35, 36, 17) * num_of_maps);
202 
203 /* Set up SLTE for dbm_seg so that we get an ASTE and address withdrawal when
204    we call make_sdw. make_sdw was already called for dbm_seg. It did neither,
205    since dbm_seg has the abs_seg attribute in the SLTE */
206 
207           slte.abs_seg = "0"b;
208           slte.cur_length, slte.max_length = bit (divide (dbm_seg_size +1023, 1024, 9, 0), 9);
209 
210           call make_sdw$unthreaded (dbm_segno, tsdw, astep, ptp);
211           if astep = null ()
212                then call syserr (CRASH, "dbm_man: Cannot get ASTE for dbm_seg");
213           call pmut$swap_sdw (addr (dbm_seg$), addr (tsdw));
214 
215           unspec (local_area_info) = "0"b;
216           area_infop = addr (local_area_info);
217           area_info.version = area_info_version_1;
218           area_info.zero_on_free = "1"b;
219           area_info.size = dbm_seg_size - binary (rel (addr (dbm.area)), 18);
220           area_info.areap = addr (dbm.area);
221           call define_area_ (area_infop, code);
222           if code ^= 0 then
223                call syserr$error_code (CRASH, code, "dbm_man: unable to initialize area");
224           dbm.lock_data.event = unspec (DBM_LOCK_EVENT);
225           dbm.init = "1"b;
226           return;
227 %page;
228 
229 lock_dbm: proc;
230                dbmp = addr (dbm_seg$);
231                call lock$lock_fast (addr (dbm.lock));
232                return;
233           end lock_dbm;
234 
235 unlock_dbm: proc;
236                call lock$unlock_fast (addr (dbm.lock));
237                return;
238           end unlock_dbm;
239 
240 get_pvte: proc;
241                code = 0;
242                pvtx = a_pvtx;
243                pvt_arrayp = addr (pvt$array);
244                pvtep = addr (pvt_array (pvtx));
245                return;
246           end get_pvte;
247 
248 set_bit:  proc (idx, type, value);
249 dcl  value bit (1) aligned;
250 dcl  type fixed bin;
251 dcl  idx fixed bin;
252 
253                call get_mapp (type, "1"b);
254 again2:        dump_it (idx) = value;
255                if dump_it (idx) ^= value then do;
256                     call syserr (LOG, "dbm_man: csl failure");
257                     goto again2;
258                end;
259                return;
260           end set_bit;
261 
262 reset_curn_vtocx: proc (type);
263 dcl  type fixed bin;
264                if pvte.curn_dmpr_vtocx (type) ^= -1 then do;
265                     call set_bit (fixed (pvte.curn_dmpr_vtocx (type)), type, "1"b);
266                     pvte.curn_dmpr_vtocx = -1;
267                end;
268                return;
269           end reset_curn_vtocx;
270 
271 get_mapp: proc (type, crash_on_error);
272 dcl  type fixed bin;
273 dcl  crash_on_error bit (1) aligned;
274 
275                mapp = ptr (dbmp, pvte.dbmrp (type));
276                if mapp = dbmp then
277                     if crash_on_error then
278                          call syserr (CRASH, "dbm_man: bit map relp not set in pvte for PV on ^a_^a^[^a^;^1s^]",
279                               pvte.devname, convert (p99, pvte.logical_area_number), pvte.is_sv, pvte.sv_name);
280                     else mapp = null ();
281           end get_mapp;
282 %page;
283 dcl  a_pvtx fixed bin;
284 dcl  a_pvtep ptr;
285 dcl  a_vtocx fixed bin;
286 dcl  a_pageno fixed bin;
287 dcl  a_reset bit (1) aligned;
288 dcl  a_switch bit (1) aligned;
289 dcl  a_type fixed bin;
290 dcl  a_bmp ptr;
291 dcl  a_code fixed bin (35);
292 
293 dcl  code fixed bin (35);
294 dcl  reset bit (1) aligned;
295 dcl  first bit (1) aligned;
296 dcl  fp bit (18);
297 dcl  first_fp bit (18);
298 dcl  pvtx fixed bin;
299 dcl  type fixed bin;
300 dcl  i fixed bin;
301 dcl  idx fixed bin;
302 dcl  free bit (1) aligned;
303 dcl  switch bit (1) aligned;
304 dcl  bit_map_len fixed bin;
305 dcl  cnt1 fixed bin;
306 dcl  cnt fixed bin;
307 dcl  from_ptr ptr;
308 dcl  to_ptr ptr;
309 dcl  dbm_seg_size fixed bin (19);
310 dcl  dbm_segno fixed bin (18);
311 dcl  tsdw fixed bin (71);
312 dcl  ptp ptr;
313 dcl  p99 picture "99";
314 
315 dcl 1 local_area_info like area_info aligned;
316 
317 dcl  copy (cnt) bit (36) based;
318 dcl  bit_map (bit_map_len) bit (36) aligned based;
319 dcl  mapp ptr init (null ());
320 dcl  dump_it (0:1) bit (1) unaligned based (mapp);
321 
322 dcl  area condition;
323 
324 dcl  bit_map_offset fixed bin static init (8) options (constant);
325 dcl  num_of_maps fixed bin static init (2) options (constant);
326 dcl  DBM_LOCK_EVENT char (4) static options (constant) aligned init ("dbm_");
327 
328 dcl  sst_seg$ fixed bin external static;
329 dcl  pvt$n_entries fixed bin external static;
330 dcl  slt$ external static;
331 
332 dcl 1 sst$level (0 : 3) aligned external static,
333     2 ausedp bit (18) unaligned,
334     2 no_aste bit (18) unaligned;
335 
336 dcl  error_table_$end_of_info ext fixed bin (35);
337 
338 dcl  define_area_ entry (ptr, fixed bin (35));
339 dcl  lock$lock_ast entry;
340 dcl  lock$unlock_ast entry;
341 dcl  lock$lock_fast entry (ptr);
342 dcl  lock$unlock_fast entry (ptr);
343 dcl  make_sdw$unthreaded entry (fixed bin (18), fixed bin (71), ptr, ptr);
344 dcl  pmut$swap_sdw entry (ptr, ptr);
345 dcl  syserr entry options (variable);
346 dcl  syserr$error_code entry options (variable);
347 
348 dcl (addrel, addr, baseno, binary, bit, clock, convert, divide, fixed, hbound, min, max, null, ptr, rel, substr, size, unspec) builtin;
349 %page; %include area_info;
350 %page; %include area_structures;
351 %page; %include aste;
352 %page; %include backup_static_variables;
353 %page; %include dbm;
354 %page; %include disk_pack;
355 %page; %include pvte;
356 %page; %include slt;
357 %page; %include slte;
358 %page; %include syserr_constants;
359 %page; %include vtoce;
360 %page;
361 /* BEGIN MESSAGE DOCUMENTATION
362 
363    Message:
364    dbm_man: csl failure
365 
366    S:     $log
367 
368    T:     $run
369 
370    M:     The CSL instruction appears to have failed on one of the processors.
371 
372    A:     $ignore
373 
374    Message:
375    dbm_man: attempt to initialize already initialized map for PV on dskX_NNS
376 
377    S:     $crash
378 
379    T:     $run
380 
381    M:     $err
382 
383    A:     $recover
384 
385    Message:
386    dbm_man: unable to allocate dumper bit map for PV on dskX_NNS
387 
388    S:     $crash
389 
390    T:     $run
391 
392    M:     The system was unable to allocate a dumper bit map in dbm_seg for
393    the volume on dskX_NNS.  Too many volumes are online, or there is something
394    wrong with the volume header.
395 
396    A:     $recover
397 
398    Message:
399    dbm_man: Cannot get ASTE for dbm_seg
400 
401    S:     $crash
402 
403    T:     $init
404 
405    M:     The system was unable to create the dbm_seg and obtain an ASTE
406    for this segment.
407 
408    A:     $contact_sa
409 
410    Message:
411    dbm_man: unable to initialize area: ERROR_MESS
412 
413    S:     $crash
414 
415    T:     $run
416 
417    M:     $err
418 
419    A:     $recover
420 
421    Message:
422    dbm_man: bit map relp not set in pvte for PV on dskX_NNS
423 
424    S:     $crash
425 
426    T:     $run
427 
428    M:     $err
429 
430    A:     $recover
431 
432    END MESSAGE DOCUMENTATION */
433 
434      end dbm_man;