Question about runtime.Pinner

282 views
Skip to first unread message

Pascal Costanza

unread,
Oct 12, 2023, 8:07:02 AM10/12/23
to golang-nuts
Hi, 

I have a question about runtime.Pinner: The documentation states that you can only pin an object when it’s the result of calling new, taking the address of a composite literal, or taking the address of a local variable.

At the same time, the Go language specification states that a slice created with make allocates a hidden array, and gives the example that make([]int, 50, 100) is the same as new([100]int)[0:50].

Taken together, this suggests that the following sequence should be correct:

var p runtime.Pinner
s := make([]int, 100)
p.Pin(&s[0])

…since &s[0] can be understood as being the result of calling new.

Is that intended?

Also: I believe it would be good if the documentation would state that the zero value for type runtime.Pinner is ready to use.


Thanks,
Pascal

Ian Lance Taylor

unread,
Oct 12, 2023, 9:55:12 AM10/12/23
to Pascal Costanza, golang-nuts
On Thu, Oct 12, 2023 at 5:06 AM Pascal Costanza
<pascal....@intel.com> wrote:
>
> I have a question about runtime.Pinner: The documentation states that you can only pin an object when it’s the result of calling new, taking the address of a composite literal, or taking the address of a local variable.
>
> At the same time, the Go language specification states that a slice created with make allocates a hidden array, and gives the example that make([]int, 50, 100) is the same as new([100]int)[0:50].
>
> Taken together, this suggests that the following sequence should be correct:
>
> var p runtime.Pinner
> s := make([]int, 100)
> p.Pin(&s[0])
>
> …since &s[0] can be understood as being the result of calling new.
>
> Is that intended?

Yes.


> Also: I believe it would be good if the documentation would state that the zero value for type runtime.Pinner is ready to use.

That's the general default behavior for types in the standard library.
If nothing says otherwise, the zero value is ready to use. That said,
I'm not opposed to mentioning it if someone wants to send a patch.

Ian

Michael Knyszek

unread,
Oct 12, 2023, 9:59:34 AM10/12/23
to golang-nuts
On Thursday, October 12, 2023 at 8:07:02 AM UTC-4 Pascal Costanza wrote:
Hi, 

I have a question about runtime.Pinner: The documentation states that you can only pin an object when it’s the result of calling new, taking the address of a composite literal, or taking the address of a local variable.


At the same time, the Go language specification states that a slice created with make allocates a hidden array, and gives the example that make([]int, 50, 100) is the same as new([100]int)[0:50].

Taken together, this suggests that the following sequence should be correct:

var p runtime.Pinner
s := make([]int, 100)
p.Pin(&s[0])

…since &s[0] can be understood as being the result of calling new.
I think that's not quite following the spirit of the documentation, but as you point out, it's already possible to pin (and call runtime.SetFinalizer) on memory that doesn't strictly follow the documentation. It's even possible to pin strings, but it requires unsafe.StringData (or something similar).

I'm of the opinion that we should broaden the scope of runtime.Pinner at least slightly, to allow for things like slices and strings explicitly. Sometime soon I'll file a proposal about this since it's very technically an API change. In the same vein, the cgo pointer passing rules have some restrictions that I'm not sure are necessary, but I'm concerned that I may be missing something subtle and I haven't had the time to think about it more thoroughly. (All of this stuff is pretty subtle.)


Is that intended?

Also: I believe it would be good if the documentation would state that the zero value for type runtime.Pinner is ready to use.
That is a good point. I'll send a doc change for that. 



Thanks,
Pascal

Michael Knyszek

unread,
Oct 12, 2023, 10:05:37 AM10/12/23
to golang-nuts
On Thursday, October 12, 2023 at 9:55:12 AM UTC-4 Ian Lance Taylor wrote:
On Thu, Oct 12, 2023 at 5:06 AM Pascal Costanza
<pascal....@intel.com> wrote:
>
> I have a question about runtime.Pinner: The documentation states that you can only pin an object when it’s the result of calling new, taking the address of a composite literal, or taking the address of a local variable.
>
> At the same time, the Go language specification states that a slice created with make allocates a hidden array, and gives the example that make([]int, 50, 100) is the same as new([100]int)[0:50].
>
> Taken together, this suggests that the following sequence should be correct:
>
> var p runtime.Pinner
> s := make([]int, 100)
> p.Pin(&s[0])
>
> …since &s[0] can be understood as being the result of calling new.
>
> Is that intended?

Yes.
I always figured it at least wasn't unintended and that's why this hasn't been some bug to be fixed. But it is also true that you can't just pass a slice or string directly to Pin, and IMO it's a bit strange as to why that's not allowed when &s[0] works. Perhaps I'm missing something.
Reply all
Reply to author
Forward
0 new messages