On 2/2/2021 11:02 AM, Marcel Mueller wrote:
> Am 01.02.21 um 23:00 schrieb Chris M. Thomasson:
>> Yeah. I think your right. Well, it might be nice for C++ to perhaps
>> create a new smart pointer based on Joe's atomic_ptr. But, then they
>> would get into the realm of possibly violating some patents... Humm...
>
> Hmm, indeed, patents might be a show stopper here.
Shit.
>>> However, one can write a partial specialization of
>>> std:atomic<shared_ptr<T>>) that implements the appropriate behavior.
>>> This /should/ be part of C++20. But there is no guarantee that this
>>> is implemented lock-free with an outer ref count. And obviously not
>>> all compilers already support this feature at all. :-/
>>
>> iirc, Peter Dimov tried really hard to get shared_ptr to support
>> strong thread safety, but failed to do so.
>
> With modifications to the shared_ptr class this should be straight forward.
> - The atomic shared pointer implementation needs to be a friend to
> access the internal structures.
> - AFAIR some care needs to be taken when a reference is freed because
> the ref counter could become negative for a short time due to threading
> issues.
>
>
>>> I implemented a lock free atomic version of a smart pointer several
>>> years ago. It was an intrusive pointer in my case, but this makes no
>>> significant difference.
>>
>> I think I remember you way back on comp.programming.threads. Do you
>> have any code remaining for your intrusive algorihtm?
>
> The code is still online and under a BSD like license. But it is also
> still designed for IBM VisualAge C++ 3 from the 90s, not even supporting
> C++03.
>
>
https://github.com/maazl/pm123/blob/master/src/utils/cpp/smartptr.h
Oh that's great. Will study up on it for sure. Thanks for the link
Marcel. Its been a while since I used the stolen bits hack: They can do
some magical things, indeed... ;^)
> I have same newer implementations too, but not public.
>
>> It would be fun to code it up in Relacy to check for any possible
>> issues, if any.
>
> The code needs to be rewritten to fit modern C++ standards firstly.
> Secondly it uses the stolen bits hack, so it does not depend on double
> word CAS. This was perfectly valid on the target platform and passed any
> tests hacking on the same shared instance with several dozens of threads.
Okay, nice. Humm... Iirc, I think Relacy might have some issues
simulating the stolen bits. Need to dig back into it. For me personally,
running the code through a race detector is always fun. I probably just
have to talk to Dmitry Vyukov. Its been a while since we discussed
Relacy. I have found some issues with it over the years, and he promptly
corrected them. He is working on the Go language, and ThreadSanitizer.
Iirc, ThreadSanitizer uses a lot of Relacy concepts. Also, I think he is
working on TensorFlow as well.
> With generic C++ the stolen bits hack is critical although it performs
> even better on 64 bit because you can safely use 3 bits. I am unsure if
> it can be implemented without introducing UB - although it is likely to
> work on any real hardware.
Yeah... It probably does have a UB issue. However, like you said, its
going to work on a vast majority of hardware.
>> It seems that C++ does not have std::intrusive_ptr. Iirc, it was in
>> boost. I might be missing something.
>
> You are absolutely right. In fact I always used my own smart pointers in
> projects. I even did not use the boost implementation of intrusive_ptr
> either. So I accidentally assumed that intrusive pointers made it into
> the standard.
>
> I mostly needed strong thread safety and, well, intrusive reference
> counting is by far more efficient. And the helper functions of
> boost::intrusive_ptr prevented strong thread safety. A reference counter
> need to be exposed as atomic<some_integer> somehow for strong thread
> safety.
Thanks for that info wrt boost::intrusive_ptr. I vaguely remember way
back on comp.programming.threads where somebody was trying to convince
me that strong thread safety is hardly ever needed. Iirc, my response
was that its not needed, until it is needed. ;^)
>>> So at the end no custom atomic lock free implementation of std shared
>>> pointer can exist because it does not allow access to the reference
>>> counter.
>>
>> Damn. Iirc, this is akin to what Peter was mentioning way back.
>> Existing shared_ptr needs to be modified at the implementation level
>> without breaking any existing use case.
>
> Exactly.
>
>> Perhaps, it might be better for C++20 to create a new smart pointer
>> that has strong thread safety... If you do not need strong thread
>> safety, use shared_ptr. If you do, use atomic_ptr. Sound Kosher?
>
> No, I don't think so.
>
> Only a new type for strongly thread safe instances is needed. This type
> should smoothly integrate with shared_ptr. atomic<shared_ptr> might
> become this type.
Ahhhh. Agreed. It sure seems to be the prime candidate.
atomic<shared_ptr> would be, or sure seems to be, the perfect place for it.
> It is very important, that the overhead for strong thread safety does
> not apply to all local instances and that object storage can be shared
> between normal and shared instances.
Big time! The separation of the use cases is essential. Joe did that
with atomic_ptr and local_ptr.
> And some operation cannot be implemented in a lock free manner at all.
> E.g. swapping two shared instances atomically is not possible. It would
> require transactional memory.
>
>
>> Have you taken a look at my experimental proxy collector code?
>
> No, I do not even know what code you refer here.
Ahhh, okay. Well here is a link to a crude C++ port. When you get some
free time to kill, can you give it a go?
C++11 version:
https://pastebin.com/raw/p1E9WN5i
Read this thread for context:
https://groups.google.com/g/comp.lang.c++/c/KwreljoeJ0k/m/KdQVJocuCQAJ
(oh shit! a google group link... The google might ban comp.lang.c++
next... shit)
It has some issues I need to clean up with negating unsigned. Just need
to get on that and get rid of some nasty casts. Fwiw, here is the
original thread where I posted it into the wild in the form of a Relacy
test unit:
https://groups.google.com/g/lock-free/c/X3fuuXknQF0/m/0VF_u-7shrsJ?pli=1
The Relacy Test Unit code:
https://pastebin.com/raw/f71480694
Passes all tests.
>> Still, I don't think it can be used to make shared_ptr strongly thread
>> safe. Well, perhaps it can, but it would have to be an internal
>> mutation of an existing implementation f shared_ptr. Oh well...
>
> Indeed.
Yeah, agreed. In closing, I will deeply read your code! Thanks again.