5 ms·
I think this is based on a fear of having an API that wasn't needed and needs to be maintained forever. I bet that Linux's syscall design would be much nicer if
by cyphar 8y ago
I think this is based on a fear of having an API that wasn't needed and needs to be maintained forever. I bet that Linux's syscall design would be much nicer if iterating on APIs was possible (as we see in other Unix-likes).
My personally least favourite syscall design misstep is how VFS flags work. AT_ flags were supposed to be generic but we now have AT_STATX_, O_ flags are overused, and some at(2) syscalls like renameat2(2) have their own brand of flags (RENAME_). Internally VFS has uniform flags for lookup and other various things, so it's a bit silly that these flags are all basically incompatible.
(Also, the fact that O_RDWR != O_RDONLY|O_WRONLY is just silly. It takes up just as many bytes but makes life needlessly difficult when designing new extensions to openat(2).)
- quotemstr 8y agoIf I had my way, the application stable ABI would be libc, not SYSENTER. Windows gets this right and is able to iterate faster on kernel interfaces as a result. A while ago, I proposed a kernel supplied libc add-on that would provide the syscall wrappers that glibc won't. Maybe we could declare that all applications must make new system calls through this interface and maintain syscall compatibility only for the current legacy set of system calls.
- jcranmer 8y agoThat is how it works on OS X and the BSDs as well--compatibility is maintained at the C level, not the SYSENTER level. (Although it should be noted that some of the BSDs don't guarantee forever-compatible syscall ABI in the first place).
- asveikau 8y agoI don't understand how Windows "gets this right" other than by accident. In the Win32 heyday it was in their interest to have you code against kernel32, advapi, etc. so that your stuff works on 9x and NT, maybe CE. Now 9x/CE are gone and ntdll often has the "good" interfaces and the public wrapper APIs kind of lag behind. (Maybe ntdll itself having stubs and not telling the program to SYSENTER directly is the "good" design?) Meanwhile in the Linux world you have plenty of iteration on syscalls, you might say there is too much. They have to maintain cruft but OK. libc as the boundary doesn't make sense either as glibc is not the Linux kernel, by design, and there are other libcs in common production, like in a billion Android phones.
- int_19h 8y agoIt's not just Windows that gets it right. The situation is the same on macOS, and on all the BSDs. The notion of userspace doing syscalls directly is really pretty much unique to Linux at this point. And no, you still can't use NTDLL on Windows - not unless you're doing (OS-specific) drivers. It might work in practice, but it also breaks sometimes, because there's no API stability guarantee.
- asveikau 8y agoIn those projects the libc is part of the tree. In Linux it is not the case. This is logically consistent for the project at hand. You can advocate a different way and I can agree but it wouldn't be Linux. (I am no stranger to BSD either. Been using *BSDs in some form for 19 years.) By the way Windows CRT ships new versions with Visual Studio out of devdiv... So Windows doesn't even work that way if you draw the boundary at libc. This is part of my comment, I don't understand which part of it is MS doing it right? Ntdll abstracting sysenter? Kernel and advapi abstracting ntdll? I don't think the latter example is one of great technical execution, it just sort of happened to promote compatibility with 9x and they're stuck with it.
- int_19h 8y agoBy "libc" I mean the userspace layer here broadly - on Windows that would be kernel32 etc. What VC++ calls CRT is built on that in turn. Although as of Win10, the actual CRT is also an API-stable OS-level component now, not a VC++-specific thing: https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introduci... The right thing here is the general notion of abstracting away core kernel APIs in userspace. It lets you refactor the whole thing significantly without breaking everything. And userspace calls are easier to maintain long-term for legacy support reasons, as well (at some point you can make it into a DLL that doesn't even have to be distributed with the OS, and just ship that with apps that need it).
- asveikau 8y ago
- monocasa 8y ago> Windows gets this right and is able to iterate faster on kernel interfaces as a result. The only place that'd have any bearing is for modified syscalls. Newly added obviously aren't an issue, And looking at syscalls removed, it's because they removed whole subsystems that never had anyone using it. Those would probably not even get upstreamed into the mainline kernel to being with. I'm not seeing any evidence of what you're saying while looking at how the NT syscall layer has changed over the past couple decades. https://j00ru.vexillium.org/syscalls/nt/64/ https://j00ru.vexillium.org/syscalls/nt/64/
- loeg 8y agoPros and cons to the libc ABI approach. It works very well for things that are C or mostly C-compatible (C++, maybe Rust, maybe other more esoteric languages), or interpreters with a strong grounding in C (Python; Ruby; historically, Java). It doesn't mesh well with Golang's choice to avoid linking libc, which in practice probably only works out because Linux maintains syscall ABI stability forever.
- tedunangst 8y agoGo works reasonably well on openbsd despite syscall churn. You really only need to make it to uname() to decide what to do.
- int_19h 8y agoIt also means that older compiled code might not necessarily work on new releases. This is probably not a big deal on OpenBSD, but on e.g. macOS it was big enough that they moved to libc.
- favorited 8y agoBy contrast, Go would break constantly on macOS betas. The Mac/iOS kernel interface is libSystem, not direct syscalls. Thankfully, they changed that in Go 1.11 (https://golang.org/doc/go1.11#runtime https://golang.org/doc/go1.11#runtime)
- loeg 8y agoThat's not really contrast; OpenBSD doesn't maintain syscall ABI stability and only supports releases for six months at a time. It's a similar problem.
- favorited 8y agoBy "contrast" I was referring to the statement "Go works reasonably well on openbsd." I don't consider breaking on macOS betas working "reasonably well."