Subj : Re: Memory visibility with Pthreads To : comp.programming.threads From : David Schwartz Date : Thu Aug 11 2005 02:21 am "Maciej Sobczak" wrote in message news:ddet5n$43b$1@sunnews.cern.ch... Note that I'm assuming POSIX functions all through. >> Yes, the mutex functions are defined by POSIX to fully synchronize >> memory. > 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*. And for this, it makes a difference whether that other thread has memory barriers or not. 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. 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. > In other discussions about this issue it was usually stressed that writes > cannot be moved *from inside to outside* of the critical section embraced > by lock+unlock. I got an impression that it is always OK for the platform > to move "outer" writes *into* the section, which here would mean this: > > lock > A = 10; > B = 10; > unlock > > Is it allowed? 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 the order as seen on the CPU bus? The cache 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. > But is it allowed also to reorder the critical section with regard to > other outer writes? If yes, then the answer to the OP's question is no - > there is nothing that guarantees anything about the value of A when it's > read in thread 2. That is the answer either way. Regardless of the write order, the read orders aren't enforced. Even if thread 1 writes them in the correct order, that won't help the OP if thread 2 reads them in the wrong order, will it? > But if it is not allowed to move A=10; from before lock to after unlock, > then it means that lock and unlock are not really in pairs with regard to > memory visibility and each of them, even in separation, provides some > guarantees that can be relied upon (in the OP's case, the assumption is > that if lock2 is after unlock1, then everything after lock2 sees the > changes from before lock1). Is that true? No, not if the seeing thread has no memory barriers. The compiler is free to reorder reads unless memory barriers exist. DS .