Re: [go-nuts] How to use atomic_int in cgo?

2021-02-20 Thread Ian Lance Taylor
On Sat, Feb 20, 2021 at 8:34 AM changkun  wrote:
>
> Dear Ian, thanks for the inspiration and sorry for the late response. I just 
> got a chance to test your suggestion.
> But, it turns out that the wrapping struct can cause the following error:
>
> panic: runtime error: cgo argument has Go pointer to Go pointer
>
> If my understanding of Cgo constraints correctly, the panic is to prevent a 
> potential error when GC moves the Go pointer,
> although we don't manipulate the Go pointer (to the channel) from the C side.
>
> How could we avoid this?

Oh, sorry.  There are lots of ways to go, depending on the details.
The easiest is to store the channel in a global variable on the Go
side, though of course then only one goroutine can use this system at
a time.  Or you can build a map on the Go side that maps integers to
channel, then pass the integer to C which will pass it back to Go and
the Go side will look in the map.

Ian

> On Monday, February 15, 2021 at 9:51:03 PM UTC+1 Ian Lance Taylor wrote:
>>
>> On Mon, Feb 15, 2021 at 12:39 PM changkun  wrote:
>> >
>> > Thanks for the hint, but I have some follow-up questions:
>> >
>> >>
>> >> Even if there were a way to do this, an atomic variable is not a good
>> >> synchronization mechanism, because the other side has to poll the
>> >> variable.
>> >
>> > Indeed, it the other side will be a spin loop to poll the atomic variable, 
>> > which ...
>> >
>> >
>> >>
>> >> You can do this as a last resort, but it doesn't sound like
>> >> you are at a last resort here. I suggest that you have your C
>> >> function call a Go function to write a value on a channel.
>> >
>> > seems easy to write than this (?).
>> >
>> > Say a Go function foo is called from the C side, to be able to send to the 
>> > corresponding channel, C must pass that channel to the Go function, which 
>> > brings to the initial question: pass a channel from Go to C, is it 
>> > supported at the moment (?)
>> >
>> > How could a Go function be able to send content to differently allocated 
>> > channels in correspondingly invoked C functions?
>>
>> For example, on the Go side write
>>
>> type chanToUse struct {
>> c chan int
>> }
>>
>> //export MyGoFunction
>> func MyGoFunction(u unsafe.Pointer, val int) {
>> cu = (*chanToUse)(u)
>> cu.c <- val
>> }
>>
>> ch := make(chan int)
>> ...
>> C.MyCFunction(unsafe.Pointer({ch}))
>>
>> and on the C side write
>>
>> void MyCFunction(void *goData) {
>> ...
>> MyGoFunction(goData, 0);
>> }
>>
>> Yes, it's more work. But it's not a good idea to poll an atomic
>> variable in Go. The Go scheduler reacts badly to busy loops.
>>
>> 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/19463602-158d-4539-9132-fa6d5b09a8c3n%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/CAOyqgcV69t2%3D03roiheR4oLFRT%2B0cv2ZhScWOK8cGscc01yDHg%40mail.gmail.com.


Re: [go-nuts] How to use atomic_int in cgo?

2021-02-20 Thread changkun
Dear Ian, thanks for the inspiration and sorry for the late response. I 
just got a chance to test your suggestion.
But, it turns out that the wrapping struct can cause the following error:

panic: runtime error: cgo argument has Go pointer to Go pointer

If my understanding of Cgo constraints correctly, the panic is to prevent a 
potential error when GC moves the Go pointer,
although we don't manipulate the Go pointer (to the channel) from the C 
side.

How could we avoid this?

On Monday, February 15, 2021 at 9:51:03 PM UTC+1 Ian Lance Taylor wrote:

> On Mon, Feb 15, 2021 at 12:39 PM changkun  wrote:
> >
> > Thanks for the hint, but I have some follow-up questions:
> >
> >>
> >> Even if there were a way to do this, an atomic variable is not a good
> >> synchronization mechanism, because the other side has to poll the
> >> variable.
> >
> > Indeed, it the other side will be a spin loop to poll the atomic 
> variable, which ...
> >
> >
> >>
> >> You can do this as a last resort, but it doesn't sound like
> >> you are at a last resort here. I suggest that you have your C
> >> function call a Go function to write a value on a channel.
> >
> > seems easy to write than this (?).
> >
> > Say a Go function foo is called from the C side, to be able to send to 
> the corresponding channel, C must pass that channel to the Go function, 
> which brings to the initial question: pass a channel from Go to C, is it 
> supported at the moment (?)
> >
> > How could a Go function be able to send content to differently allocated 
> channels in correspondingly invoked C functions?
>
> For example, on the Go side write
>
> type chanToUse struct {
> c chan int
> }
>
> //export MyGoFunction
> func MyGoFunction(u unsafe.Pointer, val int) {
> cu = (*chanToUse)(u)
> cu.c <- val
> }
>
> ch := make(chan int)
> ...
> C.MyCFunction(unsafe.Pointer({ch}))
>
> and on the C side write
>
> void MyCFunction(void *goData) {
> ...
> MyGoFunction(goData, 0);
> }
>
> Yes, it's more work. But it's not a good idea to poll an atomic
> variable in Go. The Go scheduler reacts badly to busy loops.
>
> 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/19463602-158d-4539-9132-fa6d5b09a8c3n%40googlegroups.com.


Re: [go-nuts] How to use atomic_int in cgo?

2021-02-15 Thread Devon H. O'Dell
Forgot to reply to the list. Oops. Sorry for the second delivery, Changkun.

On Mon, Feb 15, 2021 at 12:39 changkun  wrote:

> Hi Ian,
>
> Thanks for the hint, but I have some follow-up questions:
>
>
>> Even if there were a way to do this, an atomic variable is not a good
>> synchronization mechanism, because the other side has to poll the
>> variable.
>
> Indeed, it the other side will be a spin loop to poll the atomic variable,
> which ...
>
>
>
>> You can do this as a last resort, but it doesn't sound like
>> you are at a last resort here. I suggest that you have your C
>> function call a Go function to write a value on a channel.
>
> seems easy to write than this (?).
>
> Say a Go function foo is called from the C side, to be able to send to the
> corresponding channel, C must pass that channel to the Go function, which
> brings to the initial question:  pass a channel from Go to C, is it
> supported at the moment (?)
>
> How could a Go function be able to send content to differently allocated
> channels in correspondingly invoked C functions?
>


I think this is only a problem if you need a separate channel per
invocation for some reason, which seems unlikely. But if you did, you could
have a  map of int to chan T and pass the integer key through C.

Kind regards,

--dho


>
>
> Sincerely,
> Changkun
>
> --
> 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/7adba3a6-ee2f-4923-905d-9afc2b9f796an%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/CAFgOgC_zWPuPtNAc74CM7aimNh7k-ZbNT_TsFbCntWDT6mX_VQ%40mail.gmail.com.


Re: [go-nuts] How to use atomic_int in cgo?

2021-02-15 Thread Ian Lance Taylor
On Mon, Feb 15, 2021 at 12:39 PM changkun  wrote:
>
> Thanks for the hint, but I have some follow-up questions:
>
>>
>> Even if there were a way to do this, an atomic variable is not a good
>> synchronization mechanism, because the other side has to poll the
>> variable.
>
> Indeed, it the other side will be a spin loop to poll the atomic variable, 
> which ...
>
>
>>
>> You can do this as a last resort, but it doesn't sound like
>> you are at a last resort here. I suggest that you have your C
>> function call a Go function to write a value on a channel.
>
> seems easy to write than this (?).
>
> Say a Go function foo is called from the C side, to be able to send to the 
> corresponding channel, C must pass that channel to the Go function, which 
> brings to the initial question:  pass a channel from Go to C, is it supported 
> at the moment (?)
>
> How could a Go function be able to send content to differently allocated 
> channels in correspondingly invoked C functions?

For example, on the Go side write

type chanToUse struct {
c chan int
}

//export MyGoFunction
func MyGoFunction(u unsafe.Pointer, val int) {
cu = (*chanToUse)(u)
cu.c <- val
}

ch := make(chan int)
...
C.MyCFunction(unsafe.Pointer({ch}))

and on the C side write

void MyCFunction(void *goData) {
...
MyGoFunction(goData, 0);
}

Yes, it's more work.  But it's not a good idea to poll an atomic
variable in Go.  The Go scheduler reacts badly to busy loops.

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/CAOyqgcV--J_RWUhonaDtVh%3DS0ON-6xiqSBJQXEaqLsMtWK%3DV1Q%40mail.gmail.com.


Re: [go-nuts] How to use atomic_int in cgo?

2021-02-15 Thread changkun
Hi Ian,

Thanks for the hint, but I have some follow-up questions:


> Even if there were a way to do this, an atomic variable is not a good 
> synchronization mechanism, because the other side has to poll the 
> variable.

Indeed, it the other side will be a spin loop to poll the atomic variable, 
which ...

 

> You can do this as a last resort, but it doesn't sound like 
> you are at a last resort here. I suggest that you have your C 
> function call a Go function to write a value on a channel.

seems easy to write than this (?). 

Say a Go function foo is called from the C side, to be able to send to the 
corresponding channel, C must pass that channel to the Go function, which 
brings to the initial question:  pass a channel from Go to C, is it 
supported at the moment (?)

How could a Go function be able to send content to differently allocated 
channels in correspondingly invoked C functions?


Sincerely,
Changkun

-- 
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/7adba3a6-ee2f-4923-905d-9afc2b9f796an%40googlegroups.com.


Re: [go-nuts] How to use atomic_int in cgo?

2021-02-15 Thread Ian Lance Taylor
On Mon, Feb 15, 2021 at 1:32 AM changkun  wrote:
>
> I would like to call a C function from Go and get notified about the 
> execution status in Go, say a goroutine wait until the C function finally 
> made some progress.
> Initially, I thought about passing a channel to C but the cgo document does 
> not say anything about that:
>
> Later, I am thinking about using an atomic variable to sync status according 
> to its value, but somehow I end up with this warning while I am compiling a 
> cgo program:
>
> package main
>
> /*
> #include 
> void ainit(atomic_int *val) {
> atomic_init(val, 0);
> }
> */
> import "C"
>
> func main() {
> var v C.atomic_int
> C.ainit()
> }
>
> cgo-gcc-prolog: In function ‘_cgo_8a67e594de48_Cfunc_ainit’:
> cgo-gcc-prolog:49:14: warning: passing argument 1 of ‘ainit’ from 
> incompatible pointer type [-Wincompatible-pointer-types]
> ./main.go:5:24: note: expected ‘_Atomic atomic_int *’ {aka ‘_Atomic int *’} 
> but argument is of type ‘int *’
> 5 | void ainit(atomic_int *val) {
>   |^~~
>
> According to the warning and note, it seems that cgo is lacking translating 
> atomic_init? Did I do anything wrong? Or is there any better and preferred 
> way to get notified from C function?

Even if there were a way to do this, an atomic variable is not a good
synchronization mechanism, because the other side has to poll the
variable.  You can do this as a last resort, but it doesn't sound like
you are at a last resort here.  I suggest that you have your C
function call a Go function to write a value on a channel.

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/CAOyqgcU7UFk%2BecZcRNOgA8vspQx%3D2rvTSSGmYpF2kD%2Bm_UqUPQ%40mail.gmail.com.


[go-nuts] How to use atomic_int in cgo?

2021-02-15 Thread changkun
Hi golang-nuts,

I would like to call a C function from Go and get notified about the 
execution status in Go, say a goroutine wait until the C function finally 
made some progress.
Initially, I thought about passing a channel to C but the cgo document does 
not say anything about that:

Later, I am thinking about using an atomic variable to sync status 
according to its value, but somehow I end up with this warning while I am 
compiling a cgo program:

package main

/*
#include 
void ainit(atomic_int *val) {
atomic_init(val, 0);
}
*/
import "C"

func main() {
var v C.atomic_int
C.ainit()
}

cgo-gcc-prolog: In function ‘_cgo_8a67e594de48_Cfunc_ainit’:
cgo-gcc-prolog:49:14: warning: passing argument 1 of ‘ainit’ from 
incompatible pointer type [-Wincompatible-pointer-types]
./main.go:5:24: note: expected ‘_Atomic atomic_int *’ {aka ‘_Atomic int *’} 
but argument is of type ‘int *’
5 | void ainit(atomic_int *val) {
  |^~~

According to the warning and note, it seems that cgo is lacking translating 
atomic_init? Did I do anything wrong? Or is there any better and preferred 
way to get notified from C function?

-- 
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/b4e8b7c7-015d-4b9e-80ef-e49c07bea301n%40googlegroups.com.