1 " ***********************************************************
  2 " *                                                         *
  3 " * Copyright, (C) Honeywell Bull Inc., 1987                *
  4 " *                                                         *
  5 " * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6 " *                                                         *
  7 " * Copyright (c) 1972 by Massachusetts Institute of        *
  8 " * Technology and Honeywell Information Systems, Inc.      *
  9 " *                                                         *
 10 " ***********************************************************
 11 
 12 " HISTORY COMMENTS:
 13 "  1) change(85-10-28,Fawcett), approve(86-04-03,MCR7277),
 14 "     audit(86-04-03,Farley), install(86-04-07,MR12.0-1036):
 15 "      Fix a looping problem that caused the system to hang
 16 "                                                      END HISTORY COMMENTS
 17 
 18 
 19 " " " " " " " " " " " " " " " " " " " " " " " " "
 20 "
 21 "         post_purge -- This entry contains the code to post purge a process.
 22 "
 23 "         Last Modified (Date and Reason)
 24 "         4/8/74 by S.H.Webber to change decision tree and add scheduling trace
 25 "         03/18/81, W. Olin Sibert, for ADP conversion
 26 "         06/21/82, E. N. Kittlitz, to move core map.
 27 "         83-12-03 BIM to sys_trace.incl.alm
 28 "
 29 "         This program was originally part of pre_page but has since been renamed
 30 "         as we no longer do anything about pre_paging.
 31 "
 32 " " " " " " " " " " " " " " " " " " " " " " " " "
 33 
 34           name      post_purge
 35           segdef    post_purge
 36 
 37           include   pxss_page_stack
 38           include   add_type
 39           include   page_info
 40           include   sst
 41           include   sys_trace
 42           include   aste
 43           include   sdw
 44           include   ptw
 45           include   cmp
 46           include   apte
 47 
 48 " ^L
 49 
 50 "         The following is the decision tree used
 51 "         at post-purge time.
 52 "
 53 "         The current algorithm is as follows:
 54 "
 55 "         post_purge                    never
 56 "         move                          if per-process and in core
 57 "         used bit off                  never
 58 "         working set                   if used in quantum by some process
 59 "
 60 "
 61           bool      working_set,000010  " How to interpret the bits
 62           bool      used_bit_off,000004
 63           bool      post_purge_bit,000002
 64           bool      moved_bit,000001
 65 
 66           equ       ptw.pre_paged,ptw.er " Special use for this bit here
 67 
 68 code_tree:
 69           oct       020042104200
 70           oct       020042104200
 71           oct       020042104200
 72           oct       020042104200
 73           oct       020042104200
 74           oct       062146314620
 75           oct       020042104200
 76           oct       062146314620
 77 
 78 post_purge:
 79           push
 80           tsx6      page_fault$init_savex initialize x7 save stack
 81           lda       post_purge_entry,dl set entry switch
 82           sta       entry_sw
 83           tsx7      page_fault$lock_ptl lock the page table lock
 84 
 85           read_clock                    meter post-purge time
 86           staq      pre_time            save start time in stack
 87 
 88           fld       0,dl                initialize counters
 89           staq      pre_temp
 90           staq      pre_temp+2
 91           staq      pre_temp+4
 92 
 93 "
 94 "         The post purge code starts searching the post purge trace list from "trace_index"
 95 "         to "trace_size" -- watching out for possible wrap-around.
 96 "
 97           eppap     pds$trace           get pointer to trace data
 98           ldx0      ap|trace.index_word get starting index
 99 post_loop:
100           cmpx0     ap|trace.next_free_word       are we done?
101           tze       done_post           yes, finish up
102           increment sst|sst.post_list_size count number of pages in core at purge
103           sxl0      pre_temp+1          save current index
104           lda       ap|trace.data+1,0   get page number from entry
105           cana      =o770000,du         this better be a page fault list entry
106           tnz       next_entry          it isn't, skip it
107           sta       temp                save it for a second
108           ldx3      ap|trace.data,0     get current AST entry pointer
109           eax2      aste_size,3         fabricate page table pointer
110           adlx2     temp                add in word number to get ptwp
111           eppbp     sst|0,2             get a pointer to the PTW
112           lda       ptw.pre_paged,dl    check if we've already looked at this ptw
113           cana      ptw|0               ..
114           tze       looked              we haven't, continue
115           increment sst|sst.thrashing   count thrashing
116           tra       next_entry          and skip this one
117 looked:
118           orsa      ptw|0               turn on pre_paged bit (already looked)
119           lda       ptw|0               refetch the ptw
120 "
121 "         Now get decision index
122 "
123           ldq       0,dl                The object of this game is to make Q1, Q2,
124           cana      ptw.phu1,dl         and Q3 contain PHU, PHM, and PHU1, resp.
125           tze       *+2                 We accomplish this by inspecting each PTW bit
126           orq       =o040000,du         and setting the appropriate bit in Q.
127           cana      ptw.phm+ptw.phm1,dl
128           tze       *+2
129           orq       =o100000,du
130           cana      ptw.phu,dl
131           tze       *+2
132           orq       =o200000,du
133 
134           cana      add_type.core,dl    check if core address
135           tze       not_in_core         if not skip cme stuff
136 "
137 "         It's in core, get CMEP
138 "
139           orq       =o400000,du         turn on the in core bit for decision
140           arl       3-1                 compute core map entry pointer
141           eax4      sst|sst.cmp,*au
142           increment sst|sst.post_in_core meter
143           lda       page_fault$cme_devadd,*4 extract device ID from core map entry
144 not_in_core:
145           cana      add_type.pd,dl      is this on pd?
146           tnz       pp.yes_pd
147           eaa       0
148           tra       *+2
149 pp.yes_pd:
150           lda       1,dl
151           lrl       1
152           lda       ast|aste.per_process_word,3   get aste word
153           cana      aste.per_process,du           is it p/p?
154           tnz       pp.yes_pp
155           eaa       0
156           tra       *+2
157 pp.yes_pp:
158           lda       1,dl
159           lrl       1                   shift in mlsw bit to complete index
160           qrl       30                  right justify the decision index
161           increment sst|sst.tree_count,ql meter the decision
162           stq       pre_temp+5          save index in stack
163 
164           lls       33                  split the index into wordno and shift value
165           qrl       15
166           lrl       3
167           qrl       15
168 "
169 "         QU now contains the word offset
170 "         QL contains the shift index
171 "
172           lda       code_tree,qu        get code word in a
173           arl       code_shift,ql*      shift to lower a
174           ana       =o17,dl             leave only decision bits
175           sta       pre_temp
176 
177           cana      working_set,dl      should we count this page in working set ?
178           tze       *+2                 no, skip count instruction
179           aos       pre_temp+4          yes, count it
180 
181           cana      post_purge_bit,dl   should we purge the page?
182           tze       check_move          no, go check if we should move the core map entry
183 
184           lxl0      ptw|0               see if page is out of service
185           canx0     ptw.os,du           ..
186           tnz       check_move          yes, skip write request
187           canx0     ptw.valid,du        see if page not in core
188           tze       check_move          yes, skip write request
189           increment sst|sst.post_purgings
190           tsx7      page_fault$write_page see if must write the page and do so if must
191           eppap     pds$trace get pointer to array again
192 check_move:
193           lda       pre_temp            see if we should move in list
194           cana      moved_bit,dl
195           tze       check_used          no, look at next entry
196           tsx7      page_fault$thread_to_lru yes, move in core map
197 check_used:
198           lda       pre_temp            retrieve coded value again
199           cana      used_bit_off,dl
200           tze       next_entry
201           lcq       ptw.phu+ptw.phu1+1,dl         turn OFF used bit in PTW
202           ansq      ptw|0
203 
204 next_entry:
205           lxl0      pre_temp+1          get next free slot in pre-page list
206           eax0      2,0                 increment to next entry
207           cmpx0     ap|trace.last_available_word
208           tmi       *+2
209           eax0      0                   yes, reset index
210           tra       post_loop           loop back for another entry
211 
212 done_post:
213 "
214 "         Now reset all pre-paged flags
215 "
216           lca       ptw.pre_paged+1,dl  get mask to turn off flag
217           ldx0      ap|trace.index_word start at beginning of list again
218 turn_off: cmpx0     ap|trace.next_free_word are we done?
219           tze       mtime               yes, abort loop
220           ldq       ap|trace.data+1,0   get word 1 for page number
221           canq      =o770000,du         see if page fault entry
222           tnz       next_turn_off       no, skip the entry
223           stq       temp                save for subtract
224           ldx3      ap|trace.data,0     get astep
225           eax2      aste_size,3         fabricate ptp
226           adlx2     temp                ..
227           ansa      sst|0,2             turn off pre-paged bit
228 next_turn_off:
229           eax0      2,0                 go to next entry
230           cmpx0     ap|trace.last_available_word wrap-around?
231           tmi       *+2                 no,
232           eax0      0                   yes
233           tra       turn_off            loop back
234 
235 mtime:
236           ldx0      ap|trace.next_free_word reset pointer to start of active list
237           stx0      ap|trace.index_word
238 
239           eppap     pds$apt_ptr,*       set pre-page-size in APT entry
240           ldq       pre_temp+4
241           mpy       tc_data$working_set_factor
242           qrl       18
243           adq       tc_data$working_set_addend
244           stq       ap|apte.ws_size
245           asq       sst|sst.pre_page_size
246 
247           read_clock                    meter time
248           sbaq      pre_time
249           adaq      sst|sst.post_purge_time
250           staq      sst|sst.post_purge_time
251           increment sst|sst.post_purge_calls
252 
253           tsx7      page_fault$trace_scheduling
254           tsx7      page_fault$unlock_ptl
255           return
256 
257 code_shift:
258           arg       32
259           arg       28
260           arg       24
261           arg       20
262           arg       16
263           arg       12
264           arg       8
265           arg       4
266 
267 
268           end