Hello Mike!
> When thinking about thread-safety I've been assuming that the
> following are automatically thread-safe without the need for any
> explicit locking by the programmer:
>
> - Reading a reference value
This depends on the size of the Reference. Reading Word-Sizes (Int32 on x32)
are thread-safe, but above not (Int64 on x32). Obviously for 64 bit
Platforms, reading Int64 is also threadsafe.
> - Writing a reference value
The same.
> - Reading/writing built-in simple types sized 32 bits or less (Int32,
> Boolean etc)
This depends on the Type.
Less == yes
Boolean: Yes (Normaly the XXX.i1 OpCodes are used for working with bools,
there are no explicit OpCodes for Boolean)
DateTime: No (DateTime is an UInt64 in terms of memory)
> I'm slightly worried that I've never seen these assumptions explicitly
> confirmed. It's implied in some places - e.g. there's an
> Interlocked.Read(ref long) but no Interlocked.Read(ref int) - but I
> was hoping someone could point me to an official guarantee in the
> docs.
[Interlocked.Read Method (System.Threading)]
http://msdn2.microsoft.com/en-us/library/system.threading.interlocked.read.aspx
> I've also been assuming that static constructors are automatically
> thread-safe
The Runtime garantuees that the static constructor of any Type will only be
called once. That's all. Of cause it is possible, to write un-threadsafe
code within a cctor.
GP
Mike Capp - 12 Dec 2007 17:27 GMT
Hi Günter, thanks for the reply.
> > When thinking about thread-safety I've been assuming that the
> > following are automatically thread-safe without the need for any
[quoted text clipped - 3 lines]
>
> This depends on the size of the Reference.
I think we may be talking about different things. By "reference value"
I meant a reference to instances of Object-derived types, e.g.
object o = myObject; // is this guaranteed to be atomic?
rather than
void f(ref int i) { i = 123; }
Since I believe native-sized pointer read/write is atomic on all
likely systems, I suppose the question is really: is a CLR object
reference (guaranteed to be) no larger than a System.IntPtr on any
given system?
> > - Reading/writing built-in simple types sized 32 bits or less (Int32, Boolean etc)
>
> This depends on the Type. Less == yes
The question was about "32 bits or less", so that's fine.
> > It's implied in some places - e.g. there's an
> > Interlocked.Read(ref long) but no Interlocked.Read(ref int) - but I
> > was hoping someone could point me to an official guarantee in the
> > docs.
>
> [Interlocked.Read Method (System.Threading)]http://msdn2.microsoft.com/en-us/library/system.threading.interlocked...
Yes, I'd seen that, it just wasn't explicit about 32-bit values on a
32-bit system.
> The Runtime garantuees that the static constructor of any Type will only be
> called once.
Great, that's what I was looking for.
- Mike
Jon Skeet [C# MVP] - 12 Dec 2007 17:53 GMT
> > When thinking about thread-safety I've been assuming that the
> > following are automatically thread-safe without the need for any
[quoted text clipped - 5 lines]
> are thread-safe, but above not (Int64 on x32). Obviously for 64 bit
> Platforms, reading Int64 is also threadsafe.
That depends on what you mean by "thread-safe". They're atomic, but
unless you take *some* sort of action, there'll be no guarantee you get
the latest value.
Personally, I don't count "I'll read a value which was definitely valid
at some point, but might be an hour out of date" as thread-safe :)

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Mike Capp - 12 Dec 2007 18:37 GMT
> > Reading Word-Sizes (Int32 on x32)
> > are thread-safe, but above not (Int64 on x32). Obviously for 64 bit
[quoted text clipped - 6 lines]
> Personally, I don't count "I'll read a value which was definitely valid
> at some point, but might be an hour out of date" as thread-safe :)
Good point. I don't think that's a danger in the particular case I'm
looking at - the scope in question is very tight and doesn't contain
any loops - but I should probably be declaring 'volatile' if only for
the self-documentation aspect.
thanks,
Mike