1 " ***********************************************************
2 " * *
3 " * Copyright, C Honeywell Bull Inc., 1987 *
4 " * *
5 " * Copyright, C Honeywell Information Systems Inc., 1983 *
6 " * *
7 " * Copyright c 1972 by Massachusetts Institute of *
8 " * Technology and Honeywell Information Systems, Inc. *
9 " * *
10 " ***********************************************************
11
12 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
13 "
14 " pxss -- The Multics Traffic Controller Scheduler
15 "
16 " Last Modified: Date and Reason
17 "
18 " February 1985 by Keith Loepere to fix initialization disk polling.
19 " January 1985 by Keith Loepere to fix window in ips sending and oob in
20 " set_work_class.
21 " December 1984 by Keith Loepere for page_pause and pause functions.
22 " 84-11-21 by E. Swenson for IPC event channel validation.
23 " October 1984 by M. Pandolf for getwork suspension
24 " 84-07-23 by E. Swenson to clean up ittes of dead processes
25 " correctly.
26 " 07/16/84 by R. Michael Tague: Changed the $ips_wakeup and
27 " $ips_wakeup_int entries to expect an ips bit mask
28 " as an indicator of the signal to be sent instead
29 " of a name.
30 " 84-02 BIM for sst$ references instead of sst.
31 " October 1983 by Keith Loepere for disk polling during initialization.
32 " June 1983 by E. A. Ranzenbach for operator console polling.
33 " June 1983 by Chris Jones to call the new IOI entries.
34 " May 1983 by BIM for call-side pre-empt and stop.
35 " April 1983 by E. N. Kittlitz to DRL instead of 0,ic looping.
36 " February 1983 by E. N. Kittlitz for hex floating point.
37 " December 1982 by C. Hornig to punt NCP
38 " October 1982 by C. Hornig for no ITT message on fast channels.
39 " August 1982 by J. Bongiovanni for realtime_io priority,
40 " relinquish_priority
41 " April 1982 by J. Bongiovanni to enhance governing
42 " February 1982 by J. Bongiovanni to fix masking bug
43 " September 1981 by J. Bongiovanni for procs_required, moving
44 " code to tc_util
45 " June 1981 by J. Bongiovanni for governed work classes,
46 " -tcpu, +pre_empt_sample_time
47 " May 1981 by J. Bongiovanni for response time metering
48 " 03/01/81 by W. Olin Sibert, for Phase One of ADP conversion
49 " March 1981 by J. Bongiovanni for page pinning, saved stack_0's,
50 " argument copying protocol, initialization NTO
51 " February 1981 by J. Bongiovanni for fast connect
52 " March 1981 by E. Donner for new ipc - include file for itt entry
53 " and to change check for fast channel
54 " February 1981 by J. Bongiovanni to fix set_proc_required
55 " January 1981 by J. Bongiovanni to fix ITT overflow, credit
56 " clipping
57 " Spring 1979 by B. Greenberg for shared stack_0's.
58 " Fall 1978 RE Mullen for +ptl_NTO, +disable int_q, -XED's
59 " Winter 1977 RE Mullen for lockless lockfull? scheduler:
60 " concurrent read_lock, ptlocking state, apte.lock,
61 " unique_wakeup entry, tcpu_scheduling
62 " Spring 1976 by RE Mullen for deadline scheduler
63 " 02/17/76 by S. Webber for new reconfiguration
64 " 3/10/76 by B Greenberg for page table locking event
65 " Spring 1975 RE Mullen to implement priority scheduler and
66 " delete loop_wait code. Also fixed plm/lost_notify bug.
67 " Last modified on 02/11/75 at 19:49:10 by R F Mabee. Fixed arg-copying & other bugs.
68 " 12/10/74 by RE Mullen to add tforce, ocore, steh, tfmax & atws
69 " disciplines to insure response in spite of long quanta, and
70 " fix bugs in get_processor, set_newt, and loop_wait unthreading.
71 " 12/6/74 by D. H. Hunt to add access isolation mechanism checks
72 " 4/8/74 by S.H.Webber to merge privileged and unprivileged code.
73 " and to add quit priority and fix lost notify bug
74 " 5/1/74 by B. Greenberg to add cache code
75 " 8/8/72 by R.B.Snyder for follow-on
76 " 2/2/72 by R. J. Feiertag to a simulated alarm clock
77 " 9/16/71 by Richard H. Gumpertz to add entry rws_notify
78 " 7/**/69 by Steve H. Webber
79 "
80 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
81
82 " HISTORY COMMENTS:
83 " 1) change1986-05-13GJohnson, approve1986-05-13MCR7387,
84 " audit1986-05-13Martinson, install1986-05-14MR12.0-1056:
85 " Correct error message documentation.
86 " 2) change1986-08-09Kissel, approve1986-08-12MCR7479,
87 " audit1986-10-08Fawcett, install1986-11-03MR12.0-1206:
88 " Changed to check the flags in an event channel name when sending a
89 " wakeup. If the flags indicate that this is an asynchronous event
90 " channel, then send an IPS wkp_ signal in addition to the normal IPC
91 " wakeup. This code uses an algorithm copied from ipc_validate_ to decode
92 " the event channel flags, hence, any changes must be reflected in both
93 " places.
94 " 3) change1988-09-16Fawcett, approve1988-10-06MCR8004,
95 " audit1988-10-06Farley, install1988-10-10MR12.2-1156:
96 " Removed check in compute_virtual_clocks which was testing for a zero
97 " second word in prds$last_recorded_time to determine if it should be
98 " initialized. The initialization is already done in init_processor. All
99 " this check was doing was opening a timing hole for errors to occur i.e.
100 " the last 36 bits of the clock roll over ~ every 19 hours.
101 " 4) change1988-10-05Fawcett, approve1988-10-05MCR7999,
102 " audit1988-10-06Farley, install1988-10-10MR12.2-1156:
103 " Changed to always reset the number a pages in use used before giving
104 " the processor the process. This enables a more acturate measure of
105 " memory units.
106 " 5) change2018-05-31Anthony, approve2018-05-31MCR10050,
107 " audit2019-05-11Swenson, install2019-05-11MR12.6g-0017:
108 " Promote loop_lock_time to
109 " fixed bin 71.
110 " 6) change2019-05-19Swenson, approve2019-05-19MCR10054,
111 " audit2019-05-19GDixon, install2019-05-20MR12.6g-0019:
112 " Fix for preempting for procs_required processes.
113 " END HISTORY COMMENTS
114
115 name pxss
116
117
118 iftarget adp
119 warn This has not been converted yet for the ADP. Beware.
120 ifend
121
122
123 link prds_link,prds$+0
124
125 even
126 channel_mask_set:
127 oct 17,17
128
129 null: its -1,1 null pointer
130
131 null_epaq:
132 vfd 3/0,15/-1,18/0,18/1,18/0
133
134 ring0_timer_event:
135 aci "dlay"
136 even
137 "^L
138 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
139 "
140 " Table of contents
141 "
142 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
143
144
145 entry addevent
146 entry block
147 entry delevent
148 entry dvctl_retry_ptlwait
149 entry empty_t
150 entry fast_ipc_block
151 entry fast_ipc_get_event
152 entry force_stop
153 entry free_itt
154 entry get_entry
155 entry get_event
156 entry guaranteed_eligibility_off
157 entry guaranteed_eligibility_on
158 entry io_wakeup
159 entry ips_wakeup
160 entry ips_wakeup_int
161 entry lock_apt
162 entry lock_apte
163 entry notify
164 entry page_notify
165 entry page_pause
166 entry page_wait
167 entry pause
168 entry pre_empt
169 entry pre_empt_poll
170 entry ptl_notify
171 entry ptl_wait
172 entry relinquish_priority
173 entry ring_0_wakeup
174 entry set_cpu_timer
175 entry set_procs_required
176 entry set_timer
177 entry set_work_class
178 entry start
179 entry stop
180 entry stop_wakeup
181 entry suspend_getwork
182 entry thread_in_idle
183 entry unique_ring_0_wakeup
184 entry unlock_apt
185 entry unlock_apte
186 entry unthread_apte
187 entry usage_values
188 entry wait
189 entry waitp
190 entry wakeup
191 entry wakeup_int
192
193 "^L
194 include apte
195 "^L
196 include aste
197 "^L
198 include drl_macros
199 "^L
200 include event_channel_name
201 "^L
202 include ips_mask_data
203 "^L
204 include itt_entry
205 "^L
206 include mc
207 "^L
208 include mode_reg
209 "^L
210 include ptw
211 "^L
212 include pxss_page_stack
213 "^L
214 include response_transitions
215 "^L
216 include scs
217 "^L
218 include stack_0_data
219 "^L
220 include stack_frame
221 "^L
222 include stack_header
223 "^L
224 include state_equs
225 "^L
226 include tc_meters
227 "^L
228 include wcte
229 "^L
230
231 macro read_clock
232 rccl sys_info$clock_,*
233 &end
234
235 "^L
236 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
237 "
238 " BLOCK -- entry to block a process.
239 "
240 " Call is
241 " call pxss$block;
242 "
243 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
244
245 block: eppbp short_ret
246 sprpbp pds$ipc_block_return
247
248 equ ipcv.retsw,1
249
250 fast_ipc_block:
251 tsplb setup_mask mask, switch_stack
252 aos bb|te_block
253 aos bb|blocks
254 lda bp|apte.flags check for wakeup waiting
255 cana apte.wakeup_waiting,du
256 tnz block_ez able to avoid heavy lock!
257 tsx7 update_te update te in own APT entry
258 tsx6 WRITE_LOCK block locks
259 tsx6 LOCK_bp block locks
260 lda bp|apte.flags check for wakeup waiting
261 cana apte.wakeup_waiting,du
262 tnz block_not there is one, return
263 ldq BLOCK_PROCESS,dl
264 tsx7 meter_response_time$tc this is a response transition
265 tsx7 unthread thread out of ready list
266 ldx0 blocked,du set state to blocked
267 tsx7 update_execution_state
268 tsx7 revoke_elig block
269 tsx7 reschedule block
270 tsx7 purge_UNLOCK block
271 tsx7 getwork
272 ldaq bp|apte.virtual_cpu_time note vtime at gain elig
273 staq pds$virtual_time_at_eligibility
274 tsx6 LOCK_bp
275 block_returns:
276 lcx0 apte.wakeup_waiting+1,du turn off wakeup waiting
277 ansx0 bp|apte.flags
278 return_event_messages:
279 lda bp|apte.flags check for interrupts pending
280 ana apte.stop_pending,du look for stop connect
281 ora bp|apte.ips_message or ips signals
282 tze *+2 if interrupt pending leave 1
283 lda 1,dl ..
284 ldq bp|apte.flags2 get special interrupts
285 anq apte.special_chans,dl ..
286 ersq bp|apte.flags2 turn off special chans
287 qls apte.chans_offset ..
288 lls 17 put info together
289 eax3 0,al remember info
290 eax4 0 use to zero event thread
291 ldx2 bp|apte.ipc_pointers return event thread
292 stx4 bp|apte.ipc_pointers zero event thread in APT entry
293 tsx6 UNLOCK_bp
294 tsx7 switch_back_ret_pds
295 stz pds$itt_head
296 stx2 pds$itt_head
297 eaq 0,3 get info
298 lda 0,dl zero a
299 lls 1 split info
300 orsq pds$events_pending store special chans
301 orsa pds$ipc_vars+ipcv.retsw store return sw
302 lprpbp pds$ipc_block_return
303 epbpsb pds$stack_0_ptr,* Load this up for fast_hc_ipc,
304 "who can't do it himself.
305 tra bp|0
306
307 "
308 "here if find wakeup_waiting after full lock, to back off big lock
309 "
310 block_not:
311 tsx6 UNLOCK only need self locked
312 tra block_returns
313
314 "
315 "here if notice wakeup_waiting before locking anything
316 "
317 block_ez: tsx6 LOCK_bp only need to lock self
318 tra block_returns
319
320 " ^L
321 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
322 "
323 " GET_EVENT -- procedure to return a process' event thread
324 "
325 " Call is
326 " call pxss$get_eventevent
327 "
328 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
329
330 get_event:
331 eppbp short_ret
332 sprpbp pds$ipc_block_return
333 fast_ipc_get_event:
334 tsplb setup_mask
335 tsx6 LOCK_bp
336 tra return_event_messages
337 " ^L
338 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
339 "
340 " WAKEUP
341 "
342 " call pxss$wakeupprocessidevent_channelevent_messagestate
343 "
344 " entry to wake up a process given event channel and event message
345 "
346 " The following entries have the same calling sequence:
347 "
348 " wakeup - send wakeup, give interactive credit if blocked
349 " more than priority_sched_inc
350 "
351 " ring_0_wakeup - send wakeup, give interactive credit if blocked
352 "
353 " unique_ring_0_wakeup - send wakeup only if this wakeup is unique
354 " in ITT for this process, give interactive credit if
355 " blocked.
356 "
357 " io_wakeup - send wakeup, give interactive credit if blocked,
358 " give realtime credit if blocked and tuning parameter
359 " set.
360 "
361 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
362
363 ring_0_wakeup:
364 wakeup_int:
365 tsx6 setup_
366 lca 1,dl set flag saying ring_0_wakeup entry
367 sta pds$wakeup_flag set flag saying ring_0_wakeup entry
368 tra wjoin
369 unique_ring_0_wakeup:
370 tsx6 setup_
371 stz pds$wakeup_flag set flag for unique_ring_0_wakeup
372 tra wjoin
373 io_wakeup:
374 tsx6 setup_
375 lca 2,dl set flag for io_wakeup entry
376 sta pds$wakeup_flag set flag for io_wakeup entry
377 tra wjoin
378
379 wakeup:
380 tsx6 setup_
381 stc1 pds$wakeup_flag set flag saying wakeup entry
382 wjoin:
383 lda ap|2,* get processid
384 sta pds$arg_1
385 ldaq ap|4,* save event channel in pds$arg_2
386 staq pds$arg_2
387 ldaq ap|6,* save event message in pds$arg_3
388 staq pds$arg_3
389 tsplb setup_check switch stacks and lock
390 arg 0,6
391
392 szn pds$wakeup_flag see if ring_0_wakeup entry
393 tmoz w_rz it is. do later code
394 lda pds$validation_level it isn't.
395 sta tmp_ring get ready to make ITT message
396 stz dev_signal
397 tra copy_evs skip code for ring_0_wakeup entry
398 w_rz: stz tmp_ring
399 lda 1,dl
400 sta dev_signal must be a device signal
401 copy_evs:
402 ldaq pds$arg_2 finish setup for make ITT message
403 staq tmp_ev_channel
404 ldaq pds$arg_3
405 staq tmp_ev_message
406
407 ldx2 0,du pre-set execution state to zero
408 tsx6 WRITE_LOCK Wakeup may need to thread in
409 tsx7 hash_LOCK wakeup finds and locks
410 arg wakeup_returns_nul indirect if error
411 lda bp|apte.flags see if this is idle process
412 cana apte.idle,du
413 tnz wakeup_returns can't wakeup an idle process
414 aos bb|wakeups
415 lxl0 bp|apte.state check for stopped process
416 cmpx0 stopped,du
417 tze wakeup_returns
418
419 ldq NON_TTY_WAKEUP,dl
420 tsx7 meter_response_time$tc response transition
421
422 ldq pds$wakeup_flag should we give priority ?
423 tpnz non_ring_0 no,normal wakeup
424 lxl0 bp|apte.state recover process state
425 cmpx0 blocked,du no interaction credit unless blocked
426 tnz no_int_credit ..at time of wakeup.
427 lda apte.interaction,du give priority ... turn on interaction sw.
428 orsa bp|apte.flags in APT entry of process getting wakeup
429 cmpq =-2 io_wakeup?
430 tnz no_int_credit no
431 szn bb|realtime_io_priority_switch are we giving realtime priority?
432 tze no_int_credit no
433 lda apte.realtime_burst,du
434 orsa bp|apte.flags yes
435 no_int_credit:
436 tsx7 make_itt_message wakeup adds itt_msg to process' queue
437
438 " See if we have to send an IPS wkp_ signal
439 " This algorithm is copied from ipc_validate_
440
441 lda pds$arg_2 Get event_channel_name.encoded_idx
442 arl 18 in al
443 sba bp|apte.ipc_r_offset Subtract the r_offset to get the decoded_index
444 arl decoded_index.flags_shift-18 Get the flag bits we already shifted 18 above
445 ana decoded_index.flags_mask,dl For now there are only 2 possibilities
446 tze wakeup_wake We have the normal flags
447 " We have to send an IPS wkp_ signal
448
449 lda sys_info$wkp_mask We want to send a wkp_ signal
450 tsx6 send_ips_wakeup Do the real work, destroys pds$arg_3
451 " Next instruction may be skipped on return
452 wakeup_wake:
453 tsx7 wake Go to common wakeup code
454 lxl2 bp|apte.state return arg in x2
455 szn errcode
456 tze *+2
457 lxl2 errcode
458 wakeup_returns:
459 tsx6 UNLOCK_bp Wakeup unlocks target apte
460 wakeup_returns_nul:
461 tsx6 UNLOCK Wakeup unlocks
462 tsx7 switch_back_ret Exit from wakeup if pid invalid and no apte locked
463 stz ap|8,* return execution state
464 sxl2 ap|8,*
465 short_return
466
467 non_ring_0:
468 "Here are the checks for the
469 "Access Isolation Mechanism
470
471 ldaq bp|apte.access_authorization if target has ipc privilege
472 orq pds$access_authorization+1 or if sender has ipc privilege,
473 canq apte.no_ipc_check,dl
474 tnz no_int_credit then it is OK to send the wakeup.
475 ldx0 bp|apte.access_authorization+1 get level of target process
476 cmpx0 pds$access_authorization+1 if it's less than sender's level,
477 tmi send_down do not allow wakeup to be sent.
478 ana pds$access_authorization if the category set of the sender
479 cmpa pds$access_authorization is contained in or equal to
480 tze no_int_credit the category set of the target,
481 "then it is OK to send the wakeup.
482 send_down:
483 ldx2 100,du this error code indicates
484 tra wakeup_returns an IPC send-down attempt.
485
486 " ^L
487 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
488 "
489 " WAKE -- internal subroutine used to wake up a process
490 " and award it a processor if it is warrented.
491 "
492 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
493
494 wake:
495 tsx6 subroutine_save
496 szn bp|apte.lock ASSUME bp locked
497 drlnz pxss: APTE not locked ASSUME bp locked
498 lda apte.wakeup_waiting,du turn on wakeup waiting flag
499 orsa bp|apte.flags
500 lxl0 bp|apte.state make sure process is blocked
501 cmpx0 blocked,du
502 tnz subroutine_unsave
503 read_clock " check for long time block
504 sbaq bp|apte.state_change_time subtract out last state chage time
505 cmpq bb|priority_sched_inc see if process has been asleep too long
506 tmi short_time just went blocked, no priority
507 tsx0 setup_p_int boost priority
508 short_time:
509 ldx0 ready,du change state to ready
510 tsx7 update_execution_state
511 tsx7 sort_in schedule and thread in
512 eax2 bp|0 fp = entry waking up
513 tsx7 get_processor does he get a processor?
514 tra subroutine_unsave
515 " ^L
516 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
517 "
518 " FREE_ITT - entry to put a list of ITT entries into the list of free ITT
519 " entries. It is always called after a process returns from block,
520 " to release its event message queue.
521 "
522 " Nothing is locked when this code is entered.
523 " Apte's are locked to validate that the processes exist.
524 " If the pid has changed we know empty_t zeroed the counter.
525 " Never looplock an APTE while holding the itt_free_list.
526 "
527 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
528
529 free_itt:
530 tsx6 setup_
531 lda ap|2,* pick up pointer to list to be freed
532 sta pds$arg_1
533 tsplb setup_check switch stacks and lock
534 arg 0,6
535
536 ldx0 pds$arg_1 get head of process's itt queue
537 tsx7 free_itt_ free them
538 tra switch_back free_itt exits
539 "^L
540
541 free_itt_:
542 "Come here to free X0->ITTE's
543 eax5 0,0 Remember newly freed head in X5
544 tze free_itt_exit there is nothing to free
545 epbpbb tc_data$ get pointer to base of tc_data
546 ldx4 -1,du put all-seven into RX4
547 eaa 0 count num freed
548 follow_itt_list:
549 sxl4 bb|itt_entry.next_itt_relp,0 tag the discarded entry for debugging
550 sba 1,dl maintain counter
551 ldx3 bb|itt_entry.origin,0 see if dev_signal
552 tnz fi_skip_sender nz means dev_signal
553 ldx3 bb|itt_entry.sender,0 was dev_signal
554 tsx6 LOCK_x3 free_itt locks sender
555 ldq bb|apte.processid,3 if process still exists
556 cmpq bb|itt_entry.sender,0
557 tnz fi_sender_gone processid has changed!
558 lcq 1,dl ok to decrement
559 asq bb|apte.ittes_sent,3
560 fi_sender_gone:
561 tsx6 UNLOCK_x3 free_itt unlocks sender
562 fi_skip_sender:
563 " get following entry's forward pointer
564 ldx2 bb|itt_entry.next_itt_relp,0
565 tze thread_in_itt_queue
566 eax0 0,2 put index 2 into XR0
567 tra follow_itt_list
568 "
569 "x5->first_freed, x0 ->last_freed, A has count
570 thread_in_itt_queue:
571 ldqc bb|itt_free_list free_itt LOCKS free list
572 tnz *+2
573 tra thread_in_itt_queue If zero somebody else has it
574
575 eax1 0,qu
576 " make tail of new -> old head
577 stx1 bb|itt_entry.next_itt_relp,0
578 ldx3 bb|itt_entry.target_id,0 prepare to decrement target counter
579 ldq bb|itt_entry.target_id,0 get rcvr pid
580 asa bb|used_itt use A-reg to decrement
581 stx5 bb|itt_free_list free_itt UNLOCKS free_list
582 tsx6 LOCK_x3 free_itt locks target
583 cmpq bb|apte.processid,3 compare processid
584 tnz rcvr_gone processid has changed!
585 asa bb|apte.ittes_got,3 use A-reg to decrement
586 rcvr_gone:
587 tsx6 UNLOCK_x3 free_itt unlocks target
588 free_itt_exit:
589 tra 0,7 free_itt_ exits
590
591 " ^L
592 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
593 "
594 " PRE_EMPT
595 " TIMER_RUNOUT
596 "
597 " This procedure is called at timer runout time and
598 " when a process gets pre-empted by a higher priority
599 " process. Pre-empt merely gives the processor away.
600 " Timer-runout gives up eligibility as well.
601 "
602 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
603
604 pre_empt_poll:
605 tsplb setup_mask
606 tra pre_empt.common
607
608 pre_empt:
609 stz pds$pre_empt_poll_return
610
611 tsx6 init_pxss_save_stack init x7 save stack
612 pre_empt.common:
613 tsx7 update_te
614 aos bb|te_pre_empt
615 lda bp|apte.flags
616 cana apte.idle,du Idle suffers pre-empt not timer-runout
617 tnz pmt_idle
618 lda bp|apte.temax See if time left in quantum
619 cmpa bp|apte.te
620 tmi tro_ None left give up elig
621
622 pmt_: tsx6 LOCK_bp pre-empt changes state
623 lcx0 apte.pre_empt_pending+1,du turn OFF flag
624 ansx0 bp|apte.flags ..
625 ldx0 ready,du set state to ready
626 tsx7 update_execution_state
627 tsx6 UNLOCK_bp pre-empt unlocks before getwk
628 tsx7 getwork
629 pre_empt.return:
630 szn pds$pre_empt_poll_return zero => this process entered pre-empt through connect fault
631 tze wired_fim$pre_empt_return Return from connect
632
633 " Switch back by hand, since the circumstances are peculiar.
634 " Code adapted from switch_back.
635
636 ldaq prds$+stack_header.stack_begin_ptr restore stack end ptr
637 staq prds$+stack_header.stack_end_ptr ..
638
639 ldaq pds$tc_mask restore previous mask
640 oraq channel_mask_set
641 anaq scs$open_level
642 lxl1 prds$processor_tag
643 lprpab scs$mask_ptr,1 get set for masking
644 xec scs$set_mask,1
645
646 eppsp pds$pre_empt_poll_return,* Adopt outer ring stack frame
647 stz pds$pre_empt_poll_return Au resevoir
648 epbpsb pds$stack_0_ptr,* So we can get to operators
649 short_return and return to caller of gate
650
651
652
653 pmt_idle: szn bb|wait_enable If idle make sure not shutting down
654 tnz pmt_ Idle pmt ok if multiprog
655 szn bb|system_shutdown
656 tze pmt_ Idle pmt ok if not shutdown
657 " Idles never get ring alarms
658 tra wired_fim$pre_empt_return Must not do getwork!
659
660
661 tro_: tsx6 WRITE_LOCK tro_ unthreads
662 tsx6 LOCK_bp tro_ locks apte
663 lcx0 apte.pre_empt_pending+1,du
664 ansx0 bp|apte.flags
665 tsx7 unthread tro_
666 ldx0 ready,du tro_
667 tsx7 update_execution_state tro_
668 tsx7 revoke_elig tro_
669 tsx7 reschedule tro_
670 tsx7 sort_in tro_
671 tsx7 purge_UNLOCK tro_
672 tsx7 getwork tro_
673 ldaq bp|apte.virtual_cpu_time note vtime at gain elig
674 staq pds$virtual_time_at_eligibility
675 tra pre_empt.return
676
677 " ^L
678 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
679 "
680 " stop - called by hcs_$stop_proc to stop a process
681 " stop is unusual in that it is a call side
682 " operation which must unthread and sort_in
683 " a ready non-eligible process
684 "
685 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
686
687 stop_wakeup:
688 stop:
689 tsx6 setup_
690 lda ap|2,* get processid
691 sta pds$arg_1
692 tsplb setup_check switch stacks and lock
693 arg 0,6
694 tsx6 WRITE_LOCK stop may need rethread
695
696 lda pds$validation_level get caller's ring number
697 sta tmp_ring
698
699 ldx2 0,du pre-set execution state to zero
700 tsx7 hash_LOCK stop finds and locks target
701 arg stop_returns_nul indirect if error
702
703 lda bb|default_procs_required set process to default
704 ana apte.procs_required_mask,du just in case
705 drlze pxss: APTE disdains all processors should never happen
706 era bp|apte.procs_required
707 ersa bp|apte.procs_required
708 ldx2 apte.default_procs_required,du set default flag
709 orsx2 bp|apte.flags
710
711 lxl2 bp|apte.state target's state to x2
712 cmpx2 stopped,du Compare to the stopped state
713 tze stop_returns If equal, target already stopped
714 stz dev_signal count it as dev_signal
715 aos dev_signal count it as dev_signal
716 lda =aquit put recognizable pattern in message
717 ldq =astop ... namely "quitstop"
718 staq tmp_ev_channel
719 staq tmp_ev_message pattern into channel & message
720 stc1 pds$wakeup_flag not require unique message
721 tsx7 make_itt_message now go make "quitstop" message
722
723 tsx0 setup_p_int boost priority
724 lxl0 bp|apte.state
725 cmpx0 blocked,du Blocked?
726 tze st_wake Yes, wake him.
727
728 ldx0 bp|apte.flags Eligible?
729 canx0 apte.eligible,du
730 tnz st_wake Yes, don't unthread
731 tsx7 unthread No, move up in queue
732 tsx7 sort_in_before
733
734 st_wake: tsx7 wake Awaken blocked target
735 lda apte.stop_pending,du turn on stop pending
736 orsa bp|apte.flags
737 tsx7 send_connect send connect if processor running
738 lxl2 bp|apte.state return state to caller
739 stop_returns:
740 tsx6 UNLOCK_bp
741 stop_returns_nul:
742 tsx6 UNLOCK stop is done
743 tsx7 switch_back_ret
744 stz ap|4,* return execution state
745 sxl2 ap|4,*
746 short_return
747 " ^L
748 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
749 "
750 " start - called by hcs_$start_proc to start a process
751 "
752 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
753
754 start:
755 tsx6 setup_
756 lda ap|2,* get processid
757 sta pds$arg_1
758 tsplb setup_check switch stacks and lock
759 arg 0,6
760
761 tsx6 WRITE_LOCK start must protect pid, rethreads
762 ldx2 0,du pre-set state to zero
763 tsx7 hash_LOCK Get pointer to apt entry
764 arg stop_returns_nul start: indirect if error
765 lcx0 apte.stop_pending+1,du turn off stop pending
766 ansx0 bp|apte.flags
767 " lxl0 bp|state pick up target's state
768 " cmpx0 stopped,du Compare it to stopped state
769 " tnz stop_returns If not equal, return
770 ldx0 blocked,du Otherwise redefine target state
771 tsx7 update_execution_state
772 tsx7 wake And awaken target
773 lxl2 bp|apte.state return target's state
774 tra stop_returns return
775 " ^L
776
777 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
778 "
779 " FORCE_STOP -- called to make the current process stop itself.
780 " sometimes known as I_stop.
781 "
782 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
783
784 force_stop:
785 getlp
786 tsplb setup_mask
787 aos bb|te_i_stop
788 tsx7 update_te
789 tsx6 WRITE_LOCK I_stop unthreads
790 tsx6 LOCK_bp
791 lda bp|apte.flags
792 cana apte.stop_pending,du check for stop pending
793 tze force_stop_not no, return
794 szn bp|apte.term_processid Is there a buzzard for this process?
795 drlze pxss: No term_processid NO - CRASH
796 ldaq bp|apte.alarm_time check for alarm pending
797 tze force_stop_getwork no alarm pending
798
799 eax0 bp|0 thread out of alarm list
800 cmpx0 bb|alarm_timer_list see if first on list
801 tnz is_scan
802
803 ldx2 bp|apte.alarm_time if so thread out
804 stx2 bb|alarm_timer_list
805 tra force_stop_getwork
806
807 is_scan: ldx2 bb|alarm_timer_list search list for entry
808 is_loop: cmpx0 bb|apte.alarm_time,2
809 tze is_done
810 ldx2 bb|apte.alarm_time,2
811 tra is_loop
812 is_done: ldx0 bp|apte.alarm_time thread out of list
813 stx0 bb|apte.alarm_time,2
814
815 force_stop_getwork:
816 tsx7 unthread istop
817 ldx0 stopped,du set state to stopped
818 tsx7 update_execution_state
819 tsx7 revoke_elig istop
820 tsx7 reschedule istop
821 tsx7 purge_UNLOCK istop
822 eax4 0
823 ldx0 bp|apte.ipc_pointers
824 stx4 bp|apte.ipc_pointers
825 tsx7 free_itt_
826 tsx7 getwork
827 drltra pxss: Stop returned from getwork should never get here, nohow
828
829
830 stop_return:
831 short_return
832
833 force_stop_not:
834 UNLOCK2_switch_back:
835 tsx6 UNLOCK_bp force_stop done
836 tsx6 UNLOCK force_stop done
837 tra switch_back
838 "^L
839 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
840 "
841 " set_procs_required - entry to set and reset the
842 " group of CPUs on which this process can run.
843 "
844 " call pxss$set_procs_required cpu_set code
845 " cpu_set = bit 8 aligned CPU mask
846 " "0"b => set to system default
847 " code = non-standard error code
848 " 0 => group set and now running in group
849 " ^0 => no member of group online
850 "
851 "
852 " system default is a CPU mask stored in tc_data$default_procs_required
853 " It is used for processes which have not requested explicitly
854 " CPUs required, and for those which have reset to the default.
855 " To avoid various races with reconfiguration default changing etc.,
856 " this cell should not be used or set without the global APT lock held
857 "
858 " THIS ENTRY MUST NOT BE CALLED ON THE PRDS
859 "
860 " It may, however, be called from a wired environment
861 " the reason for non-standard error codes
862 "
863 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
864
865 set_procs_required:
866 ldx0 lp|prds_link check whether we're on the prds
867 cmpx0 sb|stack_header.stack_begin_ptr already
868 drlze pxss: sprq already on prds invalid call--can't do much else
869
870 tsx6 setup_
871 ldq ap|2,* save argument in pds
872 stq pds$arg_1
873 stz ap|4,* clear error code
874 tsplb setup_check switch stacks and lock
875 arg 0,6
876 tsx6 WRITE_LOCK sprq locks out getwork and reset_proc_req
877
878 eax2 0 assume set_procs to non-default
879 ldq pds$arg_1 refetch the argument
880 anq apte.procs_required_mask,du strip out garbage
881 tnz pr_set set
882 ldq bb|default_procs_required system default
883 anq apte.procs_required_mask,du shouldn't be garbage, but ...
884 drlze pxss: APTE disdains all processors we do this, nobody's running anyway
885 eax2 1 reset to default
886 pr_set:
887 canq scs$processor is any CPU in the set online
888 tze UNLOCK_sprq_error yes--don't set, return error code
889 eaa 0,qu save group mask for check
890 tsx6 LOCK_me_bp sprq
891 erq bp|apte.procs_required set into APTE
892 anq apte.procs_required_mask,du
893 ersq bp|apte.procs_required
894
895 eax2 0,2 set to default
896 tnz set_default_flag yes
897 lcx0 apte.default_procs_required+1,du
898 ansx0 bp|apte.flags
899 tra set_reset_done
900 set_default_flag:
901 ldx0 apte.default_procs_required,du
902 orsx0 bp|apte.flags
903 set_reset_done:
904
905 "
906 " Now check to see if we're on a CPU in the group. If not
907 " go thru getwork which won't run us unless we're on such a CPU.
908 "
909 cana prds$processor_pattern
910 tnz UNLOCK2_switch_back already on one, unlock everything and return
911
912 call page$cam clear all caches if wrong cpu
913 tsx7 update_te get set for getwork
914 ldx0 ready,du
915 tsx7 update_execution_state
916 tsx6 UNLOCK_bp sprq unlock for getwk
917 tsx6 UNLOCK sprq unlocks before getwork
918 tsx7 getwork
919 eax7 0 short_return after switch back
920 tra switch_back_ret_pds
921
922 UNLOCK_sprq_error:
923 tsx6 UNLOCK
924 tsx7 switch_back_ret_pds
925 stc1 ap|4,* error code
926 short_return
927
928 " ^L
929 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
930 "
931 " EMPTY_T -- procedure to thread an APT entry into the APT
932 " free list.
933 "
934 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
935
936 empty_t:
937 tsx6 setup_
938 ldaq ap|2,* save input apt pointer
939 staq pds$arg_1
940 tsplb setup_check switch stacks and lock
941 arg 0,6
942 tsx6 WRITE_LOCK emtpty_t rethreads
943 eppbp pds$arg_1,* get pointer to desired APT entry
944 tsx6 LOCK_bp empty_t changes state
945 lxl0 bp|apte.state Check state first
946 cmpx0 empty,du Already empty OK
947 tze et_1
948 cmpx0 stopped,du Also stopped OK
949 drlnz pxss: empty_t APTE not stopped or empty
950 ldx0 empty,du
951 tsx7 update_execution_state Changed stopped to empty.
952 et_1:
953 eax7 0
954 ldx5 bp|apte.ipc_pointers claim ITTE's while locked, free later
955 stx7 bp|apte.ipc_pointers
956 stz bp|apte.ittes_sent safe to zero these since piud=0
957 stz bp|apte.ittes_got
958
959 " Return any stack_0 owned by the defunct process
960
961 lda bp|apte.flags
962 cana apte.shared_stack_0,du Is there as stack_0 to return?
963 tze check_stack_0_none No
964
965 tsx6 lock_stack_queue
966 eaa bp|0 au = apte offset
967 arl 18 al = apte offset
968 ldq -1,du comparison mask
969 lxl0 ab|sdt.num_stacks number of stack_0's
970 eax4 0 index into sdt
971 check_stack_0_loop:
972 cmk ab|sdt.aptep,4 this stack_0 belong to deadproc
973 tnz bump_next_stack_0 no
974 tsx6 free_stack_0 yes--give it up
975 ldx0 1,du
976 asx0 bb|max_max_eligible number available stack_0's
977 lca 1,dl
978 asa bb|stopped_stack_0 count of suspended stack_0's
979 tra check_stack_0_done
980 bump_next_stack_0:
981 eax4 sdte_size,4 bump sdt index
982 eax0 -1,0 one less sdte
983 tpnz check_stack_0_loop transfer if more to go
984 check_stack_0_done:
985 tsx6 unlock_stack_queue
986
987 check_stack_0_none:
988 tsx6 UNLOCK_bp
989 ldx4 bb|empty_q thread into free list
990 stx4 bp|apte.thread singly threaded
991 eax4 bp|0 get pointer to this entry
992 stx4 bb|empty_q to update into empty_q
993 tsx6 UNLOCK empty_t uses lock to protect empty_q
994 eax4 0
995 stx4 bp|apte.ipc_pointers zero itt thread in apte
996 eax0 0,5 restore old itt thread
997 tsx7 free_itt_
998 tra switch_back
999 " ^L
1000 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1001 "
1002 " UPDATE_EXECUTION_STATE -- subroutine to store the execution
1003 " state passed in x0 into the APTE pointed to by bp. The
1004 " appropriate counters in tc_data are also updated.
1005 "
1006 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1007
1008 update_execution_state:
1009 szn bp|apte.lock ASSUME bp locked
1010 drlnz pxss: APTE not locked ASSUME bp locked
1011 lda bp|apte.flags dont change meters for idle
1012 cana apte.idle,du
1013 tnz update_exec_ret
1014 lxl4 bp|apte.state get previous old state
1015 lca 1,dl
1016 asa bb|statistics,4
1017 aos bb|statistics,0
1018 "old_assume_state_change_ok
1019 update_exec_ret:
1020 sxl0 bp|apte.state
1021 read_clock " read the clock
1022 staq bp|apte.state_change_time for state change time
1023 tra 0,7
1024
1025
1026
1027 " ^L
1028 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1029 "
1030 " UNTHREAD -- procedure to thread the APT entry pointed to by
1031 " bp out of the list it is in.
1032 "
1033 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1034
1035 unthread:
1036 szn tc_data$apt_lock ASSUME write locked
1037 drlmi pxss: APT not locked ASSUME write locked
1038 szn bp|apte.thread check if not in a list
1039 tze 0,7 return if not in a list
1040 lxl4 bp|apte.thread x4 -> previous entry in list
1041 drlze pxss: unthread null back ptr ASSUME cur.bp nonzero
1042 eax0 bp|0 ASSUME prev.fp -> cur
1043 cmpx0 bb|apte.thread,4 ASSUME prev.fp -> cur
1044 drlnz pxss: unthread prev.fp ^= cur ASSUME prev.fp -> cur
1045 ldx0 bp|apte.thread x0 -> next entry in list
1046 drlze pxss: unthread null cur.fp ASSUME cur.fp nonzero
1047 stx0 bb|apte.thread,4 store old forward in previous
1048 sxl4 bb|apte.thread,0 store old back in next
1049 stz bp|apte.thread zero thread pointers
1050 tra 0,7
1051 " ^L
1052
1053 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1054 "
1055 " GET_ENTRY - returns pointer to empty entry
1056 "
1057 " On return, apte is unthreaded, unlocked, and procs_required
1058 " is set to the system default. Other fields are cleared.
1059 "
1060 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1061
1062 get_entry:
1063 tsplb setup_mask
1064 tsx6 WRITE_LOCK get_entry unthreads
1065 ldx0 bb|empty_q x0 points to first entry on list
1066 tnz available_entries ok if non-zero
1067 eppbp null,* None available
1068 tra get_entry_returns So return
1069 available_entries:
1070 lca 1,dl Decrement count of free APTE's
1071 asa bb|statistics+empty Caller must AOS new state
1072 ldx1 bb|apte.thread,0 thread entry out of free list
1073 stx1 bb|empty_q
1074 eppbp bb|0,0
1075 tsx6 LOCK_bp get_entry locks before zeroing
1076 mlr ,pr,fill0 Zero out APTE
1077 desc9a 0,0
1078 desc9a bp|0,size_of_apt_entry*4
1079 ldx0 apte.default_procs_required,du system default
1080 orsx0 bp|apte.flags
1081 lda bb|default_procs_required
1082 ana apte.procs_required_mask,du
1083 drlze pxss: APTE disdains all processors never happen
1084 sta bp|apte.procs_required
1085 tsx6 UNLOCK_bp get_entry makes apte lockable
1086 get_entry_returns:
1087 tsx6 UNLOCK get_entry done
1088 tsx7 switch_back_ret
1089 spribp ap|2,* return pointer to new APT entry
1090 short_return
1091
1092
1093 "^L
1094
1095 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1096 "
1097 " SET_WORK_CLASS -- entry to move a process from one work_class to
1098 " another. Call is:
1099 " call pxss$set_work_class processid new_wc old_wc code
1100 "
1101 " processid -bit 36 aligned specifies process INPUT
1102 " new_wc -fixed bin specifies new work class INPUT
1103 " old_wc -fixed bin previous value of work_class OUTPUT
1104 " code -fixed bin. 0=>OK, 1=>bad_processid, 2=>bad_work_class OUTPUT
1105 "
1106 " The steps are:
1107 " 1. Find apte given processid.
1108 " 2. Compute old_wc from apte.wct_index.
1109 " 3. Compute new wct_index from new_wc.
1110 " 4. If ready & not eligible move to new queue.
1111 "
1112 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1113
1114 set_work_class:
1115 tsx6 setup_
1116 lda ap|2,* get processid
1117 sta pds$arg_1
1118 lda ap|4,* get new_wc
1119 sta pds$arg_2 into wired storage.
1120
1121 tsplb setup_check switch stacks and lock
1122 arg 0,6
1123 tsx6 WRITE_LOCK set_work_class rethreads, protects pid
1124 stz pds$arg_3 Clear old_wc now.
1125 lda 1,dl Assume processid bad,
1126 sta pds$arg_4 set code to 1.
1127 tsx7 hash_LOCK
1128 arg swc_ret_nul indirect if error
1129 lda bp|apte.flags If process is idle
1130 cana apte.idle,du skip craziness.
1131 tnz swc_ret Return code = 1.
1132
1133 aos pds$arg_4 Preset code to 2, bad new_wc
1134 ldq bp|apte.wct_index Pick up old index into WCT.
1135 eax1 0,qu oldwc in X1
1136 sbq bb|min_wct_index Convert it to a number.
1137 div size_of_wct_entry,du The first wc_num is zero.
1138 stq pds$arg_3 Reurn old_wc.
1139
1140 ldq pds$arg_2 Pick up new wc number.
1141 tmi swc_ret Return code = 2, bad new_wc.
1142 mpy size_of_wct_entry,du Convert number to index.
1143 adlq bb|min_wct_index
1144 tmi swc_ret user gave us very big wc
1145 cmpq bb|max_wct_index Make sure not oob on WCT
1146 tpnz swc_ret Return code = 2, bad new_wc.
1147 lda bb|wcte.flags,qu Make sure this wc is defined.
1148 cana wcte.defined,du
1149 tze swc_ret Return code = 2, bad new_wc.
1150 stbq bp|apte.wct_index,60 OK- set new value.
1151 stz pds$arg_4 Clear code now.
1152
1153 szn bp|apte.thread Threaded in some queue?
1154 tze swc_ret No. All done.
1155 lda bp|apte.flags Yes.
1156 cana apte.eligible,du In the eligible queue?
1157 tnz swc_elig Yes. Don't mess around.
1158 tsx7 unthread Not eligible, remove from curr rdyq.
1159 lda bp|apte.ts If ts is non-zero then sort in before
1160 sta before but if ts is zero, sort in after.
1161 lda bp|apte.ti Prepare to jump into sort subr
1162 tsx7 sort_in_again which requires ti in the A.
1163 swc_ret:
1164 tsx6 UNLOCK_bp set_wc unlocks APTE
1165 swc_ret_nul:
1166 tsx6 UNLOCK set_wc unlocks
1167 lxl2 pds$arg_4 Get pseudo errcode
1168 tsx7 switch_back_ret
1169 lda pds$arg_3 Return output args to caller.
1170 sta ap|6,*
1171 xec swc_code_table,2 Load A with real errcode
1172 sta ap|8,*
1173
1174 short_return
1175
1176 swc_elig:
1177 lca 1,dl
1178 asa bb|wcte.nel,1 Reduce former wc
1179 aos bb|wcte.nel,qu Increm new
1180 tra swc_ret
1181 "
1182 "Table to map err = 0|1|2 to real but unwired error_code
1183 swc_code_table:
1184 eaa 0 No error
1185 lda error_table_$bad_processid
1186 lda error_table_$bad_work_class
1187
1188
1189
1190 "^L
1191 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1192 "
1193 " GUARANTEED_ELIGIBILITY_ON - this primitive guarantees that this
1194 " process has at least a certain minimum amount of time left in its
1195 " eligibility quantum. The primitive does not return until the process will
1196 " retain eligibility for the specified minimum time. Also if the process
1197 " loses its eligibility it is given a higher priority scheduling quaranteeing
1198 " the process some fixed percentage of an eligibility slot. The high priority
1199 " scheduling is in effect until turned off.
1200 "
1201 " GUARANTEED_ELIGIBILITY_OFF - this primitive turns off the high
1202 " priority scheduling granted by guarranteed_eligibility_on.
1203 "
1204 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1205
1206 guaranteed_eligibility_on:
1207 eppbp pds$apt_ptr,* set bp-> own apte
1208 lda apte.prior_sched,dl Turn on high priority mode
1209 orsa bp|apte.flags2
1210 lda 4,du Boost time slice
1211 asa bp|apte.temax
1212 short_return
1213
1214 guaranteed_eligibility_off:
1215 eppbp pds$apt_ptr,* set bp-> own apte
1216 lca apte.prior_sched+1,dl turn off priority scheduling
1217 ansa bp|apte.flags2 ..
1218 lda bp|apte.temax Reduce time slice if need be
1219 tmi ge_off_ret
1220 sba 4,du
1221 tpl *+2 Leave positive, tho ..
1222 lda 1000,dl
1223 sta bp|apte.temax
1224 ge_off_ret:
1225 short_return
1226 "^L
1227 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1228 "
1229 " RELINQUISH_PRIORITY
1230 "
1231 " This primitive lowers the traffic control priority of the
1232 " invoking process by moving it to the tail of the eligible queue.
1233 " This is intended for long-running ring-0 functions which operate
1234 " as background e.g. the scavenger. A long-running ring-0
1235 " function migrates to the head of the eligible queue and thereby
1236 " gains a high priority.
1237 "
1238 " call pxss$relinquish_priority
1239 "
1240 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1241
1242 relinquish_priority:
1243 tsplb setup_mask " Switch stacks and mask
1244 tsx6 WRITE_LOCK " We rethread
1245 tsx6 LOCK_bp " And change state
1246
1247 tsx7 unthread " Remove from eligible queue
1248 ldx0 ready,du
1249 tsx7 update_execution_state " Change state from running
1250 eax1 bb|eligible_q_tail " Thread to end of eligible queue
1251 tsx7 thread_him_in
1252
1253 tsx6 UNLOCK_bp
1254 tsx6 UNLOCK
1255 aos bb|relinquishes " Meter
1256 tsx7 getwork
1257 tra switch_back_pds
1258
1259 "^L
1260 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1261 "
1262 " SET_TIMER -- entry to set the per-process cpu timer.
1263 " Call is:
1264 " call pxss$set_timerdelta_t ev_channel
1265 "
1266 " dcl delta_t fixed bin 35, /* time to be added to current time.
1267 " ev_channel fixed bin 71
1268 "
1269 " If ev_channel is zero an IPS signal will be sent rather than
1270 " a wakeup.
1271 " Nothing need be locked for setting timer, provided the
1272 " time_out cell is cleared while operating. This is so getwork
1273 " will ignore the timer channel if we happen through getwork.
1274 "
1275 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1276
1277 set_timer:
1278 eppbp pds$apt_ptr,* Get ptr to own apte
1279 fld 0,dl Put zero in AQ
1280 staq pds$timer_time_out Cancel any timer
1281 ldaq ap|4,* Now safe to set channel
1282 staq pds$timer_channel
1283
1284 fld 0,dl Want two words but given one
1285 ldq ap|2,* Pick up delta_t
1286 tmoz zero_chan if delta_t <= 0 then reset
1287 tra rel_time else set relative timer
1288
1289 set_cpu_timer:
1290 eppbp pds$apt_ptr,* Get ptr to own apte
1291 fld 0,dl Cancel any timer
1292 staq pds$timer_time_out Now if we getwork we will not have timer go off
1293 ldaq ap|6,* safe to set channel now
1294 staq pds$timer_channel
1295
1296 ldaq ap|2,* Put time arg in AQ
1297
1298 lxl0 ap|4,* pick up timesw arg
1299 cmpx0 2,du Absolute timer?
1300 tze abs_time If so go do it
1301 cmpx0 1,du Relative timer?
1302 tze rel_time If so then relative
1303
1304 zero_chan:
1305 fld 0,dl resetting--timeout already zero
1306 staq pds$timer_channel
1307 short_return
1308
1309 rel_time: adaq bp|apte.virtual_cpu_time
1310 abs_time: staq pds$timer_time_out Now safe to set timeout
1311 short_return
1312 " ^L
1313 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1314 "
1315 " PXSS$LOCK_APT PXSS$UNLOCK_APT
1316 "
1317 " Externally available entries to manipulate
1318 " apt lock. Caller must be wired and masked.
1319 "
1320 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1321
1322 lock_apt: push
1323 tsx6 WRITE_LOCK Give caller protection.
1324 return
1325
1326
1327 unlock_apt:
1328 push
1329 tsx6 UNLOCK
1330 return
1331
1332 "^L
1333 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1334 "
1335 " PXSS$LOCK_APTE
1336 "
1337 " Externally available routine to lock an APTE
1338 "
1339 " call pxss$lock_apte processid aptep code
1340 "
1341 " processid is Input
1342 " aptep is set on return null if APTE not locked
1343 " code = 0 => APTE locked
1344 " ^=0 => processid invalid
1345 "
1346 " Caller must be wired and masked and real careful
1347 "
1348 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1349
1350 lock_apte:
1351 push
1352 eppbb tc_data$
1353 lda ap|2,* processid
1354 sta pds$arg_1 for hash_LOCK
1355 stc1 ap|6,* non-zero return code
1356 tsx7 hash_LOCK Try to lock APTE
1357 arg lock_apte_null Fail
1358 stz ap|6,* Succeed - zero return code
1359 lock_apte_null:
1360 spribp ap|4,* aptep
1361 return
1362
1363 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1364 "
1365 " PXSS$UNLOCK_APTE
1366 "
1367 " Externally available entry to unlock an APTE
1368 "
1369 " call pxss$unlock_apte aptep
1370 "
1371 " aptep is a pointer to the APTE to unlock
1372 " caller should still be masked and wired
1373 "
1374 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1375
1376 unlock_apte:
1377 push
1378 eppbp ap|2,* ptr to aptep
1379 eppbp bp|0,* aptep
1380 epbpbb bp|0 tc_data
1381 tsx6 UNLOCK_bp Unlock APTE
1382 return
1383 "^L
1384 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1385 "
1386 " Subroutines to lock and unlock the APT
1387 " Meaning of lock values is
1388 " +N APT is locked for single writer with caller||cpu_tag
1389 " 0 lock is busy/hidden/out_to_lunch
1390 " -1 APT is unlocked
1391 " -N+1 APT is locked for N readers
1392 "
1393 " Note that the lock value is claimed by a
1394 " primitive LDAC and restored by a primitive STA.
1395 " Note that lock_loops take special care not to
1396 " keep lock in busy state ~anti-hog hardware
1397 "
1398 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1399
1400 READ_LOCK:
1401 read_clock " setup for metering looplocks
1402 staq temp
1403 eax5 0 but assume no need to meter looplocks
1404 read_:
1405 ldac tc_data$apt_lock
1406 tpnz r_put was write locked
1407 tze read_ was busy try again
1408 sba 1,dl was unlocked or read locked
1409 sta tc_data$apt_lock one more reader
1410 rw_ret: eax5 0,5 See if looplock metering needed
1411 tze 0,6
1412 read_clock
1413 sbaq temp
1414 adaq tc_data$loop_lock_time
1415 staq tc_data$loop_lock_time
1416 aos tc_data$loop_locks
1417 tra 0,6
1418
1419 r_put: sta tc_data$apt_lock restor locks state
1420 r_wait: szn tc_data$apt_lock loop till unlocked or readlocked
1421 tmi read_ was unlocked or read locked
1422 eax5 1 force looplock metering
1423 tra r_wait was busy or write locked
1424
1425
1426 WRITE_LOCK:
1427 read_clock
1428 staq temp
1429 eax5 0
1430 write_:
1431 ldac tc_data$apt_lock
1432 cmpa unlocked_APT
1433 tnz w_fail busy or lockd for read or write
1434 eaa 0,6 lock with caller||cpunum
1435 ada prds$processor_tag
1436 sta tc_data$apt_lock
1437 tra rw_ret join looplock meter code
1438 w_fail: cmpa 0,dl if was not busy
1439 tze w_wait
1440 sta tc_data$apt_lock then restor lock value
1441 w_wait: lda unlocked_APT loop till unlocked
1442 cmpa tc_data$apt_lock
1443 tze write_
1444 eax5 1 force looplock metering/
1445 tra w_wait
1446
1447
1448 UNLOCK: ldac tc_data$apt_lock
1449 tmi unread
1450 tze UNLOCK busy so retry
1451 lda unlocked_APT was write locked so now unlock
1452 tra unlock_
1453 unread: ada 1,dl one less reader
1454 drlze pxss: unlock apt read lock bad count DEBUG somebody lostcount
1455 unlock_: sta tc_data$apt_lock
1456 tra 0,6
1457
1458
1459 WRITE_TO_READ:
1460 ldac tc_data$apt_lock
1461 tpnz w_to_r got lock
1462 tze WRITE_TO_READ
1463 drltra pxss: write_to_read bad lock count somebody lost count
1464 w_to_r:
1465 cmpa tc_data$apt_lock DEBUG
1466 drlze pxss: write_to_read ldac failed DEBUG ldac must have failed to clear
1467 lca 2,dl set lock value to one reader
1468 sta tc_data$apt_lock
1469 tra 0,6
1470
1471 unlocked_APT:
1472 dec -1
1473
1474 "^L
1475 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1476 "
1477 " APTE LOCKING PROCEDURES
1478 " apte is locked if apte.lock = 0
1479 " apte is unlocked if apte.lock ^= 0
1480 " Note that address of caller of unlock is saved in apte.lock
1481 "
1482 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1483
1484 LOCK_me_bp:
1485 eppbp pds$apt_ptr,* get ptr to own apte
1486 epbpbb bp|0 get ptr to base of tcdata
1487 LOCK_bp:
1488 sznc bp|apte.lock
1489 tnz 0,6
1490 tra LOCK_bp
1491
1492 UNLOCK_bp:
1493 szn bp|apte.lock DEBUG
1494 drlnz pxss: UNLOCK_bp not locked DEBUG
1495 stx6 bp|apte.lock Remember last unlocker
1496 tra 0,6
1497
1498 LOCK_x2:
1499 sznc bb|apte.lock,2
1500 tnz 0,6
1501 tra LOCK_x2
1502
1503 UNLOCK_x2:
1504 szn bb|apte.lock,2 DEBUG
1505 drlnz pxss: UNLOCK_X2 not locked DEBUG
1506 stx6 bb|apte.lock,2 Remember last unlocker
1507 tra 0,6
1508
1509 LOCK_x3:
1510 sznc bb|apte.lock,3
1511 tnz 0,6
1512 tra LOCK_x3
1513
1514 UNLOCK_x3:
1515 szn bb|apte.lock,3 DEBUG
1516 drlnz pxss: UNLOCK_x3 not locked DEBUG
1517 stx6 bb|apte.lock,3 Remember last unlocker
1518 tra 0,6
1519
1520 "^L
1521 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1522 "
1523 " stack switching subroutines
1524 "
1525 " A routine which holds the global traffic control lock or an
1526 " APTE lock cannot be interrupted in a way which would cause
1527 " reinvocation of pxss. For this reason, pxss must run on the
1528 " PRDS. However, most of its entries may be called from an
1529 " unwired environment. To accomplish this, arguments to pxss
1530 " are copied into wired storage in the PDS prior to any stack
1531 " switching. This copying may result in loss of control of
1532 " a CPU and reinvocation of pxss e.g. because of a page
1533 " fault, and overwriting of the PDS cells used for argument
1534 " storage. To avoid this interference, all entries of pxss
1535 " which can be called from an unwired environment adhere to
1536 " following protocol:
1537 "
1538 " tsx6 setup_
1539 "
1540 " Copy arguments to PDS and set any flags used as temporaries
1541 " in the PDS - x6 and pr0 must be preserved in this code
1542 "
1543 " tsplb setup_check
1544 " arg 0,6
1545 " Next Instruction
1546 "
1547 " On return to Next Instruction, we are running on the PRDS
1548 " with interrupts masked, and the values of all temporaries in
1549 " the PDS are guaranteed to be those set between the call to
1550 " setup_ and the call to setup_check. These values are
1551 " guaranteed to be safe until either getwork is called or one of
1552 " the routines to switch stacks back is called.
1553 "
1554 " Routines which can be called only from a wired environment
1555 " must set the cell pds$pxss_args_invalid to non-zero if they
1556 " use ANY temporaries in the PDS.
1557 "
1558 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1559 "^L
1560 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1561 "
1562 " setup_
1563 "
1564 " subroutine to mark begin of argument copy to PDS
1565 "
1566 " tsx6 setup_
1567 "
1568 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1569
1570 setup_: stz pds$pxss_args_invalid clear interference flag
1571 tra 0,6 return to next instruction
1572
1573 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1574 "
1575 " setup_check
1576 "
1577 " subroutine to check for successful copy of temporaries
1578 "
1579 " tsplb setup_check
1580 " arg <return if args must be re-copied>
1581 " <return if args copied successfully, wired and masked>
1582 "
1583 " On successful return, bp -> apte for this process
1584 " bb -> base of tc_data
1585 " ap has been saved in pds$tc_argp
1586 "
1587 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1588
1589 inhibit on <+><+><+><+><+><+><+><+><+><+><+><+><+><+><+><+><+>
1590 setup_check:
1591 sznc pds$pxss_args_invalid Did we get overwritten?
1592 tnz lb|0,* Cause err exit, get args copied again.
1593 epplb lb|1 Fix return address.
1594
1595 " Fall through to setup_mask
1596
1597 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1598 "
1599 " setup_mask
1600 "
1601 " mask to sys_level, save current mask in pds$tc_mask unless on PRDS and
1602 " switch stacks to PRDS by invoking setup
1603 "
1604 " tsplb setup_mask
1605 "
1606 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1607
1608 setup_mask:
1609 spriap pds$tc_argp
1610 eppab sp|0
1611 ldx0 lp|prds_link are we on the PRDS
1612 cmpx0 sb|stack_header.stack_begin_ptr
1613 tze easy yes - already masked - fall thru
1614 lxl1 prds$processor_tag
1615 lprpab scs$mask_ptr,1 get set for masking
1616 xec scs$read_mask,1
1617 staq pds$tc_mask THIS MUST BE WIRED!
1618 ldaq scs$sys_level
1619 xec scs$set_mask,1
1620
1621 " Fall through to setup
1622 "^L
1623 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1624 "
1625 " setup
1626 "
1627 " switch stacks to PRDS. If stacks are indeed
1628 " switched not running on PRDS already, the current stack
1629 " pointer is saved in pds$last_sp
1630 "
1631 " setup is intended to be called directly only by page control
1632 " "side doors", where it is known that we are running on
1633 " the PRDS. These "side doors" must not call any switch_back_xxx
1634 " routines, as this would re-load an interrupt mask saved elsewhere.
1635 "
1636 " tsplb setup
1637 "
1638 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1639
1640 setup:
1641 eppab sp|0 save stack pointer
1642 ldx0 lp|prds_link are we on prds ?
1643 cmpx0 sb|stack_header.stack_begin_ptr
1644 tze easy yes, easy save
1645
1646 sprisp pds$last_sp save pointer to previous stack frame
1647 eppsp prds$+stack_header.stack_begin_ptr,* get ptr to new frame
1648 epbpsb sp|0 get stack base ptr
1649 easy: push
1650 spriab sp|stack_frame.prev_sp save prev sp
1651 eppbp pds$apt_ptr,* get own apt pointer
1652 epbpbb bp|0 set bb to point at base of tc_data
1653 tsx6 init_pxss_save_stack
1654 tra lb|0 return
1655
1656 "^L
1657 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1658 "
1659 " routines to switch back to calling environment
1660 "
1661 " These routines all restore the interrupt mask to the value
1662 " saved in pds$tc_mask and the value of ap to the value
1663 " saved in pds$tc_argp
1664 "
1665 " tsx7 switch_back_xxx
1666 " Next Instruction
1667 "
1668 " switch_back_pds - return to caller of pxss on unwired stack
1669 "
1670 " switch_back - pop a stack frame, switching stacks if necessary,
1671 " return to caller of pxss
1672 "
1673 " switch_back_ret - pop a stack frame, switching stacks if necessary,
1674 " return to Next Instruction
1675 "
1676 " switch_back_ret_pds - switch to unwired stack, return to
1677 " Next Instruction
1678 "
1679 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1680
1681 switch_back_pds: "return uncond. to pds history
1682 eax7 0
1683 tra restore_sp
1684
1685 switch_back:
1686 eax7 0 flag to distinguish from switch_back_ret
1687 switch_back_ret:
1688 ldx0 lp|prds_link do we have to switch stacks
1689 cmpx0 sp|stack_frame.prev_sp ..
1690 tnz restore_sp yes, skip simple switch
1691 eppsp sp|stack_frame.prev_sp,* go back one frame
1692 tra no_change_mask and keep masked
1693 restore_sp:
1694 switch_back_ret_pds:
1695 eppsp pds$last_sp,* switch to other stack
1696 ldaq prds$+stack_header.stack_begin_ptr restore stack end ptr
1697 staq prds$+stack_header.stack_end_ptr ..
1698
1699 epbpsb sp|0
1700 ldaq pds$tc_mask restore previous mask
1701 oraq channel_mask_set
1702 anaq scs$open_level
1703 lxl1 prds$processor_tag
1704 lprpab scs$mask_ptr,1 get set for masking
1705 xec scs$set_mask,1
1706 no_change_mask:
1707 stc1 pds$pxss_args_invalid Signal possible mutual interference.
1708 eax7 0,7 check who made call
1709 tze short_ret
1710 eppap pds$tc_argp,* Get pxss arg list
1711 tra 0,7
1712
1713 inhibit off <-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->
1714
1715 init_pxss_save_stack:
1716 eaa pxss_save_stack get address of save stack base
1717 ora pxss_stack_size*64,dl set up a tally word for storing into pxss_save_stack
1718 sta pxss_stackp stash this away
1719 tra 0,6 return to caller
1720
1721
1722 subroutine_save:
1723 stx7 pxss_stackp,id store x7 in save stack using tally word
1724 ttf 0,6 return to the caller if tally not runout
1725 drltra pxss: subroutine_save stack overflow die - we have run off the save stack
1726
1727 subroutine_unsave:
1728 ldx7 pxss_stackp,di pop value of x7 also updating tally word properly
1729 tra 0,7
1730
1731 send_connect:
1732 ldq bp|apte.flags see if processor to be stopped is running
1733 canq apte.dbr_loaded,du by checking the dbr-loaded flag
1734 tze 0,7 not running, return
1735
1736 eax0 bp|0 APTE offset in X0
1737 cmpx0 pds$apt_ptr+1 is this process target of connect?
1738 tze delay_connect if so, just set ring alarm for now
1739
1740 ldq bp|apte.flags2 is running- must send cpu stop connect
1741 anq apte.pr_tag_mask,dl leave only processor tag
1742 cioc scs$cow_ptrs,ql* zap the processor
1743 tra 0,7 return to caller
1744
1745 delay_connect:
1746 lda 1,dl set ring alarm register
1747 sta pds$alarm_ring ..
1748 lra pds$alarm_ring ..
1749 tra 0,7 and return to caller
1750
1751 " ^L
1752 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1753 "
1754 " MAKE_ITT_MESSAGE
1755 "
1756 " subroutine to make a wakeup-associated message,
1757 " allocate an entry for it in the ITT, and add this entry
1758 " to the tail of this process' event queue in the APT.
1759 "
1760 " Caller must set pds$wakeup_flag to control whether non-unique
1761 " messages will be sent.
1762 "
1763 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
1764
1765 make_itt_message:
1766 " bp points to process' APT entry and must not be changed
1767
1768 bool event_channel_type_mask,040000
1769
1770 szn bp|apte.lock ASSUME bp locked
1771 drlnz pxss: APTE not locked ASSUME bp locked
1772 stz errcode we have run into no problem yet
1773
1774 lda tmp_ev_channel+1 check for special channel
1775 ana event_channel_type_mask,du mask everything but type
1776 tnz mimj2 if not, continue
1777
1778 lxl0 tmp_ev_channel+1 get special channel index
1779 lda =o400000,du get wakeup bit
1780 arl apte.chans_offset-1,0 move to correct cell
1781 ana apte.special_chans,dl change only special channels
1782 orsa bp|apte.flags2 put in APT
1783 tra 0,x7 " return
1784
1785 mimj2:
1786 ldac bb|itt_free_list Grab head
1787 tmi itt_overflows there are no more entries available
1788 tze *-2
1789
1790 eax1 0,au move head to X1
1791 " XR0 contains forward thread
1792 ldx0 bb|itt_entry.next_itt_relp,1
1793 stx0 bb|itt_free_list restor free-list-head
1794
1795 aos bb|used_itt count ITT entry usage
1796 lda tmp_ring get caller's validation ring
1797 sta bb|itt_entry.origin,1 put ring number in ITT message
1798 lda pds$processid get this process sender's ID
1799 sta bb|itt_entry.sender,1 put sender ID in ITT message
1800 eax3 0,au X3 -> sender
1801 lxl0 dev_signal get origin flag1=dev-signal
1802 tnz *+2 if not dev_signal
1803 aos bb|apte.ittes_sent,3 charge sender
1804 stx0 bb|itt_entry.origin,1 store in origin LHE
1805 aos bp|apte.ittes_got charge rcvr
1806 lda pds$arg_1 get processid of target
1807 sta bb|itt_entry.target_id,1 store target process' ID in ITT message
1808 ldaq tmp_ev_message get event message
1809 staq bb|itt_entry.message,1 put event message in ITT entry
1810 ldaq tmp_ev_channel get target event channel's name
1811 staq bb|itt_entry.channel_id,1 put channel name in ITT message, and AQ-reg
1812 " zero thread this entry will be the last
1813 stz bb|itt_entry.next_itt_relp,1
1814
1815 "
1816 "Check situation and counts to see if we allow usage of itte.
1817 stz count if count is zero there is no per channel limit
1818 eax5 0
1819 lda bb|used_itt if U < C/4 then no checks
1820 cmpa bb|cid4
1821 tmi mim_check_done
1822 lda bb|initializer_id load A-reg for mi_iz_xxx
1823 ldx0 bb|itt_entry.origin,1 dev_signals are different
1824 tnz mim_check_ds nz means dev_signal
1825 "Checks for non-dev_signal
1826 ldq bb|cid2
1827 tsx6 mm_iz_either D = C/2 or 0
1828 adq bb|cid3
1829 cmpq bb|apte.ittes_sent,3
1830 tmi unmake_message if sent > D + C/3 then REJECT
1831 cmpq bp|apte.ittes_got
1832 tmi unmake_message if got > D + C/3 then REJECT
1833
1834 sbq bb|cid3
1835 adq bb|cid2
1836 sbq bb|apte.ittes_sent,3
1837 sbq bp|apte.ittes_got
1838 tmi unmake_message if sent+got > D + C/2 then REJECT
1839
1840 ldq bb|itt_size
1841 sbq bb|used_itt
1842 sbq bb|apt_size
1843 tmi unmake_message if U > C then REJECT
1844 tra mim_check_done
1845
1846 "Checks for dev_signals
1847 mim_check_ds:
1848 ldq bb|cid4
1849 cmpq bp|apte.ittes_got if got < C/4 then OK
1850 tpl mim_check_done
1851 qls 18 else chan_limit = C/4
1852 stq count
1853 mim_check_done:
1854 " append this message to the tail of the process' event queue
1855 ldx0 bp|apte.ipc_pointers get head of process' event message queue
1856 tnz find_queue_end go follow queue to end
1857 eax0 0,1 load XR0 from XRR1
1858 stx0 bp|apte.ipc_pointers this entry is first in q
1859 tra 0,7 end of event message production
1860 find_queue_end:
1861 ldaq tmp_ev_channel event channel for compare
1862 szn pds$wakeup_flag should we insure uniqueness?
1863 tze mumloop yes - go to that loop
1864 szn count must we count wkups on chan?
1865 tnz mumloop yes - go to that loop
1866
1867 mimloop:
1868 " get forward thread from next entry
1869 ldx4 bb|itt_entry.next_itt_relp,0
1870 tze append_itt_message it is the end of the queue
1871 eax0 0,4 XR0 points to next entry
1872 tra mimloop
1873
1874 mumloop: cmpaq bb|itt_entry.channel_id,0 this chan = new?
1875 tze mum_ck
1876 mum_ok: ldx4 bb|itt_entry.next_itt_relp,0
1877 tze maybe_append_itt_message x0 -> last itte
1878 eax0 0,4
1879 tra mumloop
1880
1881 mum_ck:
1882 eax5 1,5 Another itte for this channel
1883 szn pds$wakeup_flag
1884 tnz mum_ok not unique entry, just counting
1885 ldaq tmp_ev_message is msg = new?
1886 cmpaq bb|itt_entry.message,0
1887 tnz mum_ck_ret not same - go fix AQ then loop more
1888 ldaq bb|itt_entry.origin,1 test origin,ring,target
1889 cmpaq bb|itt_entry.origin,0
1890 tze unmake_message everthing same=> dont need itte
1891 mum_ck_ret:
1892 ldaq tmp_ev_channel restor chan to AQ for compare
1893 tra mum_ok
1894
1895
1896 maybe_append_itt_message:
1897 szn count
1898 tze append_itt_message
1899 cmpx5 count
1900 tpnz unmake_message too many for this chan
1901 append_itt_message:
1902 " thread new entry to end of queue
1903 stx1 bb|itt_entry.next_itt_relp,0
1904 tra 0,7
1905
1906 unmake_message:
1907 lca 1,dl meter ITTE non-usage
1908 ldx4 bb|itt_entry.origin,1
1909 tnz um_is_ds
1910 asa bb|apte.ittes_sent,3
1911 um_is_ds: asa bp|apte.ittes_got
1912 asa bb|used_itt
1913 lda 200,dl
1914 sta errcode 200 means wakeup not sent itt_ovfl
1915
1916 ldac bb|itt_free_list give back itt_entry
1917 tnz *+2 ok -free list locked
1918 tra *-2 loop on itt_free_list lock
1919 eax0 0,au x0 -> former top free itte
1920 " put that relp in returned itte
1921 stx0 bb|itt_entry.next_itt_relp,1
1922 stx1 bb|itt_free_list
1923 tra 0,7
1924 itt_overflows:
1925 drltra pxss: ITT overflows error condition
1926 " at this point something must be done to decongest the ITT
1927 tra 0,7
1928 "
1929 "Subr called via x6 to set Q to zero if not Iz
1930 "Iz pid must be in A, Iz delta in Q, X3 must -> sender
1931 mm_iz_either:
1932 cmpa bb|apte.processid,3
1933 tze 0,6
1934 mm_iz_rcvr:
1935 cmpa bp|apte.processid
1936 tze 0,6
1937 eaq 0
1938 tra 0,6
1939 " ^L
1940 "come here for various functions during initialization
1941 pw1:
1942 eppap pds$apt_ptr,*
1943 ldac ap|apte.wait_event get wait event
1944 sta tc_data$init_event save the event
1945
1946 inhibit on <+><+><+><+><+><+><+><+><+><+><+>
1947 pi_wait:
1948 lxl1 prds$processor_tag get processor tag for masking
1949 lprpab scs$mask_ptr,1
1950 xec scs$read_mask,1 find current mask
1951 staq pds$tc_mask and save for return
1952 ldaq scs$open_level open up mask to await interrupt
1953 xec scs$set_mask,1
1954
1955 sprisp pds$last_sp save sp because we will change it to non-PRDS
1956 eppsp null,*
1957
1958 read_clock
1959 staq tc_data$init_wait_time save time of wait
1960
1961 check_pi_event:
1962 lca 1,dl for display
1963 ldq tc_data$init_event
1964 tze pi_wait_ret notify has occured
1965
1966 ldt =o200,du about 1/8 second
1967 inhibit off <-><-><-><-><-><-><-><-><->
1968 dis 0
1969 inhibit on <+><+><+><+><+><+><+><+><+>
1970
1971 szn tc_data$init_event 0 => event has occurred
1972 tze pi_wait_ret
1973 read_clock " check for notify-time-out
1974 sbaq tc_data$init_wait_time " aq = time waiting
1975 cmpaq tc_data$init_wait_timeout " more than allowed
1976 tmi check_pi_event " no -wait some more
1977
1978 pi_wait_ret:
1979 eppsp pds$last_sp,* restore stack pointer
1980 epbpsb sp|0 ..
1981 ldaq pds$tc_mask must be pwait or page_wait
1982 xec scs$set_mask,1
1983
1984 szn tc_data$init_event did we NTO
1985 tze pi_wait_ret_con no--event occurred
1986
1987 " check for possible disk polling
1988
1989 szn pds$pc_call
1990 tmi pi_wait_no_poll normal wait
1991
1992 ldaq scs$sys_level mask down for poll sake
1993 xec scs$set_mask,1
1994
1995 lxl3 disk_poll_entry get address of routine to call
1996 call lp|0,3*null_arglist make call to disk poller
1997
1998 ldaq pds$tc_mask
1999 xec scs$set_mask,1
2000
2001 szn tc_data$init_event did we NTO
2002 tze pi_wait_ret_con no--event occurred
2003
2004 pi_wait_no_poll:
2005 szn tc_data$init_timeout_severity do we want to print NTO message
2006 tmi pi_nto_no_message no
2007 szn tc_data$init_timeout_recurse are we recursing
2008 tze pi_call_syserr no
2009 pi_nto_no_message:
2010 stz tc_data$init_event just notify, don't blow the whistle
2011 tra pi_wait_ret_con
2012
2013
2014 " call syserr tc_data$init_timeout_severity "pxss: notify time out: event=^w. During init/shutdown."
2015
2016 pi_call_syserr:
2017 aos tc_data$init_timeout_recurse
2018 push
2019 epplb pds$last_sp,*
2020 sprilb pre_temp
2021 lda pds$pc_call
2022 sta pre_temp+2
2023 epplb tc_data$init_timeout_severity
2024 sprilb arg+2
2025 epplb pi_timeout_mess
2026 sprilb arg+4
2027 epplb tc_data$init_event
2028 sprilb arg+6
2029 epplb fixed_desc
2030 sprilb arg+8
2031 sprilb arg+12
2032 epplb pi_timeout_desc
2033 sprilb arg+10
2034 ldaq =v18/6,18/4,18/6,18/0
2035 staq arg
2036 call syserr$syserrarg
2037 epplb pre_temp,*
2038 sprilb pds$last_sp
2039 lda pre_temp+2
2040 sta pds$pc_call
2041 stz tc_data$init_event
2042 lca 1,dl
2043 asa tc_data$init_timeout_recurse
2044 tra pi_wait_ret_con
2045
2046 pi_timeout_mess:
2047 aci "pxss: notify time out: event=^w. During init/shutdown."
2048 equ pi_timeout_mess_words,*-pi_timeout_mess
2049 equ pi_timeout_mess_char,4*pi_timeout_mess_words
2050 pi_timeout_desc:
2051 vfd 1/1,6/21,5/0,24/pi_timeout_mess_char
2052 "^L
2053
2054 pi_wait_ret_con:
2055 eppsp pds$last_sp,* restore machine state
2056 szn pds$pc_call check if pc wait or not
2057 tze *+2 don't reset ap for page_fault
2058 eppap sp|stack_frame.operator_ptr,*
2059 tmi nwait_ret normal wait
2060 szn pds$pc_call is the a pc call?
2061 tze page_fault$wait_return no
2062 tra device_control$pwait_return
2063
2064 nwait_ret:
2065 rtcd sp|stack_frame.return_ptr
2066 inhibit off <-><-><-><-><-><-><-><-><-><->
2067 "^L
2068 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2069 "
2070 " ADDEVENT -- entry to set up event into APT entry prior
2071 " to a call to wait.
2072 " There is no need to lock anything.
2073 " Call is
2074 " call pxss$addeventevent
2075 "
2076 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2077
2078 addevent:
2079 ldq ap|2,* pick up input event
2080 tnz *+2 event must be non-zero
2081 ldq =o707070,dl so force it so
2082 szn tc_data$wait_enable during initialization ?
2083 tze pi_add yes, special code
2084 eppbp pds$apt_ptr,*
2085 stq bp|apte.wait_event store event in APT entry
2086 short_ret:
2087 short_return
2088
2089 pi_add:
2090 stq tc_data$init_event
2091 tra short_ret
2092
2093 fixed_desc:
2094 oct 404000000005
2095
2096
2097 "^L
2098 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2099 "
2100 " DELEVENT -- entry to remove interest in event.
2101 " Call is
2102 " call pxss$delevent event
2103 "
2104 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2105
2106 delevent:
2107 szn tc_data$wait_enable
2108 tze pi_notify
2109 eaa 0
2110 ldq ap|2,* pick up event
2111 eppbp pds$apt_ptr,* get ptr to own apte
2112 stacq bp|apte.wait_event
2113 short_return
2114 " ^L
2115 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2116 "
2117 " PAGE_WAIT -- special purpose entry to wait for a page.
2118 "
2119 " This entry is a combination of pxss$addevent and pxss$wait.
2120 " The argument wait event is passed in pds$arg_1.
2121 " Called by page_fault, returns to page_fault$wait_return to
2122 " restart a page fault.
2123 "
2124 " " " " " " " " " " " " " " " " " " " " " "" " " " " " " " " "
2125
2126 page_wait:
2127 stc1 pds$pxss_args_invalid Signal overwriting of temporaries.
2128 stz pds$pc_call set flag for page_wait, vs. waitp.
2129 szn tc_data$wait_enable see if during initialization
2130 tze pw1 yes, special code
2131 tsx6 init_pxss_save_stack init x7 save stack
2132 pwait: "COME FROM WAITP
2133 tsx7 update_te update times
2134
2135 tsx6 LOCK_bp -- Wait --
2136 szn bp|apte.wait_event wait?
2137 tze UNLOCK_bp_unpwait no -event may have occured
2138 ldx0 waiting,du set state to waiting
2139 tsx7 update_execution_state
2140 tsx6 UNLOCK_bp page_wait to call getwk
2141 lda apte.page_wait_flag,du set flag indicating page wait
2142 orsa bp|apte.flags set flag ON in APT entry
2143 aos bb|waits
2144 ldx0 prds$depth get depth in queue
2145 aos bb|pfdepth,0 for metering
2146 tsx7 getwork
2147 read_clock " meter time ready after notify
2148 sbaq bp|apte.state_change_time
2149 ldx0 prds$depth get depth in queue
2150 adx0 prds$depth multiply depth by 2
2151 aos bb|readytime,0
2152 asq bb|readytime+1,0
2153 unpwait:
2154 szn pds$pc_call see if page_wait or waitp
2155 tze page_fault$wait_return page_wait
2156 waitp_return:
2157 eppsp pds$last_sp,* restore pds stack history
2158 epbpsb sp|0 makes dvctl happy
2159 ldaq prds$+stack_header.stack_begin_ptr reset prds too
2160 staq prds$+stack_header.stack_end_ptr ..
2161 tra device_control$pwait_return
2162
2163 UNLOCK_bp_unpwait:
2164 tsx6 UNLOCK_bp if not waiting and APTE locked ..
2165 tra unpwait
2166 "^L
2167 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2168 "
2169 " PAGE_PAUSE
2170 "
2171 " This primitive is a combination of pause, which
2172 " causes the process to delay in ring 0 and page_wait.
2173 " It is used by page control when it must delay a page operation,
2174 " usually for defeating a covert channel.
2175 " This routine returns to page_fault$wait_return when done.
2176 "
2177 " The time to delay until is in pds$arg_1.
2178 "
2179 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2180
2181 page_pause:
2182 stc1 pds$pxss_args_invalid " overwriting temps
2183 stz pds$pc_call " indicates page_wait
2184 szn tc_data$wait_enable
2185 tze page_fault$wait_return " pxss not setup to delay
2186 tsx6 init_pxss_save_stack " init x7 save stack
2187 eppbp pds$apt_ptr,* " our apte
2188 epbpbb bp|0 " tc_data
2189
2190 tsx6 WRITE_LOCK " changing next_ring0_timer
2191 lda ring0_timer_event
2192 sta bp|apte.wait_event " we are waiting for timer
2193 ldaq pds$arg_1 " delay time
2194 cmpaq bb|next_ring0_timer
2195 tpl *+2 " timer will expire before our time
2196 staq bb|next_ring0_timer " our time comes first
2197 cmpaq bb|next_alarm_time
2198 tpl *+2
2199 staq bb|next_alarm_time " also update next system alarm
2200 tsx6 UNLOCK " done updating
2201 aos bb|pauses " meter
2202 tra pwait
2203 "^L
2204 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2205 "
2206 " PAUSE
2207 "
2208 " This primitive causes the current process to pause in ring 0.
2209 " It is used when it is necessary to delay an operation,
2210 " usually for defeating a covert channel.
2211 "
2212 " call pxss$pause delay_time;
2213 "
2214 " The delay_time is the desired wakeup time. Note, though, that
2215 " this function may return before this time, so it is necessary
2216 " for the caller to repeat the call, if necessary.
2217 "
2218 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2219
2220 pause: szn tc_data$wait_enable
2221 tnz pause.setup
2222 short_return " pxss not setup to delay
2223
2224 pause.setup:
2225 tsx6 setup_
2226 ldaq ap|2,* " desired delay til time
2227 staq pds$arg_1 " copy into wired place
2228
2229 tsplb setup_check " switch stacks & mask
2230 arg 0,6
2231
2232 tsx6 WRITE_LOCK " changing next_ring0_timer
2233 tsx6 LOCK_me_bp " rescheduling
2234 lda ring0_timer_event
2235 sta bp|apte.wait_event " we are waiting for timer
2236 ldaq pds$arg_1 " delay time
2237 cmpaq bb|next_ring0_timer
2238 tpl *+2 " timer will expire before our time
2239 staq bb|next_ring0_timer " our time comes first
2240 cmpaq bb|next_alarm_time
2241 tpl *+2
2242 staq bb|next_alarm_time " also update next system alarm
2243 aos bb|pauses " meter
2244
2245 ldx0 waiting,du
2246 tsx7 update_execution_state
2247 tsx6 UNLOCK_bp
2248 tsx7 update_te
2249 tsx6 UNLOCK
2250 tsx7 getwork " pause!
2251 tra switch_back_pds
2252 "^L
2253 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2254 "
2255 " WAITP -- General purpose entry to wait for a page control event.
2256 "
2257 " Called by device_control$pwait, we gain control
2258 " masked at sys level, wired stack, and event in pds$arg_1
2259 "
2260 " Control is returned to caller of device_control$pwait.
2261 "
2262 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2263
2264 waitp:
2265 stc1 pds$pxss_args_invalid Signal overwriting of temporaries.
2266 lda 1,dl
2267 sta pds$pc_call set switch for pds return
2268 szn tc_data$wait_enable see if in initialization
2269 tze pw1 yes, do special code
2270 tsplb setup switch stacks
2271 tra pwait
2272
2273
2274 "^L
2275
2276
2277 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2278 "
2279 " WAIT -- entry called to wait for a predictably short time.
2280 " Call is
2281 " call pxss$wait
2282 "
2283 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2284
2285 wait:
2286 szn tc_data$wait_enable in initialization ?
2287 tze w1 yes, special code
2288 tsplb setup_mask
2289 tsx6 LOCK_me_bp
2290 szn bp|apte.wait_event have we been notified yet?
2291 tze wait_not yes so return
2292 ldx0 waiting,du set state to waiting
2293 tsx7 update_execution_state
2294 tsx6 UNLOCK_bp
2295 aos bb|te_wait
2296 tsx7 update_te update times
2297 tsx7 getwork
2298 wait_returns:
2299 tra switch_back_pds return to pds stack history
2300
2301 wait_not:
2302 tsx6 UNLOCK_bp
2303 tra switch_back
2304
2305 w1: lca 1,dl get negative flag
2306 sta pds$pc_call
2307 tra pi_wait
2308 " ^L
2309 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2310 "
2311 " PAGE_NOTIFY -- special porpose entry for notifies on pages
2312 "
2313 " This entry is like notify except that an extra argument is passed.
2314 " The extra argument is the device ID of the device whose
2315 " page transfer has just completed. This is used for latency
2316 " metering.
2317 "
2318 " The event being notified is passed in pds$arg_1.
2319 " The device ID is passed in pds$arg_2
2320 "
2321 "
2322 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2323
2324 page_notify:
2325 stc1 dev_signal flag says special notify
2326 pn2: stc1 pds$pxss_args_invalid Signal overwriting of temporaries.
2327 szn tc_data$wait_enable during initialization?
2328 tze pn1 yes, special code
2329
2330 eppbb tc_data$ set ptr to base of tcdata
2331 tsx6 init_pxss_save_stack init x7 save stack
2332
2333 aos bb|page_notifies
2334 tsx6 notify_ go notify
2335 """"" lxl5 x5 restore x5
2336 tra notify_return
2337 pn1:
2338 ldq pds$arg_1 see if we are waiting for the event being notified
2339 cmpq tc_data$init_event is it what we're waiting for?
2340 tnz notify_return no, return
2341 stz tc_data$init_event yes, reset event
2342 notify_return:
2343 tra page$notify_return
2344 "^L
2345 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2346 "
2347 " NOTIFY -- entry to notify that an event has happened.
2348 " Call is
2349 " call pxss$notifyevent
2350 "
2351 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2352
2353 notify:
2354 szn tc_data$wait_enable in initialization ?
2355 tze pi_notify yes, special code
2356 tsx6 setup_
2357 ldq ap|2,* pick up event to notify
2358 tnz *+2 can't allow zero, so use 707070
2359 ldq =o707070,dl
2360 stq pds$arg_1 save in PDS
2361 tsplb setup_check switch stacks and lock
2362 arg 0,6
2363 stz dev_signal set flag for normal return
2364 aos bb|notifies
2365 "
2366 "Come here to notify event which is in pds$arg_1
2367 notify_:
2368 stx6 x5 save index 6 used by get_processor
2369 tsx6 READ_LOCK notify freezes threads
2370 eax2 bb|eligible_q_head X2 -> eligible_q_head
2371 eax5 0 USELESS NOTIFY?
2372 ldq pds$arg_1 Put event in Q-reg and stack
2373 stq tmp_event
2374 nfy_loop:
2375 ldx2 bb|apte.thread,2 go to next entry
2376 szn bb|apte.flags,2 stop at sentinel
2377 tmi nfy_ret
2378 cmpq bb|apte.wait_event,2 check current APT for same event
2379 tnz nfy_loop not equal, skip
2380 "
2381 " Fall thru here if must notify this process
2382 tsx6 LOCK_x2
2383 lcx0 apte.page_wait_flag+1,du turn off page wait flag
2384 ansx0 bb|apte.flags,2
2385 stz bb|apte.wait_event,2
2386 eax5 1,5 USELESS NOTIFY?
2387 lxl0 bb|apte.state,2 make sure dont change running state
2388 cmpx0 waiting,du
2389 tnz nfy_not_waiting not waiting, dont change state
2390 ldx0 ready,du set state to ready
2391 eppbp bb|0,2 bp must be set for update..
2392 tsx7 update_execution_state
2393 tsx6 UNLOCK_x2
2394 eax7 nfy_restor set ret addr for get_idle_processor
2395 szn bb|gp_at_notify see which flavor gp
2396 tze get_idle_processor
2397 tra get_processor
2398 nfy_restor:
2399 ldq tmp_event Restore event to Q
2400 tra nfy_loop continue scan
2401 nfy_not_waiting:
2402 tsx6 UNLOCK_x2
2403 tra nfy_restor restor back
2404 nfy_ret:
2405 eax5 0,5 USELESS NOTIFY?
2406 tnz *+3 USELESS NOTIFY?
2407 stq bb|notify_nobody_event USELESS NOTIFY?
2408 aos bb|notify_nobody_count USELESS NOTIFY?
2409 tsx6 UNLOCK notify is done
2410 ldx6 x5 restore x6
2411 szn dev_signal check return flag
2412 tnz 0,6 return to caller
2413 tra switch_back
2414
2415 pi_notify:
2416 ldq ap|2,* get event
2417 tnz *+2 if non-zero, OK
2418 ldq =o707070,dl otherwise use special coded event
2419 cmpq tc_data$init_event
2420 tnz short_ret not the right one
2421 stz tc_data$init_event
2422 short_return
2423 " ^L
2424 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2425 "
2426 " PTL_WAIT -- wait for page table lock
2427 "
2428 " special cased to avoid cluttering up page_wait even further.
2429 "
2430 " Note that the per APTE lock protects processes interest in
2431 " ptl_wait_ct. ptl_wait_ct is >= num of unlocked processes in the
2432 " ptlocking state. It is greater only temporarily, while
2433 " some process is making sure a notify is not lost.
2434 "
2435 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2436
2437 ptl_wait:
2438 stc1 pds$pxss_args_invalid
2439 stz pds$pc_call set return switch
2440 eppbb tc_data$
2441 tsx6 init_pxss_save_stack
2442
2443 ptlw_: szn sst$ptl quick check on ptl
2444 tze ptlw_ez not locked - meter and retn
2445 tsx6 LOCK_me_bp
2446 ldx0 ptlocking,du go ptlocking
2447 tsx7 update_execution_state now I cannot miss notify
2448 aos sst$ptl_wait_ct guar notify next time ptl unlocked
2449 szn sst$ptl see if still locked
2450 tze ptlw_not no - dont wait
2451 tsx6 UNLOCK_bp
2452 tsx7 update_te
2453 aos bb|ptl_waits meter these
2454 tsx7 getwork
2455 ptlw_ret: szn pds$pc_call test return switch
2456 tze page_fault$ptl_wait_return return to locking code
2457 tra waitp_return take fancy return to dvctl trylock
2458
2459 ptlw_not: lca 1,dl
2460 asa sst$ptl_wait_ct dont notify on my account
2461 ldx0 running,du like delevent ..
2462 tsx7 update_execution_state
2463 tsx6 UNLOCK_bp
2464 ptlw_ez: aos bb|ptl_not_waits meter this window
2465 tra ptlw_ret
2466
2467 dvctl_retry_ptlwait:
2468 lda 1,dl
2469 sta pds$pc_call set return switch
2470 tsplb setup
2471 tra ptlw_ join common ptlwait code
2472
2473 "^L
2474 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2475 "
2476 " PTL_NOTIFY -- notify one process that ptl is unlocked
2477 "
2478 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2479
2480 ptl_notify:
2481 stc1 pds$pxss_args_invalid
2482 eppbb tc_data$
2483 tsx6 init_pxss_save_stack
2484 tsx6 READ_LOCK ptl_notify freezes threads
2485
2486 lda bb|eligible_q_head
2487 ptln_loop:
2488 ldaq bb|apte.thread,au
2489 tra ptln_tv,ql*
2490
2491 arg ptln_ret sentinel
2492 ptln_tv: arg DRL_empty_apte empty
2493 arg ptln_loop running
2494 arg ptln_loop ready
2495 arg ptln_loop waiting
2496 arg DRL_blocked_apte blocked
2497 arg DRL_stopped_apte stopped
2498 arg ptln_found_ptlocking
2499
2500 " This is the place where jump indirects through tables come when they feel
2501 " a need to punt. We lose a few hreg entries, but not so many as a arg *,*!
2502
2503 DRL_empty_apte:
2504 drltra pxss: untenable empty APTE
2505 DRL_blocked_apte:
2506 drltra pxss: untenable blocked APTE
2507 DRL_stopped_apte:
2508 drltra pxss: untenable stopped APTE
2509
2510 ptln_found_ptlocking:
2511 szn sst$ptl is ptl actually unlocked now?
2512 tnz ptln_ret no - abort ptln
2513
2514 lxl2 bb|apte.thread,au make X2 -> ptlocking process
2515 tsx6 LOCK_x2 ptln locks to test and set state
2516 lxl0 bb|apte.state,2
2517 cmpx0 ptlocking,du
2518 tnz ptln_not_ptlocking
2519
2520 lca 1,dl
2521 asa sst$ptl_wait_ct one fewer waiting for ptl
2522 eppbp bb|0,2 set bp for ues
2523 ldx0 ready,du
2524 tsx7 update_execution_state
2525 tsx6 UNLOCK_x2
2526
2527 eax7 ptln_ret set ret addr for get_idle_processor
2528 szn bb|gp_at_ptlnotify see which flavor gp
2529 tze get_idle_processor
2530 tra get_processor
2531
2532 ptln_ret: tsx6 UNLOCK
2533 """"" lxl5 x5 ??????
2534 tra core_queue_man$ptl_notify_return
2535
2536 ptln_not_ptlocking:
2537 tsx6 UNLOCK_x2
2538 tra ptln_loop
2539
2540 "^L
2541 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2542 "
2543 " UPDATE_TE -- procedure to update the virtual cpu time used by
2544 " the running process into "te".
2545 "
2546 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2547
2548 update_te:
2549 eppbp pds$apt_ptr,* get own apt pointer
2550 epbpbb bp|0 set bb to point at base of tc_data
2551 szn pds$vtime_count
2552 tpl te_vtime_1
2553 read_clock
2554 sbaq pds$cpu_time
2555 tra te_vtime_2
2556 te_vtime_1:
2557 ldaq pds$time_v_temp
2558 te_vtime_2:
2559 sbaq pds$virtual_delta
2560 sbaq pds$virtual_time_at_eligibility
2561 stq bp|apte.te
2562 tra 0,7
2563
2564
2565
2566 " ^L
2567 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2568 "
2569 " USAGE_VALUES -- procedure to return the total page faults
2570 " for this process as well as the total cpu time this process
2571 " has been charged with.
2572 "
2573 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2574
2575 usage_values:
2576 szn tc_data$wait_enable see if during initialization
2577 tze ret_zero if so return zeros
2578 inhibit on <+><+><+><+><+><+><+><+><+><+><+><+><+><+><+><+><+>
2579 read_clock
2580 sbaq pds$cpu_time compute virtual time
2581 sbaq pds$virtual_delta convert to virtual cpu time
2582 staq ap|4,* return value
2583 ldq pds$page_waits also return page waits
2584 stq ap|2,* return value
2585 short_return
2586 inhibit off <-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><-><->
2587
2588 ret_zero:
2589 fld 0,dl zero a-q
2590 staq ap|4,* return time of zero
2591 stz ap|2,* return zero page_waits
2592 short_return
2593 "^L
2594 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2595 "
2596 " SORT_IN -- procedure to sort a process into the ready list at
2597 " the appropriate spot depending on his updated ti value.
2598 " bp must point to the APT entry for the process to be sorted
2599 " in.
2600 "
2601 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2602
2603 sort_in_before:
2604 stc1 before here to sort in before those of same ti
2605 tra *+2
2606 sort_in:
2607 stz before
2608 aos bb|schedulings
2609 ldx0 apte.interaction,du check interaction switch
2610 canx0 bp|apte.flags
2611 tze sort_no_int no interaction
2612 tsx0 setup_int boost priority
2613 lcx0 apte.interaction+1,du
2614 ansx0 bp|apte.flags turn off interaction bit
2615
2616 sort_no_int:
2617 lda bp|apte.ti
2618 cmpa bp|apte.timax must always be less than timax
2619 tmi *+2 ok, use new value
2620 lda bp|apte.timax must use max value
2621 sta bp|apte.ti
2622
2623 ldx0 bp|apte.flags
2624 canx0 apte.realtime_burst,du realtime boost
2625 tze sort_in_again no
2626 tsx0 setup_io_realtime yes
2627 tra realtime_sort
2628 sort_in_again:
2629 "old_assume_bp_not_eligible
2630 "old_assume_bp_wct_index
2631 ldx1 bp|apte.wct_index here to put in right rdy_q
2632 szn bb|wcte.realtime,1 if realtime
2633 tnz realtime_sort sort into realtime_q
2634 szn bb|deadline_mode else if not percenting
2635 tnz virtual_sort then put in interactive_q
2636 lda bb|wcte.interactive_q_word,1 See if interactive queue is
2637 cana wcte.interactive_q,du enabled for this WC
2638 tze ti_loop Not enabled
2639 "
2640 " here to sort into workclass or interactive queue by ti
2641 ti_sort: ldx4 bp|apte.ti put ti in X4 for sort
2642 tnz ti_loop sort into X1 -> wc_q
2643 szn bp|apte.ts also if ts not zero
2644 tnz ti_loop sort into X1 -> wc_q
2645 szn bb|int_q_enabled also if int_q turned off
2646 tze ti_loop sort into X1 -> wc_q
2647 eax1 bb|interactive_q else direct to tail of int_q
2648 tra thread_him_in
2649 ti_loop:
2650 ldx1 bb|apte.thread,1 chase to next
2651 szn bb|apte.sentinel,1 put before sentinel
2652 tmi thread_him_in
2653 cmpx4 bb|apte.ti,1 compare to this ti
2654 tpnz ti_loop if greater, go deeper
2655 tmi thread_him_in if less, put before
2656 szn before if equal and told to put before
2657 tnz thread_him_in then put before
2658 tra ti_loop else go deeper
2659 "
2660 " various deadline sorts follow
2661 realtime_sort:
2662 ldx0 apte.realtime_burst,du mark as realtime
2663 orsx0 bp|apte.flags
2664 eax1 bb|realtime_q here to put in realtime_q
2665 tra deadline_sort
2666 virtual_sort:
2667 eax1 bb|interactive_q int_q has vir deadlines
2668 deadline_sort:
2669 ldaq bp|apte.deadline here for general deadline sort
2670 ds_loop:
2671 ldx1 bb|apte.thread,1 chase to next
2672 szn bb|apte.sentinel,1 put before sentinel
2673 tmi thread_him_in
2674 cmpaq bb|apte.deadline,1 compare to this deadline
2675 tpl ds_loop sooner => fall thru to thread before
2676 "
2677 "Subroutine to thread unthreaded APTE at bp|0 before that at bb|0,1.
2678 "
2679 thread_him_in:
2680 szn tc_data$apt_lock ASSUME write_locked
2681 drlmi pxss: APT not locked ASSUME write_locked
2682 szn bp|apte.thread ASSUME bp_unthreaded
2683 drlnz pxss: thread_him_in already threaded ASSUME bp_unthreaded
2684 eax1 0,1 ASSUME x1_nonzero
2685 drlze pxss: thread_him_in x1 zero ASSUME x1_nonzero
2686 lxl4 bb|apte.thread,1 thread new entry in here
2687 drlze pxss: thread_him_in x4 zero ASSUME x4_nonzero
2688 cmpx1 bb|apte.thread,4 ASSUME x4->apte.fp = x1
2689 drlnz pxss: thread_him_in x4->apte.fp ^= x1 ASSUME x4->apte.fp = x1
2690 lxl0 bp|apte.state
2691 cmpx0 ready,du ASSUME apte.state = "ready"
2692 drlnz pxss: apte.state ^= ready
2693 eax0 bp|0
2694 drlze pxss: thread_him_in x0 zero ASSUME x0_nonzero
2695 sxl0 bb|apte.thread,1
2696 stx0 bb|apte.thread,4
2697 sxl4 bp|apte.thread
2698 stx1 bp|apte.thread
2699 tra 0,7
2700 " ^L
2701 " " " " " " " " " " " " " " " " " " " " " " " " " " "
2702 "
2703 " THREAD_IN_IDLE -- entry to thread an idle process into the
2704 " ready list. Called during initialization and reconfiguration.
2705 "
2706 " call pxss$thread_in_idleapt_ptr
2707 "
2708 " Where:
2709 "
2710 " apt_ptr is an its pointer to an idle process apt entry
2711 "
2712 " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2713
2714 thread_in_idle:
2715 tsx6 setup_
2716 ldaq ap|2,* save apt_ptr in PDS
2717 staq pds$arg_1
2718 tsplb setup_check switch stacks and lock
2719 arg 0,6
2720 tsx6 WRITE_LOCK thread_in_idle rethreads
2721 eppbp pds$arg_1,* get pointer to APT entry
2722 tsx7 unthread thread entry out of any list it's in
2723 ldx1 bb|eligible_q_tail
2724 tsx7 thread_him_in thread into list
2725 tsx6 UNLOCK thread_in_idle is done
2726 tra switch_back
2727 "^L
2728 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2729 "
2730 " UNTHREAD_APTE -- entry to unthread an APTE from whatever
2731 " queue it's in. Called by stop_cpu during reconfiguration.
2732 "
2733 " call pxss$unthread_apte apt_ptr
2734 "
2735 " Where:
2736 " apt_ptr is a pointer to the APTE to be unthreaded.
2737 "
2738 "
2739 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2740
2741 unthread_apte:
2742 tsx6 setup_
2743 ldaq ap|2,*
2744 staq pds$arg_1
2745 tsplb setup_check
2746 arg 0,6
2747 tsx6 WRITE_LOCK pxss$unthread_apte
2748
2749 eppbp pds$arg_1,*
2750 tsx7 unthread
2751 tsx6 UNLOCK pxss$unthread_apte
2752 tra switch_back
2753 "^L
2754 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2755 "
2756 " GET_PROCESSOR -- procedure to award a processor via
2757 " pre_emption of a lower priority process.
2758 " First check idle processes, then check eligible processes starting
2759 " with lowest priority eligible process).
2760 "
2761 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2762 "
2763 " GET_IDLE_PROCESSOR -- procedure to award a processor via
2764 " pre-emption of an idle process. This procedure should be
2765 " called instead of get_processor when the process for whom we
2766 " are pre-empting may not even be eligible yet.
2767 "
2768 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2769
2770 get_idle_processor:
2771 eax0 1 just check idle processes
2772 ldx3 bb|apte.wct_index,2 fall thru to full gp if realtime
2773 szn bb|wcte.realtime,3
2774 tze gp_init go check idle queue
2775 get_processor:
2776 eax0 2 check both idle and elig queues
2777
2778 gp_init: lda bb|apte.thread,2 pre-empting on behalf of X2
2779 sta temp save unique threads for compares
2780
2781 lda bb|apte.procs_required,2 get procs_required for process being pre-empted
2782 ana apte.procs_required_mask,du mask out all but required processors
2783 sta temp_procs_required and save in our stack
2784
2785 lda bb|idle_tail start with idle processes
2786 aos bb|gp_start_count For getwork/get_processor window
2787 "
2788 "All set up. Now for the main loop. It will be executed over the
2789 "Idle processes first. If no Idle process is running then if the
2790 "XR0 is > 1 ie: came in at get_processor entry
2791 "not get_idle_processor then the loop will be executed over the
2792 "elig processes.
2793 "
2794 gp_loop: ldaq bb|apte.thread,al go higher in queue
2795 cmpa temp is this process which was notified?
2796 tnz gp_tv,ql* no - branch on state
2797 tra gp_return yes - give up and return
2798
2799 arg check_eligible -1 => sentinel
2800 gp_tv: arg gp_loop gp found empty ok-may be idle
2801 arg gp_found_running
2802 arg gp_loop gp found ready
2803 arg gp_loop gp found waiting
2804 arg DRL_blocked_apte gp found blocked
2805 arg DRL_stopped_apte gp found stopped
2806 arg gp_loop gp found ptlocking
2807
2808 gp_found_running:
2809 lxl3 bb|apte.thread,au extract addr from next's backptr
2810 tsx6 LOCK_x3 gp locks
2811 ldq bb|apte.flags,3 grab fresh copy of flags
2812 canq apte.pre_empted,du have we pre-empted it before?
2813 tnz gp_skip yes, skip it
2814
2815 ldq bb|apte.flags2,3 get processor tag
2816 anq apte.pr_tag_mask,dl
2817 orq =o400000,du convert processor tag to bit position
2818 qrl 0,ql
2819 anq temp_procs_required is prempting process allowed to use this cpu?
2820 tze gp_skip no, skip
2821
2822 lda apte.pre_empted+apte.pre_empt_pending,du turn on pre_empted bit
2823 orsa bb|apte.flags,3
2824 ldq bb|apte.flags2,3 get processor tag
2825 anq apte.pr_tag_mask,dl
2826 cmpq prds$processor_tag this cpu?
2827 tze gp_this_cpu dont cioc if so
2828 cioc scs$cow_ptrs,ql*
2829 tsx6 UNLOCK_x3 gp unlocks
2830 tra gp_return
2831
2832 gp_this_cpu:
2833 tsx6 UNLOCK_x3 gp unlocks
2834 lda 1,dl set alarm to r1
2835 sta pds$alarm_ring
2836 lra pds$alarm_ring
2837 tra gp_return
2838
2839 gp_skip: tsx6 UNLOCK_x3
2840 tra gp_loop have not clobbered AL -> next
2841
2842 check_eligible:
2843 eax0 -1,0 need check the eligibles?
2844 tze gp_return no - return to caller
2845
2846 lda bb|eligible_q_tail now check eligibles
2847 tra gp_loop
2848 gp_return:
2849 aos bb|gp_done_count For getwork/get_processor window
2850 tra 0,7 gp ret to caller
2851 " ^L
2852 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2853 "
2854 " FIND_NEXT_ELIGIBLE -- the policy implementing part of the
2855 " scheduler. This code could be in-line in getwork but is
2856 " separated for clarity. It is entered at find_next_eligible
2857 " from getwork if no eligible process can be run. It is entered
2858 " with the traffic controller locked for multiple readers but
2859 " must run with the exclusive lock allowing rethreading and awarding
2860 " eligibility. It will return to getwork with x2 -> newly elig
2861 " or will return to find idle. In either case before returning
2862 " the lock will be changed to allow concurrency.
2863 " This code will also be entered at AWARD with the write lock set,
2864 " from the part of getwork that decides to award eligibility
2865 " to process with realtime deadlines which are past.
2866
2867 "
2868 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
2869 find_next_eligible:
2870 tsx6 UNLOCK fne must unlock read before write
2871 tsx6 WRITE_LOCK fne rethreads, awards elig
2872 "
2873 "If there are any processes which have just interacted,
2874 "we must run them immediately. So check the interactive_queue.
2875 "If we are in deadline mode the interactive queue contains most processes
2876 "and also some special conditions must be fulfilled.
2877 "
2878
2879 stz depth
2880 eax2 bb|interactive_q
2881 stz temp2 no work class restrictions so far
2882 lr_loop:
2883 ldx2 bb|apte.thread,2 step to next process.
2884 szn bb|apte.sentinel,2 If none then scan wc queues.
2885 tmi lr_wcq Look in workclass queues
2886 szn bb|deadline_mode If deadline mode make checks.
2887 tze test_award Else return this X2 to getwork.
2888
2889 ldx1 bb|apte.wct_index,2 Check if limit on n elig
2890 ldq bb|wcte.maxel,1
2891 tze lr_e_ok OK if no limit.
2892 cmpq bb|wcte.nel,1 Else compare to limit.
2893 tpnz lr_e_ok Below limit.
2894 stc1 temp2 Flag work class restriction
2895 tra lr_loop And go deeped
2896 lr_e_ok:
2897 lda bb|max_batch_elig Limit on batch?
2898 tze test_award No.
2899 lxl1 bb|apte.flags2,2 Yes.
2900 canx1 apte.batch,du Is this process batch?
2901 tze test_award No, limit doesn't matter.
2902 cmpa bb|num_batch_elig Yes, check limit.
2903 tpnz test_award OK, within limit.
2904 stc1 temp2 Flag work class restriction
2905 tra lr_loop Go deeper.
2906
2907 lr_wcq:
2908 "
2909 "Nobody found in interactive/virtual_deadline queue. We must
2910 "update the credits in each workclass before scanning the workclass queues.
2911 "
2912 szn bb|deadline_mode
2913 tze sc_loop not dmode => scatter credits
2914 stz bb|credit_bank clear cell prvents ovfl
2915 tra sc_done
2916
2917 sc_loop:
2918 lda bb|credit_bank Are there credits to scatter?
2919 tmi sc_done No.
2920 stz bb|credits_scattered None scattered yet.
2921 ldq bb|telast Credits always < 4*telast
2922 qls 2
2923 ldx1 bb|min_wct_index Start at first work class.
2924
2925 sc_wc_loop:
2926 szn bb|wcte.realtime,1 Is this wc getting some percent?
2927 tnz sc_check No, go to next wc. after clipping
2928 lda bb|wcte.minf,1 Yes, give credits.
2929 asa bb|wcte.credits,1
2930 asa bb|credits_scattered Note we scattered some.
2931 sc_check:
2932 szn bb|wcte.credits,1 don't let credits go negative
2933 tpl *+2
2934 stz bb|wcte.credits,1
2935 cmpq bb|wcte.credits,1 Make sure credits < 4*telast
2936 tpl sc_next OK.
2937 stq bb|wcte.credits,1 CREDIT SINK
2938 sc_next:
2939 eax1 size_of_wct_entry,1 Move to next work class.
2940 cmpx1 bb|max_wct_index Done all?
2941 tmoz sc_wc_loop more wc to do.
2942
2943 lca bb|credits_scattered Did we scatter any?
2944 tze sc_done No. Don't loop back!
2945 asa bb|credit_bank Yes. Bookkeep and
2946 tra sc_loop loop back to scatter more.
2947 sc_done:
2948
2949 "
2950 " Now scan the workclass queues to find the most worthy workclass
2951 " which has a non-empty queue. In this process, governing credits
2952 " are distributed to governed work classes. Any governed work
2953 " class whose governing credits are negative will not be
2954 " considered for eligibility.
2955 "
2956
2957 ldx2 -1,du Preset to none-found.
2958 ldx1 bb|min_wct_index Start at first work class.
2959 lda =o400000,du Anybody can beat this.
2960 sta bb|best_credit_value
2961
2962 eax0 -1 preset to do-not-pass-out-gv-credits
2963 szn bb|governing_credit_bank
2964 tmi fne_loop none to pass out
2965 lda bb|governing_credit_bank pass out, decrementing bank
2966 sba bb|credits_per_scatter
2967 ars 1 allow to grow to 2*credits_per_scatter
2968 cmpa bb|credits_per_scatter limit growth in the bank
2969 tmoz *+2
2970 lda bb|credits_per_scatter must be S&L
2971 als 1
2972 sta bb|governing_credit_bank
2973 eax0 0 pass-out-gv-credits
2974
2975 fne_loop:
2976 lda bb|wcte.governed_word,1 is this W.C. governed
2977 cana wcte.governed,du
2978 tze fne_not_governed No
2979 eax0 0,0 governing credits to pass out
2980 tmi fne_no_gv_credits no
2981 lda bb|wcte.maxf,1 credits for this W.C. per scatter
2982 asa bb|wcte.governing_credits,1
2983 fne_no_gv_credits:
2984 lda bb|gv_integration limit of abs value of gv credits
2985 cmpa bb|wcte.governing_credits,1
2986 tpl *+2
2987 sta bb|wcte.governing_credits,1
2988 szn bb|wcte.governing_credits,1 is this W.C. in the hole?
2989 tpl fne_not_governed no - can consider for eligibility
2990 neg 0 areg = -limit ov abs value of gv credits
2991 cmpa bb|wcte.governing_credits,1 there's a limit on the hole
2992 tmi *+2 negative but not bankrupt
2993 sta bb|wcte.governing_credits,1 minimum value
2994 cmpx1 bb|wcte.thread,1 Th to self => none ready
2995 tze fne_try_next
2996 stc1 temp2 flag work class restriction
2997 tra fne_try_next
2998
2999 fne_not_governed:
3000 cmpx1 bb|wcte.thread,1 Th to self => none rdy.
3001 tze fne_try_next
3002 szn bb|wcte.credits,1 Credits never left negative
3003 tpl *+2
3004 stz bb|wcte.credits,1 CREDIT SOURCE
3005
3006 ldx3 bb|wcte.thread,1
3007 lca bb|telast maximize credits - min ti 2*telast
3008 als 1
3009 cmg bb|apte.ti,3 deal with abs values
3010 tmi *+2
3011 lca bb|apte.ti,3
3012
3013 ada bb|wcte.credits,1
3014 cmpa bb|best_credit_value See if this is best sofar.
3015 tmi fne_try_next Wasn't, move to next.
3016
3017 sta bb|best_credit_value Was, remember value.
3018 eax2 0,3 remember the champ
3019
3020 fne_try_next:
3021 eax1 size_of_wct_entry,1 Move to next work class.
3022 cmpx1 bb|max_wct_index If any.
3023 tmoz fne_loop
3024 eax2 0,2 Neg=> nobody
3025 tpl test_award See if process fits in core.
3026 tra recheck_real Continue looking for candidate.
3027
3028 "
3029 "Come here if no processes found in int/vird queue or in
3030 "the workclass queues. We determine whether any process is present in the
3031 "realtime queue. If so such a process will be awarded eligibility subject
3032 "to the usual constraints even though its deadline has not
3033 "arrived yet.
3034 "
3035 recheck_real:
3036 ldx2 bb|realtime_q REALTIME AWARD?
3037 szn bb|apte.sentinel,2
3038 tmi fne_fail
3039 "
3040 "Arrive here with x2 pointing at a candidate for eligibility.
3041 "A few more checks are made to determine if eligibility will
3042 "actually be awarded.
3043 "
3044 test_award:
3045 lda bb|apte.flags,2
3046 cana apte.dbr_loaded,du
3047 tze *+3 dbr not loaded ok to award elig
3048 cmpx2 pds$apt_ptr+1
3049 tnz fne_fail dbr loaded ok only if this cpu
3050
3051 lxl0 bb|n_eligible get number of eligible processes
3052 cmpx0 bb|min_eligible Below min eligible?
3053 tmi award Yes, make eligible.
3054 cmpx0 bb|max_eligible At max eligible?
3055 tpl fne_fail Yes, go idle.
3056 cmpx0 bb|max_max_eligible
3057 tpl fne_fail
3058 ldq bb|ws_sum See if it fits.
3059 adq bb|apte.ws_size,2
3060 cmpq sst$nused
3061 tpl fne_fail no, go idle.
3062 "
3063 "Here to award eligibility to x2-> apte. Arrive here
3064 "either by falling through above code or directly from getwork
3065 "if a process 's realtime deadline has arrived.
3066 "
3067 award:
3068 aos bb|n_eligible increment count of eligible s
3069 lxl1 bb|apte.flags2,2 DIGS
3070 canx1 apte.batch,du
3071 tze *+2
3072 aos bb|num_batch_elig
3073 ldx1 bb|apte.wct_index,2
3074 aos bb|wcte.nel,1 and per wc count
3075 ldx0 apte.eligible,du
3076 ersx0 bb|apte.flags,2
3077 ldq bb|apte.ws_size,2 ws_sum = ws_sum + ws_size,2
3078 anq -1,dl Leave only ws estimate
3079 asq bb|ws_sum
3080 "
3081 "put the newly elig process in the proper place in elig queue
3082 "note bp is fudged for sort subr's, then reset
3083 "
3084 eppbp bb|0,2 Set bp to process of interest
3085 tsx7 unthread Remove from ready queue
3086 eax1 bb|eligible_q_tail Assume put at eltail.
3087
3088 ldx0 bb|apte.flags,2
3089 canx0 apte.realtime_burst,du Normal process?
3090 tze put_in_el_q Yes, put at tail of el queue.
3091 lcx0 apte.realtime_burst+1,du Reset flag
3092 ansx0 bb|apte.flags,2
3093
3094 ldx1 bb|eligible_q_head Could sort by deadline here
3095 stz depth Reset depth.
3096 put_in_el_q:
3097 tsx7 thread_him_in
3098 ldq AWARD_ELIGIBILITY,dl
3099 tsx7 meter_response_time$tc response transition
3100 eppbp pds$apt_ptr,* Restore bp -> old_user
3101 tsx6 LOCK_x2 Claim this apte now
3102 tsx6 WRITE_TO_READ shift lock to read before return
3103
3104 ldx1 bb|apte.wct_index,2 Determine work class.
3105 lda bb|apte.temax,2 Decrement wc credits in advance
3106 tnz *+2
3107 lda bb|process_initial_quantum Must be first time thru
3108 sta bb|apte.saved_temax,2 Save to compensate later
3109 neg
3110 asa bb|wcte.credits,1
3111 ldq bb|wcte.governed_word,1 Is wc governed
3112 canq wcte.governed,du
3113 tze *+2 No
3114 asa bb|wcte.governing_credits,1
3115 aos bb|wcte.eligibilities,1 Meter elig awarded.
3116
3117 ldq bb|apte.ts,2 see if first time since wakeup
3118 adq bb|apte.ti,2 continue with check ...
3119 tnz no_response non-zero means not first time
3120 read_clock " meter response time
3121 sbaq bb|apte.state_change_time,2 get time this process was ready
3122 adaq bb|response_time add in to total meter
3123 staq bb|response_time
3124 aos bb|response_count count number of times we added in
3125 no_response:
3126 tra gw_ck_suspend Success return from fne
3127
3128 fne_fail:
3129 tsx6 WRITE_TO_READ
3130 tra find_idle Failure return from fne
3131
3132
3133 "^L
3134 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
3135 "
3136 " GETWORK -- procedure which is invoked when the running
3137 " process is ready to give the processor to another process.
3138 " When it is invoked bb->bp must point into tc_data.
3139 "
3140 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
3141
3142 getwork:
3143 stc1 pds$pxss_args_invalid Signal overwriting of temporaries.
3144 stz pds$post_purged reset flag indicating purge is done
3145 read_clock " meter getwork time
3146 staq getwork_temp save for user being switched to
3147 sxl7 bp|apte.savex7 save x7 in APT entry
3148 aos bb|depth_count
3149 lcx0 apte.pre_empted+apte.pre_empt_pending+1,du turn off pre-empted flags
3150 ansx0 bp|apte.flags
3151
3152 gw_retry:
3153 "
3154 " The following code, checked each time through the traffic controller, checks to see
3155 " if the running processor is to be deleted. If so, it branches to the
3156 " appropriate code which ultimately DISes.
3157 " 1. Force idle process to run on this cpu.
3158 " 2. Rather than returning from getwork, transfer to DIS-ing code.
3159 "
3160 lxl1 prds$processor_tag get our own processor tag
3161 lda scs$processor_data,1 get our control word from SCS
3162 cana processor_data.delete_cpu,du
3163 tnz find_idle_for_delete
3164 "
3165 " End of reconfiguration tests
3166 "
3167 read_clock " get time in AQ for several tests
3168
3169 cmpaq bb|next_alarm_time go boost priority if time
3170 tpl alarm_timer ..
3171
3172 cmpaq bb|nto_check_time go check notify_timeouts if time
3173 tpl nto_check
3174
3175 ldx2 bb|realtime_q maybe realtime award?
3176 szn bb|apte.sentinel,2
3177 tmi gw_lock_init_loop nobody
3178 cmpaq bb|apte.deadline,2
3179 tmi gw_lock_init_loop Not yet
3180
3181 tsx6 WRITE_LOCK probable realtime award
3182 lxl0 bb|n_eligible
3183 cmpx0 bb|max_max_eligible
3184 tpl no_real
3185 ldx2 bb|realtime_q REALTIME AWARD?
3186 szn bb|apte.sentinel,2
3187 tmi no_real
3188 read_clock
3189 cmpaq bb|apte.deadline,2
3190 tmi no_real Delay him for now.
3191
3192 lda bb|apte.flags,2
3193 cana apte.dbr_loaded,du
3194 tze award dbr not loaded ok to award elig
3195 cmpx2 pds$apt_ptr+1
3196 tze award dbr loaded ok only if this cpu
3197 no_real:
3198 tsx6 WRITE_TO_READ cant make realtime elig so shift to readlock
3199 tra gw_init_loop
3200
3201 gw_lock_init_loop:
3202 tsx6 READ_LOCK
3203 gw_init_loop:
3204 lda bb|gp_done_count If gp occur we must not idle
3205 sta temp1 So we remember the count
3206 lda bb|eligible_q_head ELIGIBLE to RUN?
3207 ldx1 -1,du keep depth in X1
3208
3209 gw_loop:
3210 ldaq bb|apte.thread,au go to next entry via AU
3211 eax1 1,1 increase depth
3212 tra gw_tv,ql* dispatch on state in QL
3213
3214 arg find_next_eligible state was -1 ie sentinel
3215 gw_tv: arg DRL_empty_apte found empty
3216 arg gw_loop state was running so go deeper
3217 arg gw_found_ready
3218 arg gw_loop state was waiting so go deeper
3219 arg DRL_blocked_apte found blocked
3220 arg DRL_stopped_apte found stopped
3221 arg gw_loop found ptlocking
3222
3223
3224
3225 gw_found_ready:
3226 ldx2 bb|apte.thread,al extract ready's addr from prev's fp
3227 tsx6 LOCK_x2 gw must make sure x2 is ready etc
3228 sxl1 depth remember depth
3229 gw_ck_suspend:
3230 lda bb|tc_suspend_lock see if someone wants exclusive use of the system
3231 tze gw_ck_ready no one does, so bypass the following checks
3232 cmpa bb|apte.processid,2 is it I that wants the system?
3233 tze gw_ck_ready if so, then I get to run.
3234 lda bb|apte.flags,2 otherwise,
3235 cana apte.idle,du is this an idle process?
3236 tze gw_cant_run well, if it's not, then it can't be run
3237 gw_ck_ready:
3238 lda bb|apte.flags,2 pick up flags&state from locked apte
3239 eax0 0,al put state in X0
3240 cmpx0 ready,du really ready?
3241 tnz gw_cant_run not really ready
3242 cana apte.dbr_loaded,du Is dbr_loaded?
3243 tze gw_dbr_ok no - ok to run
3244 cmpx2 pds$apt_ptr+1 yes - Is this self?
3245 tnz gw_cant_run_dbrl not self - must not touch
3246 gw_dbr_ok:
3247 cana apte.loaded,du is this process loaded?
3248 tze load_him no, load the process
3249
3250 lda bb|apte.procs_required,2 see whether this process
3251 ana apte.procs_required_mask,du can run on this CPU
3252 ana prds$processor_pattern
3253 tnz gw_can_run OK to run
3254
3255 gw_cant_run:
3256 tsx6 UNLOCK_x2 unlock the apte
3257 lda bb|apte.thread,2 repair AU
3258 tra gw_loop go loop to next
3259 gw_cant_run_dbrl:
3260 lca 1,dl force gw retry if we idle
3261 asa temp1 by spoiling gw_gp_window test
3262 tra gw_cant_run
3263
3264 gw_can_run:
3265 "
3266 "We have decided to run this process, but will retry getwork if this
3267 "process is idle and if there has been a get_processor in progress while
3268 "we were chasing down the eligible queue. Strictly speaking, we should retry
3269 "even if the found process is not idle -- but who cares. Strictly speaking
3270 "we need not retry cannot lose a get_processor unless BOTH a process has
3271 "been readied AND a get_processor has been in progress DURING this getwork.
3272 "
3273 eppbp bb|0,2 processor addevent!
3274 ldx0 running,du mark as running
3275 tsx7 update_execution_state
3276
3277 lda bb|gp_start_count
3278 ssa temp1 temp1 is nonzero if donet0 ^= startt1
3279
3280 gw_can_really_run:
3281 tsx7 compute_virtual_clocks
3282 tsx7 set_newt calculate the time to run
3283 lxl0 depth set depth meter
3284 cmpx0 max_depth-1,du depth can't be bigger than max
3285 tmi *+2
3286 ldx0 max_depth-1,du
3287 stx0 prds$depth
3288 eppap pds$apt_ptr,* get pointer to own APT entry
3289 stz pds$number_of_pages_in_use
3290 spriap apt_ptr save pointer to last user to run
3291 eppbp bb|0,2 make bp -> our APTE
3292
3293 " " " " " " " " " " " " " " " " " " " " "
3294 " "
3295 " P R O C E S S S W I T C H I N G "
3296 " "
3297 " D O N E H E R E "
3298 " "
3299 " " " " " " " " " " " " " " " " " " " " "
3300 ldx0 lp|prds_link pick up segno of prds
3301 adlx0 lp|prds_link multiply by two add it in again
3302 sbar pds$base_addr_reg save base address reg for process
3303 ldt prds$last_timer_setting and load with new value
3304 inhibit on <+><+><+><+><+><+><+><+><+><+><+><+>
3305 ldaq dseg$+0,0 pick up prds SDW address
3306 ldbr bp|apte.dbr load the dbr
3307 staq dseg$+0,0 store prds SDW in new DSEG
3308
3309 spribp prds$apt_ptr mark process running this cpu
3310 lda prds$processor_tag set proc tag for
3311 era bp|apte.flags2
3312 ana apte.pr_tag_mask,dl
3313 tze *+2
3314 cams 4 clear cache if different cpu
3315 ersa bp|apte.flags2
3316 eppab prds$mode_reg_enabled
3317 lca mr.enable_hfp+1,dl is hex fp enabled for this process?
3318 ana prds$mode_reg
3319 szn pds$hfp_exponent_enabled
3320 tze *+2
3321 ora mr.enable_hfp,dl
3322 sta prds$mode_reg
3323 ora mr.enable_mr+mr.enable_hist,dl enable mode reg and enable hist regs
3324 sta ab|0
3325 lcpr ab|0,04
3326 inhibit off <-><-><-><-><-><-><-><-><-><-><-><->
3327
3328 lda ap|apte.flags OLD USER TO BE UNLOADED?
3329 cana apte.eligible+apte.always_loaded,du Loadedness protected?
3330 tnz dont_unload yes - skip unload
3331 cana apte.loaded,du Currently loaded?
3332 tze dont_unload no - can't unload
3333
3334 lcx0 apte.loaded+1,du turn off loaded bit
3335 ansx0 ap|apte.flags
3336
3337 lda ap|apte.asteps pick up both asteps
3338 lcq ptw.wired+1,dl set bit for turnoff
3339 ansq sst$+aste_size,au unwire one
3340 ansq sst$+aste_size,al unwire other
3341 lcq 2,dl unwired total of two pages
3342 asq sst$wired keep pc counter up to date
3343 dont_unload:
3344 "
3345 "At this point we can pass the apte.dbr_loaded bit to the new user.
3346 "This simple bit prevented anything interesting from happening
3347 "to old user from the time he left the running state until now.
3348 "Old user cannot have regained elig, except on this cpu, if it was lost.
3349 "Old user cannot be running on any other cpu.
3350 "Old user not subject to load/unload race: gw not go to load_him if dbr_loaded
3351 "If old lost elig then old not in elig_q then old not being loaded.
3352 "There is a window in the opposite direction, analogous to the gp/gw race:
3353 "Old user is HIDDEN from getwork on other cpu's. It is possible for
3354 "another cpu to go idle because this cpu has hidden old_user. This possibility
3355 "is prevented by forcing a gw_gp_window retry of getwork if
3356 "a processor is about to go idle but has seen and skipped
3357 "a ready process because that process had it dbrloaded
3358 "on another processor.
3359 "
3360 lcx0 apte.dbr_loaded+1,du turn off dbr_loaded bit for old user
3361 ansx0 ap|apte.flags
3362 ldx0 apte.dbr_loaded,du turn on dbr_loaded bit for new user
3363 orsx0 bp|apte.flags
3364
3365 tsx6 UNLOCK_bp gw unlocks new user
3366 tsx6 UNLOCK
3367
3368 stop_check:
3369 eppbp apt_ptr,* OLD USER STOPPED?
3370 lxl0 bp|apte.state check for stopped
3371 cmpx0 stopped,du
3372 tze stop_check_ jump out_of_line
3373 end_stop_check:
3374
3375 cpu_monitor_check:
3376 szn bp|apte.cpu_monitor OLD USER MONITOR TIME?
3377 tnz cpu_monitor_ maybe time now
3378 end_cpu_monitor:
3379
3380 cput_check:
3381 eppbp pds$apt_ptr,* NEW USER CPUT?
3382 lda bp|apte.flags see if idle
3383 cana apte.idle,du yes, skip timer check
3384 tnz end_cput_check ..
3385 szn pds$timer_time_out+1 see if non-zero time exists
3386 tze end_cput_check no, continue with getwork
3387 ldaq bp|apte.virtual_cpu_time see if process is over time limit
3388 cmpaq pds$timer_time_out
3389 tmi end_cput_check no, continue with getwork
3390 fld 0,dl zero the time out value
3391 staq pds$timer_time_out
3392 ldaq pds$timer_channel time up, check if ev chan is zero
3393 tnz cput_wakeup it's non-zero, need full wakeup
3394 lda sys_info$cput_mask
3395 tsx6 add_ips_message use stacq
3396 tra end_cput_check
3397 cput_wakeup:
3398 stz tmp_ring set up for call to 'make_itt_message'
3399 stz dev_signal count it as dev_signal
3400 aos dev_signal count it as dev_signal
3401 lda =acput ev message is 'cputimer'
3402 ldq =aimer
3403 staq tmp_ev_message save in stack
3404 ldaq pds$timer_channel copy ev channel into stack
3405 staq tmp_ev_channel
3406 lda bp|apte.processid copy processid for make_itt_message
3407 sta pds$arg_1
3408 stc1 pds$wakeup_flag not require unique message
3409 tsx6 LOCK_bp cput_wakeup protects event thread
3410 tsx7 make_itt_message
3411 lda apte.wakeup_waiting,du Cheap wakeup of self
3412 orsa bp|apte.flags
3413 tsx6 UNLOCK_bp cput_wakeup is done
3414 end_cput_check:
3415
3416 lda bp|apte.flags check stop or ips pending
3417 ana apte.stop_pending,du
3418 ora bp|apte.ips_message see if an ips signal must be sent
3419 tze no_more_pending no, skip over SMIC
3420 lda 1,dl set ring alarm for exit from ring 0
3421 sta pds$alarm_ring
3422 no_more_pending:
3423
3424 lbar pds$base_addr_reg get base address reg for new process
3425 lra pds$alarm_ring get his ralr setting too
3426
3427 ldaq prds$last_recorded_time calc this process's CPU time
3428 sbaq bp|apte.time_used_clock fudge it for easy calc later
3429 staq pds$cpu_time save in the PDS for the process
3430
3431 read_clock " meter rest of getwork time
3432 sbaq getwork_temp set on entry to getwork by 'old_user'
3433 adaq bb|getwork_time keep running total
3434 staq bb|getwork_time
3435 aos bb|getwork_time+2 keep count of getworks
3436 eppbp pds$apt_ptr,* set bp to apt entry
3437 "
3438 " Still masked and wired, check for need to allocate a stack_0
3439 " and if needed do so.
3440
3441 szn pds$stack_0_sdwp,*
3442 tnz already_got_stack_0 Doin' fine, no problem.
3443
3444 tsx6 lock_stack_queue
3445 ldx0 ab|sdt.freep
3446 drlze pxss: no available stack_0 A fine time to run out of stacks.
3447 ldx4 ab|sdte.nextp,0 Thread out.
3448 stx4 ab|sdt.freep
3449 eax4 0
3450 stx4 ab|sdte.nextp,0 Clean thread
3451 eax2 bp|0
3452 sxl2 ab|sdte.aptep,0 For debugging.
3453 ldaq ab|sdte.sdw,0
3454 staq pds$stack_0_sdwp,* Store the SDW in DSEG.
3455 cams 4 Clear cache. Think about it.
3456 "cams 0 not needed, did ldbr since last stack_0.
3457 tsx6 unlock_stack_queue
3458 lda apte.shared_stack_0,du Flag stack to be returned
3459 orsa bp|apte.flags
3460 already_got_stack_0:
3461
3462 lda bp|apte.flags Load flags once again
3463 cana apte.firstsw+apte.idle,du First time & ^idle ?
3464 tze stproc is first time. do special return
3465 "
3466 cana apte.idle,du idle process?
3467 tze no_idle_no_del if not, don't do next check
3468 lxl1 prds$processor_tag get CPU tag
3469 lda scs$processor_data,1 look at data for this CPU
3470 cana processor_data.delete_cpu,du to be deleted?
3471 tnz delete_me if so, stop it now
3472 szn temp1 before going idle, see if there was interference
3473 tze no_idle_no_del was none, ok to idle
3474 lda 1,dl
3475 sta pds$alarm_ring set ring_alarm to remind idle to come back
3476 lda apte.pre_empt_pending,du
3477 orsa bp|apte.flags
3478 aos bb|gw_gp_window_count meter these
3479 no_idle_no_del:
3480
3481 lxl7 bp|apte.savex7 restore x7 for return
3482 tra 0,7
3483
3484 stproc: lda apte.firstsw,du turn ON flag saying we're initialized
3485 orsa bp|apte.flags
3486 lda bb|process_initial_quantum Give special quantum first time
3487 sta bp|apte.temax put initial quantum in APTE
3488 "
3489 "Unlock,switch stacks, restore mask, and perform special first time call.
3490 "
3491 eppsp pds$last_sp,*
3492 ldaq sb|stack_header.stack_begin_ptr Truncate PRDS.
3493 staq sb|stack_header.stack_end_ptr
3494 epbpsb sp|0
3495 lda bp|apte.processid
3496 cmpa tc_data$initializer_id Is this the initializer?
3497 tze dont_reset_stack_0
3498 ldaq sb|stack_header.stack_begin_ptr Clean out any old crud
3499 staq sb|stack_header.stack_end_ptr
3500 dont_reset_stack_0:
3501 inhibit on <+><+><+><+><+><+><+><+><+><+><+><+>
3502 ldaq scs$open_level
3503 lxl1 prds$processor_tag
3504 lprpab scs$mask_ptr,1
3505 xec scs$set_mask,1
3506 inhibit off <-><-><-><-><-><-><-><-><-><-><-><->
3507 eppap =its-11,*
3508 eppbp pds$initial_procedure
3509 rtcd bp|0
3510
3511
3512
3513
3514 " ^L
3515 "
3516 " NTO_CHECK -- This code checks for lost notifies.
3517 " Salient features include:
3518 " 1. It is executed every nto_delta microsec.
3519 " 2. It is entered with no locks set.
3520 " 3. It looks for processes unchanged for > nto_delta.
3521 " 4. If one is found it is notified, metered, and johndeaned.
3522 " 5. If none, the time of the next check is set.
3523 " 6. It returns to gw_retry with no locks set.
3524 nto_check:
3525 tsx6 READ_LOCK
3526 eax2 bb|eligible_q_head
3527 nto_loop: ldx2 bb|apte.thread,2 step to next process
3528 szn bb|apte.sentinel,2
3529 tmi nto_reset_time have done them all, all done
3530 tsx6 LOCK_x2 no need for speed here
3531 lxl0 bb|apte.state,2 only ptlwaiters get nto'd
3532 cmpx0 waiting,du waiter?
3533 tze nto_wait this one is waiting now
3534 cmpx0 ptlocking,du waiter on PTL?
3535 tnz nto_not no
3536 lda =aptlw yes, fake the event
3537 sta bb|apte.wait_event,2
3538 tra nto_wait now go notify
3539
3540 nto_not: tsx6 UNLOCK_x2 not waiting
3541 tra nto_loop so go to next
3542
3543 nto_wait: ldaq bb|apte.state_change_time,2
3544 adl bb|nto_delta
3545 cmpaq getwork_temp State change more than nto_delta ago?
3546 tpl nto_not No, go to next
3547
3548 aos bb|nto_count meter notify timeouts
3549 ldac bb|apte.wait_event,2 Yes, reset state
3550 sta tmp_event
3551 sta bb|nto_event
3552 lda bb|apte.processid,2
3553 sta temp1
3554 lcx0 apte.page_wait_flag+1,du
3555 ansx0 bb|apte.flags,2
3556 ldx0 ready,du
3557 eppbp bb|0,2
3558 tsx7 update_execution_state
3559 tsx6 UNLOCK_x2
3560 tsx7 get_processor
3561 szn bb|time_out_severity negative means dont print
3562 tmi nto_loop can continue looping
3563 tsx6 UNLOCK don't call out with lock set
3564 "
3565 " call syserr tc_data|time_out_severity"pxss: notify time out: event=^w pid=^w"
3566 " apte.wait_event apte.processid
3567 "
3568 epplb bb|time_out_severity
3569 sprilb arg+2
3570 epplb nto_message
3571 sprilb arg+4
3572 epplb tmp_event
3573 sprilb arg+6
3574 epplb temp1
3575 sprilb arg+8
3576 epplb fixed_desc
3577 sprilb arg+10
3578 sprilb arg+14
3579 sprilb arg+16
3580 epplb nto_message_desc
3581 sprilb arg+12
3582 ldaq =v18/8,18/4,18/8,18/0
3583 staq arg
3584 call syserr$syserrarg
3585 tra gw_retry nto_check returns with no lock set
3586 "
3587 "Come here when scan of eligible queue has found no nto's.
3588 nto_reset_time:
3589 read_clock
3590 adl bb|nto_delta
3591 staq bb|nto_check_time
3592 tsx6 UNLOCK nto_check returns with no lock set
3593 tra gw_retry
3594 nto_message_desc:
3595 oct 524000000047
3596 nto_message:
3597 aci "pxss: notify time out: event=^w, pid=^w"
3598
3599 "^L
3600 load_him: cana apte.being_loaded,du see if we must load him
3601 tnz gw_cant_run sombody already loading this process
3602
3603 lda apte.being_loaded,du turn on being loaded flag
3604 orsa bb|apte.flags,2
3605 tsx6 UNLOCK_x2
3606 tsx6 UNLOCK
3607 eppap apt_ptr
3608 spriap arg+2
3609 eppap bb|0,2
3610 spriap apt_ptr
3611 fld =1b24,dl
3612 staq arg
3613 call wired_plm$loadarg load the process
3614 tsx6 LOCK_x2
3615 eppbp bb|0,2 set bp to this entry
3616 lda bp|apte.wait_event should we wait for the loading to complete ?
3617 tze loaded_test no, loading may be complete
3618 lda apte.page_wait_flag,du
3619 orsa bp|apte.flags
3620 ldx0 waiting,du -- Wait --
3621 tsx7 update_execution_state
3622 tra load_him_done start over
3623 " must verify loading with APTE locked
3624 loaded_test:
3625 lda bp|apte.asteps Get both asteps in Areg
3626 ldq ptw.wired+ptw.valid,dl Get mask in Qreg
3627 anq sst$+aste_size,au Require this page
3628 anq sst$+aste_size,al AND that page
3629 cmpq ptw.wired+ptw.valid,dl have required bits on.
3630 tnz load_him_done Didn't, must retry getwork.
3631 lda apte.loaded,du turn loaded flag on
3632 orsa bb|apte.flags,2
3633 aos bb|loadings
3634 load_him_done:
3635 lcx0 apte.being_loaded+1,du Turn off being loading bit
3636 ansx0 bp|apte.flags
3637 tsx6 UNLOCK_x2
3638 tra gw_retry load_him retries getwork from the top
3639
3640 find_idle_for_delete:
3641 tsx6 READ_LOCK
3642 find_idle:
3643 ldx2 prds$idle_ptr+1
3644 tsx6 LOCK_x2
3645 stz bb|apte.te,2 zero idle's te
3646 tra gw_can_run
3647 "^L
3648 " This section of code is invoked when a simulated alarm
3649 " clock interrupt is detected. Metering is kept of the lag of
3650 " the simulated timer from when it should really gone off.
3651
3652 alarm_timer:
3653 tsx6 WRITE_LOCK alarm timer
3654 at_retry:
3655 read_clock
3656 sbaq bb|next_alarm_time compute lag in simulated timer
3657 tpnz at_now
3658 tsx6 UNLOCK false alarm
3659 tra gw_retry
3660
3661 at_now:
3662 aos bb|clock_simulations count number of clock simulations
3663 cmpq bb|max_clock_lag keep maximum lag
3664 tmi *+2 ..
3665 stq bb|max_clock_lag ..
3666 adaq bb|total_clock_lag add to total
3667 staq bb|total_clock_lag ..
3668 read_clock " remember clock time
3669 staq bb|next_alarm_time ..
3670
3671 " The following code checks to see if a process timer should have
3672 " gone off.
3673
3674 next_timer:
3675 ldx2 bb|alarm_timer_list get next process on timer list
3676 tze priority_scheduling no one is on list
3677 eppbp bb|0,2 set APT pointer
3678 ldaq bp|apte.alarm_time when should process timer go off
3679 ana =o777777,dl mask off thread
3680 cmpaq bb|next_alarm_time has time passed
3681 tpl priority_scheduling if not then we are done here
3682 ldx3 bp|apte.alarm_time unthread from list
3683 stx3 bb|alarm_timer_list
3684 fld 0,dl zero out time
3685 staq bp|apte.alarm_time ..
3686 lxl3 bp|apte.state make sure process is alive
3687 cmpx3 stopped,du ..
3688 tze next_timer if process dead, forget it
3689 tsx6 LOCK_bp wakup alrm
3690 ldaq bp|apte.alarm_event get event channel
3691 tnz wakeup_alarm if channel then go wakeup
3692 lda sys_info$alrm_mask
3693 tsx6 add_ips_message
3694 tsx7 send_connect send connect if running
3695 tra at_wake
3696 wakeup_alarm:
3697 stz tmp_ring send wakeup
3698 stz dev_signal count it as dev_signal
3699 aos dev_signal count it as dev_signal
3700 lda =aseta event message is setalarm
3701 ldq =alarm ..
3702 staq tmp_ev_message save in stack
3703 ldaq bp|apte.alarm_event get event channel
3704 staq tmp_ev_channel save in stack
3705 lda bp|apte.processid copy process id for ITT message
3706 sta pds$arg_1 ..
3707 stc1 pds$wakeup_flag not require unique message
3708 tsx7 make_itt_message create wakeup message
3709 at_wake: tsx7 wake wake up process
3710 tsx6 UNLOCK_bp wakup alrm
3711 tra next_timer see if more timers to go off
3712
3713 " Now we check to see if there are any priority scheduling processes
3714 " that must have their priority boosted.
3715
3716 priority_scheduling:
3717 ldaq bb|next_alarm_time see if any processes need boosting
3718 cmpaq bb|priority_sched_time ..
3719 tmi check_ring0_timer no processes need boosting
3720 ldaq bb|end_of_time_loc set time to high value
3721 staq bb|priority_sched_time
3722 ldx2 bb|min_wct_index begin search of ready lists
3723
3724 ps_get_rq_head:
3725 ldx2 bb|wcte.thread,2 get index of top guy in ready queue
3726 ps1: eppbp bb|0,2 get pointer to next entry in ready list
3727 szn bp|apte.sentinel stop if end of ready list
3728 tmi ps_next_ready_queue Now at sentinel, x2-> wcte again
3729 ldx2 bp|apte.thread save index to next before rethreading!
3730 lda bp|apte.flags2 is process in priority sched mode
3731 cana apte.prior_sched,dl ..
3732 tze ps1 if not then go to next entry
3733 ldaq bp|apte.state_change_time get time lost eligibility
3734 adl bb|priority_sched_inc add in increment for rescheduling
3735 cmpaq bb|next_alarm_time ..
3736 tmi ps_boost ..
3737 cmpaq bb|priority_sched_time see if this is next process to be boosted
3738 tpl ps1 if not then go to next entry
3739 staq bb|priority_sched_time if so then remember time
3740 tra ps1 go to next entry
3741 ps_boost:
3742 szn bp|apte.ti already interactive?
3743 tze ps1 don't boost again, and avoid tail chasing
3744 tsx0 setup_p_int boost priority
3745 tsx7 unthread thread out of ready list
3746 tsx7 sort_in sort into ready list in new place
3747 aos bb|boost_priority count number of boosts
3748 tra ps1 go to next entry
3749 ps_next_ready_queue:
3750 eax2 size_of_wct_entry,2 Move to next wcte
3751 cmpx2 bb|max_wct_index If If there is one.
3752 tmoz ps_get_rq_head
3753 "^L
3754 check_ring0_timer:
3755 ldaq bb|next_ring0_timer
3756 cmpaq bb|next_alarm_time
3757 tpl check_polling
3758
3759 ldaq bb|end_of_time_loc don't allow this again
3760 staq bb|next_ring0_timer
3761
3762 " wake up any ring 0 process waiting for a short time
3763
3764 tsx6 UNLOCK unlock for notify
3765 ldq ring0_timer_event
3766 stq pds$arg_1
3767 stc1 dev_signal flag says special notify
3768 tsx6 notify_ notify waiters
3769 tsx6 WRITE_LOCK return to polling checks
3770
3771 " Now we check to see if the disk DIM or tty DIM need
3772 " to be polled.
3773
3774 check_polling:
3775 eax4 n_polling_table-4 initialize index for table search
3776 polling_loop:
3777 xec polling_table+2,4 execute before test
3778 test_poll:
3779 ldaq bb|next_alarm_time get time for this alarm
3780 ldx3 polling_table,4 get address of link to time
3781 cmpaq lp|0,3* has time matured?
3782 tmi skip_polling if not, skip this call
3783
3784 adl polling_table+1,4 compute time of next poll
3785 staq lp|0,3* and set new time
3786
3787 tsx6 UNLOCK call out with APT unlocked
3788 lxl3 polling_table,4 get address of routine to call
3789 call lp|0,3*null_arglist make call
3790 tsx6 WRITE_LOCK relock the APT now
3791 tra next_poll on to the next
3792
3793 skip_polling:
3794 xec polling_table+3,4 execute after test
3795 next_poll:
3796 eax4 -4,4 step to next table entry
3797 tpl polling_loop and loop
3798
3799 " Now we compute the next simulated alarm clock time.
3800
3801 compute_next_alarm:
3802 ldx2 bb|alarm_timer_list get next process timer
3803 tze *+5 no process timer
3804 ldaq bb|apte.alarm_time,2 ..
3805 ana =o777777,dl mask off thread
3806 cmpaq bb|priority_sched_time is it before priority sched time
3807 tmi *+2
3808 ldaq bb|priority_sched_time if sched time first use it
3809 cmpaq bb|next_ring0_timer how about ring0 timers?
3810 tmi *+2
3811 ldaq bb|next_ring0_timer
3812
3813 eax4 n_polling_table-4 initialize index for table search
3814 next_alarm_loop:
3815 ldx3 polling_table,4 get pointer to time
3816 cmpaq lp|0,3* test for earliest time
3817 tmi *+2 ..
3818 ldaq lp|0,3* ..
3819
3820 eax4 -4,4 try next table entry
3821 tpl next_alarm_loop ..
3822
3823 staq bb|next_alarm_time set time for next alarm
3824 tra at_retry go check time again
3825
3826 even
3827 null_arglist:
3828 oct 4,0 arglist with no args
3829
3830 polling_table:
3831 disk_poll_entry:
3832 link disk_polling_time,tc_data$disk_polling_time
3833 link disk_poll,page$time_out
3834 zero disk_polling_time,disk_poll
3835 dec 15b15
3836 nop
3837 nop
3838
3839 link ioi_polling_time,tc_data$tape_polling_time
3840 link ioi_poll,ioi_masked$timer
3841 zero ioi_polling_time,ioi_poll
3842 dec 16b15
3843 nop
3844 nop
3845
3846 link mos_polling_time,tc_data$mos_polling_time
3847 link mos_poll,mos_memory_check$poll
3848 zero mos_polling_time,mos_poll
3849 dec 600b15
3850 nop
3851 nop
3852
3853 link opc_polling_time,tc_data$opc_polling_time
3854 link opc_poll,ocdcm_$poll_for_timeout
3855 zero opc_polling_time,opc_poll
3856 dec 30b15
3857 nop
3858 nop
3859
3860 link volmap_poll_time,tc_data$volmap_polling_time
3861 link volmap_poll,page$poll_volmap_io
3862 zero volmap_poll_time,volmap_poll
3863 dec 30b15
3864 nop
3865 nop
3866
3867 equ n_polling_table,*-polling_table
3868 " ^L
3869 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "" " "
3870 "
3871 " COMPUTE_VIRTUAL_CLOCKS -- procedure to figure out what type of
3872 " idle time we have, and also to update the time used in the
3873 " APT entry for the process just run.
3874 " A meter lock protects per-system doubleword variables
3875 "
3876 " Idle time is categorized as follows:
3877 "
3878 " zero idle - all processes blocked except idle processes
3879 " nmp idle - all processes which could be eligible are eligible
3880 " loading idle - not all processes which could be eligible are
3881 " eligible, and not all eligible processes are loaded
3882 " work class idle - not all processes which could be eligible are
3883 " eligible, at least one work class was
3884 " skipped because of work class limits
3885 " governing max eligible for work class,
3886 " and system maxe has not been reached
3887 " mp idle - not all processes which could be eligible are
3888 " eligible, and criteria for work class idle
3889 " not met
3890 "
3891 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
3892
3893 compute_virtual_clocks:
3894 eppbp pds$apt_ptr,* set bp to this process
3895 lda pds$page_waits copy page fault count into APT entry
3896 sta bp|apte.page_faults
3897 ldaq bp|apte.virtual_cpu_time Remember bp's vcpu
3898 staq temp Use temp for delta virtual time.
3899
3900 read_clock
3901 staq bb|last_time save last time anyone run
3902 sbaq prds$last_recorded_time delta t in microseconds
3903 staq delta_t
3904 asq bb|governing_credit_bank
3905
3906 adaq bp|apte.time_used_clock update time used in APT
3907 staq bp|apte.time_used_clock
3908 sbaq pds$virtual_delta update the virtual CPU time
3909 staq bp|apte.virtual_cpu_time
3910
3911 sbaq temp Subtract old vcpu from new
3912 staq temp Remember for idle meters.
3913
3914 ldaq delta_t meter last recorded time
3915 adaq prds$last_recorded_time
3916 staq prds$last_recorded_time
3917
3918 mlock_loop:
3919 ldac bb|metering_lock LOCK LOCK LOCK LOCK LOCK LOCK LOCK
3920 tnz mlocked OK- meters are locked
3921 tra mlock_loop retry locking meters
3922 mlocked:
3923 ldaq delta_t meter total CPU time for system
3924 adaq bb|processor_time
3925 staq bb|processor_time
3926
3927 ldaq prds$last_recorded_time compute ave queue length
3928 anq =o3777777 sample every sec 2**20 usec
3929 adq delta_t+1
3930 qrl 20-18 convert to sec
3931 agl: eaq -1,qu count seconds
3932 tmi age
3933 lda bb|statistics+running get queue length
3934 ada bb|statistics+ready
3935 ada bb|statistics+waiting running+ready+waiting
3936 als 18 give answer 6 octal points
3937 sba bb|avequeue new ave=oldave+cur-oldave/64
3938 ars 6
3939 asa bb|avequeue
3940 lda bb|n_eligible now get average eligible
3941 als 18
3942 sba bb|ave_eligible
3943 ars 6
3944 asa bb|ave_eligible
3945 tra agl
3946
3947 age:
3948
3949 lda bp|apte.flags check for idle process
3950 cana apte.idle,du
3951 tnz cvidle is
3952
3953 ldx0 prds$depth count runs at depth
3954 aos bb|depths,0
3955 adx0 prds$depth double index
3956 ldaq delta_t bump time at level
3957 adaq bb|tdepth,0
3958 staq bb|tdepth,0
3959
3960 ldaq temp Update vcpu used by nonidle
3961 adaq bb|system_virtual_time
3962 staq bb|system_virtual_time
3963
3964 ldx0 bp|apte.wct_index Update work_class data.
3965 ldaq delta_t Workclasses get % of tcpu - not vcpu
3966 szn bb|wcte.realtime,0 Realtime not add to bank.
3967 tnz *+2
3968 asq bb|credit_bank But others do.
3969
3970 adaq bb|wcte.cpu_sum,0 Add to time gotten
3971 staq bb|wcte.cpu_sum,0
3972 lcq delta_t+1 Decrement credits.
3973 asq bb|wcte.credits,0
3974 lda bb|wcte.governed_word,0 Is W.C. governed
3975 cana wcte.governed,du
3976 tze m_unlock no
3977 asq bb|wcte.governing_credits,0
3978 tra m_unlock Now go unlock metering data.
3979
3980 cvidle: ldaq temp up total idle vcpu
3981 adaq bb|idle_time
3982 staq bb|idle_time
3983
3984 ldaq delta_t Update idle real cpu time.
3985 adaq bb|gross_idle_time
3986 staq bb|gross_idle_time
3987
3988 ldaq temp up idle vcpu by type
3989 ldx0 bp|apte.term_processid recall our idle type
3990 tze m_unlock ignore first time
3991 adaq bb|0,0
3992 staq bb|0,0
3993
3994 m_unlock: stc1 bb|metering_lock UNLOCK UNLOCK UNLOCK UNLOCK UNLOCK
3995 cvidt: lda bb|apte.flags,2 Is new guy idle?
3996 cana apte.idle,du
3997 tze 0,7 no, not idle
3998 eax0 zero_idle yes, figure type
3999 lda bb|statistics+running
4000 ada bb|statistics+ready
4001 ada bb|statistics+waiting
4002 ada bb|statistics+ptlocking
4003 tze cvst Will be zero_idle
4004 eax0 nmp_idle
4005 cmpa bb|n_eligible
4006 tze cvst Will be NMP idle
4007 eax0 loading_idle
4008 lxl1 bb|eligible_q_tail
4009 ldx1 bb|apte.flags,1
4010 canx1 apte.loaded,du
4011 tze cvst Will be Loading idle
4012 eax0 mp_idle
4013 szn temp2 Work class limit reached?
4014 tze cvst No, will be MP idle
4015 lxl1 bb|n_eligible Are we at system max eligible?
4016 cmpx1 bb|max_eligible
4017 tpl cvst Yes, will be MP idle
4018 eax0 work_class_idle No, will be work class idle
4019 cvst: stx0 bb|apte.term_processid,2 Remember idle type.
4020 tra 0,7
4021 " ^L
4022 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4023 "
4024 " SET_NEWT -- procedure to figure out how long the new process
4025 " should run.
4026 "
4027 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4028
4029 set_newt:
4030 lda bb|apte.flags,2 if idle, give him much time
4031 cana apte.idle,du
4032 tze sn1 if not idle then compute new timer
4033
4034 read_clock " compute time to next alarm
4035 sbaq bb|next_alarm_time ..
4036 tpl setsmall make sure time has not already passed
4037 negl 0 make time positive
4038 cmpaq idle_runout is it very large
4039 tmi sn2 no, go set it
4040 ldaq idle_runout yes, reduce it
4041 tra sn2 then set it
4042 sn1:
4043
4044 eaa 0
4045 ldq bb|apte.temax,2 Pick up correct quantum
4046 sbq bb|apte.te,2
4047 cmpq 4000,dl
4048 tpl sn_ck_big
4049 ldq 4000,dl
4050 tra sn2
4051 sn_ck_big:
4052 cmpaq bb|max_timer_register
4053 tmi sn2
4054 ldaq bb|max_timer_register
4055
4056 sn2:
4057 qls 3+1 binary point at 3, round
4058 div apte.timer_factor,dl convert to clock ticks
4059 adq 1,dl round
4060 qls 12-1 timer_shift, round bit
4061 tpl *+2 must have positive time value
4062 setsmall: ldq =o010000,dl small timer value
4063 stq prds$last_timer_setting
4064 tra 0,7 success return
4065
4066 even
4067 idle_runout:
4068 dec 0,250000 timer runout for idle process
4069 " ^L
4070 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4071 "
4072 " hash_LOCK -- called with alleged processid in pds$arg_1
4073 "
4074 " if processid is valid:
4075 " apt_ptr, BP -> APTE
4076 " APTE is locked
4077 " return to 1,7
4078 "
4079 " if processid is invalid:
4080 " apt_ptr, BP = null
4081 " nothing new is locked
4082 " return is indirect through 0,7
4083 "
4084 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4085
4086 hash_LOCK:
4087 ldq pds$arg_1 get processid
4088 tmi not_found Neg pid may cause overflow fault
4089 sbq bb|apt_offset subtract apt offset
4090 div size_of_apt_entry,du
4091 cmpq bb|apt_size check against bounds of array
4092 trc not_found was invalid offset
4093
4094 mpy size_of_apt_entry,dl Apply array to index
4095 eppbp tc_data$apt,ql
4096 spribp apt_ptr return pointer to apt entry
4097 tsx6 LOCK_bp hash_lock must lock to check pid
4098 ldq pds$arg_1
4099 cmpq bp|apte.processid make sure it's the same one
4100 tze 1,7 success return from hash_lock
4101 tsx6 UNLOCK_bp hash_lock found wrong pid
4102 not_found:
4103 eppbp null,* get null pointer, return
4104 spribp apt_ptr null this too
4105 tra 0,7* hash_lock failure indirect return
4106
4107 even
4108 " ^L
4109 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4110 "
4111 " IPS_WAKEUP -- entry to wake up a process, turn on the ips_pending
4112 " flag and resort the process with high priority.
4113 " Call is
4114 " call pxss$ips_wakeupprocessidmessage
4115 " wher processid is the process id of the process to be awakened, and
4116 " message specifies which IPS message is being sent.
4117 " Currently 'message' is declared char 4, eventually it will be fixed
4118 "
4119 " " " " " " " " " " " " " " " " " " " " " " "" " " " " " " " " " " " " " " " "
4120
4121
4122 ips_wakeup_int:
4123 tsx6 setup_
4124 stz pds$wakeup_flag save info about which entry
4125 tra ijoin
4126 ips_wakeup:
4127 tsx6 setup_
4128 stc1 pds$wakeup_flag
4129 ijoin:
4130 lda ap|2,* get processid
4131 sta pds$arg_1
4132 lda ap|4,* pick up IPS bit string
4133 sta pds$arg_2 save in PDS
4134 tsplb setup_check switch stacks and lock
4135 arg 0,6
4136 tsx6 WRITE_LOCK ips_wakeup protect pid, rethreads
4137 tsx7 hash_LOCK hash search for the APTE
4138 arg ips_wakeup_returns_nul no, don't continue
4139 lxl0 bp|apte.state make sure not stopped
4140 cmpx0 stopped,du
4141 tze ips_wakeup_returns
4142 lda pds$arg_2 get IPS bit string
4143 tsx6 send_ips_wakeup Do the real work, destroys pds$arg_3
4144 " Next instruction may be skipped on return
4145 nop 0 The subroutine already did the right thing
4146 ips_wakeup_returns:
4147 tsx6 UNLOCK_bp We're all done now
4148 ips_wakeup_returns_nul:
4149 tsx6 UNLOCK
4150 tra switch_back Return to caller
4151 "^L
4152 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
4153 "
4154 " SEND_IPS_WAKEUP: called via tsx6. It saves the value
4155 " of x6 in pds$arg_3 for use when returning. This is OK
4156 " since the current callers are WAKEUP and IPS_WAKEUP
4157 " who know what they are doing. It expects the IPS bit
4158 " string to be in the a register when it is called. It
4159 " also expects pds$wakeup_flag to be set to 0 if good
4160 " priority is desired and to > 0 if not.
4161 "
4162 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
4163
4164 send_ips_wakeup:
4165 stx6 pds$arg_3 save x6 for later return
4166 tsx6 add_ips_message
4167
4168 szn pds$wakeup_flag should we give good priority ?
4169 tpnz send_ips_ij2 no, skip code which gives priority
4170
4171 lxl0 bp|apte.state get state of process being awakened
4172 cmpx0 ptlocking,du bugfix:dont OOB quit buckets
4173 tpl *+2 bugfix:dont OOB quit buckets
4174 aos bb|quit_counts,0 and count this ips priority wakeup
4175
4176 ldq bp|apte.te first update ti
4177 adq bp|apte.ts
4178 adq bp|apte.ti
4179 mpy bb|quit_priority get new priority
4180 lls 36-18 binary point at 18
4181 eax3 0,au Save ti in X3
4182 tsx0 setup_p_int boost priority
4183 stx3 bp|apte.ti Store ti from X3.
4184 send_ips_ij2:
4185 ldx0 bp|apte.flags don't move if eligible
4186 canx0 apte.eligible,du
4187 tze send_ips_non_elig
4188 canx0 apte.dbr_loaded,du however, running may never notice
4189 tnz send_ips_connect
4190 tra send_ips_wakeup_returns otherwise will notice at next run time
4191 send_ips_non_elig:
4192 lxl0 bp|apte.state
4193 cmpx0 blocked,du if not blocked, move in q
4194 tze send_ips_connect
4195 tsx7 unthread
4196 tsx7 sort_in
4197 send_ips_connect:
4198 tsx7 send_connect send connect if process running
4199 tsx7 wake wake up process
4200 ldx6 pds$arg_3 restore x6
4201 tra 1,x6 return to wake done place
4202 send_ips_wakeup_returns:
4203 ldx6 pds$arg_3 restore x6
4204 tra 0,x6 return to no wake done place
4205 "^L
4206 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
4207 "
4208 " SETUP_INT: called via tsx0, sets apte variables to give
4209 " high priority and initial quantum following interaction.
4210 " SETUP_P_INT: gives high priority etc w/o interaction.
4211 "
4212
4213 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
4214 setup_p_int:
4215 aos bb|p_interactions Meter priority interactions.
4216 lcx1 apte.interaction+1,du
4217 ansx1 bp|apte.flags Turn off interaction flag.
4218
4219 setup_int:
4220 ldx1 bp|apte.wct_index
4221 stz bp|apte.ti High priority.
4222 stz bp|apte.ts
4223 stz bp|apte.te
4224 read_clock " Calc new deadline.
4225 adaq bb|wcte.resp1,1 By adding to curr time.
4226 staq bp|apte.deadline
4227
4228 ldq bb|wcte.quantum1,1 Pick up new quantum.
4229 lda bb|deadline_mode If deadline mode
4230 ada bb|wcte.realtime,1 or realtime process
4231 tpnz *+2 use per-workclass quantum.
4232 ldq bb|tefirst use default.
4233 stq bp|apte.temax
4234
4235 tra 0,0 Return from setup_int.
4236 "^L
4237 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4238 "
4239 " SETUP_IO_REALTIME: called via tsx0, sets apte variables
4240 " for a realtime burst of eligibility
4241 "
4242 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4243
4244 setup_io_realtime:
4245 read_clock
4246 adl bb|realtime_io_deadline
4247 staq bp|apte.deadline
4248 ldq bb|realtime_io_quantum " And quantum
4249 stq bp|apte.temax
4250 aos bb|realtime_priorities " Meter
4251 tra 0,0
4252
4253 "^L
4254 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4255 "
4256 " REVOKE_ELIG: called with write_lock, turns off elig, decrements counters
4257 "
4258 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4259
4260 revoke_elig:
4261 lcx1 apte.eligible+1,du take away eligibilty
4262 ansx1 bp|apte.flags
4263 lca 1,dl Put -1 in Areg for subtracts ..
4264 asa bb|n_eligible
4265 lxl1 bp|apte.flags2 If was batch
4266 canx1 apte.batch,du then decrement batch counter
4267 tze *+2 else dont
4268 asa bb|num_batch_elig use -1 in the A
4269
4270 ldx1 bp|apte.wct_index Decrement workclass counter.
4271 asa bb|wcte.nel,1
4272 lda bp|apte.saved_temax Make up for init decrement
4273 asa bb|wcte.credits,1 of wc credits.
4274 ldq bb|wcte.governed_word,1 Is wc governed
4275 canq wcte.governed,du
4276 tze *+2 No
4277 asa bb|wcte.governing_credits,1
4278 lca bp|apte.ws_size Sub ws from sum of elig ws
4279 asa bb|ws_sum
4280 stz bp|apte.wait_event he won't get notified
4281
4282 " Give up the stack_0 if it has a shared one
4283
4284 lda bp|apte.flags
4285 cana apte.shared_stack_0,du
4286 tze 0,7
4287
4288 " Don't give up the stack for a stopped process, unless the
4289 " limit of such suspended stacks has been reached
4290
4291 lxl0 bp|apte.state
4292 cmpx0 stopped,du is he stopped
4293 tnz give_up_stack no--OK to release stack
4294 lda bb|stopped_stack_0 check limit on suspended
4295 cmpa bb|max_stopped_stack_0 stacks
4296 tpl give_up_stack too bad--flush the stack
4297 aos bb|stopped_stack_0 add to count of suspended stacks
4298 ldx0 -1,du and decrement count of
4299 asx0 bb|max_max_eligible available stacks
4300 tra 0,7
4301 give_up_stack:
4302
4303 " Check the validity of the stack
4304
4305 eppab sst$
4306 ldaq pds$stack_0_sdwp,*
4307 arl 12
4308 sbla sst$ptwbase
4309 eppab ab|0,al ptr to ptw for page 0
4310
4311 lda ab|0 get the ptw
4312 cana ptw.wired,dl check page 0 wired
4313 drlnz pxss: stack_0 page 0 wired SHOULD NOT BE!!!!
4314
4315 tsx6 lock_stack_queue
4316 ldaq pds$stack_0_sdwp,* Get stack SDW
4317 drlze pxss: no stack_0 sdw LOSE! snb/0
4318 lxl0 ab|sdt.num_stacks This is how many slots
4319 eax4 0 Entry index
4320 free_stack_0_loop:
4321 cmpaq ab|sdt.sdw,4
4322 tze free_stack_0_got
4323 eax4 sdte_size,4
4324 eax0 -1,0
4325 tpnz free_stack_0_loop
4326 drltra pxss: freeing unknown stack_0 STACK NOT FOUND
4327 free_stack_0_got:
4328 tsx6 free_stack_0 Give it up
4329 fld 0,dl
4330 staq pds$stack_0_sdwp,* Clear out SDW for getwork check.
4331
4332 tsx6 unlock_stack_queue
4333
4334 lcx0 apte.shared_stack_0+1,du
4335 ansx0 bp|apte.flags reset flag
4336 tra 0,7 return from revoke_elig
4337
4338 "^L
4339 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4340 "
4341 " RESCHEDULE: called with write_lock set
4342 "
4343 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4344
4345
4346 reschedule:
4347 lda bp|apte.te update te into ts
4348 tmi *+2 avoid neg ts
4349 asa bp|apte.ts
4350
4351 ldx1 bp|apte.wct_index
4352 read_clock " Calc new deadline.
4353 adaq bb|wcte.resp2,1 By adding to cutime.
4354 staq bp|apte.deadline
4355
4356 ldq bb|wcte.quantum2,1 Pick up new quantum.
4357 lda bb|deadline_mode If in deadline_mode
4358 ada bb|wcte.realtime,1 or realtime process
4359 tpnz *+2 then use per workclass quantum.
4360 ldq bb|telast
4361 stq bp|apte.temax
4362
4363 lda bb|tefirst if ts>mintefirst+titimax
4364 ada bp|apte.ti
4365 cmpa bp|apte.timax
4366 tmi *+2
4367 lda bp|apte.timax
4368 cmpa bp|apte.ts
4369 tpl nupti
4370 lda bp|apte.ts update ts into ti
4371 asa bp|apte.ti
4372 stz bp|apte.ts
4373 nupti: stz bp|apte.te
4374
4375 lda bp|apte.flags2 is this a guaranteed eligibility process
4376 cana apte.prior_sched,dl ..
4377 tze rs_ps_done if not then OK
4378 aos bb|lost_priority_eligibility record loss of eligibility
4379 ldaq bp|apte.state_change_time compute when to boost priority
4380 adl bb|priority_sched_inc
4381 cmpaq bb|priority_sched_time remember when to boost next
4382 tpl rs_ps_done ..
4383 staq bb|priority_sched_time
4384 cmpaq bb|next_alarm_time update time of next alarm if necessary
4385 tpl rs_ps_done ..
4386 staq bb|next_alarm_time
4387 rs_ps_done:
4388 tra 0,7 reschedule returns
4389
4390 "^L
4391 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4392 "
4393 " purge_UNLOCK: called with write_lock and apte_lock, it unlocks both
4394 "
4395 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4396
4397
4398 purge_UNLOCK:
4399 stz bp|apte.ws_size
4400
4401 tsx6 UNLOCK_bp UNLOCK own apte before call out
4402 tsx6 UNLOCK
4403
4404 szn bb|post_purge_switch If at all.
4405 tze pU_ret
4406 ldx1 bp|apte.wct_index
4407 szn bb|wcte.purging,1 Purge on per wc basis
4408 tze pU_ret
4409 call page$post_purge clean up last process's pages
4410 pU_ret: tra 0,7 Return from purge_UNLOCK
4411
4412
4413 " ^L
4414 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4415 "
4416 " stop_check_ -- call if old user probably is stopped
4417 "
4418 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4419
4420
4421 stop_check_:
4422 tsx6 WRITE_LOCK prevent empty_t interference
4423 lxl0 bp|apte.state check for really stopped
4424 cmpx0 stopped,du
4425 tnz stop_ul not stopped, dont notify
4426 lda =astop message will be "stopstop"
4427 sta tmp_ev_message ..
4428 sta tmp_ev_message+1
4429 tsplb wake_term_pid send stopstop to term pid
4430 eppbp apt_ptr,* repair BP for next test
4431 stop_ul: tsx6 UNLOCK
4432 tra end_stop_check stop_check_ ret to getwork
4433
4434
4435
4436 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4437 "
4438 " cpu_monitor_ -- called if probably need to send cpulimit wakeup
4439 "
4440 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4441
4442 cpu_monitor_:
4443 ldaq bp|apte.virtual_cpu_time
4444 lrs 10 convert to 1/1024 secs
4445 cmpq bp|apte.cpu_monitor
4446 tmi end_cpu_monitor
4447 tsx6 WRITE_LOCK
4448 tsx6 LOCK_bp
4449 szn bp|apte.cpu_monitor
4450 tze cm_not
4451 ldaq bp|apte.virtual_cpu_time
4452 lrs 10 convert to 1/1024 secs
4453 cmpq bp|apte.cpu_monitor
4454 tmi cm_not
4455 stz bp|apte.cpu_monitor clear cell
4456 tsx6 UNLOCK_bp
4457 ldaq cpulimit_msg
4458 staq tmp_ev_message
4459 tsplb wake_term_pid send cpulimit to term_pid
4460 cm_done: tsx6 UNLOCK
4461 tra end_cpu_monitor return to gw
4462
4463 cm_not: tsx6 UNLOCK_bp
4464 tra cm_done
4465
4466 even
4467 cpulimit_msg:
4468 aci "cpulimit"
4469 "^L
4470
4471 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4472 "
4473 " WAKE_TERM_PID -- send tmp_ev_message to term_pid over term_chan
4474 "
4475 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4476
4477 wake_term_pid:
4478 stz dev_signal count it as dev_signal
4479 aos dev_signal count it as dev_signal
4480 ldaq bp|apte.term_channel
4481 staq tmp_ev_channel
4482 stz tmp_ring
4483 lda bp|apte.term_processid
4484 sta pds$arg_1
4485 stc1 pds$wakeup_flag not require unique message
4486 eppbp bb|0,au make bp -> target_apte
4487 tsx6 LOCK_bp wake_term_pid locks target of wakeup
4488 tsx7 make_itt_message
4489 tsx7 wake
4490 tsx6 UNLOCK_bp wake_term_pid unlocks target apte
4491 tra lb|0 wake_term_pid returns
4492
4493 "^L
4494 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4495 "
4496 " DELETE_ME
4497 "
4498 " This is the legendary CPU Graveyard, where CPUs go to die
4499 " when taken off-line. When a CPU is to be deleted, getwork
4500 " will run only an idle process on it. When this happens,
4501 " the process will transfer to this routine. This routine
4502 " does the following:
4503 "
4504 " 1. Under the Global APT lock, checks whether the system default
4505 " CPU set would contain no online CPUs.
4506 "
4507 " 2. If the system default CPU set would contain no online
4508 " CPUs, it changes the system default CPU set to all
4509 " CPUs, unlocks, and prints a message on the console.
4510 " Under the Global APT lock, checks the system default CPU
4511 " set again. This second check is necessary to avoid races,
4512 " since the call to syserr must be made with the Global APT
4513 " lock unlocked. If the second check fails, the first is
4514 " repeated. This should happen very rarely.
4515 "
4516 " 3. Changes the state of the idle process for this CPU to
4517 " empty, unthreading it, but not returning it to the empty
4518 " list.
4519 "
4520 " 4. Under the connect lock, turn off the bit for this CPU
4521 " in scs$processor this must be done under the connect
4522 " lock to prevent other CPUs doing connects from spinning
4523 " forever waiting for this one to respond.
4524 "
4525 " 5. Walk the APTE array, looking for processes whose set of
4526 " required CPUs includes no online CPUs. Any such are changed
4527 " to require the current system default. This must be done
4528 " under the Global APT lock.
4529 "
4530 " 6. Unlock the Global APT lock and die inhibited DIS.
4531 "
4532 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4533
4534 delete_me:
4535 tsx6 WRITE_LOCK delete_me locks out sprq
4536
4537 lda prds$processor_pattern bit for this CPU
4538 era scs$processor Areg = bits for remaining CPUs
4539 ana bb|default_procs_required Any left in default?
4540 tnz procs_required_ok Yes
4541 retry_delete_me: " Also come here if lost race
4542 lda all_procs_required,du Set default to all CPUs
4543 sta bb|default_procs_required
4544
4545 tsx6 UNLOCK Unlock before call-out
4546
4547 " call syserr 3 "pxss: System default procs required reset to ABCDEFGH"
4548
4549 epplb reset_system_procs_severity
4550 sprilb arg+2
4551 epplb reset_system_procs_mess
4552 sprilb arg+4
4553 epplb fixed_desc
4554 sprilb arg+6
4555 epplb reset_system_procs_desc
4556 sprilb arg+8
4557 ldaq =v18/4,18/4,18/4,18/0
4558 staq arg
4559 call syserr$syserrarg
4560
4561 tsx6 WRITE_LOCK relock before checking again
4562
4563 lda prds$processor_pattern Bit for this CPU
4564 era scs$processor Areg = bits for remaining CPUs
4565 ana bb|default_procs_required Any left online
4566 tze retry_delete_me No - lost race
4567
4568 procs_required_ok:
4569
4570 " Walk APTE array, looking for processes which can't run
4571
4572 ldq scs$processor Bits for CPUs still running
4573 anq apte.procs_required_mask,du Strip out garbage
4574 erq prds$processor_pattern And bit for this CPU
4575 lca 1,dl
4576 era apte.procs_required_mask,du To reset procs required
4577 ldx3 bb|default_procs_required To set to default
4578 anx3 apte.procs_required_mask,du Strip out garbage
4579 ldx2 apte.default_procs_required,du To set bit saying it's default
4580 eppap tc_data$apt Begin of APTE array
4581 lxl1 bb|apt_size Number APTEs
4582 check_proc_loop:
4583 ldx0 ap|apte.flags
4584 canx0 apte.idle,du Skip idle processes
4585 tnz check_proc_next
4586 canq ap|apte.procs_required Any left for this process?
4587 tnz check_proc_next Yes
4588 ansa ap|apte.procs_required Clear procs required
4589 orsx3 ap|apte.procs_required Set to default
4590 orsx2 ap|apte.flags And remember it's the default
4591 check_proc_next:
4592 eppap ap|size_of_apt_entry Next APTE
4593 eax1 -1,1 One less to go
4594 tpnz check_proc_loop But still some left
4595
4596 inhibit on <+><+><+><+><+><+><+><+><+><+><+><+>
4597
4598 lxl1 prds$processor_tag
4599 lcx0 processor_data.online+1,du turn this bit OFF
4600 ansx0 scs$processor_data,1 ..
4601
4602 eppbp prds$idle_ptr,* bp -> APTE for idle process
4603 tsx6 LOCK_bp
4604 ldx0 empty,du set empty state
4605 tsx7 update_execution_state ..
4606 tsx6 UNLOCK_bp
4607
4608 inhibit off <-><-><-><-><-><-><-><-><-><-><-><->
4609 lda pds$processid lock the connect lock
4610 stac scs$connect_lock before diddling scs$processor
4611 nop
4612 nop
4613 tnz -3,ic
4614 lca 1,dl one's in A
4615 era prds$processor_pattern make a mask
4616 ansa scs$processor turn off bit for this processor
4617 lda 0,dl clear the A
4618 ansa scs$connect_lock can undo lock now
4619
4620 inhibit on <+><+><+><+><+><+><+><+><+><+><+><+>
4621 lxl1 prds$processor_tag
4622 lcx0 processor_data.delete_cpu+1,du turn this bit OFF
4623 ansx0 scs$processor_data,1
4624 ldx0 processor_data.offline+processor_data.halted_cpu,du turn these bits ON
4625 orsx0 scs$processor_data,1
4626
4627 tsx6 UNLOCK undo the lock before dying
4628
4629 dis =o777,dl
4630 tra *-1
4631
4632 inhibit off <-><-><-><-><-><-><-><-><-><-><->
4633
4634 reset_system_procs_severity:
4635 dec 3 " severity of syserr message
4636 reset_system_procs_mess:
4637 aci "pxss: System default procs required reset to ABCDEFGH"
4638 equ reset_system_procs_words,*-reset_system_procs_mess
4639 equ reset_system_procs_chars,4*reset_system_procs_words
4640 reset_system_procs_desc:
4641 vfd 1/1,6/21,5/0,24/reset_system_procs_chars
4642 "
4643 "^L
4644 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4645 "
4646 " Hardcore stack queue locking/unlocking
4647 "
4648 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4649
4650 lock_stack_queue:
4651 lda pds$processid
4652 eppab stack_0_data$
4653 cmpa ab|sdt.lock
4654 drlze pxss: mylock on stack queue mylock err
4655 stac ab|sdt.lock
4656 nop
4657 nop
4658 tnz *-3
4659 nop
4660 cmpa ab|sdt.lock Check for stac loss.
4661 drlnz pxss: lock_stack_queue stac failed
4662 tra 0,6 That's why locks are expensive in Multics.
4663
4664 unlock_stack_queue:
4665 ldq pds$processid
4666 cmpq ab|sdt.lock Check for other random lossage
4667 drlnz pxss: unlock_stack_queue not my lock
4668 eaa 0
4669 stacq ab|sdt.lock
4670 drlnz pxss: unlock_stack_queue stacq failed stacq claims failure
4671 nop
4672 cmpq ab|sdt.lock Stacq really win?
4673 drlze pxss: unlock_stack_queue stacq failed
4674 tra 0,6
4675 "^L
4676 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4677 "
4678 " subroutine to return a stack_0 to the free list
4679 "
4680 " tsx6 free_stack_0
4681 "
4682 " On entry -
4683 " sdt lock must be owned
4684 " ab -> stack_0_data$
4685 " x4 = index of sdte for this stack
4686 "
4687 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4688
4689 free_stack_0:
4690 eax0 0
4691 sxl0 ab|sdt.aptep,4 No aptep
4692 eax0 ab|sdt.stacks,4 Thread in
4693 ldx4 ab|sdt.freep
4694 stx4 ab|sdte.nextp,0
4695 stx0 ab|sdt.freep
4696 tra 0,6
4697
4698 add_ips_message:
4699 sta tmp_event "Remember the event
4700 add_ips.retry:
4701 ldq bp|apte.ips_message
4702 lda bp|apte.ips_message
4703 ora tmp_event
4704 stacq bp|apte.ips_message
4705 tnz add_ips.retry
4706 tra 0,x6
4707
4708 "^L
4709 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4710 "
4711 " SUSPEND_GETWORK -- entry to loop until getwork all suspended
4712 "
4713 " Call is
4714 " call pxss$suspend_getwork
4715 "
4716 "
4717 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "
4718
4719 suspend_getwork:
4720 lda pds$processid see if i have the suspension lock
4721 cmpa tc_data$tc_suspend_lock
4722 tnz sg_returns return if we don't hold lock
4723
4724 tsplb setup_mask going to have the APT locked
4725 tsx6 WRITE_LOCK while we pre-empt other processes
4726
4727 lda bb|eligible_q_head
4728 sg_pe_loop:
4729 ldaq bb|apte.thread,au
4730 tra sg_pe_tv,ql*
4731
4732 arg sg_pe_done -1 => sentinel
4733 sg_pe_tv: arg DRL_empty_apte empty - in eligible list??
4734 arg sg_pre_empt_it running - get the process out of there
4735 arg sg_pe_loop ready - skip it
4736 arg sg_pe_loop waiting - skip it
4737 arg DRL_blocked_apte blocked - doesn't belong here
4738 arg DRL_stopped_apte stopped - doesn't belong here
4739 arg sg_pe_loop ptlwait - skip it
4740
4741 sg_pre_empt_it:
4742 lxl3 bb|apte.thread,au get this apte addr from next apte
4743 tsx6 LOCK_x3
4744 ldq bb|apte.flags,3 get a copy of the flags
4745 canq apte.pre_empted,du is it already pre-empted?
4746 tnz sg_pe_skip yes, so skip it
4747 lda apte.pre_empted+apte.pre_empt_pending,du
4748 orsa bb|apte.flags,3 turn on flags to indicate pre-emption
4749 ldq bb|apte.flags2,3 get processor tag for the connect
4750 anq apte.pr_tag_mask,dl
4751 cmpq prds$processor_tag is it this processor?
4752 tze sg_pe_skip yes, don't connect myself
4753 cioc scs$cow_ptrs,ql*
4754
4755 sg_pe_skip:
4756 tsx6 UNLOCK_x3 release the apte
4757 ldaq bb|apte.thread,3 clobbered by sg_pre_empt_it code
4758 tra sg_pe_loop
4759
4760 sg_pe_done:
4761 tsx6 UNLOCK give up the lock for a few microseconds
4762
4763 nop 0 delay between lockings
4764 nop 0
4765
4766 tsx6 READ_LOCK for seeing if all are off the cpus
4767
4768 lda bb|eligible_q_head
4769 sg_wt_loop:
4770 ldaq bb|apte.thread,au
4771 tra sg_wt_tv,ql*
4772
4773 arg sg_wt_done -1 => sentinel
4774 sg_wt_tv: arg DRL_empty_apte empty - in eligible list??
4775 arg sg_check_it running - see who it is
4776 arg sg_wt_loop ready - skip it
4777 arg sg_wt_loop waiting - skip it
4778 arg DRL_blocked_apte blocked - doesn't belong here
4779 arg DRL_stopped_apte stopped - doesn't belong here
4780 arg sg_wt_loop ptlwait - skip it
4781
4782 sg_check_it:
4783 lxl3 bb|apte.thread,au get this apte addr from next apte
4784 tsx6 LOCK_x3
4785 ldq bb|apte.flags,3 get a copy of the flags
4786 canq apte.idle,du is it an idle?
4787 tnz sg_wt_skip yes - this is ok.
4788 ldq bb|apte.flags2,3 get processor tag for this process
4789 anq apte.pr_tag_mask,dl
4790 cmpq prds$processor_tag is it me??
4791 tze sg_wt_skip yes - this is also ok.
4792
4793 tsx6 UNLOCK_x3 no - unlock and check all over again
4794 tra sg_pe_done
4795
4796 sg_wt_skip:
4797 tsx6 UNLOCK_x3 release the apte
4798 ldaq bb|apte.thread,3 clobbered by sg_check_it code
4799 tra sg_wt_loop
4800
4801 sg_wt_done:
4802 tsx6 UNLOCK
4803 tsx7 switch_back_ret_pds
4804
4805 sg_returns:
4806 short_return
4807
4808
4809 "^L
4810 " BEGIN MESSAGE DOCUMENTATION
4811
4812 " Message:
4813 " pxss: notify time out: event=ZZZZZZZZZZZZ, pid=XXXXXXXXXXXX
4814
4815 " S: $info
4816
4817 " T: $run
4818
4819 " M: A hardcore event has not occurred within a reasonable time.
4820 " This may be due to hardware problems
4821 " or to a programming error.
4822 " The system attempts to continue operation.
4823
4824 " A: If this message persists, contact system programmers.
4825
4826
4827 " Message:
4828 " pxss: notify time out: event=ZZZZZZZZZZZZ. During init/shutdown.
4829
4830 " S: $info
4831
4832 " T: $init
4833
4834 " M: A hardcore event has not occurred within a reasonable time
4835 " during system initialization or shutdown. This may be due to hardware
4836 " problems or to a programming error. The system attempts to continue
4837 " initialization or shutdown.
4838
4839 " A: If this message persists, contact system programmers.
4840
4841
4842 " Message:
4843 " pxss: System default procs required reset to ABCDEFGH
4844
4845 " S: $beep
4846
4847 " T: During CPU deconfiguration.
4848
4849 " M: Due to the deletion of a CPU, there were no online CPUs
4850 " remaining in the default set of CPUs. These CPUs are the only CPUs
4851 " on which processes can run which have not requested to be run on
4852 " specific CPUs. The default set of CPUs has been changed to all
4853 " online CPUs.
4854
4855 " A: $inform_sa
4856
4857 " Message:
4858 " pxss: APTE not locked
4859 "
4860 " S: $crash
4861 "
4862 " T: $run
4863 "
4864 " M: $err
4865 "
4866 " A: $recover
4867
4868 " Message:
4869 " pxss: APTE disdains all processors
4870 "
4871 " S: $crash
4872 "
4873 " T: $run
4874 "
4875 " M: $err
4876 " There are no processors-required set for this APTE.
4877 "
4878 " A: $recover
4879
4880 " Message:
4881 " pxss: No term_processid
4882 "
4883 " S: $crash
4884 "
4885 " T: $run
4886 "
4887 " M: $err
4888 " As a process was about to indicate its demise to the master process,
4889 " it discovered, to its chagrin, that it had forgotten who that was.
4890 "
4891 " A: $recover
4892
4893 " Message:
4894 " pxss: Stop returned from getwork
4895 "
4896 " S: $crash
4897 "
4898 " T: $run
4899 "
4900 " M: $err
4901 "
4902 " A: $recover
4903
4904 " Message:
4905 " pxss: sprq already on prds
4906 "
4907 " S: $crash
4908 "
4909 " T: $run
4910 "
4911 " M: $err
4912 "
4913 " A: $recover
4914
4915 " Message:
4916 " pxss: empty_t APTE not stopped or empty
4917 "
4918 " S: $crash
4919 "
4920 " T: $run
4921 "
4922 " M: $err
4923 " an attempt was made to clear an APTE that of a process that was neither
4924 " stopped nor empty.
4925 "
4926 " A: $recover
4927
4928 " Message:
4929 " pxss: APT not locked
4930 "
4931 " S: $crash
4932 "
4933 " T: $run
4934 "
4935 " M: $err
4936 "
4937 " A: $recover
4938
4939 " Message:
4940 " pxss: unthread null back ptr
4941 "
4942 " S: $crash
4943 "
4944 " T: $run
4945 "
4946 " M: $err
4947 "
4948 " A: $recover
4949
4950 " Message:
4951 " pxss: unthread prev.fp ^= cur
4952 "
4953 " S: $crash
4954 "
4955 " T: $run
4956 "
4957 " M: $err
4958 "
4959 " A: $recover
4960
4961 " Message:
4962 " pxss: unthread null cur.fp
4963 "
4964 " S: $crash
4965 "
4966 " T: $run
4967 "
4968 " M: $err
4969 "
4970 " A: $recover
4971
4972 " Message:
4973 " pxss: unlock apt read lock bad count
4974 "
4975 " S: $crash
4976 "
4977 " T: $run
4978 "
4979 " M: $err
4980 "
4981 " A: $recover
4982
4983 " Message:
4984 " pxss: write_to_read bad lock count
4985 "
4986 " S: $crash
4987 "
4988 " T: $run
4989 "
4990 " M: $err
4991 "
4992 " A: $recover
4993
4994 " Message:
4995 " pxss: write_to_read ldac failed
4996 "
4997 " S: $crash
4998 "
4999 " T: $run
5000 "
5001 " M: $err
5002 " This indicates a hardware error.
5003 "
5004 " A: $recover
5005
5006 " Message:
5007 " pxss: UNLOCK_bp not locked
5008 "
5009 " S: $crash
5010 "
5011 " T: $run
5012 "
5013 " M: $err
5014 "
5015 " A: $recover
5016
5017 " Message:
5018 " pxss: UNLOCK_X2 not locked
5019 "
5020 " S: $crash
5021 "
5022 " T: $run
5023 "
5024 " M: $err
5025 "
5026 " A: $recover
5027
5028 " Message:
5029 " pxss: UNLOCK_x3 not locked
5030 "
5031 " S: $crash
5032 "
5033 " T: $run
5034 "
5035 " M: $err
5036 "
5037 " A: $recover
5038
5039 " Message:
5040 " pxss: subroutine_save stack overflow
5041 "
5042 " S: $crash
5043 "
5044 " T: $run
5045 "
5046 " M: $err
5047 "
5048 " A: $recover
5049
5050 " Message:
5051 " pxss: ITT overflows
5052 "
5053 " S: $crash
5054 "
5055 " T: $run
5056 "
5057 " M: $err
5058 "
5059 " A: $recover
5060
5061 " Message:
5062 " pxss: untenable empty APTE
5063 "
5064 " S: $crash
5065 "
5066 " T: $run
5067 "
5068 " M: $err
5069 "
5070 " A: $recover
5071
5072 " Message:
5073 " pxss: untenable blocked APTE
5074 "
5075 " S: $crash
5076 "
5077 " T: $run
5078 "
5079 " M: $err
5080 "
5081 " A: $recover
5082
5083 " Message:
5084 " pxss: untenable stopped APTE
5085 "
5086 " S: $crash
5087 "
5088 " T: $run
5089 "
5090 " M: $err
5091 "
5092 " A: $recover
5093
5094 " Message:
5095 " pxss: thread_him_in already threaded
5096 "
5097 " S: $crash
5098 "
5099 " T: $run
5100 "
5101 " M: $err
5102 "
5103 " A: $recover
5104
5105 " Message:
5106 " pxss: thread_him_in x1 zero
5107 "
5108 " S: $crash
5109 "
5110 " T: $run
5111 "
5112 " M: $err
5113 "
5114 " A: $recover
5115
5116 " Message:
5117 " pxss: thread_him_in x4 zero
5118 "
5119 " S: $crash
5120 "
5121 " T: $run
5122 "
5123 " M: $err
5124 "
5125 " A: $recover
5126
5127 " Message:
5128 " pxss: thread_him_in x4->apte.fp ^= x1
5129 "
5130 " S: $crash
5131 "
5132 " T: $run
5133 "
5134 " M: $err
5135 "
5136 " A: $recover
5137
5138 " Message:
5139 " pxss: apte.state ^= ready
5140 "
5141 " S: $crash
5142 "
5143 " T: $run
5144 "
5145 " M: $err
5146 "
5147 " A: $recover
5148
5149 " Message:
5150 " pxss: thread_him_in x0 zero
5151 "
5152 " S: $crash
5153 "
5154 " T: $run
5155 "
5156 " M: $err
5157 "
5158 " A: $recover
5159
5160 " Message:
5161 " pxss: no available stack_0
5162 "
5163 " S: $crash
5164 "
5165 " T: $run
5166 "
5167 " M: $err
5168 "
5169 " A: $recover
5170
5171 " Message:
5172 " pxss: stack_0 page 0 wired
5173 "
5174 " S: $crash
5175 "
5176 " T: $run
5177 "
5178 " M: $err
5179 " process loading was about to wire the first page of the ring 0 stack when
5180 " it discovered that it had been beaten to the punch.
5181 "
5182 " A: $recover
5183
5184 " Message:
5185 " pxss: no stack_0 sdw
5186 "
5187 " S: $crash
5188 "
5189 " T: $run
5190 "
5191 " M: $err
5192 "
5193 " A: $recover
5194
5195 " Message:
5196 " pxss: freeing unknown stack_0
5197 "
5198 " S: $crash
5199 "
5200 " T: $run
5201 "
5202 " M: $err
5203 " the stack_0 being returned could not be found in the list of stack_0s.
5204 "
5205 " A: $recover
5206
5207 " Message:
5208 " pxss: mylock on stack queue
5209 "
5210 " S: $crash
5211 "
5212 " T: $run
5213 "
5214 " M: $err
5215 "
5216 " A: $recover
5217
5218 " Message:
5219 " pxss: lock_stack_queue stac failed
5220 "
5221 " S: $crash
5222 "
5223 " T: $run
5224 "
5225 " M: $err
5226 " This indicates a hardware error.
5227 "
5228 " A: $recover
5229
5230 " Message:
5231 " pxss: unlock_stack_queue not my lock
5232 "
5233 " S: $crash
5234 "
5235 " T: $run
5236 "
5237 " M: $err
5238 "
5239 " A: $recover
5240
5241 " Message:
5242 " pxss: unlock_stack_queue stacq failed
5243 "
5244 " S: $crash
5245 "
5246 " T: $run
5247 "
5248 " M: $err
5249 " This indicates a hardware error.
5250 "
5251 " A: $recover
5252
5253 " END MESSAGE DOCUMENTATION
5254
5255 end