1 " ***********************************************************
  2 " *                                                         *
  3 " * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 " *                                                         *
  5 " * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6 " *                                                         *
  7 " ***********************************************************
  8 
  9 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 10 "
 11 "         lock_volmap
 12 "
 13 "         Routines for manipulating the per-volume volume map lock.
 14 "         Lock succeeds if the lock can be obtained and the asynchronous
 15 "         state is idle. Otherwise, it fails. The asynchronous state
 16 "         is protected in the following way:
 17 "
 18 "            To change the state from IDLE requires both the volume map
 19 "            lock and the Page Table Lock.
 20 "
 21 "            To change the state from anything else requires the Page
 22 "            Table Lock.
 23 "
 24 "         Entries:
 25 "
 26 "            lock_unwired      - lock from outside of page control
 27 "            lock_wired_nowait - lock from page control, don't wait
 28 "            lock_wired_wait   - lock from page control, set wait event
 29 "            unlock_unwired    - unlock from outside of page control
 30 "            unlock_wired      - unlock from page control
 31 "
 32 "         Written February 1982 by J. Bongiovanni
 33 "
 34 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 35 
 36           name      lock_volmap
 37 
 38           segdef    lock_unwired
 39           segdef    unlock_unwired
 40 
 41           segdef    lock_wired_nowait
 42           segdef    lock_wired_wait
 43           segdef    unlock_wired
 44 
 45           even
 46 notify_arg_list:
 47           vfd       o18/2,o18/4,o36/0
 48 
 49 "^L
 50           include   apte
 51 "^L
 52           include   page_info
 53 "^L
 54           include   pvt
 55 "^L
 56           include   pvte
 57 "^L
 58           include   pxss_page_stack
 59 "^L
 60 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 61 "
 62 "         lock_unwired
 63 "
 64 "         call page$lock_volmap (pvtep)
 65 "
 66 "         pvtep -> PVTE
 67 "
 68 "         Returns with lock held and async state idle
 69 "
 70 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 71 
 72 lock_unwired:
 73           push
 74           eppbp     ap|2,*                        " bp -> ptr -> PVTE
 75           eppbp     bp|0,*                        " bp -> PVTE
 76 
 77 lock_unwired_retry:
 78           tsx7      lock_wired_wait               " Try to lock lock
 79           tra       lock_unwired_fails            " Didn't get it
 80           return                                  " Got it
 81 
 82 lock_unwired_fails:
 83           call      pxss$wait                     " Wait event already set
 84           tra       lock_unwired_retry            " Go for it again
 85 
 86 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 87 "
 88 "         unlock_unwired
 89 "
 90 "         call page$unlock_volmap (pvtep)
 91 "
 92 "         pvtep -> PVTE
 93 "
 94 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
 95 
 96 unlock_unwired:
 97           push
 98           eppbp     ap|2,*                        " bp -> ptr -> PVTE
 99           eppbp     bp|0,*                        " bp -> PVTE
100           tsx7      unlock_wired
101           return
102 "^L
103 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
104 "
105 "         lock_wired_nowait
106 "
107 "         tsx7      lock_volmap$lock_wired_nowait
108 "         <return if failed>
109 "         <return if succeed>
110 "
111 "         On entry,
112 "             bp -> PVTE
113 "
114 "         On return,
115 "             if succeeded, then lock owned by process and async state is idle
116 "
117 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
118 
119 lock_wired_nowait:
120           increment pvt$volmap_lock_nowait_calls
121           tsx6      lock_try                      " Attempt to lock
122           tra       lock_wired_fails              " Failed
123           tra       1,x7                          " Succeeded
124 
125 lock_wired_fails:
126           increment pvt$volmap_lock_nowait_fails
127           tra       0,x7
128 "^L
129 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
130 "
131 "         lock_wired_wait
132 "
133 "         tsx7      lock_volmap$lock_wired_wait
134 "         <return if failed>
135 "         <return if succeeded>
136 "
137 "         On entry,
138 "             bp -> PVTE
139 "
140 "         On return,
141 "             if succeeded, lock help by process and async state is idle
142 "             if failed, appropriate wait event is in APTE, notify switch set
143 "
144 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
145 
146 lock_wired_wait:
147           increment pvt$volmap_lock_wait_calls
148           tsx6      lock_try                      " Try to get lock
149           tra       lock_set_wait                 " Failed
150           tra       1,x7                          " Succeeded
151 
152 lock_set_wait:
153           increment pvt$volmap_lock_wait_fails
154           stq       lock_volmap_temp              " Notify switch bit
155           eppap     pds$apt_ptr,*                 " ap -> APTE
156           sta       ap|apte.wait_event            " Set wait event
157 
158 lock_wired_retry:
159           ldq       bp|0,x0                       " Notify switch word
160           lda       bp|0,x0
161           ora       lock_volmap_temp              " Set notify switch
162           stacq     bp|0,x0                       " Into PVTE
163           tnz       lock_wired_retry              " Lost race, retry
164 
165           tsx6      lock_try                      " Try again, in case race
166           tra       0,x7                          " Failed again
167           eppap     pds$apt_ptr,*                 " Got it this time, reset wait
168           stz       ap|apte.wait_event
169           tra       1,x7
170 "^L
171 
172 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
173 "
174 "         unlock_wired
175 "
176 "         tsx7      lock_volmap$unlock_wired
177 "
178 "         On entry,
179 "             bp -> PVTE
180 "
181 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
182 
183 unlock_wired:
184           ldq       pds$processid
185           lda       0,dl
186           stacq     bp|pvte.volmap_lock           " Unlock
187           tnz       page_error$volmap_stacq_fails
188 
189           epbpap    bp|0                          " ap -> PVT
190 unlock_wired_retry:
191           ldq       ap|pvt.n_volmap_locks_held    " Meter total lock time
192           tze       0,x7                          " Something wrong
193           lda       ap|pvt.n_volmap_locks_held
194           sta       lock_volmap_temp              " Save old value
195           sba       1,dl                          " One fewer lock held
196           stacq     ap|pvt.n_volmap_locks_held    " Update
197           tnz       unlock_wired_retry            " Lost race
198 
199           ldaq      ap|pvt.last_volmap_time       " Last lock/unlock
200           staq      lock_volmap_temp_1            " Save
201           rccl      sys_info$clock_,*             " Current time
202           staq      ap|pvt.last_volmap_time
203           sbaq      lock_volmap_temp_1            " Delta
204           mpy       lock_volmap_temp              " Integral
205           adaq      ap|pvt.total_volmap_lock_time
206           staq      ap|pvt.total_volmap_lock_time " Total integral
207 
208 unlock_wired_notify_retry:
209           ldq       bp|pvte.volmap_lock_notify_word " Check for notify
210           lda       bp|pvte.volmap_lock_notify_word
211           cana      pvte.volmap_lock_notify,dl
212           tze       0,x7                          " Nobody to notify
213           era       pvte.volmap_lock_notify,dl    " Reset notify bit
214           stacq     bp|pvte.volmap_lock_notify_word " Into PVTE
215           tnz       unlock_wired_notify_retry     " Lost race
216 
217           eaa       bp|0                          " PVTE offset
218           arl       18                            " Into AL
219           epbpap    bp|0                          " ap -> PVT
220           ora       ap|pvt.volmap_lock_wait_constant " Event to notify
221 
222           sta       arg+4
223           eppap     arg+4
224           spriap    arg+2
225           ldaq      notify_arg_list
226           staq      arg
227 
228           call      pxss$notify(arg)
229 
230           tra       0,x7
231 
232 "^L
233 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
234 "
235 "         lock_try
236 "
237 "         Internal procedure to attempt lock
238 "
239 "         tsx6      lock_try
240 "         <return if fail>
241 "         <return if succeed>
242 "
243 "         On entry,
244 "             bp -> PVTE
245 "
246 "         On successful return,
247 "             Lock help by process
248 "             Async state is idle
249 "
250 "         On failure return,
251 "             Areg contains wait event
252 "             Qreg contains notify bit
253 "             x0 is offset into PVTE of notify word
254 "
255 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
256 
257 lock_try:
258           epbpap    bp|0                          " ap -> PVT
259           lda       pds$processid
260           cmpa      bp|pvte.volmap_lock           " MYLOCK?
261           tze       page_error$volmap_mylock      " Yes
262 
263           stac      bp|pvte.volmap_lock           " Go for it
264           tze       lock_try_got                  " Got it
265           eaa       bp|0                          " AU = PVTE offset
266           arl       18                            " AL = PVTE offset
267           ora       ap|pvt.volmap_lock_wait_constant " Areg = wait event
268           ldq       pvte.volmap_lock_notify,dl    " Notify bit
269           eax0      pvte.volmap_lock_notify_word  " Notify word
270           tra       0,x6
271 
272 lock_try_got:
273           ldx0      bp|pvte.volmap_async_state
274           cmpx0     VOLMAP_ASYNC_IDLE,du          " Is asynchronous state idle
275           tnz       lock_try_not_idle             " No
276 
277           aos       ap|pvt.n_volmap_locks         " Meter
278 lock_try_retry:
279           ldq       ap|pvt.n_volmap_locks_held    " Meter total lock time
280           lda       ap|pvt.n_volmap_locks_held
281           sta       lock_volmap_temp              " Save old value
282           ada       1,dl                          " One more lock held
283           stacq     ap|pvt.n_volmap_locks_held    " Update
284           tnz       lock_try_retry                " Lost race
285 
286           ldaq      ap|pvt.last_volmap_time       " Last lock/unlock
287           staq      lock_volmap_temp_1            " Save
288           rccl      sys_info$clock_,*             " Current time
289           staq      ap|pvt.last_volmap_time
290           sbaq      lock_volmap_temp_1            " Delta
291           mpy       lock_volmap_temp              " Integral
292           adaq      ap|pvt.total_volmap_lock_time
293           staq      ap|pvt.total_volmap_lock_time " Total integral
294           tra       1,x6
295 
296 lock_try_not_idle:
297           lrl       36                            " Areg = 0, Qreg = processid
298           stacq     bp|pvte.volmap_lock           " Unlock
299           tnz       page_error$volmap_stacq_fails " Bad news
300 
301           eaa       bp|0                          " AU = PVTE offset
302           arl       18                            " AL = PVTE offset
303           ora       ap|pvt.volmap_idle_wait_constant " Areg = wait event
304           ldq       pvte.volmap_idle_notify,dl    " Notify bit
305           eax0      pvte.volmap_idle_notify_word  " Notify word
306           tra       0,x6
307 
308           end