Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unreliability in C callback APIs which execute the callback on foreign thread #17

Open
wsc1 opened this issue Sep 20, 2018 · 9 comments
Assignees

Comments

@wsc1
Copy link
Member

wsc1 commented Sep 20, 2018

This issue is to address the overhead in cgo->go callbacks in host entry points which interface with a C API
which executes a client callback on a special thread.

AAudio, CoreAudio AudioUnits, do this.

For reference, there is this related golang-dev thread.

Goal: We want to 100% eliminate the overhead of cgo->go, in particular sigaltstack.

@wsc1 wsc1 self-assigned this Sep 20, 2018
@wsc1
Copy link
Member Author

wsc1 commented Sep 20, 2018

see this pr for design doc to handle this.

@hajimehoshi
Copy link

Not sure but is this the problem we can solve in Go user layer?

@wsc1
Copy link
Member Author

wsc1 commented Sep 25, 2018

Thanks for chiming in. Not sure I understand your suggestion.

Problem is basically: AAudio, CoreAudio, Jack, and similar work with C callbacks that are supposed to do only math and moving memory between pre-allocated places. These callbacks are on a thread outside Go. So if you use a C callback that calls Go, or even directly a Go function as a callback via casting and the like, it causes the runtime to do all kinds of stuff with sys calls and Go runtime which shouldn't be done in real-time audio i/o.

I don't see a way the Go user layer can fix the problem above, but I'm open and interested in all ideas. Even ideas that don't end up working (like some of my own earlier :)

@hajimehoshi
Copy link

I was not suggesting anything :-) I was trying to understand what was the problem.

If the problem is the overhead inside the lib, there is nothing we can do on Go side? At least most OS offers C APIs, so Cgo overhead would be inevitable.

@wsc1
Copy link
Member Author

wsc1 commented Sep 25, 2018

There is always some cgo overhead interfacing with C. But the case above has a lot of overhead specific to it (unrelated to for example, calling C.Foo() where C.Foo doesn't call Go) and is ubiquitous and necessary in audio I/O apis.

cb bypasses the overhead specific to the case of C callbacks on a foreign thread introduced by the underlying audio C API. It has some disadvantages as well, but it does avoid sys calls, memory allocation, goroutine stack allocation, lockosthread, etc.

@wsc1
Copy link
Member Author

wsc1 commented Sep 27, 2018

This pr is a tested, more complete update. Perhaps useable as a basis for proceeding with capture/playback with callbacks on foreign thread on a real API.

It works hard to avoid sys calls, although on some systems and in some circumstances they may still occasionally happen via runtime.Gosched().

It turns out lockosthread, although it still causes scheduling issues with the rest of the runtime, is also sufficient to avoid any sys calls in this design, but not via cgo.

@wsc1
Copy link
Member Author

wsc1 commented Oct 2, 2018

Wanted to reference this golang issue about pre-emptive scheduling in runtime.

@wsc1
Copy link
Member Author

wsc1 commented Oct 2, 2018

Also this pr pushes things forward significantly

@wsc1
Copy link
Member Author

wsc1 commented Oct 3, 2018

Also this go-nuts thread about callback problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants