On Wed, Apr 22, 2020 at 4:33 AM T L <tapir....@gmail.com> 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?

First, let me say that it's best to avoid the word "atomic" without
clearly explaining what you mean, as it has many different meanings
and implications.  In this case I think what you mean is that in Go an
assignment made by one goroutine may be interleaved with an assignment
made by a different goroutine.  Or, more precisely, you mean that a
goroutine may be interrupted in the middle of doing an assignment,
such that another goroutine may observe the assignment as started but
not fully completed.

Technically, I think you are correct: I don't know of anything in the
Go language spec that prohibits a goroutine from being interrupted
while partway through the assignment to hdr.Data.  But then the Go
language spec doesn't discuss stack resizing at all.

In practice no Go implementation is going to interrupt an assignment
that is only a single memory word.  And, of course, it would be
invalid for a Go implementation that does stack shrinking or garbage
collection to interrupt an assignment of a pointer value.  And at the
machine level, on a modern processor, an assignment of a uintptr uses
the exact same instructions as an assignment of an unsafe.Pointer.  So
I don't think there is anything to worry about here.

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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcVmaqFe_9QSKKPFmpdMM8nnDgU%2BZ%2BFcMp09rXbtf5sDJw%40mail.gmail.com.

Reply via email to