1
2
3
4
5
6
7
8
9
10 scavenge_volume:
11 proc (Pvtep, Scavenger_blockp, Scavenger_Optionsp, Sc_metersp, Code);
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 dcl Pvtep ptr;
33 dcl Scavenger_blockp ptr;
34 dcl Scavenger_Optionsp ptr;
35 dcl Sc_metersp ptr;
36 dcl Code fixed bin (35);
37
38
39
40 dcl base_vtocx fixed bin;
41 dcl conflicts_unclaimed fixed bin;
42 dcl 1 copy_options aligned like scavenger_options;
43 dcl damaged_vtoces bit (MAX_VTOCE_PER_PACK) aligned;
44 dcl device_name char (8);
45 dcl freed_vtoces bit (MAX_VTOCE_PER_PACK) aligned;
46 dcl get_vtoce_errors fixed bin;
47 dcl old_mask fixed bin (71);
48 dcl p99 pic "99";
49 dcl ptp ptr;
50 dcl ptwp ptr;
51 dcl pvtx fixed bin;
52 dcl restart_sw bit (1) aligned;
53 dcl tsdw fixed bin (71);
54 dcl vastep ptr;
55 dcl vtoce_bitsp ptr;
56 dcl vtoces_damaged fixed bin;
57 dcl vtoces_damaged_by_me fixed bin;
58
59
60
61 dcl ALL_PARTS bit (3) int static options (constant) init ("111"b);
62 dcl GET_VTOCE_ERROR_THRESHOLD fixed bin int static options (constant) init (30);
63 dcl RLV_INITIALIZED fixed bin int static options (constant) init (2);
64
65
66
67 dcl 1 file_map aligned based,
68 2 fm (0:255) fixed bin (18) uns unal;
69 dcl 1 Scavenger_Options aligned like scavenger_options based (Scavenger_Optionsp);
70 dcl 1 vtoce_bits aligned based (vtoce_bitsp),
71 2 pad bit (base_vtocx) unaligned,
72 2 remaining bit (MAX_VTOCE_PER_PACK - base_vtocx) unaligned;
73
74
75
76 dcl active_hardcore_data$pdd_uid bit (36) aligned external;
77 dcl active_hardcore_data$sl1_uid bit (36) aligned external;
78 dcl error_table_$scavenge_aborted fixed bin (35) external;
79 dcl error_table_$vtoce_free fixed bin (35) external;
80 dcl pds$process_group_id char (32) ext static;
81 dcl pvt$root_lvid bit (36) aligned external;
82 dcl sst$astap ptr external;
83 dcl sst$checksum_filemap fixed bin (35) external;
84 dcl sst$cmp ptr external;
85 dcl sst$damaged_ct fixed bin (35) external;
86 dcl 1 sst$level (0:3) aligned external,
87 2 ausedp bit (18) unaligned,
88 2 no_aste bit (18) unaligned;
89 dcl sst$pts (0:3) fixed bin external;
90 dcl sys_info$initialization_state fixed bin external;
91 dcl volmap_abs_seg$ external;
92
93
94
95 dcl filemap_checksum_ entry (ptr, fixed bin, bit (36) aligned);
96 dcl fsout_vol entry (fixed bin, fixed bin);
97 dcl lock$lock_ast entry;
98 dcl lock$unlock_ast entry;
99 dcl page$free_address_for_scavenge
100 entry (fixed bin, fixed bin (18));
101 dcl page$lock_volmap entry (ptr);
102 dcl page$unlock_volmap entry (ptr);
103 dcl pc$deposit_list entry (fixed bin, fixed bin, ptr, fixed bin, ptr);
104 dcl pc$cleanup entry (ptr);
105 dcl pmut$lock_ptl entry (fixed bin (71), ptr);
106 dcl pmut$swap_sdw entry (ptr, ptr);
107 dcl pmut$unlock_ptl entry (fixed bin (71), ptr);
108 dcl priv_delete_vtoce entry (bit (36) aligned, bit (36) aligned, fixed bin, fixed bin (35));
109 dcl pxss$relinquish_priority entry;
110 dcl search_ast$check entry (bit (36) aligned, bit (36) aligned, fixed bin, fixed bin (35))
111 returns (ptr);
112 dcl setfaults entry (ptr, bit (1) aligned);
113 dcl syserr entry options (variable);
114 dcl syserr$binary entry options (variable);
115 dcl syserr$error_code entry options (variable);
116 dcl tc_util$check_abort entry (fixed bin (35));
117 dcl update_vtoce entry (ptr);
118 dcl vtoc_man$free_vtoce_for_scavenge
119 entry (bit (36) aligned, fixed bin, fixed bin, fixed bin (35));
120 dcl vtoc_man$get_vtoce entry (bit (36) aligned, fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
121 dcl vtoc_man$put_vtoce entry (bit (36) aligned, fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
122 dcl vtoc_man$read_ahead_vtoce entry (bit (36) aligned, fixed bin, fixed bin, bit (3), fixed bin (35));
123
124 declare (addr, addrel, bin, bit, clock, convert, divide, fixed, hbound, index, null, ptr, rel, rtrim, size, stacq, substr,
125 unspec, mod) builtin;
126 ^L
127
128
129 pvtep = Pvtep;
130 scavenger_blockp = Scavenger_blockp;
131 sc_metersp = Sc_metersp;
132 copy_options = Scavenger_Options;
133 Code = 0;
134
135
136 scavenger_datap = addr (scavenger_data$);
137 pvt_arrayp = addr (pvt$array);
138 pvtx = divide (bin (rel (pvtep)) - bin (rel (pvt_arrayp)), size (pvte), 17) + 1;
139 device_name = pvte.devname || "_" || convert (p99, pvte.logical_area_number) || rtrim (pvte.sv_name);
140
141
142 call pmut$swap_sdw (addr (volmap_abs_seg$), addr (pvte.volmap_seg_sdw));
143 vol_mapp = ptr (addr (volmap_abs_seg$), pvte.volmap_offset);
144 vtoc_mapp = ptr (vol_mapp, pvte.vtoc_map_offset);
145
146 RESTART:
147 restart_sw = "0"b;
148
149 vtoces_damaged, vtoces_damaged_by_me = 0;
150 get_vtoce_errors = 0;
151 conflicts_unclaimed = 0;
152
153 unspec (freed_vtoces) = ""b;
154 unspec (damaged_vtoces) = ""b;
155
156 call lock$lock_ast;
157
158 if copy_options.fault_under_ast
159 then call FAULT ("AST Lock");
160
161 call page$lock_volmap (pvtep);
162 if copy_options.fault_under_volmap
163 then call FAULT ("VOLMAP Lock");
164
165 call COPY_VOLMAP;
166
167 pvte.deposit_to_volmap = "1"b;
168 call pmut$lock_ptl (old_mask, ptwp);
169 if copy_options.fault_under_pt
170 then call FAULT ("Global PTL");
171
172 pvte.scav_check_address = "1"b;
173 call COPY_STOCK;
174 call WALK_SST;
175 call pmut$unlock_ptl (old_mask, ptwp);
176 pvte.deposit_to_volmap = "0"b;
177
178 call page$unlock_volmap (pvtep);
179 call lock$unlock_ast;
180
181 call WALK_VOLUME;
182
183 RECOVER_OVERFLOW:
184 call RESOLVE_CONFLICTS;
185
186 if get_vtoce_errors = 0
187 then call FREE_RECORDS;
188 pvte.scav_check_address = "0"b;
189
190 if restart_sw
191 then do;
192 unspec (scavenger_block.records) = ""b;
193 unspec (scavenger_block.overflow) = ""b;
194 scavenger_block.ovfl_free_ix = 1;
195 goto RESTART;
196 end;
197
198 call CHECK_VTOCE_DAMAGE;
199 call FREE_VTOCES;
200
201 if get_vtoce_errors = 0
202 then do;
203 pvte.vol_trouble_count = 0;
204 call fsout_vol (pvtx, 0);
205 end;
206
207
208 if get_vtoce_errors > 0
209 then call syserr (ANNOUNCE, "scavenge_volume: ^d errors reading VTOCEs on ^a", get_vtoce_errors, device_name);
210
211 if vtoces_damaged > 0
212 then call syserr (ANNOUNCE,
213 "scavenge_volume: ^d VTOCEs on ^a damaged.^[ ^d damaged during this scavenge.^;^1s^]", vtoces_damaged,
214 device_name, (vtoces_damaged_by_me > 0), vtoces_damaged_by_me);
215
216 ABORT_JOIN:
217 pvte.scav_check_address = "0"b;
218
219 tsdw = 0;
220 call pmut$swap_sdw (addr (volmap_abs_seg$), addr (tsdw));
221
222 if copy_options.trap
223 then call syserr (CRASH, "scavenge_volume: Debug Trap on scavenge of ^a", device_name);
224
225
226 return;
227 %page;
228
229
230
231
232
233
234
235 COPY_VOLMAP:
236 proc;
237
238 dcl bit_mapx fixed bin;
239 dcl bx fixed bin;
240 dcl rec_add fixed bin (18);
241 dcl word_baseadd fixed bin (18);
242
243
244 do bit_mapx = 1 to vol_map.bit_map_n_words;
245 bit_map_wordp = addr (vol_map.bit_map (bit_mapx));
246 if bit_map_word.bits ^= ""b
247 then do;
248 word_baseadd = (bit_mapx - 1) * 32;
249 do bx = 1 to 32;
250 if substr (bit_map_word.bits, bx, 1) = "1"b
251 then do;
252 rec_add = word_baseadd + bx;
253 scavenger_block.records (rec_add).state = STATE_FREE;
254 end;
255 end;
256 end;
257 end;
258
259 end COPY_VOLMAP;
260 %page;
261
262
263
264
265
266
267
268
269
270
271
272 COPY_STOCK:
273 proc;
274
275 dcl rec_add fixed bin (18);
276 dcl sx fixed bin;
277
278
279 record_stockp = pvte.volmap_stock_ptr;
280 do sx = 1 to record_stock.n_in_stock;
281 if record_stock.stock (sx) ^= ""b
282 then if substr (record_stock.stock (sx), 1, 1) = "1"b
283
284 then call syserr (CRASH, "scavenge_volume: Out-of-service address in stock for ^a", device_name);
285 else do;
286 rec_add = bin (record_stock.stock (sx), 18) - pvte.baseadd + 1;
287 if scavenger_block.records (rec_add).state ^= STATE_UNSEEN
288 then scavenger_block.records (rec_add).state = STATE_CONFLICT;
289
290 else scavenger_block.records (rec_add).state = STATE_FREE;
291 end;
292 end;
293
294 end COPY_STOCK;
295 %page;
296
297
298
299
300
301 WALK_SST:
302 proc;
303
304
305 dcl astx fixed bin;
306 dcl 1 aste_file_map aligned like file_map;
307 dcl n_pages fixed bin;
308 dcl px fixed bin;
309
310
311 astep = sst$astap;
312
313 do px = 0 to hbound (sst$level, 1);
314 n_pages = sst$pts (px);
315 do astx = 1 to bin (sst$level.no_aste (px));
316 if aste.usedf & (aste.pvtx = pvtx)
317 then if (aste.vtocx ^= -1) & ^aste.hc_part & ^aste.volmap_seg
318 then do;
319 call BUILD_FILEMAP_FROM_ASTE (astep, addr (aste_file_map), n_pages);
320 call CHECK_FILE_MAP ((aste.vtocx), addr (aste_file_map), n_pages, (aste.fm_damaged));
321 if aste.fm_damaged
322 then substr (damaged_vtoces, aste.vtocx + 1, 1) = "1"b;
323 end;
324 astep = addrel (astep, size (aste) + n_pages);
325 end;
326 end;
327
328 end WALK_SST;
329 %page;
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344 WALK_VOLUME:
345 proc;
346
347 dcl bitx fixed bin;
348 dcl code fixed bin (35);
349 dcl free_it bit (1) aligned;
350 dcl 1 local_vtoce aligned like vtoce;
351 dcl 1 vtoce_file_map aligned like file_map;
352 dcl vtocx fixed bin;
353 dcl wordx fixed bin;
354
355
356 do vtocx = 0 to pvte.n_vtoce - 1;
357
358 if copy_options.debug
359 then if mod (vtocx, 1024) = 0
360 then call syserr (ANNOUNCE, "scavenge_volume: Processing vtocx ^o on ^a.", vtocx, device_name);
361
362 sc_meters.n_vtoces = sc_meters.n_vtoces + 1;
363 call vtoc_man$get_vtoce (""b, pvtx, vtocx, ALL_PARTS, addr (local_vtoce), code);
364 if code ^= 0
365 then do;
366 call syserr$error_code (SEVERITY (LOG), code, "scavenge_volume: Error reading vtocx ^o on ^a",
367 vtocx, device_name);
368 get_vtoce_errors = get_vtoce_errors + 1;
369 goto NEXT_VTOCE;
370 end;
371
372 if copy_options.no_optimize
373 then call pxss$relinquish_priority;
374 else if vtocx < pvte.n_vtoce - 1
375 then call vtoc_man$read_ahead_vtoce (""b, pvtx, vtocx + 1, ALL_PARTS, code);
376
377 if local_vtoce.uid = ""b
378 then do;
379 wordx = divide (vtocx, 32, 17);
380 bit_map_wordp = addr (vtoc_map.bit_map (wordx));
381 bitx = mod (vtocx, 32);
382 if substr (bit_map_word.bits, bitx + 1, 1) ^= "1"b
383 then substr (freed_vtoces, vtocx + 1, 1) = "1"b;
384 goto NEXT_VTOCE;
385 end;
386
387 call CHECK_VTOCE_FOR_FREE (addr (local_vtoce), "0"b, (""), free_it);
388 if free_it
389 then substr (freed_vtoces, vtocx + 1, 1) = "1"b;
390
391 call CHECK_VTOCE (vtocx, addr (local_vtoce), "0"b, ("0"b));
392 if local_vtoce.damaged | local_vtoce.fm_damaged
393 then substr (damaged_vtoces, vtocx + 1, 1) = "1"b;
394
395 call BUILD_FILEMAP_FROM_VTOCE (addr (local_vtoce), addr (vtoce_file_map));
396 call CHECK_FILE_MAP (vtocx, addr (vtoce_file_map), bin (local_vtoce.csl), (local_vtoce.fm_damaged));
397
398 NEXT_VTOCE:
399 if get_vtoce_errors > GET_VTOCE_ERROR_THRESHOLD
400 then do;
401 pvte.scav_check_address = "0"b;
402 Code = error_table_$scavenge_aborted;
403 goto ABORT_JOIN;
404 end;
405 call CHECK_ABORT;
406 end;
407
408
409
410 end WALK_VOLUME;
411
412 %page;
413
414
415
416
417 BUILD_FILEMAP_FROM_ASTE:
418 proc (Astep, File_Mapp, PT_Size);
419
420 dcl Astep ptr;
421 dcl File_Mapp ptr;
422 dcl PT_Size fixed bin;
423
424 dcl page_tablep ptr;
425 dcl px fixed bin;
426
427 dcl 1 Aste aligned like aste based (Astep);
428 dcl 1 File_Map aligned like file_map based (File_Mapp);
429
430 page_tablep = addrel (Astep, size (Aste));
431 unspec (File_Map) = ""b;
432
433 do px = 0 to PT_Size - 1;
434 ptp = addrel (page_tablep, px);
435 if l68_ptw.flags.add_type = ""b
436 then File_Map.fm (px) = 0;
437 else if l68_ptw.flags.add_type = add_type.core
438 then do;
439 cmep = addr (sst$cmp -> cma (l68_core_ptw.frame));
440 if mcme.add_type = add_type.disk
441 then File_Map.fm (px) = bin (substr (mcme.record_no, 2, 17));
442 else File_Map.fm (px) = 0;
443 end;
444 else if l68_ptw.flags.add_type = add_type.disk
445 then File_Map.fm (px) = bin (substr (l68_ptw.add, 2, 17));
446 else File_Map.fm (px) = 0;
447 end;
448
449 end BUILD_FILEMAP_FROM_ASTE;
450 %page;
451
452
453 BUILD_FILEMAP_FROM_VTOCE:
454 proc (Vtocep, File_Mapp);
455
456 dcl Vtocep ptr;
457 dcl File_Mapp ptr;
458
459 dcl px fixed bin;
460
461 dcl 1 File_Map aligned like file_map based (File_Mapp);
462 dcl 1 Vtoce aligned like vtoce based (Vtocep);
463
464
465 do px = 0 to hbound (Vtoce.fm, 1);
466 if substr (Vtoce.fm (px), 1, 1) = "1"b
467 then File_Map.fm (px) = 0;
468 else File_Map.fm (px) = bin (Vtoce.fm (px), 18);
469 end;
470
471 end BUILD_FILEMAP_FROM_VTOCE;
472
473
474 %page;
475
476
477
478
479
480
481
482 CHECK_VTOCE_DAMAGE:
483 proc;
484
485 dcl code fixed bin (35);
486 dcl 1 copy_vtoce aligned like vtoce;
487 dcl damaged_sw bit (1) aligned;
488 dcl done_damage bit (1) aligned;
489 dcl 1 local_vtoce aligned like vtoce;
490 dcl prev_damaged bit (1) aligned;
491 dcl prev_fm_damaged bit (1) aligned;
492 dcl vtocx fixed bin;
493
494
495 vtoce_bitsp = addr (damaged_vtoces);
496
497 base_vtocx = 0;
498 done_damage = "0"b;
499
500 do while (^done_damage);
501
502 vtocx = index (vtoce_bits.remaining, "1"b);
503 if vtocx = 0
504 then do;
505 done_damage = "1"b;
506 goto NEXT;
507 end;
508
509 vtocx = vtocx + base_vtocx - 1;
510 base_vtocx = vtocx + 1;
511 call vtoc_man$get_vtoce (""b, pvtx, vtocx, ALL_PARTS, addr (local_vtoce), code);
512 if code ^= 0
513 then do;
514 call syserr$error_code (SEVERITY (LOG), "scavenge_volume: Error reading vtocx ^o on ^a", vtocx,
515 device_name);
516 goto NEXT;
517 end;
518
519 if copy_options.dump
520 then unspec (copy_vtoce) = unspec (local_vtoce);
521
522 call LOCK_AST_CHECK_UID ((local_vtoce.uid), vtocx, astep);
523 if astep = null ()
524 then do;
525
526 prev_damaged = local_vtoce.damaged;
527 call CHECK_VTOCE (vtocx, addr (local_vtoce), "1"b, damaged_sw);
528
529 if local_vtoce.damaged
530 then vtoces_damaged = vtoces_damaged + 1;
531 if (local_vtoce.damaged & ^prev_damaged)
532 then vtoces_damaged_by_me = vtoces_damaged_by_me + 1;
533
534 if damaged_sw | prev_damaged
535 then call SEGDAMAGE (vtocx, addr (local_vtoce), addr (copy_vtoce), prev_damaged);
536
537 if local_vtoce.fm_damaged
538 then do;
539 prev_fm_damaged = "1"b;
540 local_vtoce.fm_damaged = "0"b;
541 if sst$checksum_filemap ^= 0
542 then do;
543 call filemap_checksum_ (addr (local_vtoce.fm), fixed (local_vtoce.csl),
544 local_vtoce.fm_checksum);
545 local_vtoce.fm_checksum_valid = "1"b;
546 end;
547 else do;
548 local_vtoce.fm_checksum_valid = "0"b;
549 local_vtoce.fm_checksum = ""b;
550 end;
551 sc_meters.n_vtoces_fmd = sc_meters.n_vtoces_fmd + 1;
552 end;
553
554 if damaged_sw | prev_fm_damaged
555 then do;
556 call vtoc_man$put_vtoce (""b, pvtx, vtocx, ALL_PARTS, addr (local_vtoce), code);
557 if code ^= 0
558 then call syserr$error_code (SEVERITY (LOG), code,
559 "scavenge_volume: Error writing vtocx ^a on ^a.", vtocx, device_name);
560 end;
561
562 end;
563 else do;
564 if aste.fm_damaged
565 then do;
566 sc_meters.n_vtoces_fmd = sc_meters.n_vtoces_fmd + 1;
567 aste.fm_damaged = "0"b;
568 end;
569 end;
570
571 call lock$unlock_ast;
572
573 NEXT:
574 end;
575
576
577
578
579 end CHECK_VTOCE_DAMAGE;
580 %page;
581
582
583
584
585
586
587 FREE_RECORDS:
588 proc;
589
590 dcl 1 deposit_list (256) aligned,
591 2 record fixed bin (18) uns unal,
592 2 pad bit (18) unal;
593 dcl dx fixed bin;
594 dcl records_freed fixed bin;
595 dcl rx fixed bin;
596
597 unspec (deposit_list) = ""b;
598 records_freed = 0;
599 dx = 0;
600
601 do rx = 1 to scavenger_block.n_records;
602
603 record_blockp = addr (scavenger_block.records (rx));
604 if record_block.state = STATE_UNSEEN
605 then do;
606 dx = dx + 1;
607 records_freed = records_freed + 1;
608 deposit_list (dx).record = rx + pvte.baseadd - 1;
609 if dx >= hbound (deposit_list, 1)
610 then do;
611 call pc$deposit_list (pvtx, dx, addr (deposit_list), -1, null ());
612 dx = 0;
613 call CHECK_ABORT;
614 end;
615 end;
616
617 end;
618
619 if dx > 0
620 then call pc$deposit_list (pvtx, dx, addr (deposit_list), -1, null ());
621
622 records_freed = records_freed - conflicts_unclaimed;
623
624 sc_meters.n_lost_records = records_freed;
625 if records_freed > 0
626 then call syserr (SEVERITY (LOG), "scavenge_volume: Freed ^d records on ^a", records_freed, device_name);
627
628 end FREE_RECORDS;
629 %page;
630
631
632
633
634
635 RESOLVE_CONFLICTS:
636 proc;
637
638 dcl rx fixed bin;
639
640
641 do rx = 1 to scavenger_block.n_records;
642 record_blockp = addr (scavenger_block.records (rx));
643 if record_block.state = STATE_CONFLICT
644 then do;
645 call RESOLVE_THIS_CONFLICT ((rx - 1 + pvte.baseadd), record_blockp);
646 call CHECK_ABORT;
647 end;
648 end;
649
650 end RESOLVE_CONFLICTS;
651 %page;
652
653
654
655
656
657
658
659
660
661
662 note
663
664
665
666
667
668
669
670
671
672
673
674
675
676 Note
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695 RESOLVE_THIS_CONFLICT:
696 proc (Record_Address, Record_Blockp);
697
698 dcl Record_Address fixed bin (18);
699 dcl Record_Blockp ptr;
700
701 dcl checksum bit (36) aligned;
702 dcl claim_count fixed bin;
703 dcl claims_address bit (1) aligned;
704 dcl code fixed bin (35);
705 dcl conflict_blockp ptr;
706 dcl 1 copy_vtoce aligned like vtoce;
707 dcl csl fixed bin;
708 dcl dir_count fixed bin;
709 dcl done_thread bit (1) aligned;
710 dcl 1 local_file_map aligned like file_map;
711 dcl 1 local_vtoce aligned like vtoce;
712 dcl not_fmd_count fixed bin;
713 dcl owner_pageno fixed bin;
714 dcl owner_vtocx fixed bin;
715 dcl pageno fixed bin;
716 dcl prev_damaged bit (1) aligned;
717 dcl real_conflict bit (1) aligned;
718 dcl records fixed bin;
719 dcl vtocx fixed bin;
720
721 dcl 1 conflict_block aligned like record_block based (conflict_blockp);
722 dcl 1 Record_Block aligned like record_block based (Record_Blockp);
723
724
725
726
727
728 sc_meters.n_conflicts = sc_meters.n_conflicts + 1;
729 real_conflict = "0"b;
730
731 conflict_blockp = Record_Blockp;
732
733 call page$free_address_for_scavenge (pvtx, Record_Address);
734
735 dir_count, claim_count, not_fmd_count = 0;
736 owner_vtocx = -1;
737 done_thread = "0"b;
738 do while (^done_thread);
739
740 vtocx = conflict_block.vtocx;
741 pageno = conflict_block.pageno;
742
743 call GET_VTOCE_CHECK_ADDRESS (vtocx, addr (local_vtoce), pageno, Record_Address, astep, claims_address,
744 code);
745 if code ^= 0
746 then do;
747 ERROR_PUNT:
748 call syserr$error_code (SEVERITY (LOG), code,
749 "scavenge_volume: Unable to resolve conflict for address ^o on ^a. Error at vtocx ^o.",
750 Record_Address, device_name, vtocx);
751 get_vtoce_errors = get_vtoce_errors + 1;
752 return;
753 end;
754 if claims_address
755 then do;
756 call lock$unlock_ast;
757 claim_count = claim_count + 1;
758 if local_vtoce.dirsw
759 then dir_count = dir_count + 1;
760 if ^local_vtoce.fm_damaged & local_vtoce.fm_checksum_valid
761 then do;
762 call filemap_checksum_ (addr (local_vtoce.fm), fixed (local_vtoce.csl, 9), checksum);
763 if local_vtoce.fm_checksum ^= checksum
764 then local_vtoce.fm_damaged = "1"b;
765 end;
766 if ^local_vtoce.fm_damaged
767 then not_fmd_count = not_fmd_count + 1;
768 if (claim_count = 1) | (local_vtoce.dirsw & (dir_count = 1))
769 | (^local_vtoce.fm_damaged & (not_fmd_count = 1) & (dir_count = 0))
770 then do;
771 owner_vtocx = vtocx;
772 owner_pageno = pageno;
773 end;
774 end;
775 if conflict_block.ovflx = 0
776 then done_thread = "1"b;
777 else conflict_blockp = addr (scavenger_block.overflow (conflict_block.ovflx));
778
779 end;
780
781
782
783
784
785
786 if claim_count = 0
787 then do;
788 FREE_RETURN:
789 call LOCK_RECORD (record_blockp);
790 Record_Block.state = STATE_UNSEEN;
791 record_block.lock = "0"b;
792 conflicts_unclaimed = conflicts_unclaimed + 1;
793 return;
794 end;
795
796 %page;
797
798 Note
799
800 done_thread = "0"b;
801 conflict_blockp = Record_Blockp;
802
803 if (claim_count > 1) & (dir_count ^= 1) & (not_fmd_count ^= 1)
804 then owner_vtocx = -1;
805
806 do while (^done_thread);
807
808 vtocx = conflict_block.vtocx;
809 pageno = conflict_block.pageno;
810 if ((vtocx ^= owner_vtocx) | (pageno ^= owner_pageno))
811 then do;
812
813 call GET_VTOCE_CHECK_ADDRESS (vtocx, addr (local_vtoce), pageno, Record_Address, astep,
814 claims_address, code);
815 if code ^= 0
816 then goto ERROR_PUNT;
817 if ^claims_address
818 then goto NEXT;
819 real_conflict = "1"b;
820
821 if copy_options.dump
822 then unspec (copy_vtoce) = unspec (local_vtoce);
823
824 if astep ^= null ()
825 then do;
826 if aste.ehs | aste.hc_sdw | aste.hc | aste.hc_part
827 then do;
828 PUNT_ASTE:
829 call lock$unlock_ast;
830 call syserr (SEVERITY (LOG),
831 "scavenge_volume: Unable to resolve conflict for address ^o on ^a. astep=^p"
832 , Record_Address, device_name, astep);
833 return;
834 end;
835 call setfaults (astep, "0"b);
836 call pc$cleanup (astep);
837 ptp = addrel (astep, size (aste) + pageno);
838 if l68_ptw.add_type ^= add_type.disk
839 then goto PUNT_ASTE;
840 l68_ptw.add_type = ""b;
841 l68_ptw.add = pv_scav_null_addr;
842 prev_damaged = aste.damaged;
843 aste.damaged = "1"b;
844 aste.fmchanged = "1"b;
845
846 call BUILD_FILEMAP_FROM_ASTE (astep, addr (local_file_map), sst$pts (bin (aste.ptsi)));
847 call COMPUTE_RECORDS_CSL (addr (local_file_map), records, csl);
848 aste.records = bit (bin (records, 9), 9);
849 aste.csl = bit (bin (csl, 9), 9);
850
851 call update_vtoce (astep);
852
853
854 end;
855 else do;
856 call vtoc_man$get_vtoce (""b, pvtx, vtocx, ALL_PARTS, addr (local_vtoce), code);
857 if code ^= 0
858 then do;
859 call lock$unlock_ast;
860 goto ERROR_PUNT;
861 end;
862 prev_damaged = local_vtoce.damaged;
863 local_vtoce.fm (pageno) = pv_scav_null_addr;
864 call BUILD_FILEMAP_FROM_VTOCE (addr (local_vtoce), addr (local_file_map));
865 call COMPUTE_RECORDS_CSL (addr (local_file_map), records, csl);
866 local_vtoce.csl = bit (bin (csl, 9), 9);
867 local_vtoce.records = bit (bin (records, 9), 9);
868 if sst$checksum_filemap = 0
869 then do;
870 local_vtoce.fm_checksum_valid = "0"b;
871 local_vtoce.fm_checksum = ""b;
872 end;
873 else do;
874 local_vtoce.fm_checksum_valid = "1"b;
875 call filemap_checksum_ (addr (local_vtoce.fm), csl, local_vtoce.fm_checksum);
876 end;
877
878 local_vtoce.damaged = "1"b;
879 call vtoc_man$put_vtoce (""b, pvtx, vtocx, ALL_PARTS, addr (local_vtoce), code);
880 if code ^= 0
881 then do;
882 call lock$unlock_ast;
883 goto ERROR_PUNT;
884 end;
885 end;
886 call lock$unlock_ast;
887 call syserr (SEVERITY (LOG),
888 "scavenge_volume: vtoce ^a at ^o (^a). ref to pageno ^o at addr ^o deleted",
889 local_vtoce.primary_name, vtocx, device_name, pageno, Record_Address);
890 if ^prev_damaged
891 then do;
892 call SEGDAMAGE (vtocx, addr (local_vtoce), addr (copy_vtoce), prev_damaged);
893 vtoces_damaged = vtoces_damaged + 1;
894 vtoces_damaged_by_me = vtoces_damaged_by_me + 1;
895 end;
896 end;
897
898 NEXT:
899 if conflict_block.ovflx = 0
900 then done_thread = "1"b;
901 else conflict_blockp = addr (scavenger_block.overflow (conflict_block.ovflx));
902 end;
903
904 if real_conflict
905 then sc_meters.n_real_conflicts = sc_meters.n_real_conflicts + 1;
906 %page;
907
908
909
910 if owner_vtocx = -1
911 then do;
912 call LOCK_RECORD (record_blockp);
913 record_block.state = STATE_UNSEEN;
914 record_block.lock = "0"b;
915 return;
916 end;
917
918 call GET_VTOCE_CHECK_ADDRESS (owner_vtocx, addr (local_vtoce), owner_pageno, Record_Address, astep,
919 claims_address, code);
920 if code ^= 0
921 then return;
922
923
924 if ^claims_address
925 then goto FREE_RETURN;
926
927 call lock$unlock_ast;
928
929 end RESOLVE_THIS_CONFLICT;
930
931 %page;
932
933
934
935
936 COMPUTE_RECORDS_CSL:
937 proc (File_Mapp, Records, Csl);
938
939 dcl File_Mapp ptr;
940 dcl Records fixed bin;
941 dcl Csl fixed bin;
942
943 dcl px fixed bin;
944
945 dcl 1 File_Map aligned like file_map based (File_Mapp);
946
947 Records, Csl = 0;
948 do px = 0 to hbound (File_Map.fm, 1);
949 if File_Map.fm (px) ^= 0
950 then do;
951 Csl = px + 1;
952 Records = Records + 1;
953 end;
954 end;
955
956 end COMPUTE_RECORDS_CSL;
957 %page;
958
959
960
961
962 GET_VTOCE_CHECK_ADDRESS:
963 proc (Vtocx, Vtocep, Pageno, Record_Address, Astep, Claims, Code);
964
965 dcl Vtocx fixed bin;
966 dcl Vtocep ptr;
967 dcl Pageno fixed bin;
968 dcl Record_Address fixed bin (18);
969 dcl Astep ptr;
970 dcl Claims bit (1) aligned;
971 dcl Code fixed bin (35);
972
973 dcl old_mask fixed bin (71);
974 dcl ptwp ptr;
975
976 dcl 1 Vtoce aligned like vtoce based (Vtocep);
977
978
979 Code = 0;
980 Astep = null ();
981 Claims = "0"b;
982
983 call vtoc_man$get_vtoce (""b, pvtx, Vtocx, ALL_PARTS, Vtocep, Code);
984 if Code ^= 0
985 then return;
986
987 call LOCK_AST_CHECK_UID ((Vtoce.uid), Vtocx, Astep);
988 if Astep = null ()
989 then do;
990 if substr (Vtoce.fm (Pageno), 1, 1) = "0"b
991 then if bin (Vtoce.fm (Pageno), 18) = Record_Address
992 then Claims = "1"b;
993 end;
994 else do;
995 if Pageno < sst$pts (fixed (Astep -> aste.ptsi, 3))
996
997 then do;
998 ptp = addrel (Astep, size (aste) + Pageno);
999 call pmut$lock_ptl (old_mask, ptwp);
1000 if l68_ptw.flags.add_type = add_type.core
1001 then do;
1002 cmep = addr (sst$cmp -> cma (l68_core_ptw.frame));
1003 if mcme.add_type = add_type.disk
1004 then if bin (substr (mcme.record_no, 2, 17)) = Record_Address
1005 then Claims = "1"b;
1006 end;
1007 else if l68_ptw.flags.add_type = add_type.disk
1008 then if bin (substr (l68_ptw.add, 2, 17)) = Record_Address
1009 then Claims = "1"b;
1010 call pmut$unlock_ptl (old_mask, ptwp);
1011 end;
1012 end;
1013
1014 if ^Claims
1015 then call lock$unlock_ast;
1016
1017
1018 end GET_VTOCE_CHECK_ADDRESS;
1019
1020
1021 %page;
1022
1023
1024
1025
1026
1027
1028
1029 FREE_VTOCES:
1030 proc;
1031
1032 dcl code fixed bin (35);
1033 dcl done_free bit (1) aligned;
1034 dcl free_it bit (1) aligned;
1035 dcl 1 local_vtoce aligned like vtoce;
1036 dcl message char (32);
1037 dcl vtoces_freed fixed bin;
1038 dcl vtocx fixed bin;
1039
1040
1041 vtoces_freed = 0;
1042 vtoce_bitsp = addr (freed_vtoces);
1043
1044 base_vtocx = 0;
1045 done_free = "0"b;
1046
1047 do while (^done_free);
1048
1049 vtocx = index (vtoce_bits.remaining, "1"b);
1050 if vtocx = 0
1051 then do;
1052 done_free = "1"b;
1053 goto NEXT;
1054 end;
1055
1056 vtocx = vtocx + base_vtocx - 1;
1057 base_vtocx = vtocx + 1;
1058 call vtoc_man$get_vtoce (""b, pvtx, vtocx, ALL_PARTS, addr (local_vtoce), code);
1059 if code ^= 0
1060 then do;
1061 call syserr$error_code (SEVERITY (LOG), code, "scavenge_volume: Error reading vtocx ^a on ^a.",
1062 vtocx, device_name);
1063 get_vtoce_errors = get_vtoce_errors + 1;
1064 goto NEXT;
1065 end;
1066
1067
1068 call CHECK_VTOCE_FOR_FREE (addr (local_vtoce), "1"b, message, free_it);
1069 if free_it
1070 then do;
1071
1072 if local_vtoce.uid = ""b
1073 then call vtoc_man$free_vtoce_for_scavenge (""b, pvtx, vtocx, code);
1074
1075 else call priv_delete_vtoce ((local_vtoce.uid), pvte.pvid, vtocx, code);
1076
1077 if code = 0
1078 then do;
1079 vtoces_freed = vtoces_freed + 1;
1080 if copy_options.debug
1081 then call syserr (SEVERITY (JUST_LOG),
1082 "scavenge_volume: Freeing ^a VTOCE ^[^a ^;^1s^]at ^o (^a)", message,
1083 (local_vtoce.uid ^= ""b), local_vtoce.primary_name, vtocx, device_name);
1084 end;
1085 else if code ^= error_table_$vtoce_free
1086 then call syserr$error_code (SEVERITY (LOG), code,
1087 "scavenge_volume: Error freeing ^a vtocx ^o on ^a", message, vtocx, device_name);
1088
1089
1090 end;
1091
1092 NEXT:
1093 call CHECK_ABORT;
1094 end;
1095
1096 sc_meters.n_vtoces_freed = vtoces_freed;
1097 if vtoces_freed > 0
1098 then call syserr (SEVERITY (LOG), "scavenge_volume: Freed ^d VTOCEs on ^a", vtoces_freed, device_name);
1099
1100 end FREE_VTOCES;
1101
1102 %page;
1103
1104
1105
1106 LOCK_AST_CHECK_UID:
1107 proc (Uid, Vtocx, Astep);
1108
1109 dcl Uid bit (36) aligned;
1110 dcl Vtocx fixed bin;
1111 dcl Astep ptr;
1112
1113
1114 call lock$lock_ast;
1115 if Uid = ""b
1116 then Astep = null ();
1117 else Astep = search_ast$check (Uid, pvte.pvid, Vtocx, (0));
1118
1119
1120 end LOCK_AST_CHECK_UID;
1121
1122
1123
1124 %page;
1125
1126
1127
1128
1129
1130 CHECK_VTOCE:
1131 proc (Vtocx, Vtocep, Loud, Damaged);
1132
1133 dcl Vtocx fixed bin;
1134 dcl Vtocep ptr;
1135 dcl Loud bit (1) aligned;
1136 dcl Damaged bit (1) aligned;
1137
1138 dcl checksum bit (36) aligned;
1139 dcl csl fixed bin;
1140 dcl cur_fstime bit (36) aligned;
1141 dcl low_add fixed bin (18);
1142 dcl high_add fixed bin (18);
1143 dcl px fixed bin;
1144 dcl rec_add fixed bin (18);
1145 dcl records fixed bin;
1146 dcl trp_bad bit (1) aligned;
1147 dcl tx fixed bin;
1148
1149 dcl 1 Vtoce aligned like vtoce based (Vtocep);
1150
1151
1152 Damaged = "0"b;
1153
1154 low_add = pvte.baseadd;
1155 high_add = pvte.baseadd + pvte.totrec - 1;
1156 csl, records = 0;
1157
1158 cur_fstime = substr (bit (bin (clock (), 71), 71), 20, 36);
1159
1160 do px = 0 to hbound (Vtoce.fm, 1);
1161 if substr (Vtoce.fm (px), 1, 1) = "0"b
1162 then do;
1163 rec_add = bin (Vtoce.fm (px), 18);
1164 if rec_add < low_add | rec_add > high_add
1165 then do;
1166 Damaged = "1"b;
1167 Vtoce.damaged = "1"b;
1168 Vtoce.fm (px) = pv_scav_null_addr;
1169 if Loud & copy_options.debug
1170 then call syserr (SEVERITY (JUST_LOG),
1171 "scavenge_volume: vtoce ^a at ^o (^a) disk addr ^o bad", Vtoce.primary_name,
1172 Vtocx, pvte.devname, device_name, rec_add);
1173 end;
1174 else do;
1175 csl = px + 1;
1176 records = records + 1;
1177 end;
1178 end;
1179 end;
1180
1181 if bin (Vtoce.records) ^= records
1182 then do;
1183 if Loud
1184 then call syserr (SEVERITY (JUST_LOG),
1185 "scavnege_volume: vtoce ^a at ^o (^a). rec used changed from ^o to ^o", Vtoce.primary_name,
1186 Vtocx, device_name, bin (Vtoce.records), records);
1187 Damaged = "1"b;
1188 Vtoce.damaged = "1"b;
1189 Vtoce.records = bit (bin (records, 9), 9);
1190 end;
1191
1192 if bin (Vtoce.csl) ^= csl
1193 then do;
1194 if Loud
1195 then call syserr (SEVERITY (JUST_LOG),
1196 "scavenge_volume: vtoce ^a at ^o (^a). cur len changed from ^o to ^o", Vtoce.primary_name,
1197 Vtocx, device_name, bin (Vtoce.csl), csl);
1198 Damaged = "1"b;
1199 Vtoce.damaged = "1"b;
1200 Vtoce.csl = bit (bin (csl, 9), 9);
1201 end;
1202
1203 if (bin (Vtoce.msl) > 256) | (bin (Vtoce.msl) < 0) | (bin (Vtoce.msl) < csl)
1204 then do;
1205 if Loud
1206 then call syserr (SEVERITY (JUST_LOG),
1207 "scavenge_volume: vtoce ^a at ^o (^a). max len changed from ^o to 400", Vtoce.primary_name,
1208 Vtocx, device_name, bin (Vtoce.msl));
1209 Damaged = "1"b;
1210 Vtoce.damaged = "1"b;
1211 Vtoce.msl = bit (bin (256, 9), 9);
1212 end;
1213
1214 trp_bad = "0"b;
1215 do tx = 0 to 1;
1216 if Vtoce.trp (tx) < 0 | bin (Vtoce.trp (tx), 36) > bin (cur_fstime, 36)
1217 then trp_bad = "1"b;
1218 end;
1219 if trp_bad
1220 then do;
1221 do tx = 0 to 1;
1222 Vtoce.trp (tx) = 0;
1223 Vtoce.trp_time (tx) = cur_fstime;
1224 end;
1225 if Loud
1226 then call syserr (SEVERITY (JUST_LOG),
1227 "scavenge_volume: vtoce ^a at ^o (^a). time-record-product reset to zero",
1228 Vtoce.primary_name, Vtocx, device_name);
1229 end;
1230
1231 if Vtoce.dirsw & pvte.lvid ^= pvt$root_lvid
1232 then do;
1233 if Loud
1234 then call syserr (SEVERITY (JUST_LOG), "scavenge_volume: dirsw turned off for ^a at ^o (^a)",
1235 Vtoce.primary_name, Vtocx, device_name);
1236 Damaged = "1"b;
1237 Vtoce.damaged = "1"b;
1238 Vtoce.dirsw = "0"b;
1239 end;
1240
1241 if Vtoce.fm_checksum_valid
1242 then do;
1243 call filemap_checksum_ (addr (Vtoce.fm), fixed (Vtoce.csl, 9), checksum);
1244 if Vtoce.fm_checksum ^= checksum
1245 then do;
1246 Vtoce.fm_damaged = "1"b;
1247 if Loud & copy_options.debug
1248 then call syserr (SEVERITY (JUST_LOG),
1249 "scavenge_volume: Invalid File Map Checksum for ^a at ^o (^a)",
1250 Vtoce.primary_name, Vtocx, device_name);
1251 end;
1252 end;
1253
1254 end CHECK_VTOCE;
1255
1256
1257
1258 %page;
1259
1260
1261
1262
1263
1264
1265 CHECK_FILE_MAP:
1266 proc (Vtocx, File_Mapp, N_Pages, Fm_Damaged);
1267
1268 dcl Vtocx fixed bin;
1269 dcl File_Mapp ptr;
1270 dcl N_Pages fixed bin;
1271 dcl Fm_Damaged bit (1) aligned;
1272
1273 dcl high_add fixed bin (18);
1274 dcl low_add fixed bin (18);
1275 dcl px fixed bin;
1276 dcl rec_add fixed bin (18);
1277
1278 dcl 1 File_Map aligned like file_map based (File_Mapp);
1279
1280 low_add = pvte.baseadd;
1281 high_add = pvte.baseadd + pvte.totrec - 1;
1282 do px = 0 to N_Pages - 1;
1283 if File_Map.fm (px) ^= 0
1284 then if (File_Map.fm (px) >= low_add) & (File_Map.fm (px) <= high_add)
1285 then do;
1286 rec_add = File_Map.fm (px) - pvte.baseadd + 1;
1287 sc_meters.n_records = sc_meters.n_records + 1;
1288 record_blockp = addr (scavenger_block.records (rec_add));
1289
1290
1291
1292 call LOCK_RECORD (record_blockp);
1293
1294
1295
1296
1297
1298
1299
1300
1301 if Fm_Damaged
1302 then do;
1303 call THREAD_IN_CONFLICT (record_blockp, Vtocx, px);
1304 sc_meters.n_fmd_conflicts = sc_meters.n_fmd_conflicts + 1;
1305 end;
1306 else if record_block.state = STATE_UNSEEN
1307 then do;
1308 record_block.state = STATE_IN_USE;
1309 record_block.vtocx = Vtocx;
1310 record_block.pageno = px;
1311 end;
1312 else if record_block.state = STATE_IN_USE
1313 then do;
1314 if record_block.vtocx ^= Vtocx | record_block.pageno ^= px
1315 then call THREAD_IN_CONFLICT (record_blockp, Vtocx, px);
1316 end;
1317 else if record_block.state = STATE_FREE | record_block.state = STATE_CONFLICT
1318 then call THREAD_IN_CONFLICT (record_blockp, Vtocx, px);
1319
1320
1321 record_block.lock = "0"b;
1322 end;
1323 end;
1324 end CHECK_FILE_MAP;
1325 %page;
1326
1327
1328
1329
1330 CHECK_VTOCE_FOR_FREE:
1331 proc (Vtocep, Meter_It, Reason, Free_It);
1332
1333 dcl Vtocep ptr;
1334 dcl Reason char (*);
1335 dcl Meter_It bit (1) aligned;
1336 dcl Free_It bit (1) aligned;
1337
1338 dcl 1 Vtoce aligned like vtoce based (Vtocep);
1339
1340
1341 Free_It = "0"b;
1342
1343 if Vtoce.uid = ""b
1344 then do;
1345 Free_It = "1"b;
1346 Reason = "lost";
1347 end;
1348 else if ^Vtoce.dirsw
1349 then do;
1350 if Vtoce.per_process & (Vtoce.uid_path (1) ^= active_hardcore_data$pdd_uid)
1351 then do;
1352 Free_It = "1"b;
1353 Reason = "per-process";
1354 if Meter_It
1355 then sc_meters.n_vtoces_per_proc = sc_meters.n_vtoces_per_proc + 1;
1356 end;
1357 else if Vtoce.deciduous & (Vtoce.uid_path (1) ^= active_hardcore_data$sl1_uid)
1358 then do;
1359 Free_It = "1"b;
1360 Reason = "deciduous";
1361 if Meter_It
1362 then sc_meters.n_vtoces_per_boot = sc_meters.n_vtoces_per_boot + 1;
1363 end;
1364 else if Vtoce.perm_flags.per_bootload & (Vtoce.uid_path (1) ^= active_hardcore_data$sl1_uid)
1365 then do;
1366 Free_It = "1"b;
1367 Reason = "per-bootload";
1368 if Meter_It
1369 then sc_meters.n_vtoces_per_boot = sc_meters.n_vtoces_per_boot + 1;
1370 end;
1371 end;
1372
1373 end CHECK_VTOCE_FOR_FREE;
1374 %page;
1375
1376
1377 SEGDAMAGE:
1378 proc (Vtocx, Vtocep, Dump_Vtocep, Prev_Damaged);
1379
1380 dcl Vtocx fixed bin;
1381 dcl Vtocep ptr;
1382 dcl Dump_Vtocep ptr;
1383 dcl Prev_Damaged bit (1) aligned;
1384
1385 dcl 1 Vtoce aligned like vtoce based (Vtocep);
1386
1387
1388 segdamage.pvid = pvte.pvid;
1389 segdamage.lvid = pvte.lvid;
1390 segdamage.uid = Vtoce.uid;
1391 segdamage.vtocx = Vtocx;
1392 segdamage.pno = -1;
1393 segdamage.uid_path = Vtoce.uid_path;
1394 call syserr$binary (SEVERITY (LOG), addr (segdamage), SB_vtoc_salv_dam, SBL_vtoc_salv_dam,
1395 "scavenge_volume: ^[damaged switch found on for^;setting damaged switch on^] ^a at ^o (^a).", Prev_Damaged,
1396 Vtoce.primary_name, Vtocx, device_name);
1397
1398 if ^Prev_Damaged
1399 then do;
1400 sst$damaged_ct = sst$damaged_ct + 1;
1401 sc_meters.n_vtoces_damaged = sc_meters.n_vtoces_damaged + 1;
1402 if copy_options.dump
1403 then call syserr$binary (SEVERITY (JUST_LOG), Dump_Vtocep, SB_vtoce, SBL_vtoce,
1404 "scavenge_volume: Damaged vtoce ^o (^a).", Vtocx, device_name);
1405 end;
1406
1407
1408 %include segdamage_msg;
1409
1410 end SEGDAMAGE;
1411 %page;
1412
1413
1414 LOCK_RECORD:
1415 proc (Record_Blockp);
1416
1417 dcl Record_Blockp ptr;
1418
1419 dcl 1 A_record_block aligned like record_block;
1420 dcl Ap ptr;
1421 dcl locked bit (1) aligned;
1422 dcl 1 Q_record_block aligned like record_block;
1423 dcl Qp ptr;
1424 dcl Wp ptr;
1425
1426 dcl A bit (36) aligned based (Ap);
1427 dcl Q bit (36) aligned based (Qp);
1428 dcl 1 Record_Block aligned like record_block based (Record_Blockp);
1429 dcl W bit (36) aligned based (Wp);
1430
1431
1432 locked = "0"b;
1433 Ap = addr (A_record_block);
1434 Qp = addr (Q_record_block);
1435 Wp = Record_Blockp;
1436 do while (^locked);
1437 unspec (Q_record_block) = unspec (Record_Block);
1438 unspec (A_record_block) = unspec (Q_record_block);
1439 if ^A_record_block.lock
1440 then do;
1441 A_record_block.lock = "1"b;
1442 locked = stacq (W, A, Q);
1443 end;
1444 end;
1445
1446 end LOCK_RECORD;
1447 %page;
1448
1449
1450 CHECK_ABORT:
1451 proc;
1452
1453 call tc_util$check_abort (Code);
1454 if Code ^= 0
1455 then goto ABORT_JOIN;
1456
1457 end CHECK_ABORT;
1458 %page;
1459
1460
1461
1462
1463 debug
1464
1465
1466
1467
1468
1469
1470 SEVERITY:
1471 proc (Severity) returns (fixed bin);
1472
1473 dcl Severity fixed bin;
1474
1475 if Severity <= BEEP
1476 then return (Severity);
1477
1478 if copy_options.debug
1479 then return (ANNOUNCE);
1480
1481 if sys_info$initialization_state < RLV_INITIALIZED
1482 then do;
1483 if Severity = LOG
1484 then return (ANNOUNCE);
1485 else return (LOG);
1486 end;
1487
1488 return (LOG);
1489
1490
1491 end SEVERITY;
1492
1493
1494 %page;
1495
1496
1497
1498
1499 THREAD_IN_CONFLICT:
1500 proc (Record_Blockp, Vtocx, Page_No);
1501
1502 dcl Record_Blockp ptr;
1503 dcl Vtocx fixed bin;
1504 dcl Page_No fixed bin;
1505
1506 dcl A bit (36) aligned;
1507 dcl free_ix fixed bin;
1508 dcl got_free bit (1) aligned;
1509 dcl next_free fixed bin;
1510 dcl ovfl_blockp ptr;
1511 dcl Q bit (36) aligned;
1512 dcl Wp ptr;
1513
1514 dcl 1 ovfl_block aligned like record_block based (ovfl_blockp);
1515 dcl 1 Record_Block aligned like record_block based (Record_Blockp);
1516 dcl W bit (36) aligned based (Wp);
1517
1518 if (Record_Block.state = STATE_UNSEEN) | (Record_Block.state = STATE_FREE)
1519 then do;
1520 Record_Block.vtocx = Vtocx;
1521 Record_Block.pageno = Page_No;
1522 end;
1523 else if (Record_Block.vtocx ^= Vtocx) | (Record_Block.pageno ^= Page_No)
1524 then do;
1525
1526 got_free = "0"b;
1527 do while (^got_free);
1528 free_ix = scavenger_block.ovfl_free_ix;
1529 if free_ix <= 0 | free_ix > scavenger_block.n_ovfl
1530 then do;
1531 call syserr (ANNOUNCE, "scavenge_volume: Overflow on scavenge of ^a. Restarting.",
1532 device_name);
1533 restart_sw = "1"b;
1534 Record_Block.lock = "0"b;
1535 goto RECOVER_OVERFLOW;
1536 end;
1537 next_free = free_ix + 1;
1538 Q = bit (bin (free_ix, 36), 36);
1539 A = bit (bin (next_free, 36), 36);
1540 Wp = addr (scavenger_block.ovfl_free_ix);
1541 got_free = stacq (W, A, Q);
1542 end;
1543
1544 ovfl_blockp = addr (scavenger_block.overflow (free_ix));
1545
1546 ovfl_block.vtocx = Vtocx;
1547 ovfl_block.pageno = Page_No;
1548 ovfl_block.state = STATE_CONFLICT;
1549 ovfl_block.ovflx = Record_Block.ovflx;
1550 Record_Block.ovflx = free_ix;
1551 end;
1552
1553 Record_Block.state = STATE_CONFLICT;
1554
1555
1556 end THREAD_IN_CONFLICT;
1557
1558 FAULT:
1559 procedure (Lock_name);
1560
1561 declare Lock_name char (*);
1562
1563 declare faulting_ptr pointer;
1564 declare 1 faulting_ptr_under_construction
1565 aligned like its_unsigned;
1566 declare foo bit (36) aligned;
1567 declare based_foo bit (36) aligned based;
1568
1569 unspec (faulting_ptr_under_construction) = ""b;
1570 faulting_ptr_under_construction.its_mod = "47"b3;
1571 unspec (faulting_ptr) = unspec (faulting_ptr_under_construction);
1572
1573 call syserr (BEEP, "scavenge_volume: Faulting under the ^a for debugging for ^a.", Lock_name,
1574 pds$process_group_id);
1575
1576 foo = faulting_ptr -> based_foo;
1577 return;
1578 end FAULT;
1579
1580
1581 %page; %include add_type;
1582 %page; %include aste;
1583 %page; %include cmp;
1584 %page; %include disk_pack;
1585 %page; %include its;
1586 %page; %include null_addresses;
1587 %page; %include "ptw.l68";
1588 %page; %include pvte;
1589 %page; %include scavenger_data;
1590 %page; %include stock_seg;
1591 %page; %include syserr_binary_def;
1592 %page; %include syserr_constants;
1593 %page; %include vol_map;
1594 %page; %include vtoc_map;
1595 %page; %include vtoce;
1596 %page;
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628 Debug
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661 debug
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750 debug
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925 end scavenge_volume;