[squeak-dev] About squeak mac vm

John M McIntosh johnmci at smalltalkconsulting.com
Mon Mar 31 20:07:14 UTC 2008


I believe you get that behavior if ioProcessEvents is not called  
enough. What happens is checkForInterrupts has to invoke  
ioProcessEvents so that
we can grab events off the os-x event queue and pass to handler, plus  
we peform any pending display flushes.  So if this does not happen  
fast enough
you get delay in macintosh menu interaction and in moving the window.

So either there is a bug in the checkForInterrupts related to clock  
rollover?  See code below.

Or the other places we call ioProcessEvents
is via ioGetNextEvent, ioGetButtonState, ioGetKeystroke, ioMousePoint,  
ioPeekKeystroke

now the last four here  ioGetButtonState, ioGetKeystroke,  
ioMousePoint, ioPeekKeystroke  date from pre event driven VM days.
So I'll bet the Morphic polling loop which calls ioGetNextEvent was  
killed. This would result in the VM sleeping because if there
is no work to be done, like waiting on socket traffic and there is no  
morphic polling we would sleep until woken, or the next timer pop.
This would affect how often checkForInterrupts is called since it  
relies on decrementing the interruptCheckCounter,
but that only happens when Squeak is running, not sleeping, so the  
frequency of calling ioProcessEvents could be quite low.


checkForInterrupts
	"Check for possible interrupts and handle one if necessary."
	| sema now |
	self inline: false.

	"Mask so same wrapping as primitiveMillisecondClock"
	now := self ioMSecs bitAnd: MillisecondClockMask.

	self interruptCheckForced ifFalse: [
		"don't play with the feedback if we forced a check. It only makes  
life difficult"
		now - lastTick < interruptChecksEveryNms
			ifTrue: ["wrapping is not a concern, it'll get caught quickly
				enough. This clause is trying to keep a reasonable
				guess of how many times per 	interruptChecksEveryNms we are calling
				quickCheckForInterrupts. Not sure how effective it really is."
				interruptCheckCounterFeedBackReset :=  
interruptCheckCounterFeedBackReset + 10]
			ifFalse: [interruptCheckCounterFeedBackReset <= 1000
					ifTrue: [interruptCheckCounterFeedBackReset := 1000]
					ifFalse: [interruptCheckCounterFeedBackReset :=  
interruptCheckCounterFeedBackReset - 12]]].

	"reset the interrupt check counter"
	interruptCheckCounter := interruptCheckCounterFeedBackReset.

	signalLowSpace
		ifTrue: [signalLowSpace := false. "reset flag"
			sema := self splObj: TheLowSpaceSemaphore.
			sema = nilObj ifFalse: [self synchronousSignal: sema]].

	now < lastTick
		ifTrue: ["millisecond clock wrapped so correct the nextPollTick"
			nextPollTick := nextPollTick - MillisecondClockMask - 1].
	now >= nextPollTick
		ifTrue: [self ioProcessEvents.
			"sets interruptPending if interrupt key pressed"
			nextPollTick := now + 200
			"msecs to wait before next call to ioProcessEvents.
			Note that strictly speaking we might need to update
			'now' at this point since ioProcessEvents could take a
			very long time on some platforms"].
	interruptPending
		ifTrue: [interruptPending := false.
			"reset interrupt flag"
			sema := self splObj: TheInterruptSemaphore.
			sema = nilObj
				ifFalse: [self synchronousSignal: sema]].

	nextWakeupTick ~= 0
		ifTrue: [now < lastTick
				ifTrue: ["the clock has wrapped. Subtract the wrap
					interval from nextWakeupTick - this might just
					possibly result in 0. Since this is used as a flag
					value for 'no timer' we do the 0 check above"
					nextWakeupTick := nextWakeupTick - MillisecondClockMask - 1].
			now >= nextWakeupTick
				ifTrue: [nextWakeupTick := 0.
					"set timer interrupt to 0 for 'no timer'"
					sema := self splObj: TheTimerSemaphore.
					sema = nilObj ifFalse: [self synchronousSignal: sema]]].

	"signal any pending finalizations"
	pendingFinalizationSignals > 0
		ifTrue: [sema := self splObj: TheFinalizationSemaphore.
			(self fetchClassOf: sema) = (self splObj: ClassSemaphore)
				ifTrue: [self synchronousSignal: sema].
			pendingFinalizationSignals := 0].

	"signal all semaphores in semaphoresToSignal"
	(semaphoresToSignalCountA > 0 or: [semaphoresToSignalCountB > 0])
		ifTrue: [self signalExternalSemaphores].

	"update the tracking value"
	lastTick := now



On Mar 28, 2008, at 2:15 AM, stephane ducasse wrote:

> Hi john
>
> I got a following behavior (while been in the train = no net  
> connection).
> I tried to load a squeakmap package and I press on apple - .
> after a while I got a wallback window. then I could only move the  
> apple
> window containing squeak is strange and extremely slow way. I had to  
> kill it.
>
> At the same time I got some other Squeak running well and which with  
> I could
> interact well and moving the mac ain window.
>
> I use 3.9.1 (in fact exactly sapphire-...
> 	Sapphire0.1-10016-2008-03-22 (which is based on 3.9.1) and is  
> available at http://sapphire.gforge.inria.fr/
>
> and the VM 3.8.18beta1U
>
> The bad news is that of course I could not reproduce it :(
>
> Stef
>

--
= 
= 
= 
========================================================================
John M. McIntosh <johnmci at smalltalkconsulting.com>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
= 
= 
= 
========================================================================





More information about the Squeak-dev mailing list