[m-dev.] thread.spawn_native

Paul Bone paul at bone.id.au
Fri Jun 13 14:01:00 AEST 2014


On Fri, Jun 13, 2014 at 01:12:44PM +1000, Michael Day wrote:
> Hi Paul,
>
>> If this isn't combined with a method of pinning the context to the engine,
>> and specifying that any foreign calls made within parallel conjunctions are
>> also executed on the same context (all implementation details) then it won't
>> work.  Which is what may_not_migrate is intended to solve.
>
> Okay, I guess I was thinking that if you called spawn_native, and the  
> Mercury code later blocked, then the whole thread would just block, 

That depends on whether the Mercury code blocks, or the foreign code blocks.
In the former we can run a seperate context (if we want to), in the latter
we cannot - which is the interesting situation.

> instead of scheduling a different Mercury context to run on it. Also,  
> that parallel conjunctions would be disabled for this thread. As a  
> result, it would give a guarantee that the code has complete ownership  
> of the thread and will not be preempted by some other unrelated code.  
> Thus no annotations on the foreign procs would be necessary.

Directly it implies that an engine has a gaurentee of what context it runs,
which _imples_ that a context has a gaurentee about which engine in runs on.
These are things that we'd have to explicitly choose.


> Does that sound too low-level, or just too incompatible with the way  
> Mercury engines and contexts work?

Yes, that could work.  However I think we can do better.  By using the
concept of contexts (N:M threading) we can write programs that can handle
large numbers of light weight threads using a small number of OS threads.
I beleive that this design goes against this goal and that other suitable
designes do not.


> Alternatively, it would be nice to hear a description of the proposed  
> may_not_migrate annotation that could be understood by a programmer with  
> no understanding of Mercury implementation details :)

If a foreign call with this annotation is executed Mercury will gaurentee that
all future foreign calls will be executed on the same operating system
thread.

>> In option #2 and because glVertex doesn't block so we can ignore
>> asynchronous IO.  there is no need to switch threads all the time.  If the
>> context is on the wrong thread then it is switched to the correct one before
>> calling glVertex and remains there until there's a different reason to
>> switch it again (maybe it goes to sleep and wakes up elsewhere?).  These
>> context switches should be rare but will be able to be measured.
>
> Right, so in this case "on the wrong thread" means not on the thread for  
> which the Mercury engine was originally created, because they've  
> switched at some point as a side-effect of other synchronisation  
> primitives? Seems like an indirect way of achieving thread-pinning,  
> similarly to trying to tie a process to a specific CPU. I was hoping  
> that spawn_native would give that by default.

First,  Mercury engines are mapped 1:1 with OS threads.  So "on the wrong
thread" is also "on the wrong engine".  (I'm sorry, sometimes we use thread
to mean context (light weight thread).)

Here by "on the wrong thread" I mean that the context is running on the
wrong OS thread (engine).  This can either be the engine that was created by
spawn_native (probably a good idea, if we go with the spawn_native
proposal) or the engine that the context was using the first time this
context executed a may_not_migrate foreign call[1].  Yes, other things such
as the context blocking on a channel, can cause the context to be executed
on a different engine later.

My goal is to pin the foreign code to a particular OS thread.  However it is
not necessary to pin the Mercury code to a particular OS thread.  So it's
relvent to ask "do we want to pin the Mercury code to a particular OS
thread?".  Not pinning the Mercury code will allow the runtime system more
flexability when scheduling such a context.  I think this could be useful
when it does a lot of computation in Mercury code and very little in foreign
code.  Or when the context executes a parallel conjunction, and we wish to
use other engines to execute the parallel conjunction.  Note that contexts
executing sparks from the parallel conjunction should inherit the
may_not_migrate property of the context that started the parallel
conjunction.

    1. Note that may_not_migrate has to have this behavour (or a similar
       one) even if spawn_native doesn't or isn't implemented.


-- 
Paul Bone



More information about the developers mailing list