David Miller <[EMAIL PROTECTED]> writes: > From: Ian Lance Taylor <[EMAIL PROTECTED]> > Date: 25 Oct 2007 21:31:56 -0700 > > > Samuel Tardieu <[EMAIL PROTECTED]> writes: > > > > > int > > > trylock() > > > { > > > int res; > > > > > > res = pthread_mutex_trylock(&mutex); > > > if (res == 0) > > > ++acquires_count; > > > > > > return res; > > > } > ... > > Code like needs to use volatile or explicit memory barriers. > > I totally disagree with you, and I think POSIX does too. > > Threaded programming is hard enough as it is. > > What's the point of the lock if a test on whether we've obtained it or > not can't be used to conditionalize code execution? > > Any write to memory is a globally visible side effect, and even > ignoring theading issues I bet similar cases can be constructed > involving signals that behave equally unexpectedly and should not > require bogus memory barriers or volatile. > > I'm not sure people realize the true ramifications of this suggested > "fix". It is rediculious, by any measure.
Conversely, I'm not sure you realize the true ramifications of any other fix. The above code happens to use pthread_mutex_trylock, but there is no need for that. We could have a global variable "lock_is_held". The code could look like this: if (lock_is_held) ++still_holding; If the earlier code should work in a multi-threaded environment, then this code should work. But then we see that there is nothing special about stores. The code could look like this: if (lock_is_held) waiting_count = threads_waiting; // Do something complicated, but don't call any functions. if (lock_is_held) if (threads_waiting > waiting_count) sched_yield(); If the earlier code should work in a multi-threaded environment, then this code should work too. But that means that we can't hoist the load of the global variable threads_waiting--we have to explicitly load it twice. And remember: this applies to all code. That means that if a single function loads a global variable, we must explicitly load it twice. And that is true even if that single function is constructed by inlining several other functions. At this point we are sacrificing significant optimization. So now we have a choice: make subtle multi-threaded code, which is not standard conformant, work as the programmer expects, or optimize programs with global variables and inline functions. There is a lot more of the latter than the former. And we do provide a way to make the former work. And the former is not standard conformant while the latter is. So I really don't think my position is all that ridiculous. And I challenge you to find anything in POSIX which says that this code is supposed to work. Ian