Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C/C++, are volatile variables guaranteed to have eventually consistent semantics betwen threads?

Is there any guarantee by any commonly followed standard (ISO C or C++, or any of the POSIX/SUS specifications) that a variable (perhaps marked volatile), not guarded by a mutex, that is being accessed by multiple threads will become eventually consistent if it is assigned to?

To provide a specific example, consider two threads sharing a variable v, with initial value zero.

Thread 1: v = 1

Thread 2: while(v == 0) yield();

Is thread 2 guaranteed to terminate eventually? Or can it conceivably spin forever because the cache coherency never kicks in and makes the assignment visible in thread 2's cache?

I'm aware the C and C++ standards (before C++0x) do not speak at all about threads or concurrency. But I'm curious if the C++0x memory model, or pthreads, or anything else, guarantees this. (Apparently this does actually work on Windows on 32-bit x86; I'm wondering if it's something that can be relied on generally or if it just happens to work there).

like image 449
Jack Lloyd Avatar asked Jun 24 '10 21:06

Jack Lloyd


2 Answers

It's going to depend on your architecture. While it is unusual to require an explicit cache flush or memory sync to ensure memory writes are visible to other threads, nothing precludes it, and I've certainly encountered platforms (including the PowerPC-based device I am currently developing for) where explicit instructions have to be executed to ensure state is flushed.

Note that thread synchronisation primitives like mutexes will perform the necessary work as required, but you don't typically actually need a thread synchronisation primitive if all you want is to ensure the state is visible without caring about consistency - just the sync / flush instruction will suffice.

EDIT: To anyone still in confustion about the volatile keyword - volatile guarantees the compiler will not generate code that explicitly caches data in registers, but this is NOT the same thing as dealing with hardware that transparently caches / reorders reads and writes. Read e.g. this or this, or this Dr Dobbs article, or the answer to this SO question, or just pick your favourite compiler that targets a weakly consistent memory architecture like Cell, write some test code and compare what the compiler generates to what you'd need in order to ensure writes are visible to other processes.

like image 150
moonshadow Avatar answered Nov 09 '22 05:11

moonshadow


If I've understood correctly the relevant sections, C++0X won't guaranteed it for standalone variable or even volatile one (volatile isn't designed for that use), but will introduce atomic types for which you'll have the guarantee (see header <atomic>).

like image 29
AProgrammer Avatar answered Nov 09 '22 07:11

AProgrammer