golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.94k stars 17.53k forks source link

proposal: support padding for generic structs #62172

Open puzpuzpuz opened 1 year ago

puzpuzpuz commented 1 year ago

I'm trying to add padding on a generic struct (the full code is here):

type slotOfPadded[I any] struct {
    slotOf[I]
    pad [64 - (unsafe.Sizeof(slotOf[I]{}) % 64)]byte
}

type slotOf[I any] struct {
    turn uint64
    item I
}

and getting a compiler error as a result:

array length 64 - (unsafe.Sizeof(slotOf[I]{}) % 64) (value of type uintptr) must be constant

The padding is required to both align atomic ops on the turn field (I need to deal with an array of slotOfPadded structs) and to prevent false sharing.

The language doesn't seem to support this use case, but maybe there are any workarounds I'm not aware of. If there are none, it would be great to support adding padding on a generic struct.

ericlagergren commented 1 year ago

I believe this is because of https://github.com/golang/go/issues/40301.

Jorropo commented 1 year ago

Having a special unsafe.Align[const int] type wouldn't require adding compiletime-turing-completness to the language.

type slotOfPadded[I any] struct {
    _ unsafe.Align[64]
    slotOf[I]
    _ unsafe.Align[64]
}

type slotOf[I any] struct {
    turn uint64
    item I
}

It would also allows to help solve bugs like the uint64 atomic on 32bits platforms.


I guess you could also leave unsafe.Sizeof non const if used within functions but then it's even more inconsistent.

zephyrtronium commented 1 year ago

That suggestion seems to be #19057.

Jorropo commented 1 year ago

It has the same roots but it proposes hardcoded types instead of some const int parameter.


Edit: I see suggestions to make arrays of .Alligned to have bigger alignments in #19057's comments, which is surprising be would work I guess.