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 
>>> <golan...@googlegroups.com> 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 golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to