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

syscall: add SyscallN #46552

Closed
xc218m opened this issue Jun 3, 2021 · 22 comments
Closed

syscall: add SyscallN #46552

xc218m opened this issue Jun 3, 2021 · 22 comments

Comments

@xc218m
Copy link

xc218m commented Jun 3, 2021

Currently Go supports calling up to 18 arguments when calling function from a Windows DLL. But there are some SDKs that have functions with 22 and more parameters. It seems there is no workaround for this issue.

@gopherbot gopherbot added this to the Proposal milestone Jun 3, 2021
@ianlancetaylor ianlancetaylor changed the title proposal: runtime/syscall_windows: add syscall_Syscall21 and syscall_Syscall24 proposal: syscall: add syscall_Syscall21 and syscall_Syscall24 Jun 3, 2021
@ianlancetaylor ianlancetaylor changed the title proposal: syscall: add syscall_Syscall21 and syscall_Syscall24 proposal: syscall: add Syscall21 and Syscall24 Jun 3, 2021
@ianlancetaylor ianlancetaylor added this to Incoming in Proposals (old) Jun 3, 2021
@ianlancetaylor
Copy link
Contributor

Any idea where we should stop?

@davecheney
Copy link
Contributor

If you have a syscall with 21 parameters, you probably missed some. (With apologies to Alan Perlis)

@cespare
Copy link
Contributor

cespare commented Jun 3, 2021

I think that MSVC allows at most 256 parameters in a function definition, so we probably shouldn't need more than that.

@alexbrainman
Copy link
Member

But there are some SDKs that have functions with 22 and more parameters.

Can you provide some reference, please.

Thank you.

Alex

@xc218m
Copy link
Author

xc218m commented Jun 4, 2021

For example a SDK for LED matrix display controller. One of the functions is:
int HDAPI Hd_Rt_SendRealTimeText(int nSendType, void *pStrParams, int nRealTimeAreaIndex, int nMaxPageCount, int nColor, int nGray, int nX, int nY, int nWidth, int nHeight, void *pText, int nTextColor, int nBackGroupColor, int nStyle, void *pFontName, int nFontHeight, int nShowEffect, int nShowSpeed,int nStayTime, int nLiveTime, int bSaveToFlash, void *pDeviceGUID);

@Profpatsch
Copy link

This is going to be sufficient, since 24 is the highest number. https://www.youtube.com/watch?v=RkP_OGDCLY0

@xc218m
Copy link
Author

xc218m commented Jun 5, 2021

It's not theoretical. It's from SDK for these controllers:
https://www.huidu.cn/en/monochromatic-and-dual-color-network-port-control-card.html
You can't find it, because it is not publicly available.
I already used another language for the SDK, so it's not a big problem for me.
I tried to add Syscall24 myself but I think that has to be changes in asmcgocall function too.

@networkimprov
Copy link

cc @zx2c4 @mattn

@rsc
Copy link
Contributor

rsc commented Jun 9, 2021

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc rsc moved this from Incoming to Active in Proposals (old) Jun 9, 2021
@zx2c4
Copy link
Contributor

zx2c4 commented Jun 9, 2021

It's not theoretical. It's from SDK for these controllers:
https://www.huidu.cn/en/monochromatic-and-dual-color-network-port-control-card.html

Just so we're clear: this isn't actually to call any Windows system API or something, but just to call some arbitrary C functions with tons of arguments from that SDK, correct? (Not that that's necessarily a bad thing.)

@mdempsky
Copy link
Member

mdempsky commented Jun 9, 2021

Any idea where we should stop?

We could add a variadic function and then we'd be done, even when NTv6 extends the max syscall list to 640KB. We already support variadic syscalls for Proc.Call and LazyProc.Call.

Edit: By which I mean, we support the API, and the compiler supports the unsafe.Pointer-safety-rules magic required to make it work. Those functions in turn currently rely on calling the SyscallNN functions.

However, it also looks like the SyscallNN functions then eventually trampoline back into a common, variadic cgo stub anyway. So it seems like the fundamentals are all in place already. We just need to cleanup the implementation, and maybe expose an extra primitive. (I don't know if Windows users care about directly issuing syscall.Syscall21, or if this only affects users indirectly via Proc.Call/LazyProc.Call.)

@alexbrainman
Copy link
Member

Just so we're clear: this isn't actually to call any Windows system API or something, but just to call some arbitrary C functions with tons of arguments from that SDK, correct? (Not that that's necessarily a bad thing.)

I agree with Jason sentiment, that this is pretty rare.

And since 24 is the Highest Number, Syscall24 should be the last API we will ever need. It shouldn't be difficult to add these APIs. We should also adjust runtime.TestSyscall18 to verify the change.

We could add a variadic function ...

Adding Syscall21 and Syscall24 is easy comparing to adding and implementing new API. And there is only 1 Syscall21 user so far. So we should not invest too much effort here.

Alternatively we can say no to Syscall21 and Syscall24. We would loose users of those controllers.

Alex

@zx2c4
Copy link
Contributor

zx2c4 commented Jun 10, 2021

However, it also looks like the SyscallNN functions then eventually trampoline back into a common, variadic cgo stub anyway.

If we're already trampolining back to a varidac sub, we should just make the primary API into this varadic, and cut out all the middle pieces. We can then rework mksyscall and that codegen around the more direct varadic route. The SyscallXX helpers will then be left around for backwards compat. That would address the concerns of this proposal, and also clean up the API considerably.

@ianlancetaylor
Copy link
Contributor

Good point, writing a varargs version seems clearly preferable. The signature would presumably be something like

SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno)

I think we can do that safely using the //go:uintptrescapes annotation.

@rsc
Copy link
Contributor

rsc commented Jun 16, 2021

OK, so it sounds like we should do SyscallN.

@rsc rsc changed the title proposal: syscall: add Syscall21 and Syscall24 proposal: syscall: add SyscallN Jun 16, 2021
@rsc
Copy link
Contributor

rsc commented Jul 14, 2021

We could limit this to Windows, but it seems like we should just implement it for all systems.
Non-Windows systems have a clearer limit, and we can handle N up to that limit and then return an error otherwise.

@rsc rsc moved this from Active to Likely Accept in Proposals (old) Jul 14, 2021
@rsc
Copy link
Contributor

rsc commented Jul 14, 2021

Based on the discussion above, this proposal seems like a likely accept.
— rsc for the proposal review group

@rsc rsc moved this from Likely Accept to Accepted in Proposals (old) Jul 21, 2021
@rsc
Copy link
Contributor

rsc commented Jul 21, 2021

No change in consensus, so accepted. 🎉
This issue now tracks the work of implementing the proposal.
— rsc for the proposal review group

@rsc rsc changed the title proposal: syscall: add SyscallN syscall: add SyscallN Jul 21, 2021
@rsc rsc modified the milestones: Proposal, Backlog Jul 21, 2021
@gopherbot
Copy link

Change https://golang.org/cl/336550 mentions this issue: syscall: add SyscallN

@cristaloleg
Copy link

Any info about performance changes? 👀

@mdempsky
Copy link
Member

I wouldn't expect any performance changes from this, but I think it would be great if someone wanted to measure and report back.

@golang golang locked and limited conversation to collaborators Aug 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Development

No branches or pull requests

13 participants