« Return to Thread: [ruby-core:20999] Supporting Thread.critical=with native threads

[ruby-core:21012] Re: Supporting Thread.critical=with native threads

by Charles Oliver Nutter-2 :: Rate this Message:

Reply to Author | View in Thread

Shri Borde wrote:
> Yes, Thread#kill and Thread#raise can be implemented in IronRuby by using System.Threading.Thread.Abort (http://msdn.microsoft.com/en-us/library/system.threading.thread.abort.aspx). It is fragile (like you say, its impossible to support such operations reliably on native threads), and can be deferred indefinitely under some circumstances. So I think we ideally need to use both Thread.Abort and checkpoints.

As under the JVM (and under any system with parallel-executing threads)
System.Threading.Thread.Abort is provably unsafe, so if that's a concern
you'll definitely need to checkpoint to support Ruby's Thread#raise and
Thread#kill.

> About Thread.critical, you said:
>> Scripts that use critical= tend to expect that they're guaranteeing more
>> than just the code in the critical section. For example, if they're
>> initializing an instance variable they expect nobody else will access it
>> during initialization
> It would seem such code will not work even with MRI. If thread 1 sets Thread.critical=true and starts initializing the instance variable, and if thread 2 is accessing the instance variable without setting Thread.critical=true, then couldn't thread 2 run into a problem even if its not scheduled, since it could be anywhere in the middle of accessing the instance variable? To be fully correct, wouldn't thread 2 have to set Thread.critical=true, even on MRI?

Once critical=true is set in a thread, all current threads will be taken
out of scheduling, so in theory they would not even get the opportunity
to access any instance variables.

I'll grant that it's pretty fuzzy; I think people use Thread.critical=
in a lot of cases simply because they don't really know what they're
doing. If critical= could be specified as simply a thread-reentrant lock
against a special global mutex, it would probably be reasonable. As it
is, the implications are far greater than simply a critical section,
since it not only prevents other existing threads from running that
given piece of code, but also from running *at all*, and code has been
written, released, and tested with that assumption.

> By the way, what is the level of atomicity supported by MRI? For example, CPython uses the global interpreter lock (GIL) for each bytecode. However, since MRI does not compile to bytecode, is the AST nodes the correct level of atomicity?

The AST node is not a fine enough measure of atomicity; for example, for
a += b, there's a couple levels of node granularity, but obviously the
outermose "op assignment" can't be atomic. And when it comes down to
that, a large number of nodes are dependent on making method calls,
which usually can't be guaranteed atomic. I think it needs to be
considered on a case-by-case basis. JRuby guarantees instance vars can
be accessed and modified concurrently, for example, but makes no
guarantees about @a += b producing the result you expect in a
multi-threaded environment.

- Charlie

 « Return to Thread: [ruby-core:20999] Supporting Thread.critical=with native threads