
Anthony Williams wrote:
"Phil Endecott" <spam_from_boost_dev@chezphil.org> writes:
Anthony Williams wrote:
One principle behind the new lock templates is that it should be easy to incorporate new mutex and lock types, and they will still work with the existing facilities (e.g. condition_variable_any).
Hi Anthony,
Can you clarify what you mean by that please? Are you saying that if I have a new mutex (e.g. my futex implementation) I should be able to use it with the existing condition_variable_any? (Is that what the "_any" means?) If that's true I'm impressed; I thought that it was necessary to have some sort of atomic unlock-A-and-lock-B method to do that.
Yes, that's what I meant, and that's what the _any means (as opposed to condition_variable which only works with unique_lock<mutex> (also known as mutex::scoped_lock)).
No, you don't need an atomic unlock-A-and-lock-B method, but it does need an extra internal mutex.
Thanks! I've found your source (for the pthreads version) here: http://svn.boost.org/svn/boost/trunk/boost/thread/pthread/condition_variable... So you're using a pthread_mutex and also a pthread_cond inside condition_variable_any. I was hoping to find that the internal mutex was the same type as the external one, and that the condition variable was implemented just using the mutexes. Hmm, actually I might want to use a different type of mutex for the internal and external locks e.g. a spinlock for the external one and a "proper" mutex (e.g. futex) for the internal one, since typically the external lock is probably low-contention while the condition itself blocks. Here's a completely rubbish pseudo-code sketch of the sort of thing I had in mind: template <typename INTERNAL_MUTEX = my_futex> class condition { std::set<INTERNAL_MUTEX> waiters; public: template <typename EXTERNAL_MUTEX> void wait(Lock<EXTERNAL_MUTEX>& l) { // This is full of races. What's the minimum functionality needed // to make this safe? (Atomic lock transfer between mutexes maybe?) INTERNAL_MUTEX w; w.lock(); waiters.insert(w); l.unlock(); w.lock(); l.lock(); waiters.erase(w); } void notify() { *(waiters.begin()).unlock(); // or all of them for notify_all() } }; I note that N2447 and your code have some swap functions for locks. Are these atomic? Also operator=. (I don't think they are.) Regards, Phil.