Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / April 2008

Tip: Looking for answers? Try searching our database.

Atomic operations

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jon Harrop - 19 Apr 2008 14:34 GMT
Can read locks on a data structure be removed safely when updates are
limited to replacing a reference? In other words, is setting a reference an
atomic operation?

I have been assuming that all writes of <=1 word of data are atomic. Is this
actually documented anywhere?

Signature

Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u

Arne Vajhøj - 19 Apr 2008 14:55 GMT
> Can read locks on a data structure be removed safely when updates are
> limited to replacing a reference? In other words, is setting a reference an
> atomic operation?
>
> I have been assuming that all writes of <=1 word of data are atomic. Is this
> actually documented anywhere?

ECAM-334 says:

12.5 Atomicity of variable references
Reads and writes of the following data types shall be atomic: bool,
char, byte, sbyte, short, ushort,
uint, int, float, and reference types. In addition, reads and writes of
enum types with an underlying type
in the previous list shall also be atomic. Reads and writes of other
types, including long, ulong, double,
and decimal, as well as user-defined types, need not be atomic. Aside
from the library functions designed
for that purpose, there is no guarantee of atomic read-modify-write,
such as in the case of increment or
decrement.

and I read the "and reference types" as if reading and writing a
reference is atomic.

Arne
Jon Harrop - 19 Apr 2008 17:01 GMT
>> Can read locks on a data structure be removed safely when updates are
>> limited to replacing a reference? In other words, is setting a reference
[quoted text clipped - 20 lines]
> and I read the "and reference types" as if reading and writing a
> reference is atomic.

Sounds good to me. :-)

Signature

Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u

Jon Skeet [C# MVP] - 19 Apr 2008 15:15 GMT
> Can read locks on a data structure be removed safely when updates are
> limited to replacing a reference?

No.

> In other words, is setting a reference an atomic operation?

Yes, but that's not the same thing.

Atomicity guarantees that you won't see an invalid value - but it
doesn't mean you'll see the *latest* value. Due to JIT optimisations
etc, if you don't have a memory barrier there's no guarantee you'll
see any changes to the data.

Basically, if shared data can change you either need a memory barrier
or a lock (the latter of which provides a memory barrier) in order to
make sure you see the changed value.

Jon
Jon Harrop - 19 Apr 2008 16:59 GMT
>> Can read locks on a data structure be removed safely when updates are
>> limited to replacing a reference?
[quoted text clipped - 7 lines]
> Atomicity guarantees that you won't see an invalid value - but it
> doesn't mean you'll see the *latest* value.

I don't need to see the latest value.

If thread X is writing then I don't mind thread Y reading either the old or
new value provided it is read correctly.

Am I correct in thinking that replacing a reference to object A with a
reference to object B in thread X will yield a valid A or B in thread Y?

Signature

Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com/products/?u

Peter Duniho - 19 Apr 2008 17:14 GMT
> [...]
> Am I correct in thinking that replacing a reference to object A with a
> reference to object B in thread X will yield a valid A or B in thread Y?

I suppose that depends on whether the reference ever referred to something  
other than A or B.  If it did, then you could at least in theory get yet  
another value other than A or B (i.e. whatever the value was before it was  
A).  I think in practice the likelihood is low, but that's no way to prove  
your codeis correct.  :)

IMHO, even if you don't care about the age of the value, you should still  
use "volatile" with the variable.  You'll still have a race condition (but  
presumably not a harmful one), but you'll at least be assured that if the  
value is out-of-date, it's only because some other thread hasn't gotten to  
update it yet.

Without "volatile", compiler optimizations can cause worse problems, such  
as values that are no longer even relevant.

Pete
Jon Skeet [C# MVP] - 19 Apr 2008 17:43 GMT
> > Atomicity guarantees that you won't see an invalid value - but it
> > doesn't mean you'll see the *latest* value.
>
> I don't need to see the latest value.

Okay, then that's a different idea of "safely" than I think most
people would have :)

(I guess it is safe but not usually desirable.)

> If thread X is writing then I don't mind thread Y reading either the old or
> new value provided it is read correctly.
>
> Am I correct in thinking that replacing a reference to object A with a
> reference to object B in thread X will yield a valid A or B in thread Y?

Yes. So long as you don't mind if you never, ever, ever see the
reference to object B in thread Y, you're fine.

Jon
Arne Vajhøj - 19 Apr 2008 18:08 GMT
>>> Atomicity guarantees that you won't see an invalid value - but it
>>> doesn't mean you'll see the *latest* value.
[quoted text clipped - 4 lines]
>
> (I guess it is safe but not usually desirable.)

If the threads are really unsynchronized that is normal (the
two scenarios X not having set the ref yet and X having
set the ref but Y can not see it yet are somewhat equivalent).

>> If thread X is writing then I don't mind thread Y reading either the old or
>> new value provided it is read correctly.
[quoted text clipped - 4 lines]
> Yes. So long as you don't mind if you never, ever, ever see the
> reference to object B in thread Y, you're fine.

Is this problem:
- something that is undefined in the C#/CLI memory model but happens
  to work on x86 and x86-64 but could fail on IA-64 and PPC
or:
- something that can fail on x86 and x86-64 as well
?

(I think I have read that the x86/x86-64 memory model are not
so aggressive)

Arne
Jon Skeet [C# MVP] - 19 Apr 2008 18:23 GMT
> > Yes. So long as you don't mind if you never, ever, ever see the
> > reference to object B in thread Y, you're fine.
[quoted text clipped - 8 lines]
> (I think I have read that the x86/x86-64 memory model are not
> so aggressive)

I don't know about references, but I've certainly seen static boolean
variables being changed in one thread but that change never being seen
in a different thread, even on a single-core x86 machine. I believe
the other thread had effectively enregistered the variable, and saw no
reason to update the registers.

Admittedly as soon as there are non-inlined method calls involved, the
problem tends to go away IIRC - because the JIT can't know that the
method call won't involve a memory barrier, making the effective
reordering invalid - but it's something to be aware of anyway.

Jon
Arne Vajhøj - 19 Apr 2008 18:02 GMT
> Am I correct in thinking that replacing a reference to object A with a
> reference to object B in thread X will yield a valid A or B in thread Y?

That is what the language standard says.

Arne
Michael Justin - 19 Apr 2008 17:43 GMT
> Can read locks on a data structure be removed safely when updates are
> limited to replacing a reference? In other words, is setting a reference an
> atomic operation?

A related question: is there somethng like AtomicBoolean etc. also
available in C# standard libraries?

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/package-summ
ary.html


This is A small toolkit of classes that support lock-free thread-safe
programming on single variables.

I have recently found that these Atomic<Datatype> classes are really
useful in multithreaded applications, and since I am still a novice to
C# maybe somebody knows if they exist...

Best Regards
Signature

Michael Justin
SCJP, SCJA
betasoft - Software for Delphi™ and for the Java™ platform
http://www.mikejustin.com - http://www.betabeans.de

Jeroen Mostert - 19 Apr 2008 18:06 GMT
>> Can read locks on a data structure be removed safely when updates are
>> limited to replacing a reference? In other words, is setting a
[quoted text clipped - 5 lines]
>
> http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/package-summ
ary.html
 

Try the Interlocked class. It should actually be possible to write classes
like AtomicBoolean in C# using that.

Signature

J.
http://symbolsprose.blogspot.com

Barry Kelly - 20 Apr 2008 03:45 GMT
> Can read locks on a data structure be removed safely when updates are
> limited to replacing a reference? In other words, is setting a reference an
> atomic operation?

As others have pointed out, these are two different questions, and don't
have the same meaning.

In the more loose memory architectures (ruling out the x86,
essentially), there are publishing issues with assigning references that
are read from a different thread. If the hardware reorders reads or
writes, then it's possible to publish a value (i.e. replace a reference
in a structure visible to other threads) that isn't fully created.

For example, in the following program it's possible that "Oh dear!" will
get printed to the console, if the hardware reorders reads and writes:

---8<---
using System;
using System.IO;
using System.Threading;

class App
{
   static Referent Reference;
   
   class Referent
   {
       public int Field;
   }
   
   static void Main()
   {
       Thread setter = new Thread(() =>
       {
           for (;;)
           {
               Referent r = new Referent();
               r.Field = 42;
               Reference = r;
           }
       });
       setter.Start();
       
       for (;;)
       {
           Referent r = Reference;
           if (r != null && r.Field == 0)
           {
               Console.WriteLine("Oh dear!");
               break;
           }
       }
       Environment.Exit(0);
   }
}
--->8---

It does, however, appear to work perfectly fine as is on x86. x86
doesn't seem to do the kinds of reorderings that can cause problems
here.

-- Barry

Signature

http://barrkel.blogspot.com/


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.