# Smarter Atomic Smart Pointers

**URL:** <https://forum.juce.com/t/smarter-atomic-smart-pointers/58997>\
**Category:** General JUCE discussion\
**Created:** [November 30, 2023, 9:56am UTC](https://forum.juce.com/t/smarter-atomic-smart-pointers/58997 "2023-11-30T09:56:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nicolasdanet](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/nicolasdanet/32/56_2.png) [@nicolasdanet](https://forum.juce.com/u/nicolasdanet)\
**Post date:** [November 30, 2023, 9:56am UTC](https://forum.juce.com/t/smarter-atomic-smart-pointers/58997/1 "2023-11-30T09:56:00Z")

</div>

I just watched again that CPPCON talk:

[![](https://us1.discourse-cdn.com/flex026/uploads/juce/original/3X/1/9/1904a05d07448b766861ed7ef2ba35a5a353ee2a.jpeg "Smarter Cpp Atomic Smart Pointers - Efficient Concurrent Memory Management - Daniel Anderson CppCon") ](https://www.youtube.com/watch?v=OS7Asaa6zmY)

I’m curious to know if somebody in that forum already considered/tried it?

> **[GitHub - cmuparlay/concurrent\_deferred\_rc: Concurrent Deferred Reference...](https://github.com/cmuparlay/concurrent_deferred_rc)**
>
> Concurrent Deferred Reference Counting. Contribute to cmuparlay/concurrent\_deferred\_rc development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![Rincewind](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/rincewind/32/10645_2.png) [@Rincewind](https://forum.juce.com/u/Rincewind)\
**Post date:** [November 30, 2023, 11:52am UTC](https://forum.juce.com/t/smarter-atomic-smart-pointers/58997/2 "2023-11-30T11:52:53Z")

</div>

I have a few remarks about this:

1. In my experience (especially for us), it is actually quite often perfectly defined who owns data and who is just reading/updating it. I also found, that by defining who owns what, you end up with better code, because you put energy into getting the design right, instead of using shared\_ptr everywhere and letting the ref-count do the thinking for you. This is of course not always the case, and I also use shared\_ptrs very often, but I always know, where the origin of the “shared\_ptr” lives and I use it to not pay attention when the origin is deleting stuff while e.g. being in an undefined order of a ListenerList.
2. When I first read about std::snapshot\_source and std::snapshot\_ptr I was pretty excited. It sounded like the perfect answer to the problem of using shared\_ptr to access data computed by the audio thread or the “rendering tree” that the audio thread is working on while the UI wants to change stuff. However, **it is not**. std::snapshot\_source is not really paying attention to the fact, who is deleting something, while we want to make absolutely sure, that it is not the audio thread calling delete.

Until I came across this: [https://github.com/PalmerHogen/Snapshots/blob/main/Include/Snapshots.h](https://github.com/PalmerHogen/Snapshots/blob/main/Include/Snapshots.h) – it is doing exactly what I want out of concurrent memory management.

---

<div class="post-metadata">

**Author:** ![nicolasdanet](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/nicolasdanet/32/56_2.png) [@nicolasdanet](https://forum.juce.com/u/nicolasdanet)\
**Post date:** [January 5, 2024, 2:25pm UTC](https://forum.juce.com/t/smarter-atomic-smart-pointers/58997/3 "2024-01-05T14:25:37Z")

</div>

Just in case you missed it, from the same person, about lock free atomic shared pointer:

https://www.youtube.com/embed/lNPZV9Iqo3U?feature=oembed&wmode=opaque&list=PLHTh1InhhwT7gQEuYznhhvAYTel0qzl72

\< [https://youtu.be/lNPZV9Iqo3U?list=PLHTh1InhhwT7gQEuYznhhvAYTel0qzl72](https://youtu.be/lNPZV9Iqo3U?list=PLHTh1InhhwT7gQEuYznhhvAYTel0qzl72) \>

---

<div class="post-metadata">

**Author:** ![JeffMcClintock](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jeffmcclintock/32/21430_2.png) [@JeffMcClintock](https://forum.juce.com/u/JeffMcClintock)\
**Post date:** [January 5, 2024, 11:42pm UTC](https://forum.juce.com/t/smarter-atomic-smart-pointers/58997/4 "2024-01-05T23:42:26Z")

</div>

> [@Rincewind](#):
>
> …getting the design right, instead of using shared\_ptr everywhere.

Good point, passing a shared\_ptr is an implicit permission to delete the referenced object, and our goal should be to _never_ perform memory management (e.g. deleting an object that is managed by a shared\_ptr) on the real-time thread.

---

<div class="post-metadata">

**Author:** ![nicolasdanet](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/nicolasdanet/32/56_2.png) [@nicolasdanet](https://forum.juce.com/u/nicolasdanet)\
**Post date:** [January 6, 2024, 7:17am UTC](https://forum.juce.com/t/smarter-atomic-smart-pointers/58997/5 "2024-01-06T07:17:04Z")

</div>

In its talk the shared\_ptr exposed uses an hazard pointer to protect the control block and defer its reclamation. It explains later that the same approach could be used also for the object owned. I suppose that it could be possible to implement the shared pointer in a way that all the deletions would be done in a background thread… 🤔 i’m not sure it is possible with futur std hazard pointers.

---

<div class="post-metadata">

**Author:** ![PalmerHogen](https://avatars.discourse-cdn.com/v4/letter/p/a88e4f/32.png) [@PalmerHogen](https://forum.juce.com/u/PalmerHogen)\
**Post date:** [February 4, 2024, 6:09am UTC](https://forum.juce.com/t/smarter-atomic-smart-pointers/58997/6 "2024-02-04T06:09:23Z")

</div>

Hey! I’m glad to hear this repo came in handy – the approach is actually very similar to the split-refcount scheme for implementing atomic shared\_ptr, but I made no attempt to implement an atomic shared\_ptr 😅

Timur did a great talk on RCU, which is very similar, and his approach works much better if you know how many threads will be reading data in advance

[![](https://us1.discourse-cdn.com/flex026/uploads/juce/original/3X/0/a/0a85b84b1d006dbe1c63e3e17c0090f937168032.jpeg "Thread synchronisation in real-time audio processing with RCU (Read-Copy-Update) - Timur Doumler ADC") ](https://www.youtube.com/watch?v=7fKxIZOyBCE)

Unfortunately, I needed a way to read data from arbitrarily-many threads (sometimes recursively) without blocking, so packing a refcount and a lookup index into a single value was what I settled on.
