Boost logo

Boost :

From: Pavel Vasiliev (pavel_at_[hidden])
Date: 2003-02-11 08:54:49


Peter Dimov wrote:

> Pavel Vasiliev wrote:
>> May be the following code answers the challenge? :-).

> Interesting...

> [...]

>> void weak_ref_control_block::release_strong()
>> {
>> if(atomic_decrement(&strong_count) == 0)
>> strong_refs_lost();
>> }

>> bool weak_ref_control_block::acquire_strong_from_weak()
>> {
>> scope_lock lock(mutex_destruct);
>> if(atomic_increment(&strong_count) > 0)
>> return true;
>>
>> atomic_set(&strong_count, atomic_int_type_MIN);
>> return false;
>> }

> Thread A, in release: atomic_decrement(&strong_count) == 0
> Thread B, in acquire: atomic_increment(&strong_count) > 0, return true
> Thread A: strong_refs_lost(); // oops, B hates us at this point

> Isn't this a problem? Not that I want to break it... I'd like a lock-less
> implementation, too. :-)

No! :-)

Thread A, in release_strong:
       atomic_decrement(&strong_count) == 0
Thread B, in acquire_strong_from_weak:
       lock,
       see atomic_increment(&strong_count) > 0,
       return true
Thread A:
       enter strong_refs_lost(),
       wait for lock,
       see strong_count == 1, do nothing.

Another scenario:
Thread A, in release_strong:
       atomic_decrement(&strong_count) == 0,
       enter strong_refs_lost(),
       lock
Thread B, in acquire_strong_from_weak:
       wait for lock
Thread A, in strong_refs_lost:
       see strong_count == 0,
       set strong_count < 0,
       unlock
       destroy,
Thread B, in acquire_strong_from_weak:
       see atomic_increment(&strong_count) < 0,
       restore negative strong_count,
       return false

       
Is that what you are asking?

Pavel

PS: still examining the Alexander's implementation...


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk