Subj : Re: Memory visibility with Pthreads To : comp.programming.threads From : Maciej Sobczak Date : Thu Aug 11 2005 01:16 pm David Schwartz wrote: >>Yes, but isn't it OK for the platform (compiler+CPU+memory+...) to reorder >>actions performed by thread 1 so that A = 10; is done after unlock? >>Something like this: >> >>lock >>B = 10; >>unlock >>A = 10; > > Your question is really meaningless. The reason is that you're missing > one critical layer of complexity. POSIX doesn't care about or talk about the > order of the operations themself, because it's not at all clear what that > would mean. All that matters is what another thread actually *sees*. Then let's assume that the above question (which considers thread 1 in OP's question) was asked in the context of what thread 2 sees. Thread 2 does this (from original post): lock if (B == 10) print("%d", A); unlock In this context - is it OK for the platform to reorder thread 1 so that assignment to A happens after thread 1's unlock? If no, then it is guaranteed that thread 2 prints 10. > And for > this, it makes a difference whether that other thread has memory barriers or > not. It has them. > So if the other thread does; > > if(A==10) ASSERT(B==10); > > Then, yes, they can be re-ordered as far as this thread sees. Without any locks nothing is guaranteed here. If you put lock/unlock around the above, then I would still ask for some clarification. The original thread 1 did this: A = 10; lock B = 10; unlock If the other thread does this: lock if (A == 10) assert(B == 10); unlock then it may fail at assertion point, since A==10 *may* be visible by thread 2 before thread 1 locks the mutex. It may be ubdefined behaviour as well, because access to A is not protected. There is no guarantee what really should happen. On the other hand, if the platform reorders thread 1 to this: lock B = 10; unlock A = 10; then there is still undefined behaviour at thread 2, for the same reason. Is this what you mean by saying that the platform *can* reorder thread 1 - by the virtue of being undefined in either case? But my question considered the original form for thread 2: lock if (B == 10) print("%d", A); unlock Here, the condition can be true only when thread 1 managed to do B = 10; and then unlock, followed by thread 2 locking the mutex. In this case, without the reordering of thread 1, thread 2 should print 10. But when the reordering of thread 1 takes place (so that assignment to A is after thread 1 unlocks), then there is undefined behaviour. Does it meant that the platform is *not* allowed to reorder thread 1? Note that even with A = 10; done outside of the critical section (but before lock), there is no undefined behaviour, since thread 2 uses A only when B == 10, which can be possible only after thread 1 finishes its stuff. > However, > if the other thread does: > > if(A==10) > { > lock > ASSERT(B==10); > unlock > } > > Then no, they cannot be re-ordered as far as this thread sees, because > the mutex functions are defined to fully synchronize memory. Here, there is undefined behaviour as well, because reading of A is not protected. > Your question is not meaningful because it's not clear what "B=10;" is > supposed to mean. Is it a write to cache? A write to main memory? Is POSIX concerned with all these concepts? In C, B=10; means assignment to a variable. I don't know what's a cache, main memory or bus. > All that matters is what another thread can see! And if that thread > doesn't use any functions that synchronize memory, it doesn't matter what > this thread does. Yes, but my question was considering the situation when *both* threads *use* functions that synchronize memory. I asked what that synchronization means with respect to assignments that are performed *outside* of the critical section made by locking and unlocking a mutex. If they are guaranteed to be visible as if they were in the same sequence as they appear in code, then fine. If they are not, then that's fine as well - but which is true is exactly what I was asking about. -- Maciej Sobczak : http://www.msobczak.com/ Programming : http://www.msobczak.com/prog/ .