Deutsch   English   Français   Italiano  
<vcb6el$3c3g5$2@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!weretis.net!feeder8.news.weretis.net!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: Paavo Helde <eesnimi@osa.pri.ee>
Newsgroups: comp.lang.c++
Subject: Re: Atomic caching of smart pointers
Date: Tue, 17 Sep 2024 09:09:26 +0300
Organization: A noiseless patient Spider
Lines: 79
Message-ID: <vcb6el$3c3g5$2@dont-email.me>
References: <vc7ahq$2akr4$1@dont-email.me> <vc7f5o$2atht$5@dont-email.me>
 <vca82m$32puo$1@dont-email.me> <vca8v5$327mo$1@dont-email.me>
 <vca96n$32c6u$2@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 17 Sep 2024 08:09:25 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="8634390b878b76fe06bd0d2d4efc76cb";
	logging-data="3542533"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX1/wW/lnDoYXMpv0+9NbtjaS5iAp99NSrT8="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:6MzJ+UHKo++Tf77SfTnN5DJJuNM=
In-Reply-To: <vca96n$32c6u$2@dont-email.me>
Content-Language: en-US
Bytes: 4937

On 17.09.2024 00:50, Chris M. Thomasson wrote:
> On 9/16/2024 2:46 PM, Chris M. Thomasson wrote:
>> On 9/16/2024 2:31 PM, Paavo Helde wrote:
>>> On 15.09.2024 23:13, Chris M. Thomasson wrote:
>>>> On 9/15/2024 11:54 AM, Paavo Helde wrote:
>>>>>
>>>>> I am thinking of developing some lock-free data structures for 
>>>>> better scaling on multi-core hardware and avoiding potential 
>>>>> deadlocks. In particular, I have got a lot of classes which are 
>>>>> mostly immutable after construction, except for some cached data 
>>>>> members which are calculated on demand only, then stored in the 
>>>>> object for later use.
>>>>>
>>>>> Caching single numeric values is easy. However, some cached data is 
>>>>> large and accessed via a std::shared_ptr type refcounted 
>>>>> smartpointers. Updating such a smartpointer in a thread-shared 
>>>>> object is a bit more tricky. There is a 
>>>>> std::atomic<std::shared_ptr> in C+ +20, but I wonder if I can do a 
>>>>> bit better by providing my own implementation which uses CAS on a 
>>>>> single pointer (instead of DCAS with additional data fields or 
>>>>> other trickery).
>>>>>
>>>>> This is assuming that
>>>>>
>>>>> a) the cached value will not change any more after assigned, and 
>>>>> will stay intact until the containing object destruction;
>>>>>
>>>>> b) it's ok if multiple threads calculate the value at the same 
>>>>> time; the first one stored will be the one which gets used.
>>>>>
>>>>> My current prototype code is as follows (Ptr<T> is similar to 
>>>>> std::shared_ptr<T>, but is using an internal atomic refcounter; 
>>>>> using an internal counter allows me to generate additional 
>>>>> smartpointers from a raw pointer).
>>>>>
>>>>> template<typename T>
>>>>> class CachedAtomicPtr {
>>>>> public:
>>>>>      CachedAtomicPtr(): ptr_(nullptr) {}
>>>>>
>>>>>      /// Store p in *this if *this is not yet assigned.
>>>>>      /// Return pointer stored in *this, which can be \a p or not.
>>>>>      Ptr<T> AssignIfNull(Ptr<T> p) {
>>>>>          const T* other = nullptr;
>>>>>          if (ptr_.compare_exchange_weak(other, p.get(), 
>>>>> std::memory_order_release, std::memory_order_acquire)) {
>>>>>              p->IncrementRefcount();
>>>>>              return p;
>>>>>          } else {
>>>>>              // wrap in an extra smartptr (increments refcount)
>>>>>              return Ptr<T>(other);
>>>>>          }
>>>>>      }
>>
>> So as long as CachedAtomicPtr is alive, the cached pointer, the one 
>> that gets installed in your AssignIfNull function, will be alive? 
>> Sorry if my question sounds stupid or something. Get trying to get a 
>> handle on your usage pattern. Also, the first pointer installed in 
>> CachedAtomicPtr will remain that way for the entire duration of the 
>> lifetime of said CachedAtomicPtr instance?
> 
> So as long as CachedAtomicPtr stays alive, the refcount on its 
> successfully _installed_ point will always be +1. In other words in 
> order for the count to drop to zero wrt its installed smart pointer, is 
> only _after_ CachedAtomicPtr has been destroyed and its dtor called? Am 
> I getting close or WAY off in the damn weeds somewhere out 
> there.... ;^) ? So one a smart pointer is installed in a 
> CachedAtomicPtr, it will never change? Am I right, or totally wrong?

Yes, all correct!

Now I see I also need to forbid assignment in the CachedAtomicPtr class 
to avoid modifying the installed smartpointer, and add a proper copy 
ctor. But that's a bit aside the main functionality of installing the 
cached smartpointer in a lock-free manner.

Thanks for the answer!
Paavo