But it’s a data race regardless. Even if the runtime did interrupt the go 
routine mid write and change the stack it would be forced to eventually correct 
the value to have the write be valid - but if another routine is reading that 
value, including the GC, there must be synchronization added. In the case of GC 
it is internal - for a user go routine it must be explicit. 

> On Apr 22, 2020, at 3:44 PM, Ian Lance Taylor <i...@golang.org> wrote:
> 
> On Wed, Apr 22, 2020 at 7:08 AM T L <tapir....@gmail.com> wrote:
>> 
>> I understand that, by the case 6 in the unsafe package docs,
>> the second program should be safe with or without the runtime.KeepAlive call.
>> I just wonder how Go runtime achieves this goal.
>> I have an impression that pointer assignments in Go by gc is atomically,
>> but is this also true for uintptr value assignments?
> 
> Using the meaning of "atomic" from my previous message, then, yes,
> both pointer assignments and uintptr assignments are done in a way
> that can not be interrupted.  That more or less happens automatically,
> as it's a single machine instruction either way.  And in fact it's the
> same machine instruction, since pointers and uintptr are the same size
> and use the same registers.
> 
> Ian
> 
> 
>>> On Wednesday, April 22, 2020 at 7:33:22 AM UTC-4, T L wrote:
>>> 
>>> 
>>> 
>>> On Tuesday, April 21, 2020 at 8:13:17 PM UTC-4, Ian Lance Taylor wrote:
>>>> 
>>>> On Tue, Apr 21, 2020 at 8:17 AM T L <tapi...@gmail.com> wrote:
>>>>> 
>>>>> And is the runtime.KeepAlive call in the following program essential to 
>>>>> keep the correctness?
>>>>> 
>>>>> package main
>>>>> 
>>>>> import (
>>>>>    "fmt"
>>>>>    "unsafe"
>>>>>    "reflect"
>>>>>    "runtime"
>>>>> )
>>>>> 
>>>>> func main() {
>>>>>    a := [6]byte{'G', 'o', 'o', 'g', 'l', 'e'}
>>>>>    bs := []byte("Golang")
>>>>>    hdr := (*reflect.SliceHeader)(unsafe.Pointer(&bs))
>>>>>    hdr.Data = uintptr(unsafe.Pointer(&a))
>>>>> 
>>>>>    runtime.KeepAlive(&a) // Is this line essential here?
>>>>> 
>>>>>    hdr.Len = 2
>>>>>    hdr.Cap = len(a)
>>>>>    fmt.Printf("%s\n", bs) // Go
>>>>>    bs = bs[:cap(bs)]
>>>>>    fmt.Printf("%s\n", bs) // Google
>>>>> }
>>>> 
>>>> I do not think the runtime.KeepAlive is required.  Setting the Data
>>>> field using a *SliceHeader should keep the value alive.
>>>> 
>>>> Ian
>>> 
>>> 
>>> 
>>> Many thanks for the answers.
>>> 
>>> I have another question, which doesn't matter with or without the 
>>> runtime.KeepAlive call.
>>> We know that assignment in Go is not atomic.
>>> Is it possible that when the assignment "hdr.Data = 
>>> uintptr(unsafe.Pointer(&a))" is half done,
>>> the stack is resized, so the address of a might be changed (assume a is 
>>> allocated on stack),
>>> the hdr.Data will be assigned the old invalid value?
>>> 
>> --
>> 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.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/2b9b1bec-4176-421f-8820-a6ff2bf2ead2%40googlegroups.com.
> 
> -- 
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVd6cjuu0Sv9SpgqcnZ8cEG%2B6kXpbLQz70VL8Jr%2B5VeBg%40mail.gmail.com.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/4AF52B71-7BE6-4118-995E-F30083C1AEAE%40ix.netcom.com.

Reply via email to