SemaphoreMonitor.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Tue, 14 Jun 2016 08:10:12 +0100
branchjv
changeset 16695 a8eda516effa
parent 15950 23be8cf85415
child 17215 4a42de8e888a
permissions -rw-r--r--
Use new CmdLineParser when generating initial application startup code. Do not use (old, unmaitained) GetOpt as CmdLineParser has (will have) more features.

"
 COPYRIGHT (c) 1997 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libtool' }"

"{ NameSpace: Smalltalk }"

SystemStatusMonitor subclass:#SemaphoreMonitor
	instanceVariableNames:'semaphores'
	classVariableNames:''
	poolDictionaries:''
	category:'Monitors-ST/X'
!

!SemaphoreMonitor class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1997 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"


!

documentation
"
    This view shows smalltalks semaphores - a debugging tool.

    [see also:]
	Semaphore SemaphoreSet
	Process ProcessorScheduler
	WindowGroup
	ProcessMonitor

    [author:]
	Claus Gittinger

    [start with:]
	SemaphoreMonitor open
"

! !

!SemaphoreMonitor class methodsFor:'defaults'!

defaultLabel
    ^ 'Semaphore Monitor'

    "Created: 23.1.1997 / 02:52:53 / cg"
! !

!SemaphoreMonitor methodsFor:'drawing'!

titleLine
    ^ ' Id     Name                   Count Owner   Waiting Process(es)                   '.

    "
     SemaphoreMonitor open
    "

    "Modified: / 17.6.1998 / 14:52:48 / cg"
!

updateList
    "update list of semaphores"

    |newList|

    shown ifTrue:[
	newList := Semaphore allSubInstances.

	"sort by hashKey - will not always generate unique numbers,
	 but most of the time, this works ... for now"

	newList sort:[:s1 :s2 | s1 identityHash < s2 identityHash].

	newList ~= semaphores ifTrue:[
	    self updateStatus:newList
	].
    ].
    updateBlock notNil ifTrue:[
	Processor removeTimedBlock:listUpdateBlock.
	Processor addTimedBlock:listUpdateBlock afterSeconds:listUpdateDelay
    ].

    "Modified: / 3.7.1996 / 13:37:29 / stefan"
    "Created: / 23.1.1997 / 02:44:48 / cg"
    "Modified: / 14.12.1999 / 20:52:44 / cg"
!

updateStatus:newSemaphoreList
    "update status display of semaphores"

    |oldList list oldSelection newSelection|

    shown ifTrue:[
	oldList := listView list.
	oldSelection := listView selectionValue.
	oldSelection notNil ifTrue:[
	    oldSelection := oldSelection collect:[:line | line asCollectionOfWords first asNumber].
	    newSelection := OrderedCollection new.
	].

	newSemaphoreList notNil ifTrue:[
	    semaphores := WeakArray withAll:newSemaphoreList.
	].
	semaphores notNil ifTrue:[
	    list := OrderedCollection new:(semaphores size + 2).
	    list add:self titleLine.
	    list add:(String new:self titleLine size withAll:$-).

	    semaphores validElementsDo:[:aSemaphore |
		|waiters waitersNames nm id str owner color line count|

		"/ need a copy - it may change while being enumerated
		[
		    count := aSemaphore count.
		    waiters := aSemaphore waitingProcesses copy.
		] valueUninterruptably.

		str := '' writeStream.
		[
		    waiters notNil ifTrue:[
			waiters do:[:aProcess |
			    str nextPut:$[.
			    aProcess id printOn:str.
			    str nextPutAll:' '''.
			    str nextPutAll:(aProcess name contractTo:40).
			    str nextPutAll:'''<'.
			    aProcess priority printOn:str.
			    str nextPutAll:'>]'.
			    str space.
			].
		    ]
		] valueUninterruptably.
		waitersNames := str contents.

		(aSemaphore respondsTo:#name) ifTrue:[
		    nm := aSemaphore name.
		    nm isNil ifTrue:[
			nm := ''
		    ]
		] ifFalse:[
		    nm := ''
		].
		id := aSemaphore identityHash bitShift:-12.
		owner := aSemaphore lastOwnerId.
		owner isNil ifTrue:[
		    owner := '     '
		] ifFalse:[
		    owner := owner printStringLeftPaddedTo:5
		].
		line := (id printStringPaddedTo:6)
			  , ' '
			  , ((nm contractTo:25) paddedTo:25)
			  , ' '
			  , (count printStringLeftPaddedTo:3)
			  , ' '
			  , owner printString
			  , ' '
			  , (waiters size printStringLeftPaddedTo:3)
			  , ' '
			  , waitersNames.

		count > 0 ifTrue:[
		    waiters size > 0 ifTrue:[
			"this happens if a low priority process is ready to run but didn't wake up yet"
			color := Color red.
"/                        self beep.
		    ] ifFalse:[
			"fine, this semaphore is available"
			color := Color blue.
		    ].
		    line := line colorizeAllWith:color.
		] ifFalse:[
		    waiters size > 0 ifTrue:[
			line := line colorizeAllWith:Color brown.
		    ].
		].

		list add:line.
		oldSelection notNil ifTrue:[
		    (oldSelection includes:id) ifTrue:[
			newSelection add:list size.
		    ]
		]
	    ].
	].
	"avoid flicker"
	(oldList notNil and:[oldList size == list size]) ifTrue:[
	    list keysAndValuesDo:[:idx :entry |
		(oldList at:idx) ~= entry ifTrue:[
		    listView at:idx put:entry
		]
	    ]
	] ifFalse:[
	    listView setList:list.
	    "the first two entries cannot be selected"
	    listView attributeAt:1 put:#disabled.
	    listView attributeAt:2 put:#disabled.
	].
	newSelection notNil ifTrue:[
	    listView selectWithoutScroll:newSelection
	].
	listView flush
    ].
    updateBlock notNil ifTrue:[
	Processor removeTimedBlock:updateBlock.
	Processor addTimedBlock:updateBlock afterSeconds:updateDelay
    ]

    "Modified: / 3.7.1996 / 13:56:01 / stefan"
    "Created: / 14.12.1999 / 20:52:29 / cg"
    "Modified: / 14.12.1999 / 20:53:14 / cg"
! !

!SemaphoreMonitor methodsFor:'menu'!

debugWaiters
    "open a debugger on the selected semaphores waiting processes"

    self selectedSemaphoresDo:[:aSema |
	aSema waitingProcesses do:[:aProcess |
	    DebugView openOn:aProcess
	]
    ]

    "Modified: / 23.1.1997 / 03:12:06 / cg"
    "Created: / 17.6.1998 / 14:56:55 / cg"
!

inspectSemaphore
    "open an inspector on the selected semaphores"

    self selectedSemaphoresDo:[:aSema | aSema inspect]

    "Modified: 23.1.1997 / 03:12:06 / cg"
    "Created: 24.1.1997 / 23:11:50 / cg"
!

inspectWaiters
    "open an inspector on the selected semaphores waiting processes"

    self selectedSemaphoresDo:[:aSema |
	aSema waitingProcesses do:[:aProcess |
	    aProcess inspect
	]
    ]

    "Modified: / 23.1.1997 / 03:12:06 / cg"
    "Created: / 17.6.1998 / 14:17:41 / cg"
!

selectedSemaphoresDo:aBlock
    "evaluate aBlock on all selected semaphores"

    |p nr sel|

    sel := listView selection.
    sel isNil ifTrue:[^ self].

    (sel isKindOf:Collection) ifTrue:[
	sel do:[:n |
	    nr := n - 2.   "for headlines"
	    nr notNil ifTrue:[
		nr > 0 ifTrue:[
		    p := semaphores at:nr.
		    (p notNil and:[p ~~ 0]) ifTrue:[
		       aBlock value:p
		    ]
		]
	    ]
	]
    ] ifFalse:[
	nr := sel - 2.     "for headlines"
	nr notNil ifTrue:[
	    nr > 0 ifTrue:[
		p := semaphores at:nr.
		(p notNil and:[p ~~ 0]) ifTrue:[
		   aBlock value:p
		]
	    ]
	]
    ].

    "Created: 23.1.1997 / 03:11:24 / cg"
!

signalSemaphore
    "signal all selected semaphores"

    self selectedSemaphoresDo:[:aSema | aSema signal]

    "Created: 23.1.1997 / 03:12:30 / cg"
!

statusMenu
    "return a popUpMenu"

    <resource: #programMenu>

    |labels selectors m|

    labels := resources array:#(
			 'Inspect'
			 'Inspect Waiters'
			 'Debug Waiters'
			 '-'
			 'Signal'
			).
    selectors := #(
			 inspectSemaphore
			 inspectWaiters
			 debugWaiters
			 nil
			 signalSemaphore
			).

    updateProcess isNil ifTrue:[
	labels := (resources array:#('Update' '-')) , labels.
	selectors := #(updateView nil) , selectors
    ].

    m := PopUpMenu labels:labels
		   selectors:selectors.


    listView hasSelection ifFalse:[
	m disableAll:#(
			 inspectSemaphore
			 signalSemaphore
		      )
    ].
    ^ m

    "Modified: / 17.6.1998 / 14:17:05 / cg"
! !

!SemaphoreMonitor methodsFor:'queries'!

preferredExtent
    "return my preferred extent"

    ^ (self font widthOf:self titleLine) + 40 @ 250

    "Modified: 23.1.1997 / 02:35:01 / cg"
    "Created: 23.1.1997 / 03:04:58 / cg"
! !

!SemaphoreMonitor methodsFor:'user actions'!

doubleClicked
    "open an inspector on the selected semaphore"

    self inspectSemaphore

    "Created: 23.1.1997 / 03:22:04 / cg"
    "Modified: 31.1.1997 / 22:33:27 / cg"
! !

!SemaphoreMonitor class methodsFor:'documentation'!

version
    ^ '$Header: /cvs/stx/stx/libtool/SemaphoreMonitor.st,v 1.18 2014-04-11 14:22:55 stefan Exp $'
! !