
Just a note on the lightweight mutex for windows OS using Interlocked operations: I had one like this before (came with doug lee's allocator) and I ran some benchmarks and saw a ~10% improvement in performance in a non-contention situation. Now that benchmark may or may not have been valid, it's too long ago for me to say with certainty, but it raises the question, what are the numbers here? Also one does not need to use a spin lock on a ref counted implementation. A much faster (and safer) way to do that is just using InterlockedIncrement and InterlockedDecrement when changing the ref count. I beleive this is what most popular ref counting implementations use.

Dan wrote:
Also one does not need to use a spin lock on a ref counted implementation. A much faster (and safer) way to do that is just using InterlockedIncrement and InterlockedDecrement when changing the ref count. I beleive this is what most popular ref counting implementations use.
If you're referring to the ref-counted shared_ptr, then it has two counts it needs to keep track of, strong_count and weak_count, so InterlockedXXXXXX can't be used. Therefore the 'spin-lock' was introduced IIUC. Cheers Russell

Russell Hind wrote:
If you're referring to the ref-counted shared_ptr, then it has two counts it needs to keep track of, strong_count and weak_count, so InterlockedXXXXXX can't be used. Therefore the 'spin-lock' was introduced IIUC.
I like the looks of the 'shared_count_x86_exp2.hpp' code. I can't see how you could implement the 'atomic_conditional_increment' function with the atomic primitives supplied by gcc (atomicity.h) or the Linux kernel (atomic.h). The problem the weak pointers introduce is syncronization between the two counters (as Russell observed). I believe, however, that this is only an issue in 'add_ref_lock'. This is because we really have two interfaces here. A weak pointer interface and a strong pointer interface. A program that calls the strong interface from a weak pointer is in error (and would cause problems in the current implementation under the right conditons). Likewise for one that uses the weak interface from a strong pointer. Thus we can assume: 1) Code that calls a strong interface routine is telling us that both use_count_ and weak_count_ will not be concurrently decremented to zero by another thread (because our thread has at least one strong reference). 2) Code that calls a weak interface routine is telling us that the weak_count_ will not be concurrently decrement to zero by another thread (because our thread has at least one weak reference). If I am correct then, we could still do the following (as Windows, Linux, and gcc all provided atomic increment/decrement functions): // Strong interface void add_ref_copy(){ atomic_increment(use_count_); } void release(){ if(atomic_decrement(use_count_)) return; dispose(); weak_release(); } // Weak interface void add_ref_lock(){ mutex_type::scoped_lock lock(mtx_); if(atomic_increment(use_count_) == 1){ --use_count_; boost::throw_exception(boost::bad_weak_ptr()); } } void weak_add_ref(){ atomic_increment(weak_count_); } void weak_release(){ if(atomic_decrement(weak_count_)) return; destruct(); } -T NOTE: The gcc/Linux atomic operations return the prior value. The Windows operations return the new value. The above code uses the Windows style. -- Tyson Whitehead (-twhitehe@uwo.ca -- WSC-) Computer Engineer Dept. of Applied Mathematics, Graduate Student- Applied Mathematics University of Western Ontario, GnuPG Key ID# 0x8A2AB5D8 London, Ontario, Canada
participants (3)
-
Dan
-
Russell Hind
-
Tyson Whitehead