Re: [boost] boost::shared_ptr<>::compare_and_swap()--AmIinsaneforwanting this?

Wow...this is great! I think I may try to code up a wrapper that privately inherits from shared_ptr and just provides the spinlock around the operations, as a proof-of-concept. I'm doing this on Linux on x86 right now (32-bit). Should I use this spinlock implementation: http://en.wikipedia.org/wiki/Spinlock Or is there a better one? What would be a good name for the wrapper, do you think? -- George T. Talbot <gtalbot@locuspharma.com>
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Peter Dimov Sent: Friday, November 10, 2006 12:28 PM To: boost@lists.boost.org Subject: Re: [boost]boost::shared_ptr<>::compare_and_swap()-- AmIinsaneforwanting this?
Talbot, George wrote:
So that seems like a bit of a useless guarantee--basically any structure constructed with shared_ptr can only be read by the same thread that's writing to the structure unless all of the pointer operations are guarded with a mutex or spinlock, right?
Or an rwlock.
Correct, the guarantee isn't useful for writing lock-free code.
Ignoring compare-and-swap, have you or anyone else experimented with using a spinlock (as you mentioned previously) to remove the above restriction? What would that do to performance and complexity? Could you use a compare-and-swap type of operation to implement read/write thread safety?
The atomic operations would look like:
shared_ptr copy( shared_ptr const & p )
lock spinlock for p shared_ptr r = p; unlock spinlock for p return r
void replace( shared_ptr & p, shared_ptr q )
lock spinlock for p p.swap( q ); unlock spinlock for p
bool compare_and_swap( shared_ptr & p, shared_ptr const & cmp, shared_ptr xchg )
lock spinlock for p bool r = p == cmp; if( r ) p.swap( xchg ); unlock spinlock for p return r;
The critical regions are comfortably short, so using a spinlock seems justified. One problem is that shared_ptr doesn't have space for a spinlock, so we'd need to use a hashed spinlock pool keyed on 'this'. Or it might be possible to reuse the pointer as a spinlock, using something like (void*)- 1 as the 'locked' state. I haven't prototyped it, but it seems workable.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Talbot, George wrote:
Wow...this is great! I think I may try to code up a wrapper that privately inherits from shared_ptr and just provides the spinlock around the operations, as a proof-of-concept. I'm doing this on Linux on x86 right now (32-bit). Should I use this spinlock implementation: http://en.wikipedia.org/wiki/Spinlock
To be on the safe side, you'll probably need something a bit more elaborate than that: for( int i = 0; i < 4; ++i ) if( atomic_exchange( &spinlock, 1 ) == 0 ) return; // got spinlock // we probably need to yield to the thread holding the lock for( int i = 0; i < 32; ++i ) { if( atomic_exchange( &spinlock, 1 ) == 0 ) return; // got spinlock sched_yield(); } // we might need to yield to a lower-priority thread holding the lock for( ;; ) { if( atomic_exchange( &spinlock, 1 ) == 0 ) return; // got spinlock nanosleep( some-small-value ); } where 4 and 32 are fudge factors. But the simple version will work for a proof of concept. On Linux, it seems easiest to just use pthread_spin_lock/unlock for the prototype.
participants (2)
-
Peter Dimov
-
Talbot, George