Subj : Re: double-checked locking in C To : comp.programming.threads From : David Hopwood Date : Thu Jul 07 2005 05:15 pm Laurent Deniau wrote: > David Schwartz wrote: >> "Laurent Deniau" wrote: >> >>> Now, there is the problem of reflecting the change of the side >>> effects to other threads. My suggestion was to put the flag inside >>> the side object itself. Therefore if the init_value is seen, the >>> object is also seen. Of course you may think that the object takes >>> place on cache line boundary and is only partially updated. That is >>> in the worst case, only the flag part and not the rest. But I am not >>> sure if this can happen. >> >> You just don't get it. We're talking about *PORTABLE* code written >> for an abstract machine. There is no such thing as a cache line. > > Right, I was try to examine how it could fail. > >> You have the guarantees the standards give you. And that's it. If >> you claim anything else is guaranteed, then you have code that's *not* >> portable. > > Then if I stick to standards, the C norm is enough (6.7.3-6 which says > all and nothing) and I just have to use volatile. Standard C90/99 doesn't define the behaviour of multithreaded code, whether volatile is used or not. POSIX explicitly says that the behaviour of your example code is undefined: # 4.10 Memory Synchronization # # Applications shall ensure that access to any memory location by more # than one thread of control (threads or processes) is restricted such # that no thread of control can read or modify a memory location while # another thread of control may be modifying it. Such access is restricted # using functions that synchronize thread execution and also synchronize # memory with respect to other threads. > At the sequence > points, the value is correct even if modified by side effects. But as > you know, it doesn't solve anything because of the presence of caches on > processors, something absent from the norm and very uncommon at the time > volatile was invented. It has nothing to do with the presence of caches. Your code can fail in practice because of reordering of memory accesses -- both processor reordering, and compiler reordering if whole-program optimization is done. -- David Hopwood .