Page 1 of 1
Thread safe access to shared data
Posted: Mon May 28, 2012 1:58 am
by AnishaKaul
From here:
http://stackoverflow.com/a/2485177/462608
For thread-safe accesses to shared data, we need a guarantee that
the read/write actually happens (that the compiler won't just store the value in a register instead and defer updating main memory until much later)
that no reordering takes place. Assume that we use a volatile variable as a flag to indicate whether or not some data is ready to be read. In our code, we simply set the flag after preparing the data, so all looks fine. But what if the instructions are reordered so the flag is set first?
- In which cases does compiler stores the value in a register and defers updating main memory? {with respect to the above quote}
- What is the "re-ordering" that the code is talking about? In what cases does it happen? How does it help? Why would compiler do that? After all doesn't it have to execute the instructions in the given order?
Re: Thread safe access to shared data
Posted: Mon May 28, 2012 3:39 am
by AnishaKaul
Thanks, that was a helpful link. I'll study it.
Meanwhile I asked this on the other forum and got to know that contents of the registers aren't visible outside a processor. Volatile keyword is used when we want to tell the compiler that this variable will be modified by some external source. So, when during multithreading on multiple processors at the same time, we may want a thread from an another processor to edit our variable, so we make it volatile by asking the compiler not to store it in the registers.
AnishaKaul wrote:Let me google "memory barriers" for you.
Thanks for the key word. I'll Google it and get back if I don't understand something.
Re: Thread safe access to shared data
Posted: Mon May 28, 2012 6:32 am
by Combuster
berkus wrote:AnishaKaul wrote:In which cases does compiler stores the value in a register and defers updating main memory?
It's the CPU, not the compiler doing the reordering.
Actually, the compiler is happy to replace
Code: Select all
bool locked = false;
void util()
{
locked = true;
/* access some stuff */
locked = false;
}
with
Code: Select all
bool locked = false;
void util()
{
/* access some stuff */
locked = false;
}
If the rest of the function does not have any dependencies on "locked". After all why would you do something if it's not going to get used anyway? The
Volatile keyword fixes that.
However, for actual mutual exclusion tasks you're usually better off using the lock bt* (for test-and-set), lock xadd (fetch-and-increment) or lock cmpxchg* (compare-and-swap) opcodes because they are designed for just that.
Re: Thread safe access to shared data
Posted: Tue Jun 05, 2012 2:44 am
by Creature
I just wanted to add that when using C/C++, using volatile should be enough to instruct the compiler to not optimize away any reads/writes to the variable nor cache it in the register. It also should not be moved around (at least according to the
VC++ compiler documentation). IIRC, things are different when using inline assembly (at least in GCC):
Code: Select all
// Mostly plug from the wiki.
__asm__("cli" : : : ); // GCC may optimize away or move around.
__asm__ __volatile__("cli": : : ); // GCC may not optimize away, but may still move around.
__asm__ __volatile__("cli": : : "memory"); // GCC may not optimize away and may not move around.
To make things even more complicated, according to some docs,
__asm__ __volatile__ should be enough to instruct the compiler to also not move the instruction around. Take a look
at the wiki and also the forum thread linked at the bottom.
If this is indeed the case and the instruction may still be moved when specifying __volatile__ and not specifying "memory" in the clobber list, forgetting to add this could lead to serious issues during optimization (particularly when CLI and STI instructions are used e.g. to prevent context switches and where their order is very important).
Re: Thread safe access to shared data
Posted: Tue Jun 05, 2012 2:52 am
by gerryg400
Re: Thread safe access to shared data
Posted: Tue Jun 05, 2012 3:26 am
by Creature
Yes, this was the thread I was referring to, thanks for placing it here. There should also be a link in the wiki at the page I linked at the bottom. I haven't been OSDevving for some time, but I remember having the exact same problem and realized after reading the thread that that was probably my mistake too.