[Vm-dev] Delay machinery (was Re: [Pharo-dev] Suspending a
eliot.miranda at gmail.com
Sun Jul 27 03:05:31 UTC 2014
On Sat, Jul 26, 2014 at 4:36 PM, Ben Coman <btc at openinworld.com> wrote:
> Eliot Miranda wrote:
> Hi Ben,
> On Fri, Jul 25, 2014 at 7:56 AM, Ben Coman <btc at openinworld.com> wrote:
>> Over the last few days I have been looking deeper into the image locking
>> when suspending a process. It is an interesting rabbit hole  that leads
>> to pondering the Delay machinery, that leads to some VM questions.
>> When pressing the interrupt key it seems to always opens the debugger
>> with the following call stack.
>> Semaphore>>critical: 'self wait'
>> BlockClosure>>ensure: 'self valueNoContextSwitch'
>> Semaphore>>critical: 'ensure: [ caught ifTrue: [self signal]]
>> Delay>>schedule 'AccessProtect critical: ['
>> Delay>>wait 'self schedule'
>> I notice...
>> Delay class >> initialize
>> TimingSemaphore := (Smalltalk specialObjectsArray at: 30).
>> Delay class >> startTimerEventLoop
>> TimingSemaphore := Semaphore new.
>> which seems incongruous that TimingSemaphore is set in differently. So
>> while I presume this critical stuff all works fine, just in an exotic way,
>> my entropy-guarding-neuron would just like confirm this is so.
> The TimingSemaphore gets installed in the specialObjectsArray via
> primSignal: aSemaphore atMilliseconds: aSmallInteger
> "Signal the semaphore when the millisecond clock reaches the value of
> the second argument. Fail if the first argument is neither a Semaphore nor
> nil. Essential. See Object documentation whatIsAPrimitive."
> <primitive: 136>
> ^self primitiveFailed
> and from that the VM sets the nextWakeupUsecs:
> "Cause the time semaphore, if one has been registered, to be
> signalled when the microsecond clock is greater than or equal to
> the given tick value. A tick value of zero turns off timer interrupts."
> | msecsObj msecs deltaMsecs sema |
> <var: #msecs type: #usqInt>
> msecsObj := self stackTop.
> sema := self stackValue: 1.
> msecs := self positive32BitValueOf: msecsObj.
> self successful ifTrue:
> [(objectMemory isSemaphoreOop: sema) ifTrue:
> [*objectMemory splObj: TheTimerSemaphore put: sema*.
> deltaMsecs := msecs - (self ioMSecs bitAnd: MillisecondClockMask).
> deltaMsecs < 0 ifTrue:
> [deltaMsecs := deltaMsecs + MillisecondClockMask + 1].
> *nextWakeupUsecs := self ioUTCMicroseconds + (deltaMsecs * 1000)*.
> ^self pop: 2].
> sema = objectMemory nilObject ifTrue:
> storePointer: TheTimerSemaphore
> ofObject: objectMemory specialObjectsOop
> withValue: objectMemory nilObject.
> *nextWakeupUsecs := 0*.
> ^self pop: 2]].
> self primitiveFailFor: PrimErrBadArgument
>> In Delay class >> handleTimerEvent the comment says...
>> "Handle a timer event....
>> -a timer signal (not explicitly specified)"
>> ...is that event perhaps a 'tick' generated periodically by the VM via
>> that item from specialObjectArray ? Or is there some other mechanism ?
> Every time the VM checks for interrupts, which, in the Cog.Stack VMs is
> controlled by the heartbeat frequency, which defaults to 2 milliseconds,
> the VM checks if the current time has progressed to or beyond
> nextWakeupUsecs and signals the timer semaphore if so.
> Thanks Eliot. Just so I'm clear... the signals to the TimingSemaphore
> from the VM depend entirely on the Delays scheduled by the Image? The VM
> never signals the TimingSemaphore independently?
Right, yes and yes.
>>  http://www.urbandictionary.com/define.php?term=Rabbit+Hole
> and the problem here is not in the VM.
> Yep. Just looking to understand the interaction between VM and image.
> So climb out and breath some fresh air ;-)
> Soon :) but for the moment its a puzzle thats got hold of me, like a dog
> on a bone. This is a "hard" problem for me, and I like hard problems. It
> provides an opportunity to hold my attention to dig deeper and learn stuff
> that I otherwise might not.
> cheers -ben
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Vm-dev