{"action":"created","issue":{"url":"https://api.github.com/repos/golang/go/issues/16051","repository_url":"https://api.github.com/repos/golang/go","labels_url":"https://api.github.com/repos/golang/go/issues/16051/labels{/name}","comments_url":"https://api.github.com/repos/golang/go/issues/16051/comments","events_url":"https://api.github.com/repos/golang/go/issues/16051/events","html_url":"https://github.com/golang/go/issues/16051","id":159996100,"number":16051,"title":"proposal: a faster C-call mechanism for non-blocking C functions","user":{"login":"eloff","id":27574,"avatar_url":"https://avatars.githubusercontent.com/u/27574?v=3","gravatar_id":"","url":"https://api.github.com/users/eloff","html_url":"https://github.com/eloff","followers_url":"https://api.github.com/users/eloff/followers","following_url":"https://api.github.com/users/eloff/following{/other_user}","gists_url":"https://api.github.com/users/eloff/gists{/gist_id}","starred_url":"https://api.github.com/users/eloff/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eloff/subscriptions","organizations_url":"https://api.github.com/users/eloff/orgs","repos_url":"https://api.github.com/users/eloff/repos","events_url":"https://api.github.com/users/eloff/events{/privacy}","received_events_url":"https://api.github.com/users/eloff/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/golang/go/labels/Proposal","name":"Proposal","color":"ededed"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/golang/go/milestones/30","html_url":"https://github.com/golang/go/milestones/Proposal","labels_url":"https://api.github.com/repos/golang/go/milestones/30/labels","id":1373555,"number":30,"title":"Proposal","description":"Proposals that are pending (not yet accepted/rejected).\r\n","creator":{"login":"rsc","id":104030,"avatar_url":"https://avatars.githubusercontent.com/u/104030?v=3","gravatar_id":"","url":"https://api.github.com/users/rsc","html_url":"https://github.com/rsc","followers_url":"https://api.github.com/users/rsc/followers","following_url":"https://api.github.com/users/rsc/following{/other_user}","gists_url":"https://api.github.com/users/rsc/gists{/gist_id}","starred_url":"https://api.github.com/users/rsc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rsc/subscriptions","organizations_url":"https://api.github.com/users/rsc/orgs","repos_url":"https://api.github.com/users/rsc/repos","events_url":"https://api.github.com/users/rsc/events{/privacy}","received_events_url":"https://api.github.com/users/rsc/received_events","type":"User","site_admin":false},"open_issues":55,"closed_issues":27,"state":"open","created_at":"2015-10-24T01:40:49Z","updated_at":"2016-07-10T02:07:28Z","due_on":null,"closed_at":null},"comments":28,"created_at":"2016-06-13T16:51:09Z","updated_at":"2016-07-11T06:59:04Z","closed_at":null,"body":"I'm not sure this is the place to submit this, the golang-dev list might also have been a good candidate.\r\n\r\nThe cgo FFI mechanism is very general, and makes some pessimistic assumptions about the function being called - specifically it has to handle the case where the called function may block, e.g. in a blocking syscall. Having to handle the worst case adds a lot of overhead to each call into C, including just calling a math function or other small function that does no syscalls or does not block.\r\n\r\nThe problem is for well-behaved calls that neither block nor call back into Go, if the called function does not do much work then the cgo overhead dominates the runtime and causes poor performance. This is a well known limitation (and often complained about on golang-nuts and elsewhere, google \"cgo overhead\" returns about 45,000 hits.) Some of this can be mitigated by making the C function do more work, e.g. exporting a chunkier vs chattier API - but that's not always feasible or desirable.\r\n\r\nFor some classes of problems this overhead is just not admissible, and people resort to doing bad things like calling C from assembly on a Go stack, which just isn't built for it. The Go runtime itself finds the C call overhead too much at times, and Dmitry Vyukov had to work around it when integrating the TSAN race checker with Go. A look at https://golang.org/src/runtime/race_amd64.s?m=text shows a custom C call mechanism that just puts the arguments into the right registers, switches stacks from the Go stack to the C stack, and calls the TSAN runtime function.\r\n\r\nSince this seems to be a requirement that cannot always be worked around, and it's a requirement of both Go users and the Go runtime itself, and the workarounds are difficult, fraught, and fragile - I would like to see a solution for this in Go itself. Such a solution should very closely mirror the functionality in race_amd64.s, ideally because that approach is about as low overhead as possible, and because it can be used to replace that code. It could take any form, but since it needs to be backwards compatible and ideally one does not introduce new syntax - something like an attribute on the function declaration, or a cgo directive would be nice. It is up to the programmer to ensure that C functions called in this way do not block, and don't call back into Go.\r\n```\r\n\r\ne.g. __attribute__ ((nonblocking)) in the declaration,\r\nor // #cgo nonblocking directly preceeding the callsite or the declaration\r\n```\r\n\r\nIs this a reasonable feature for a future version of Go?"},"comment":{"url":"https://api.github.com/repos/golang/go/issues/comments/231656031","html_url":"https://github.com/golang/go/issues/16051#issuecomment-231656031","issue_url":"https://api.github.com/repos/golang/go/issues/16051","id":231656031,"user":{"login":"kunos","id":5239944,"avatar_url":"https://avatars.githubusercontent.com/u/5239944?v=3","gravatar_id":"","url":"https://api.github.com/users/kunos","html_url":"https://github.com/kunos","followers_url":"https://api.github.com/users/kunos/followers","following_url":"https://api.github.com/users/kunos/following{/other_user}","gists_url":"https://api.github.com/users/kunos/gists{/gist_id}","starred_url":"https://api.github.com/users/kunos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kunos/subscriptions","organizations_url":"https://api.github.com/users/kunos/orgs","repos_url":"https://api.github.com/users/kunos/repos","events_url":"https://api.github.com/users/kunos/events{/privacy}","received_events_url":"https://api.github.com/users/kunos/received_events","type":"User","site_admin":false},"created_at":"2016-07-11T06:59:04Z","updated_at":"2016-07-11T06:59:04Z","body":"Well I get the same results increasing the loop count:\r\n\r\nSyscall: 2.5059244s\r\nCGO: 2.2626265s\r\n\r\nPerhaps I have a weird PC.\r\nAnd no, using the right timer on Windows you can get reasonable results even for <1ms .\r\n\r\n"}}
{"actor":{"display_login":"kunos"}}