This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Implementing atomic load as compare-and-swap for read-only memory


On Fri, 2016-06-03 at 12:03 +0200, Jakub Jelinek wrote:
> On Fri, Jun 03, 2016 at 10:34:15AM +0100, Kyrill Tkachov wrote:
> > expand_atomic_load in optabs.c tries to expand a wide atomic load using an atomic_compare_and_swap
> > with the comment saying that sometimes a redundant harmless store may be performed.
> > Is the store really valid if the memory is read-only?
> > 
> > I've been looking at implementing a similar compare-and-swap strategy for atomic_loaddi for some
> > arm targets and this concern came up. I don't think GCC can statically prove that a particular
> > piece of memory is guaranteed to be writeable at runtime in all cases, so emitting a spurious
> > store would not be always valid.
> > 
> > I see this concern was already raised in https://gcc.gnu.org/ml/gcc-patches/2011-11/msg00278.html
> > but that doesn't seem to have gone anywhere.
> > 
> > Any thoughts? Should we remove the assumption that atomic loads always access writeable memory?

I think we shouldn't store to memory that we cannot be certain is
writable.

> I guess it is a tough decision.  If you don't have HW instruction to read
> say double word aligned integer atomically, if you don't implement atomic
> load on it through compare and swap (which indeed won't work with read-only
> memory), then you probably need to fall back to locks in libatomic.

And that would be fine, IMO.  If you can't even load atomically, doing
something useful with this type will be hard except in special cases.
Also, doing a CAS (compare-and-swap) and thus potentially bringing in
the cache line in exclusive mode can be a lot more costly than what
users might expect from a load.  A short critical section might not be
much slower.

If you only have a CAS as base of the atomic operations on a type, then
a CAS operation exposed to the user will still be a just a single HW
CAS.  But any other operation besides the CAS and a load will need *two*
CAS operations; even an atomic store has to be implemented as a CAS
loop.

> But doesn't that mean you should fall back to locked operation also for any
> other atomic operation on such types, because otherwise if you atomic_store
> or any other kind of atomic operation, it wouldn't use the locking, while
> for atomic load it would?

I suppose you mean that one must fall back to using locking for all
operations?  If load isn't atomic, then it can't be made atomic using
external locks if the other operations don't use the locks.

> That would be an ABI change and quite significant
> pessimization in many cases.

A change from wide CAS to locking would be an ABI change I suppose, but
it could also be considered a necessary bugfix if we don't want to write
to read-only memory.  Does this affect anything but i686?



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]