Just to add, it is ok to have a pointer (unsafe.Pointer or otherwise) to
unreadable memory. For instance, you can use syscall.Mmap and
syscall.Mprotect to produce such a state. The GC will not dereference any
pointer that points outside the Go heap.
Public Service Announcement #1: Don't use syscall.Mprotect on the Go heap.
Public Service Announcement #2: It has to be mapped. It is not ok to have
a pointer to unmapped memory, as Go might later allocate that address for
the Go heap.
On Wednesday, August 22, 2018 at 4:53:40 PM UTC-7, Louki Sumirniy wrote:
>
> It seems to me the only way to achieve this would be to allocate a []byte
> twice the size you need, to be sure, then get the address of the start and
> offset it (if necessary) until it is a number (as in uintptr) divisible by
> 16, then it would be correctly structured. I would think you will find that
> you probably have to step quite outside of the normal go runtime to achieve
> this. Probably it would be better to write the primitives in C and then
> make glue to connect to it and stuff to make sure it's freed up at exit.
>
> On Wednesday, 22 August 2018 01:08:43 UTC+2, Carl Mastrangelo wrote:
>>
>> The answer must be more nuanced than that, because it is possible to take
>> a nil pointer and construct an unsafe.Pointer from it.
>>
>> The reason I am interested in this is (and please don't judge too early)
>> is I'm toying around with implementing some atomic primitives. In
>> particular, I would like to play around with with the cmpxchg16b
>> instruction which needs 16 byte alignment. Go does not provide a way to
>> enforce a data structure has such alignment, so I am attempting to define a
>> struct that I can index into. (assume 64bit words). For example, the
>> datastructure I want is this:
>>
>> // alignment of foo is 16
>> type foo struct {
>> uintptr
>> unsafe.Pointer
>> }
>>
>> But I can't assert this. The next best thing is to make a struct 2x the
>> size, and make a pointer to the first aligned part:
>>
>> type foo struct {
>> [4]uintptr
>> }
>>
>> This way I can get an aligned address pointing into the middle of this
>> array for using cmpxchg16b. The problem with this is that if any of the
>> interior values are not seen a pointers by the GC. In order to keep the
>> values alive they need to be unsafe.Pointer:
>>
>> type foo struct {
>> [4]unsafe.Pointer
>> }
>>
>> Now this is a problem. There is really only one pointer in here, the
>> other value is just some arbitrary bytes. Since the GC now things the
>> addresses are real, it will crash. What is the correct way to get an
>> aligned struct that contains pointers?
>>
>>
>>
>>
>>
>> On Tuesday, August 21, 2018 at 3:40:55 PM UTC-7, Ian Lance Taylor wrote:
>>>
>>> On Tue, Aug 21, 2018 at 1:19 PM, 'Carl Mastrangelo' via golang-nuts
>>> <[email protected]> wrote:
>>> >
>>> > If I create an unsafe.Pointer that points to an invalid memory
>>> address, but
>>> > I never deference it or otherwise pass it along, what happens to it?
>>>
>>> If you never deference it and never do anything with it, then in
>>> practice it most likely gets eliminated by the compiler. That said:
>>>
>>> > Is it a valid go program to just create such a pointer?
>>>
>>> No. The only way you could create such a Pointer is by converting
>>> from uintptr, or, essentially equivalently, by calling C or assembler
>>> code. The unsafe package docs explain all the cases in which it is
>>> permitted to convert a uintptr to an unsafe.Pointer. Using any other
>>> mechanism is invalid. The permitted mechanisms never produce an
>>> unsafe.Pointer that contains an invalid memory address.
>>>
>>> > The main reason I ask is
>>> > that I know the GC treats unsafe.Pointer values differently than
>>> uintptr.
>>> > If the GC were to chase this invalid pointer, it would likely get a
>>> > segfault. This means that either the GC knows not to chase such a
>>> pointer,
>>> > or it would chase it and gracefully recover.
>>>
>>> In practice, in the current implementation, what will happen is that
>>> the GC will attempt to find the object to which the pointer points,
>>> will fail, and will crash with a "pointer to unallocated span" error.
>>>
>>> > Additionally, if the unsafe.Pointer is pointing to a incorrectly
>>> aligned
>>> > address, the GC could potentially misunderstand and try to walk it.
>>> I'm
>>> > sure this has been thought of before, but it isn't called out in the
>>> docs.
>>>
>>> This isn't an issue with the current implementation. The current GC
>>> doesn't care about the type of the pointer, so pointers have no
>>> alignment requirements as far as the GC is concerned. Every pointer
>>> is effectively a *byte for GC purposes.
>>>
>>> Ian
>>>
>>
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.