151 "update status display of processes" |
163 "update status display of processes" |
152 |
164 |
153 |oldList list line dIndex con interrupted plist| |
165 |oldList list line dIndex con interrupted plist| |
154 |
166 |
155 shown ifTrue:[ |
167 shown ifTrue:[ |
156 oldList := listView list. |
168 oldList := listView list. |
157 processes notNil ifTrue:[ |
169 processes notNil ifTrue:[ |
158 list := OrderedCollection new. |
170 list := OrderedCollection new. |
159 list add:self titleLine. |
171 list add:self titleLine. |
160 list add:(String new:self titleLine size withAll:$-). |
172 list add:(String new:self titleLine size withAll:$-). |
161 |
173 |
162 interrupted := Processor interruptedProcess. |
174 interrupted := Processor interruptedProcess. |
163 |
175 |
164 dIndex := 1. |
176 dIndex := 1. |
165 1 to:processes size do:[:index | |
177 1 to:processes size do:[:index | |
166 |aProcess nm st c n| |
178 |aProcess nm st c c0 n found| |
167 |
179 |
168 aProcess := processes at:index. |
180 aProcess := processes at:index. |
169 aProcess notNil ifTrue:[ |
181 aProcess notNil ifTrue:[ |
170 (aProcess id notNil or:[hideDead not]) ifTrue:[ |
182 (aProcess id notNil or:[hideDead not]) ifTrue:[ |
171 line := aProcess id printStringPaddedTo:5. |
183 line := aProcess id printStringPaddedTo:5. |
172 (nm := aProcess name) isNil ifFalse:[ |
184 (nm := aProcess name) isNil ifFalse:[ |
173 nm := nm printString |
185 nm := nm printString |
174 ] ifTrue:[ |
186 ] ifTrue:[ |
175 nm := ' ' |
187 nm := ' ' |
176 ]. |
188 ]. |
177 nm size >= 29 ifTrue:[ |
189 nm size >= 29 ifTrue:[ |
178 nm := (nm contractTo:28) , ' ' |
190 nm := (nm contractTo:28) , ' ' |
179 ] ifFalse:[ |
191 ] ifFalse:[ |
180 nm := (nm printStringPaddedTo:29). |
192 nm := (nm printStringPaddedTo:29). |
181 ]. |
193 ]. |
182 line := line , nm. |
194 line := line , nm. |
183 "/ n := cpuUsages at:(aProcess id) ifAbsent:[0]. |
195 "/ n := cpuUsages at:(aProcess id) ifAbsent:[0]. |
184 "/ n ~~ 0 ifTrue:[ |
196 "/ n ~~ 0 ifTrue:[ |
185 "/ line := line , ((n * 4) printStringLeftPaddedTo:3) |
197 "/ line := line , ((n * 4) printStringLeftPaddedTo:3) |
186 "/ ] ifFalse:[ |
198 "/ ] ifFalse:[ |
187 "/ line := line , ' ' |
199 "/ line := line , ' ' |
188 "/ ]. |
200 "/ ]. |
189 st := aProcess state. |
201 st := aProcess state. |
190 (st == #run |
202 (st == #run |
191 and:[aProcess == interrupted]) ifTrue:[ |
203 and:[aProcess == interrupted]) ifTrue:[ |
192 c := ' *'. |
204 c := ' *'. |
193 ] ifFalse:[ |
205 ] ifFalse:[ |
194 c := ' '. |
206 c := ' '. |
195 ]. |
207 ]. |
196 line := line , c , (st printStringPaddedTo:9). |
208 line := line , c , (st printStringPaddedTo:9). |
197 line := line , (aProcess priority printStringLeftPaddedTo:3). |
209 line := line , (aProcess priority printStringLeftPaddedTo:3). |
198 line := line , (aProcess usedStackSize printStringLeftPaddedTo:11). |
210 line := line , (aProcess usedStackSize printStringLeftPaddedTo:11). |
199 line := line , (aProcess totalStackSize printStringLeftPaddedTo:10). |
211 |
200 showDetail ifTrue:[ |
212 n := aProcess numberOfStackSegments. |
201 n := aProcess numberOfStackSegments. |
213 n == 0 ifTrue:[ |
202 line := line , '(' , n printString , ')'. |
214 con := nil |
203 n == 0 ifTrue:[ |
215 ] ifFalse:[ |
204 con := nil |
216 con := aProcess suspendedContext. |
205 ] ifFalse:[ |
217 con isNil ifTrue:[ |
206 con := aProcess suspendedContext. |
218 aProcess == Processor activeProcess ifTrue:[ |
207 con isNil ifTrue:[ |
219 con := thisContext |
208 aProcess == Processor activeProcess ifTrue:[ |
220 ] |
209 con := thisContext |
221 ] |
210 ] |
222 ]. |
211 ] |
223 showDetail ifTrue:[ |
212 ]. |
224 line := line , (aProcess totalStackSize printStringLeftPaddedTo:10). |
213 con notNil ifTrue:[ |
225 line := line , '(' , n printString , ')'. |
214 line := line , ' '. |
226 con notNil ifTrue:[ |
215 line := line , ((ObjectMemory addressOf:con) printStringRadix:16). |
227 line := line , ' '. |
216 line := line , ' .. '. |
228 line := line , ((ObjectMemory addressOf:con) printStringRadix:16). |
217 [con sender notNil] whileTrue:[ |
229 line := line , ' .. '. |
218 con := con sender |
230 c := con. |
219 ]. |
231 [c sender notNil] whileTrue:[ |
220 line := line , ((ObjectMemory addressOf:con) printStringRadix:16). |
232 c := c sender |
221 ] ifFalse:[ |
233 ]. |
222 line := line , (String new:20) |
234 line := line , ((ObjectMemory addressOf:c) printStringRadix:16). |
223 ]. |
235 ] ifFalse:[ |
224 line := line , ' '. |
236 line := line , (String new:20) |
225 line := line , (aProcess numberOfStackBoundaryHits printStringLeftPaddedTo:5). |
237 ]. |
226 ]. |
238 line := line , ' '. |
227 list add:line. |
239 line := line , (aProcess numberOfStackBoundaryHits printStringLeftPaddedTo:5). |
228 processes at:dIndex put:aProcess. |
240 ]. |
229 dIndex := dIndex + 1 |
241 |
230 ] |
242 con notNil ifTrue:[ |
231 ]. |
243 "/ search for a semaphore-wait in the top 10 contexts |
232 ]. |
244 found := false. |
233 dIndex to:processes size do:[:index | |
245 c := con. |
234 processes at:index put:nil |
246 1 to:10 do:[:n | |
235 ] |
247 found ifFalse:[ |
236 ]. |
248 c notNil ifTrue:[ |
237 "avoid flicker" |
249 (c receiver isMemberOf:Semaphore) ifTrue:[ |
238 (oldList notNil and:[oldList size == list size]) ifTrue:[ |
250 c selector == #wait ifTrue:[ |
239 list keysAndValuesDo:[:idx :entry | |
251 found := true. |
240 (oldList at:idx) ~= entry ifTrue:[ |
252 ] |
241 listView at:idx put:entry |
253 ]. |
242 ] |
254 c := c sender. |
243 ] |
255 ] |
244 ] ifFalse:[ |
256 ] |
245 listView setList:list. |
257 ]. |
246 "the first two entries cannot be selected" |
258 found ifFalse:[ |
247 listView attributeAt:1 put:#disabled. |
259 c := con. |
248 listView attributeAt:2 put:#disabled. |
260 1 to:10 do:[:n | |
249 ] |
261 found ifFalse:[ |
|
262 c notNil ifTrue:[ |
|
263 (c receiver ~~ Processor) ifTrue:[ |
|
264 found := true. |
|
265 ] ifFalse:[ |
|
266 c := c sender. |
|
267 ] |
|
268 ] |
|
269 ] |
|
270 ] |
|
271 ]. |
|
272 found ifFalse:[ |
|
273 c := con |
|
274 ]. |
|
275 [c isBlockContext] whileTrue:[ |
|
276 c := c home |
|
277 ]. |
|
278 n := c receiver class name , '>>' , c selector. |
|
279 line := line , ' ' , n |
|
280 ]. |
|
281 list add:line. |
|
282 processes at:dIndex put:aProcess. |
|
283 dIndex := dIndex + 1 |
|
284 ] |
|
285 ]. |
|
286 ]. |
|
287 dIndex to:processes size do:[:index | |
|
288 processes at:index put:nil |
|
289 ] |
|
290 ]. |
|
291 "avoid flicker" |
|
292 (oldList notNil and:[oldList size == list size]) ifTrue:[ |
|
293 list keysAndValuesDo:[:idx :entry | |
|
294 (oldList at:idx) ~= entry ifTrue:[ |
|
295 listView at:idx put:entry |
|
296 ] |
|
297 ] |
|
298 ] ifFalse:[ |
|
299 listView setList:list. |
|
300 "the first two entries cannot be selected" |
|
301 listView attributeAt:1 put:#disabled. |
|
302 listView attributeAt:2 put:#disabled. |
|
303 ] |
250 ]. |
304 ]. |
251 updateBlock notNil ifTrue:[ |
305 updateBlock notNil ifTrue:[ |
252 Processor removeTimedBlock:updateBlock. |
306 Processor removeTimedBlock:updateBlock. |
253 Processor addTimedBlock:updateBlock afterSeconds:updateDelay |
307 Processor addTimedBlock:updateBlock afterSeconds:updateDelay |
254 ] |
308 ] |
255 ! |
309 ! |
256 |
310 |
257 updateView |
311 updateView |
258 self updateList. |
312 self updateList. |
259 self updateStatus |
313 self updateStatus |
|
314 ! ! |
|
315 |
|
316 !ProcessMonitor methodsFor:'events'! |
|
317 |
|
318 keyPress:key x:x y:y |
|
319 <resource: #keyboard ( #InspectIt ) > |
|
320 |
|
321 key == #InspectIt ifTrue:[ |
|
322 ^ self inspectProcess. |
|
323 ]. |
|
324 ^ super keyPress:key x:x y:y |
|
325 ! |
|
326 |
|
327 canHandle:key |
|
328 ^ key == #InspectIt |
260 ! ! |
329 ! ! |
261 |
330 |
262 !ProcessMonitor methodsFor:'initialization'! |
331 !ProcessMonitor methodsFor:'initialization'! |
263 |
332 |
264 initialize |
333 initialize |
361 suspendedColor := suspendedColor on:device. |
430 suspendedColor := suspendedColor on:device. |
362 |
431 |
363 self startUpdateProcess. |
432 self startUpdateProcess. |
364 ! ! |
433 ! ! |
365 |
434 |
366 !ProcessMonitor methodsFor:'private'! |
|
367 |
|
368 selectedProcessesDo:aBlock |
|
369 |p nr sel| |
|
370 |
|
371 sel := listView selection. |
|
372 sel isNil ifTrue:[^ self]. |
|
373 (sel isKindOf:Collection) ifTrue:[ |
|
374 sel do:[:n | |
|
375 nr := n - 2. "for headlines" |
|
376 nr notNil ifTrue:[ |
|
377 nr > 0 ifTrue:[ |
|
378 p := processes at:nr. |
|
379 p notNil ifTrue:[ |
|
380 aBlock value:p |
|
381 ] |
|
382 ] |
|
383 ] |
|
384 ] |
|
385 ] ifFalse:[ |
|
386 nr := sel - 2. "for headlines" |
|
387 nr notNil ifTrue:[ |
|
388 nr > 0 ifTrue:[ |
|
389 p := processes at:nr. |
|
390 p notNil ifTrue:[ |
|
391 aBlock value:p |
|
392 ] |
|
393 ] |
|
394 ] |
|
395 ]. |
|
396 ! |
|
397 |
|
398 selectedProcessesSend:aSelector |
|
399 self selectedProcessesDo:[:p | |
|
400 p perform:aSelector |
|
401 ]. |
|
402 self updateView. |
|
403 ! ! |
|
404 |
|
405 !ProcessMonitor methodsFor:'menu actions'! |
435 !ProcessMonitor methodsFor:'menu actions'! |
406 |
|
407 hideDead:aBoolean |
|
408 hideDead := aBoolean |
|
409 ! |
|
410 |
|
411 terminateProcess |
|
412 "terminate the selected process" |
|
413 |
|
414 self selectedProcessesSend:#terminate |
|
415 ! |
|
416 |
|
417 debugProcess |
|
418 "open a debugger on the selected process" |
|
419 |
|
420 self selectedProcessesDo:[:p | |
|
421 Debugger openOn:p |
|
422 ] |
|
423 ! |
|
424 |
|
425 abortProcess |
|
426 "abort (raise AbortSignal in) the selected process" |
|
427 |
|
428 self selectedProcessesDo:[:p | |
|
429 p interruptWith:[AbortSignal raise] |
|
430 ] |
|
431 ! |
|
432 |
|
433 inspectProcess |
|
434 "open an inspector on the selected process" |
|
435 |
|
436 self selectedProcessesSend:#inspect |
|
437 ! |
|
438 |
|
439 resumeProcess |
|
440 "resume the selected process (i.e. let it run) " |
|
441 |
|
442 self selectedProcessesSend:#resume |
|
443 ! |
|
444 |
436 |
445 processMenu |
437 processMenu |
446 |labels selectors m| |
438 |labels selectors m| |
447 |
439 |
448 device ctrlDown ifTrue:[ |
440 device ctrlDown ifTrue:[ |
516 "lower the selected processes priority" |
551 "lower the selected processes priority" |
517 |
552 |
518 self selectedProcessesDo:[:p | |
553 self selectedProcessesDo:[:p | |
519 p priority:(p priority - 1) |
554 p priority:(p priority - 1) |
520 ] |
555 ] |
521 ! |
556 ! ! |
522 |
557 |
523 detail |
558 !ProcessMonitor methodsFor:'private'! |
524 showDetail := showDetail not. |
559 |
525 self updateView |
560 selectedProcessesDo:aBlock |
526 ! ! |
561 |p nr sel| |
527 |
562 |
528 !ProcessMonitor methodsFor:'destroying'! |
563 sel := listView selection. |
529 |
564 sel isNil ifTrue:[^ self]. |
530 destroy |
565 (sel isKindOf:Collection) ifTrue:[ |
531 updateBlock notNil ifTrue:[ |
566 sel do:[:n | |
532 Processor removeTimedBlock:updateBlock. |
567 nr := n - 2. "for headlines" |
533 Processor removeTimedBlock:listUpdateBlock. |
568 nr notNil ifTrue:[ |
|
569 nr > 0 ifTrue:[ |
|
570 p := processes at:nr. |
|
571 p notNil ifTrue:[ |
|
572 aBlock value:p |
|
573 ] |
|
574 ] |
|
575 ] |
|
576 ] |
534 ] ifFalse:[ |
577 ] ifFalse:[ |
535 updateProcess notNil ifTrue:[updateProcess terminate] |
578 nr := sel - 2. "for headlines" |
536 ]. |
579 nr notNil ifTrue:[ |
537 super destroy |
580 nr > 0 ifTrue:[ |
|
581 p := processes at:nr. |
|
582 p notNil ifTrue:[ |
|
583 aBlock value:p |
|
584 ] |
|
585 ] |
|
586 ] |
|
587 ]. |
|
588 ! |
|
589 |
|
590 selectedProcessesSend:aSelector |
|
591 self selectedProcessesDo:[:p | |
|
592 p perform:aSelector |
|
593 ]. |
|
594 self updateView. |
538 ! ! |
595 ! ! |
539 |
596 |
540 !ProcessMonitor methodsFor:'queries'! |
597 !ProcessMonitor methodsFor:'queries'! |
541 |
598 |
542 preferredExtent |
599 preferredExtent |
543 ^ (font widthOf:self titleLine) + 40 @ 100 |
600 ^ (font widthOf:self titleLine) + 40 @ 100 |
544 ! ! |
601 ! ! |
545 |
602 |
546 !ProcessMonitor methodsFor:'events'! |
|
547 |
|
548 canHandle:key |
|
549 ^ key == #InspectIt |
|
550 ! |
|
551 |
|
552 keyPress:key x:x y:y |
|
553 <resource: #keyboard ( #InspectIt ) > |
|
554 |
|
555 key == #InspectIt ifTrue:[ |
|
556 ^ self inspectProcess. |
|
557 ]. |
|
558 ^ super keyPress:key x:x y:y |
|
559 ! ! |
|