1
2
3
4
5
6
7
8
9
10
11
12 wire_proc: proc (wireptr, code);
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 dcl wireptr ptr parameter;
30 dcl code fixed bin (35) parameter;
31
32 dcl linkno fixed bin (18);
33 dcl linkoff fixed bin (18);
34 dcl segno fixed bin (18);
35 dcl tseg fixed bin (18);
36
37 dcl sdwp pointer;
38 dcl callptr pointer;
39 dcl freep pointer;
40 dcl ip pointer;
41 dcl linkptr pointer;
42
43 dcl fp fixed bin;
44 dcl freei fixed bin;
45 dcl i fixed bin;
46 dcl lp fixed bin;
47 dcl np fixed bin;
48 dcl size fixed bin;
49 dcl temp_fp fixed bin;
50 dcl temp_lp fixed bin;
51 dcl increment fixed bin;
52
53 dcl wire_call bit (1) aligned;
54 dcl repeated_call bit (1) aligned;
55 dcl locked bit (1) aligned;
56
57 dcl pds$process_id bit (36) aligned external static;
58 dcl dseg$ (0:1023) fixed bin (71) aligned external static;
59 dcl unpaged_page_tables$ external;
60
61 dcl sys_info$system_type fixed bin external static;
62 dcl sst$wire_proc_data bit (36) aligned external static;
63 dcl sst$temp_w_event bit (36) aligned external static;
64
65 dcl 1 lot$ aligned like lot external static;
66
67 dcl error_table_$nolinkag fixed bin (35) external static;
68
69 dcl pxss$wait entry;
70 dcl pxss$addevent entry (bit (36) aligned);
71 dcl pxss$delevent entry (bit (36) aligned);
72 dcl pxss$notify entry (bit (36) aligned);
73 dcl get_ptrs_$given_segno entry (fixed bin (18)) returns (ptr);
74 dcl pc_wired$wire_wait entry (ptr, fixed bin, fixed bin);
75 dcl pc_wired$unwire entry (ptr, fixed bin, fixed bin);
76 dcl syserr entry options (variable);
77 dcl wired_utility_$caller entry () returns (ptr);
78
79 dcl (addr, baseptr, bin, divide, hbound, max, null, ptr, stac, stacq) builtin;
80
81
82
83 wire_call = "1"b;
84 increment = 1;
85 goto join_not_me;
86
87
88 wire_proc$unwire_proc: entry (wireptr, code);
89
90 wire_call = "0"b;
91 increment = -1;
92
93 join_not_me:
94 code = 0;
95 callptr = wireptr;
96 go to join;
97
98
99 wire_proc$wire_me: entry ();
100
101 wire_call = "1"b;
102 increment = 1;
103 goto join_me;
104
105
106 wire_proc$unwire_me: entry ();
107
108 wire_call = "0"b;
109 increment = -1;
110
111 join_me: callptr = wired_utility_$caller ();
112
113
114 join: wpdp = addr (sst$wire_proc_data);
115 upt_ptr = addr (unpaged_page_tables$);
116
117 segno = bin (baseno (callptr), 18);
118
119 locked = stac (addr (wpd.temp_w_lock), pds$process_id);
120 do while (^locked);
121 call pxss$addevent (sst$temp_w_event);
122 locked = stac (addr (wpd.temp_w_lock), pds$process_id);
123 if ^locked then call pxss$wait;
124 else call pxss$delevent (sst$temp_w_event);
125 end;
126 size = wpd.temp_w_max;
127 repeated_call = "0"b;
128 freei = hbound (wpd.temp_w, 1) + 1;
129 twep = null;
130 do i = size + 1 to 1 by -1;
131 ip = addr (wpd.temp_w (i));
132 tseg = bin (ip -> twe.segno, 18);
133 if tseg = segno
134 then do;
135 twep = ip;
136 if wire_call
137 then repeated_call = "1"b;
138 else if bin (twe.count, 18) ^= 1
139 then repeated_call = "1"b;
140 end;
141 if tseg = 0
142 then do;
143 freep = ip;
144 freei = i;
145 end;
146 end;
147
148 linkno = binary (baseno (lot$.lp (segno)), 18);
149 if linkno = 0
150 then code = error_table_$nolinkag;
151 else do;
152 if ^repeated_call
153 then do;
154 if twep = null
155 then do;
156 linkoff = binary (rel (lot$.lp (segno)), 18);
157 linkptr = ptr (baseptr (linkno), linkoff);
158 if freei > hbound (wpd.temp_w, 1)
159 then call syserr (1, "wire_proc: too many temp wired segments.");
160 else wpd.temp_w_max = max (size, freei);
161 twep = freep;
162
163 twe.seg_w = check_unpaged (addr (dseg$ (segno)));
164 twe.link_w = check_unpaged (addr (dseg$ (linkno)));
165
166 twe.segno = bit (segno, 18);
167 twe.linkno = bit (linkno, 18);
168 twe.flp = bit (divide (linkoff, 1024, 8, 0), 8);
169
170 temp_lp = linkoff - 1 + bin (linkptr -> header.block_length, 18);
171 twe.llp = bit (divide (temp_lp, 1024, 8, 0), 8);
172 end;
173
174 if ^twe.link_w
175 then do;
176 fp, temp_fp = bin (bin (twe.flp, 8), 17);
177 lp, temp_lp = bin (bin (twe.llp, 8), 17);
178 do i = 1 to size;
179 ip = addr (wpd.temp_w (i));
180 if ip ^= twep
181 then if linkno = bin (ip -> twe.linkno, 18)
182 then if fp = bin (ip -> twe.llp, 8)
183 then fp = temp_fp + 1;
184 else if lp = bin (ip -> twe.flp, 8)
185 then lp = temp_lp - 1;
186 end;
187
188 if fp <= lp
189 then do;
190 astep = get_ptrs_$given_segno (linkno);
191 np = lp - fp + 1;
192 if wire_call
193 then call pc_wired$wire_wait (astep, fp, np);
194 else call pc_wired$unwire (astep, fp, np);
195 end;
196 end;
197
198 if ^twe.seg_w
199 then do;
200 astep = get_ptrs_$given_segno (segno);
201 if wire_call
202 then call pc_wired$wire_wait (astep, 0, -1);
203 else call pc_wired$unwire (astep, 0, -1);
204 end;
205
206 if ^wire_call
207 then do;
208 twe.segno = (18)"0"b;
209 twe.linkno = (18)"0"b;
210 if twep = addr (wpd.temp_w (size))
211 then wpd.temp_w_max = size - 1;
212 end;
213 end;
214
215
216 twe.count = bit (bin (bin (twe.count, 18) + increment, 18), 18);
217 end;
218 if stacq (wpd.temp_w_lock, "0"b, pds$process_id) then call pxss$notify (sst$temp_w_event);
219 else call syserr (1, "wire_proc: lock not locked");
220 return;
221 %page;
222 check_unpaged: proc (sdw_ptr) returns (bit (1) aligned);
223
224
225
226 dcl sdw_ptr pointer;
227
228 if sys_info$system_type = ADP_SYSTEM then
229 return ((bin (sdw_ptr -> adp_sdw.add, 26) < upt.sst_absloc)
230 | (upt.sst_last_loc < bin (sdw_ptr -> adp_sdw.add, 26)));
231 else
232 return ((bin (sdw_ptr -> l68_sdw.add, 24) < upt.sst_absloc)
233 | (upt.sst_last_loc < bin (sdw_ptr -> l68_sdw.add, 24)));
234 end;
235 %page; %include wire_proc_data;
236 %page; %include linkdcl;
237 %page; %include lot;
238 %page; %include aste;
239 %page; %include system_types;
240 %page; %include "sdw.l68";
241 %page; %include "sdw.adp";
242 %page; %include unpaged_page_tables;
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276 end wire_proc;