[Vm-dev] Re: Problem with alien callbacks

Igor Stasenko siguctua at gmail.com
Mon Apr 4 07:01:58 UTC 2011


On 4 April 2011 05:52, Javier Pimás <elpochodelagente at gmail.com> wrote:
>
> We were researching about this problem for some days now. We also met with Richie yesterday and he explained us a bit what we were seeing. If we are right, the problem is that the interpreter is not fully reentrant, so for callbacks mechanism to work you have to first set the interpreter in a state that it waits the callback to come in. That way, when the callback arrives, the interpreter is ready to handle it, and when it finishes handling, the state is correctly restored. Is that right?
> But in the multithreaded stack VM, you Eliot solved this in other way, right? I think you said that you set the stack as if it was full so that on the next method activation (well here I'm just guessing) or the next heartbeat you detected it and made space for the callback to come. I may have said nonsense sorry if that happened.
> The thing is that for our application of paging we need to solve the callback instantly, no matter what the interpreter is doing at the moment. So if I was correct about the StackVM, then we couldn't use that either. In that case what we'd need for this special type of callbacks is to be able to save all the context of the interpreter. We don't want to have a perfect solution, just a fine enough one (then we can improve it after moving to cog, but we must finish this step first, one at a time). Could you tell us which variables of the interpreter must be saved and which mustn't?
>
> Maybe Igor you had some experience about this with hydravm, right? Also, how do the nativeboost callbacks work, they might be just what we are looking for.
> Regards,
>           Javier.

Javier,
you can check the method
NBCoInterpreter>>swapActiveContext: newContext restoreMethod: aMethodOop

this is what i used to handle callbacks.

swapActiveContext: newContext restoreMethod: aMethodOop
	"swap active context with provided one,
	return old context pointer, or 0 on error"
	<export: true>
	| oldContext theFrame thePage |
	
	self push: instructionPointer.
	self externalWriteBackHeadFramePointers.
	oldContext := self ensureFrameIsMarried: framePointer SP: stackPointer.

	(self fetchClassOf: newContext) ~~ (self splObj: ClassMethodContext) ifTrue:
		[^0].
	aMethodOop ~= 0 ifTrue: [ newMethod := aMethodOop ].
	
	(self isStillMarriedContext: newContext)
		ifTrue:
			[theFrame := self frameOfMarriedContext: newContext.
			 thePage := stackPages stackPageFor: theFrame]
		ifFalse:
			[thePage := self makeBaseFrameFor: newContext.
			 theFrame := thePage baseFP].
	self assert: thePage headFP = theFrame.
	self setStackPageAndLimit: thePage.
	stackPointer := thePage headSP.
	framePointer := thePage headFP.
	(self isMachineCodeFrame: framePointer) ifFalse:
		[self setMethod: (self iframeMethod: framePointer)].

	instructionPointer := self popStack.
	
	^oldContext

-----
in nativeboost i'm not tried to do fancy things, after all, i am only
beginning to understand internals of Cog/Stack VM
So, what i did is just used same technique i used for Squeak VM - to
swap active context for callback, and then swap it back
when time to return.

The idea is simple:
once callback arrives,

the callback handler creating a new context, sets all required values there,
and then swaps the active context with a new one.

And same thing, when callback is done and its time to return to
caller, it again, before leaving , makes a call to same method
and swaps the context back to original (and also restores the method
oop, which were the method from which a primitive was called,
which then led to callback).

It worked before Eliot's changes (before Dec, 2010)... but now
something seems a bit broken. :)


-- 
Best regards,
Igor Stasenko AKA sig.


More information about the Vm-dev mailing list