Multi-thread Question in Morph?

Rob Withers rwithers12 at comcast.net
Sat Jan 31 23:33:55 UTC 2004


Stef,  maybe SqueakElib would provide some ideas.  (on SqueakMap)   
There are plenty of problems unsolved, including the one you are  
having, but it does allow you to send messages to promises.   You could  
create the BotCommand as an eventual reference then send a  
#whenResolved: msg to it like so:


>>> addAction: aSelector arguments: anArray
>>>
>>> | anAction |
>>> anAction := (BotCommand selector: aSelector arguments: anArray).
>>> actionQueue addLast: anAction.
>>> ^ anAction eventual

and

>>> diamNumber
>>>
>>> ^ (self addAction: #diamNumberPrimitive)

finally

bot diamNumber whenResolved: [:eNum | transcript show: eNum asString].


or you could inspect the bot and inspect diamNumber, a promise which  
will #become an eventual reference to the diamNumber result.  You could  
replace the future in the BotCommand with an eventual reference to the  
BotCommand above.  My example here makes the sys double futured in a  
sense.  If you want to wait for the value, send #immediate to the  
eventual reference.  That will block until it resolves.

Now the missing stuff.     Evaluating expressions in an inspector on an  
eventual ref will get screwed up.  I think it has something to do with  
it getting confused about where to compile the DoIt, since there is a  
double proxy there.   It may also have trouble referencing self.  Bad  
inspector, no spyglass and no pipe!   Another issue is that #immediate  
blocks for the resolution, but it doesn't unwrap the eventual reference  
proxy.  I can't recall if I have another msg that does that.    All in  
all the behavior of these things are quite intriguing but my  
implementation is very complicated and there are big holes.   One of  
the biggest holes is that you can't use an eventual reference as a  
parameter to a primitive, so I had to hack a bunch of asString methods  
to even allow the inspector to work.  Bad solution - a hack long ago.    
I think I'd eventually like to see the VM detect primitive args are  
eventual and basically condition the eval of the primitive on  
resolution of all args.  I think this is creating a continuation on the  
primitive eval...

sorry for the discombobulated answer.  SqueakElib itself is a bit  
discombobulated.

cheers,
Rob

ps.  DESPlugins for linux and Windows are at:  
http://minnow.cc.gatech.edu/squeak/2410  at the very bottom.


Instead of blocking on the future by sending value,
On Saturday, January 31, 2004, at 02:57 PM, ducasse wrote:

>> Your problem is that the UI process (which is responsible for invoking
>> #step) waits for the promise to compute its value. However, that  
>> promise
>> will only be evaluated upon the next step, which would have to be run  
>> via
>> the UI process which blocks on the promise. In short, you have a  
>> classic
>> deadlock.
>
> Yes I see that :). Naively I was thinking that Morphic was more  
> concurrent.
> I was wondering how I can introduce more concurrency in the problem.  
> I'm bit afraid by the idea of forking
> the stepping mechanism.
> I will try to see how I can make a workspace that does not create the  
> deadlock and
> play with the solutions suggested by boris.
>
> I was wondering if other people using Morphic for simulation did not  
> get the same problem
>
> Stef
>
>
> On 31 janv. 04, at 23:03, Andreas Raab wrote:
>
>> Hi Stef,
>>
>>
>> Cheers,
>>   - Andreas
>>
>> ----- Original Message -----
>> From: "ducasse" <ducasse at iam.unibe.ch>
>> To: "The general-purpose Squeak developers list"
>> <squeak-dev at lists.squeakfoundation.org>
>> Sent: Sunday, February 01, 2004 1:52 AM
>> Subject: Multi-thread Question in Morph?
>>
>>
>>> Hi all
>>>
>>> I'm designing a simple environment with a bot evolving in a maze. The
>>> user can control the bots from a kind of workspace.
>>> In an old implementation, I did not use step and put some delay and
>>> World doOneCycle. Not so good. I decided to
>>> clean that and  to use the step method to execute commands sent to  
>>> this
>>> morph.
>>>
>>>
>>> The morph has a queue of actions (which are reified message sends  
>>> with
>>> a future to hold their result).
>>>
>>> For example the method go is implemented as
>>> NewBot>>go
>>>
>>> self addAction: #goPrimitive
>>>
>>> this means that when the action is executed the method goPrimitive  
>>> will
>>> be executed which is in fact implemented.
>>>
>>> goPrimitive
>>>
>>> self position: (self position + (10 at 10))
>>>
>>> addAction: and similar methods are implemented that way: a command
>>> object is created and put in the queue and returned.
>>>
>>> addAction: aSelector arguments: anArray
>>>
>>> | anAction |
>>> anAction := (BotCommand selector: aSelector arguments: anArray).
>>> actionQueue addLast: anAction.
>>> ^ anAction
>>>
>>> A command object is a message reification that holds a future so  
>>> that I
>>> can get result back to the sender when necessary (for exmaple getter
>>> method, as in the following example. result in that case get the  
>>> future
>>> and ask its value.
>>>
>>> diamNumber
>>>
>>> ^ (self addAction: #diamNumberPrimitive) result
>>>
>>> The step method goes over the queue and execute the actions one after
>>> the other. It then puts the future value
>>>
>>> step
>>>
>>> | action res |
>>> ^ actionQueue isEmpty
>>> ifFalse: [action := self removeAction.
>>> res := self perform: action selector withArguments: action
>>> arguments.
>>> action setFutureValue: res]
>>>
>>>
>>> Now I have the following problem that you can try just by loading the
>>> cs.
>>> If I create a morph NewBot new openInWorld, inspect it and execute  
>>> self
>>> diamNumber in an inspector, the complete environment
>>> is blocked.
>>>
>>> I simplified the problem to its essence in the attached file. If you
>>> open an inspect and evaluate self diamNumber
>>> the system freezes. Apparently there is not enough thread in morphic.
>>> So I started to see where I could
>>> put another thread. The problem is that
>>> - in an inspector doing [self diamNumber] fork does not help because  
>>> I
>>> would need another future to get the value form the thread
>>> - opening an inspector in another block (self inspect fork) and in  
>>> this
>>> new inspector doing self diamNumber still freezes the system
>>> My impression is that the UI scheduler does not let me doing that.
>>>
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------- 
>> ------
>> ----
>>
>>
>>>
>>>
>>> does anybody has an idea of how I could solve that problem?
>>>
>>>
>>>
>>> stef
>>
>>
>> ---------------------------------------------------------------------- 
>> ------
>> ----
>>
>>
>>>
>>>
>>
>>
>




More information about the Squeak-dev mailing list