Boost logo

Boost :

From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2020-06-01 19:27:10


Hi Peter,

Peter Dimov wrote:
> shared_ptr has a number of platform-specific implementations for its control
> block, specifically the atomic reference count manipulation:
>
> https://github.com/boostorg/smart_ptr/blob/develop/include/boost/smart_ptr/detail/sp_counted_base.hpp
>
> Those have been accumulated over the years and I'd like to clean them up,
> remove the unused ones and fold as many of them as possible into a few
> generic implementations using either std::atomic, GCC atomic intrinsics
> (https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/_005f_005fatomic-Builtins.html)
> or GCC/intel sync intrinsics
> (https://gcc.gnu.org/onlinedocs/gcc-10.1.0/gcc/_005f_005fsync-Builtins.html).
>
> But I have no experience with non-x86 platforms and don't know where
> boost::shared_ptr is still used and which of the platform-specific
> implementations are still needed. (Neither do I know on which platforms the
> atomic and the sync intrinsics actually work, as opposed to just compile and
> then fail to link.)

This brings back memories. It's about a decade since I was writing
ARM code for Boost.Atomic and/or shared_ptr.

At the time I suggested that shared_ptr should use Boost.Atomic, so that
we could do all the architecture-specific code once. That didn't
happen, not
least because it was a while before Boost.Atomic was actually reviewed and
included.

I think the summary is that on gcc + ARM platforms you should use the gcc
atomic builtins, or libstdc++ std::atomic (which invokes those
builtins) if
it exists. They do the right thing with minimal work. No need for any
assembler.

Before ARMv6 the only atomic instruction was an atomic swap. There are
still ARMv4t systems shipping; I'm coding for one right now. But they are
probably all microcontrollers, and it would be surprising to find anyone
using shared_ptr on them. There is still support in gcc; you can use
std::atomic if you implement __atomic_* (which might involve disabling
interrupts, for example). I've just tried std::shared_ptr, which compiles
and seems to use a non-atomic reference count.

ARMv5 embedded systems running Linux are also still shipping. On Linux,
the gcc builtins have kernel support which makes them quite efficient. Linux
distributions still support ARMv5 (Debian dropped support for ARMv4 last
year) so all sorts of exotic code is regularly being built for ARMv5 on
their build farms; you don't want to break this. None of these systems
are multiprocessor.

ARMv6 added ldrex/strex, and atomics can be implemented without OS
support using these in a loop. Again the gcc atomic builtins do the right
thing. This was mostly unchanged in ARMv8 and ARMv8 though at some point
byte and halfword and possible 8-byte atomics have been added. This
represents the vast majority of ARM systems. On iOS, I'd guess that
clang must provide the same atomic builtins as gcc which will do the
right thing but I've not checked that.

ARMv8.2 added a true set of atomic instructions. I believe the new AWS
ARM instances support these so they could be important to some users.
Presumably the gcc builtins would support them but only if a sufficiently-new
gcc knew it was targetting only that architecture variant. That raises the
question of executables that attempt to determine what atomic implementation
to use at run time....

Regards, Phil.


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