| Deutsch English Français Italiano |
|
<vcb5ij$3c3g5$1@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 08:54:28 +0300
Organization: A noiseless patient Spider
Lines: 73
Message-ID: <vcb5ij$3c3g5$1@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>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Tue, 17 Sep 2024 07:54:28 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="8634390b878b76fe06bd0d2d4efc76cb";
logging-data="3542533"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18/kstBsuAEnumZ+tfXlIDzhR/N8168JKA="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:SZ/h1qEzhH0IKC0yHVXJExiTq5k=
Content-Language: en-US
In-Reply-To: <vca8v5$327mo$1@dont-email.me>
Bytes: 4343
On 17.09.2024 00:46, 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?
Correct. The `p->IncrementRefcount();` line will keep the assigned T
object alive, regardless of how many other smartpointers there are
pointing to it in any threads. The refcount is decremented in
~CachedAtomicPtr().
> 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?
Correct. Otherwise I would need a mutex, DCAS or some other trickery for
avoiding races.
Thanks for the answer!
Paavo