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

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

by David Flanagan :: Rate this Message:

Reply to Author | View in Thread

Charlie, Evan, Shri:

Just to be clear here, would you all agree that Thread.critical= is a
deprecated feature--removed in Ruby 1.9, and that your discussion of it
is limited to compatibility for Ruby 1.8 programs?  None of you are
proposing to revive it as a non-deprecated feature in your
implementations, are you?

        David Flanagan

Evan Phoenix wrote:

>
> On Dec 30, 2008, at 11:55 PM, Charles Oliver Nutter wrote:
>
>> 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.
>
> The way that I talk about what Thread.critical does is manipulate the
> preemptive Thread scheduler. So, it inhibits Threads from switching
> "randomly" at any point. Instead, Threads can only be scheduled
> explicitly. This means via Thread methods (inspect, value, join, run),
> as well as some IO methods that explicitly switch Threads.
>
> So, to use terms that people working with green threads use:
>
> "Thread.critical = false" == preemptive scheduling enabled
> "Thread.critical = true"  == cooperative scheduling enabled
>
> Obviously the idea with using cooperative scheduling is that the user
> knows what operations cause Threads to switch. Sadly in MRI, that
> knowledge completely known.
>
>>
>>
>> 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