On Sat, Feb 4, 2017 at 7:34 AM 'Axel Wagner' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> I find this an inappropriate answer. Yes, they need care, but it should at
> least be possible to figure out how to use them from reading documentation
> (carefully). I tend to agree, that neither the spec nor the documentation
> of the atomic package is particularly helpful about these questions; at
> least I fail to read them in a way that unambiguously answers them.
> Without an authoritative and unambiguous description about what is
> guaranteed it is impossible to implement this robustly and if the spec
> isn't sufficiently unambiguous, it's natural to ask questions. Saying "you
> are not supposed to use them, unless you know how to use them" is, in
> context of all of this, just shutting people out.
>
> FWIW, I read the spec
> <https://golang.org/ref/spec#Size_and_alignment_guarantees>, Dave
> Cheney's blog post <https://dave.cheney.net/2015/10/09/padding-is-hard>
> about padding, the therein referenced #599 <https://golang.org/issue/599> and
> the atomic-documentation <https://godoc.org/sync/atomic#pkg-note-bug>, I
> find the whole situation still somewhat confusing. To try to interpret all
> of this and answer OPs question:
>
> I believe, that fields do not necessarily need to be properly aligned
> (explaining 599). However, *structs* have a necessary alignment, as
> required by their fields. So, if you do
> type S struct {
>     A uint32
>     B uint64
> }
> then there is no guarantee, that B is 64-bit aligned. The spec tells us,
> that unsafe.Alignof(s.A) will return 4 ("The functions Alignof and Sizeof
> take an expression x of any type and return the alignment or size,
> respectively, of a hypothetical variable v as if v was declared via var v =
> x", s.A is of type uint32 and such a variable has alignment 4),
> unsafe.Alignof(s.B) will return 8 and thus, unsafe.Alignof(s) will return 8
> ("For a variable x of struct type: unsafe.Alignof(x) is the largest of all
> the values unsafe.Alignof(x.f) for each field f of x, but at least 1").
>
> This means, that the compiler needs to align S on 64 bits. Now, #599 tells
> us, that on some archs s.B will *not* be 64 bit aligned. This is in
> accordance with the spec though, as confusing as that seems; the spec says
> only, how *a variable of the same type *as s.B must be aligned, not how
> s.B itself must be aligned (this is, where the confusion stems from). So a
> compiler might or might not insert padding.
>
> What all of this means, I believe, is
> * The atomic-documentation (maybe?) tells you, that the first field in a
> struct can be relied upon to be aligned. It says "the first word", though,
> and from what I can tell, there is nothing preventing a compiler to insert
> arbitrary padding at the beginning of a struct, technically speaking.
> * Thus you can guarantee that s.B is 8-byte aligned, by switching the
> fields around
> * Thus, your question about the embedding of expvar.Float seems to be
> "yes, it's safe", as the struct itself must be 64-bit aligned, even if
> embedded, and the 64-bit field is the only one contained
>

Wait, I don't think you've explained why expvar.Float would be aligned even
if embedded in another struct. I don't think that's guaranteed. The size
and alignment guarantees in the spec only make guarantees about variables,
not struct fields (even if they are themselves structs).


> * Your question about WaitGroup seems to be answerable by referring to the
> fact, that *technically *the noCopy field could misalign the data. But I
> tend to agree, that this reading would allow us to use a uint64, if we
> switch noCopy and state.
>

I don't agree with this either. Why do you think that structs embedded in
other structs are guaranteed to be aligned?


> Dave Cheney's blog post about padding wouldn't create technical problems
> here, because noCopy isn't the last field, thus gets no storage allocated…
> * Also, all of that reading seems to suggest that there really is no
> reliable, guaranteed way, to have multiple fields with a guaranteed
> alignment. So, if you need multiple variables to be accessed by atomics,
> you are out of luck.
>

Here I disagree again. As long as all fields in a struct variable before
yours are n*64 bits wide, you can be sure it will be 64 bit aligned.
Perhaps this needs to be documented. Also, doesn't this contradict your
statements above that structs embedded in other structs have alignment
guarantees?

Now, all of that being said, my reading could also be wrong. In any case,
> in my opinion, the fact that there is considerable guesswork involved,
> seems to suggest, that the spec is either ambiguous or insufficient to
> actually allow safe usage of atomics. It would be nice, if it could be a
> bit more explicit about what happens to fields.
>

I agree! :-)


> I understand, though, that we don't want to restrict too much the
> flexibility of a compiler to insert padding. But maybe a guarantee about
> the first field (not "word", what does that even mean?) of a struct being
> aligned, even the first fields (plural), if they all have the same
> alignment as the struct, would be clear enough *and* compatible with what
> compilers are already doing.
>
>
> On Sat, Feb 4, 2017 at 3:31 PM, Lars Seipel <lars.sei...@gmail.com> wrote:
>
> On Sat, Feb 04, 2017 at 01:30:49AM -0800, T L wrote:
> > Get it. This is quite bug prone to write programs on 64bit OSes and the
> > programs are expected to run on 32bit OSes too.
>
> Well, there's a reason the sync/atomic package docs have this statement
> right at the top:
>
> > These functions require great care to be used correctly. Except for
> special,
> > low-level applications, synchronization is better done with channels or
> the
> > facilities of the sync package.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to