1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1984 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 
 13 /* format: style4 */
 14 makeunknown_: proc (a_segno, a_switches, zero_lot, a_code);
 15 
 16 /*
 17 
 18    Written March 1975 by R. Bratt
 19 
 20    Last modified by:
 21 
 22    R. Bratt July 13 1975 to not report segno_in_use
 23    R. Bratt Janurary 26 1976 for nss
 24    M. Weaver April 22 1977 to indicate zero usage count
 25    B. Margulies to protect nonnull-refnames when terminating null ones
 26    E. N. Kittlitz February 1983 for kst_util$unthread_kste.
 27    K. Loepere November 1984 to rename to makeunknown_.
 28 
 29    --->  makeunknown_ removes the KST  entry  for  a   segment   given   its  segment   number.
 30    makeunknown_  operates  as  follows.  If the kste has a positive usage count in the caller's
 31    ring then the usage  count is  decremented  unless the caller specified  force,  in  which
 32    case  the  usage  count  is  forcably  zeroed.  If  all usage counts  are  not zero,  then
 33    makeunknown_  returns.  Otherwise, makeunknown_ verifies that  the  segment   has   no   known
 34    inferiors.   If   this  condition obtains  then  makeunknown_  unbinds  the  segment  number
 35    from the object. If rsw is set then the freed  segment  number  is  marked   as  reserved.
 36    Otherwise,  the segment number is returned to the pool of free segment numbers.
 37    USAGE: call makeunknown_ (segno, switches, zero_lot, code)
 38 
 39    segno fixed bin(17) - - - segment number of the segment
 40    switches bit(36) aligned - - - switches
 41    1 - - - reserve switch
 42    x1 - - - force switch
 43    zero_lot bit (1) aligned - - - indicates whether lot entry should be zeroed
 44    code fixed bin (35) - - - error code (output)
 45 
 46    ---> CALL makeunknown_$protect_names (segno, n_names, switches, zero_lot, code);
 47    This is as makeunknown_, but there must be at least n_names+1 references
 48    or a code is returned.
 49 
 50 */
 51 
 52 dcl  a_segno fixed bin (17),
 53      a_switches bit (36) aligned,
 54      zero_lot bit (1) aligned,
 55      a_code fixed bin (35);
 56 dcl  a_n_names fixed bin;
 57 
 58 dcl  pkstep ptr,
 59      ring fixed bin,
 60      code fixed bin (35),
 61      segno fixed bin (17);
 62 dcl  n_names fixed bin;
 63 
 64 dcl  1 switches aligned,
 65        2 rsw bit (1) unal,
 66        2 force bit (1) unal,
 67        2 pad bit (34) unal;
 68 
 69 dcl  setfaults$disconnect ext entry (fixed bin (17)),
 70      pathname_am$clear ext entry (fixed bin (17)),
 71      get_kstep ext entry (fixed bin (17), ptr, fixed bin (35)),
 72      kst_util$unthread_kste ext entry (ptr),
 73      level$get ext entry returns (fixed bin);
 74 
 75 dcl  (error_table_$known_in_other_rings, error_table_$infcnt_non_zero) ext fixed bin (35);
 76 dcl  error_table_$no_null_refnames fixed bin (35) ext static;
 77 
 78 dcl  (addr, baseno, baseptr, binary, fixed, null, rel, substr, unspec) builtin;
 79 
 80 %include kst;
 81 ^L
 82 
 83           n_names = 0;
 84           go to Join;
 85 
 86 protect_names:
 87      entry (a_segno, a_n_names, a_switches, zero_lot, a_code);
 88           n_names = a_n_names;
 89 
 90 Join:
 91           string (switches) = a_switches;
 92           segno = a_segno;
 93           zero_lot = "0"b;
 94           a_code = 0;
 95           kstp = pds$kstp;
 96           ring = level$get ();
 97                                                             /* make sure segno is good */
 98           call get_kstep (segno, kstep, code);
 99           if code ^= 0 then call abort (code);
100                                                             /* update usage count */
101                                                             /* Force_switch is not permitted with n_names > 0 */
102 
103           if n_names > 0
104           then if kste.usage_count (ring) ^> n_names        /* see only null */
105                then do;
106                     a_code = error_table_$no_null_refnames;
107                     return;
108                end;
109 
110           if switches.force
111           then kste.usage_count (ring) = 0;
112           else if kste.usage_count (ring) > 0
113           then kste.usage_count (ring) = kste.usage_count (ring) - 1;
114                                                             /* don't terminate if still in use */
115 
116 /*        LOT, ISOT entries should be zeroed when usage count goes to 0 */
117           if kste.usage_count (ring) = 0 then if (ring > 0) & (^kste.dirsw) then zero_lot = "1"b;
118 
119           if unspec (kste.usage_count) ^= "0"b
120           then if switches.force
121                then call abort (error_table_$known_in_other_rings);
122                else return;
123                                                             /* don't terminate if known inferiors */
124           if kste.infcount ^= 0 & kste.flags.dirsw
125           then call abort (error_table_$infcnt_non_zero);
126                                                             /* decrement parent's inferior count */
127           if kste.entryp ^= null
128           then do;
129                pkstep = addr (kst.kst_entry (fixed (baseno (kste.entryp), 17)));
130                pkstep -> kste.infcount = pkstep -> kste.infcount - 1;
131           end;
132                                                             /* hash out of uid hash thread */
133           call kst_util$unthread_kste (kstep);
134                                                             /* let the world know its gone */
135           call setfaults$disconnect (segno);
136           if kste.flags.dirsw then call pathname_am$clear (segno);
137                                                             /* make kste look nice */
138           unspec (kste) = "0"b;
139           kste.segno = segno;
140                                                             /* thread kste on to free chain */
141           if switches.rsw
142           then kste.fp = (18)"1"b;
143           else do;
144                kste.fp = kst.free_list;
145                kst.free_list = rel (kstep);
146           end;
147           return;
148 
149 abort: proc (code);
150 dcl  code fixed bin (35);
151           a_code = code;
152           go to non_local_return;
153      end abort;
154 
155 non_local_return:
156           return;
157 
158      end makeunknown_;