On 10/22/07, Andrew Haley <aph-gcc at littlepinkcloud dot COM> wrote:
> The core problem here seems to be that the "C with threads" memory > model isn't sufficiently well-defined to make a determination > possible. You're assuming that you have no responsibility to mark > shared memory protected by a mutex as volatile, but I know of nothing > in the C standard that makes such a guarantee. A prudent programmer > will make conservative assumptions. I agree that according to the C and C++ language standards, any variable shared over threads should be declared volatile. But it is nearly impossible to live with this requirement: this requirement implies that for each library function that modifies data through pointers a second version should be added that accepts a volatile pointer instead of a regular pointer. Consider e.g. the function snprintf(), which writes to the character buffer passed as its first argument. When snprintf() is used to write to a buffer that is not shared over threads, the existing snprintf() function is fine. When however snprintf() is used to write to a buffer that is shared by two or more threads, a version is needed of snprintf() that accepts volatile char* as its first argument. My opinion is that it should be possible to declare whether C/C++ code has acquire, release or acquire+release semantics. The fact that code has acquire semantics means that no subsequent load or store operations may be moved in front of that code, and the fact that code has release semantics means that no preceding load or store operations may be moved past that code. Adding definitions for acquire and release semantics in pthread.h would help a lot. E.g. pthread_mutex_lock() should be declared to have acquire semantics, and pthread_mutex_unlock() should be declared to have release semantics. Maybe it is a good idea to add the following function attributes in gcc: __attribute__((acquire)) and __attribute__((release)) ? A refinement of these attributes would be to allow to specify not only the acquire/release attributes, but also the memory locations to which the acquire and release apply (pthreads synchronization functions always apply to all memory locations). I'm not inventing anything new here -- as far as I know the concepts of acquire and release were first defined by Gharachorloo e.a. in 1990 (Memory consistency and event ordering in scalable shared-memory multiprocessors, International Symposium on Computer Architecture, 1990, http://portal.acm.org/citation.cfm?id=325102&dl=ACM&coll=GUIDE). Bart Van Assche.