2014-06-23 22:50 GMT+02:00 Nicolas Cellier <
[email protected]>:

>
>
>
> 2014-06-23 22:38 GMT+02:00 Norbert Hartl <[email protected]>:
>
> Hmmm,
>>
>> I'm trying to write a test for it and I wonder why
>>
>> testDynamicVariableAccessFromDifferentProcess
>> | process  sem1 result    |
>>  sem1 := Semaphore new.
>>  process := [
>> TestDynamicVariable
>> value: 123
>> during: [ sem1 wait ] ] fork.
>>  Processor activeProcess
>> evaluate: [  result := TestDynamicVariable value ]
>>  onBehalfOf: process.
>> sem1 signal.
>> self assert: result = 123
>>
>> does not work. The variable accessing is in
>>
>> DynamicVariable>>#value: anObject during: aBlock
>> | p oldValue |
>> p := Processor activeProcess.
>>  oldValue := (p psValueAt: index) ifNil: [ self default ].
>> ^ [
>> p psValueAt: index put: anObject.
>>  aBlock value ] ensure: [ p psValueAt: index put: oldValue ]
>>
>> Any ideas?
>>
>
> But what happens when you immediately fork, are you sure the forked
> process immediately pre-empts the activeProcess?
> What if you introduce Processor activeProcess yield after the fork?
>
>

Ah, I just tried, it's Processor yield.

[Transcript cr; show: 'A' ] fork.
Processor yield.
Transcript cr; show: 'B' .

produces the required transcripting order.
Without yielding, B comes before A.



>
>>
> Norbert
>>
>> Am 23.06.2014 um 21:29 schrieb Eliot Miranda <[email protected]>:
>>
>>
>>
>>
>>  On Mon, Jun 23, 2014 at 12:05 PM, Norbert Hartl <[email protected]>
>> wrote:
>>
>>> Hi Eliot,
>>>
>>> thank you very much. I imported your changes in a pharo 3 image and it
>>> works awesome. So I'm preparing a slice for pharo.
>>>
>>> Thanks again, a very annoying problem seems to be solved,
>>>
>>
>> glad to hear it, and thanks for your prompting me as it's now in Squeak
>> trunk too.
>>
>>
>>>
>>> Norbert
>>>
>>> Am 23.06.2014 um 19:29 schrieb Eliot Miranda <[email protected]>:
>>>
>>> and here are the changes I've just committed to Squeak trunk.
>>>
>>>
>>> On Mon, Jun 23, 2014 at 10:05 AM, Eliot Miranda<[email protected]>
>>>  wrote:
>>>
>>>> Hi Norbert,
>>>>
>>>>     [ let me try again.  never try and get code out too early in the
>>>> morning ;-) ]
>>>>
>>>>     it is the debugger that needs fixing, not your code !! :-).  The
>>>> debugger needs to respect process identity.  Andreas and I (mostly Andreas)
>>>> came up with the following changes at Qwaq.  Your message is a good
>>>> reminder that I need to add this to Squeak asap.
>>>>
>>>> The idea is for Process to have an additional inst var
>>>> 'effectiveProcess' that holds the actual process running code.  For the
>>>> most part this is self, but in the debugger we substitute the process being
>>>> debugged:
>>>>
>>>> *Process methods for accessing*
>>>> *effectiveProcess*
>>>> "effectiveProcess is a mechanism to allow process-faithful debugging.
>>>>  The debugger executes code
>>>>  on behalf of processes, so unless some effort is made the identity of
>>>> Processor activeProcess is not
>>>>   correctly maintained when debugging code.  The debugger uses
>>>> evaluate:onBehalfOf: to assign the
>>>>  debugged process as the effectiveProcess of the process executing the
>>>> code, preserving process
>>>>   identity."
>>>> ^effectiveProcess ifNil: [self]
>>>>
>>>> then the relevant methods in Process and processorScheduler defer to
>>>> effectiveProcess, e.g.
>>>>
>>>> *ProcessorScheduler methods for process state change*
>>>> *terminateActive*
>>>>  "Terminate the process that is currently running."
>>>>
>>>> activeProcess effectiveProcess terminate
>>>>
>>>> and the debugging methods use evaluate:onBehalfOf: to install the
>>>> process being debugged:
>>>>
>>>> *Process methods for private*
>>>> *evaluate: aBlock onBehalfOf: aProcess*
>>>>  "Evaluate aBlock setting effectiveProcess to aProcess.  Used
>>>>  in the execution simulation machinery to ensure that
>>>>   Processor activeProcess evaluates correctly when debugging."
>>>> | oldEffectiveProcess |
>>>> oldEffectiveProcess := effectiveProcess.
>>>>  effectiveProcess := aProcess.
>>>> ^aBlock ensure: [effectiveProcess := oldEffectiveProcess]
>>>>
>>>> *Process methods for changing suspended state*
>>>> *step*
>>>>
>>>> ^Processor activeProcess
>>>>  evaluate: [suspendedContext := suspendedContext step]
>>>> onBehalfOf: self
>>>>
>>>> *stepToCallee*
>>>>  "Step until top context changes"
>>>>
>>>> Processor activeProcess
>>>> evaluate:
>>>>  [| ctxt |
>>>> ctxt := suspendedContext.
>>>> [ctxt == suspendedContext] whileTrue: [
>>>>  suspendedContext := suspendedContext step]]
>>>> onBehalfOf: self.
>>>> ^suspendedContext
>>>>
>>>> etc.  Changes from a Qwaq image attached.
>>>>
>>>> HTH
>>>>
>>>>
>>>> On Mon, Jun 23, 2014 at 4:50 AM, Norbert Hartl <[email protected]>
>>>> wrote:
>>>>
>>>>> In my code I'm using a DynamicVariable to request a context object
>>>>> when needed. Until now I knew the name DynamicVariable only from seaside.
>>>>> There it is called WADynamicVariable and it is an exception. So I blindly
>>>>> assumed the pharo DynamicVariable works the same.
>>>>> I thought this might be a good optimization not to travel the stack
>>>>> all the time but put in the process.
>>>>> Now that I am using it I can see the difference. I find it real hard
>>>>> using it because I don't know how to debug/step in code. DynamicVariable 
>>>>> is
>>>>> a process specific variable but as soon as a debugger opens it is very
>>>>> likely to be in another process. This makes stepping in method using the
>>>>> DynamicVariable impossible. The only way round is to set break points 
>>>>> after
>>>>> the dynamic lookup and step from there. But this feels just wrong.
>>>>> What would be the best way to have DynamicVariable and be able to
>>>>> debug anything? Or is there a variant that uses the stack instead of the
>>>>> "active" process?
>>>>>
>>>>> thanks,
>>>>>
>>>>> Norbert
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> best,
>>>> Eliot
>>>>
>>>
>>>
>>>
>>> --
>>> best,
>>> Eliot
>>> <trunk4.6EffectiveProcessMethods.st
>>> <http://trunk4.6effectiveprocessmethods.st/>>
>>>
>>>
>>>
>>
>>
>> --
>> best,
>> Eliot
>>
>>
>>
>

Reply via email to