[squeak-dev] Need help with identifying the problem

Igor Stasenko siguctua at gmail.com
Wed Apr 29 07:17:16 UTC 2009


In VM w/o closures, i implemented a new primitive,
#primitiveInterrupt, which looks like following:

primitiveInterrupt
	"primitive"
	| context interruptProcess sched oldProc |
	self export: true.
	context := self stackTop.

	sched := self schedulerPointer.
	"check that we using a new scheduler , which having additional
instance variables:
	 - interruptProcess
	 - interruptedProcess"
	(self lastPointerOf: sched) >= (InterruptedProcessIndex *
BytesPerWord + BaseHeaderSize)
		ifFalse: [ ^ self primitiveFail ].

	oldProc := self fetchPointer: ActiveProcessIndex ofObject: sched.
	interruptProcess := self fetchPointer: InterruptProcessIndex ofObject: sched.
	oldProc == interruptProcess ifTrue: [
		"we are already in interrupt, proceed as with sending #value to block"
		^ self primitiveValue
		].
	self storePointer: InterruptedProcessIndex ofObject: sched withValue: oldProc.
	self storePointer: SuspendedContextIndex ofObject: interruptProcess
withValue: context.
	self putToSleep: oldProc.
	self transferTo: interruptProcess.

	self pop: 1 thenPush: self nilObject
	

A primitive is hooked in
BlockContext>>primInterrupt :

primInterrupt
	"Primitive. Evaluate the block in special interrupt process"
	<primitive: 'primitiveInterrupt' module: ''>
	self primitiveFail


And code, which is using it looks like following:

Processor>>interruptWith: aBlock
	"Interrupt the currently running process to evaluate given block
argument inside
	interrupt process"
	| result |
	[ result := aBlock value.  activeProcess suspend. ] asContext primInterrupt.
	^ result
	
the VM crashing at attempt to return from aBlock value (it never gets
to the point for evaluating 'activeProcess suspend').

if i write code like following:

Processor>>interruptWith: aBlock
	"Interrupt the currently running process to evaluate given block
argument inside
	interrupt process"
	| result |
	[ [ result := aBlock value. ] value  activeProcess suspend. ]
asContext primInterrupt.
	^ result

Then VM does not crashing, but silenty quits to OS.

The only way how i managed to make it work, is to do it as:

Processor>>interruptWith: aBlock
	"Interrupt the currently running process to evaluate given block
argument inside
	interrupt process"
	[ self runBlock: aBlock ] asContext primInterrupt.

and runBlock: aBlock is:

runBlock: aBlock
	
	aBlock value.
	activeProcess suspend.

it works fine, except that i unable to use the returned result. - i
could put it to instance variable.. but its a bit awkward :(

I suspect this somehow connected with the return to context who having
sender = nil. (a bottom context of process always having sender =
nil).
But i wonder, why my code not working, while code, which used for
#fork, it does? Any suggestions?

newProcess
	"Answer a Process running the code in the receiver. The process is not
	scheduled."

	<primitive: 19> "Simulation guard"
	^ Process
		forContext:
			[self value.
			Processor terminateActive] asContext
		priority: Processor activePriority

here, the initial context of newly created process will point to:

[self value. Processor terminateActive]

and in my case, an initial context of interrupt process is set in
#primitiveInterrupt and points to:
[ result := aBlock value.  activeProcess suspend. ]

why i works for above case, but not for mine, no idea...

-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list