Is the C runtime and library a legitimate part of the Unix API? (2017)
utcc.utoronto.ca
utcc.utoronto.ca
It's hard to reconcile this with the fact that every other language besides Go manages to interface with the standard c library just fine. It seems like if it were such a big problem, you'd see more languages opting out.
The closest I can think of is Java, but I have no idea how much is reimplemented in pure Java to avoid the overhead of JNI.
* Go uses its own calling convention that's different from C.
* Go doesn't use system stacks (goroutines have their own growable stacks).
* Goroutines are implemented as green threads using collaborative scheduling. Any call to C has to play nice with the scheduler to avoid blocking other goroutines running on the same thread.
* Garbage collection often requires that data be copied in order to be passed to the C library, since the original data may be freed by GC during execution.
Honestly, as someone who started their software developer education from Turbo Pascal/Delphi on DOS/Windows, system-level libc, and system-dictated ABI was a very surprising concept. Why do I have to follow some arbitrary register-usage rules inside my code? Why do I have to export functions from .so files using exactly this calling convention? Why does no one export "FreeXxx" from their libraries, why do they think I can just call "free()" when I'm done with the object they returned to me, I don't even have C's "free()" in my language?
When the whole custom-memallocs rage hit the Linux scene, it was very amusing to watch how people were suddenly realizing the existence of "wait, a program can have several "malloc()/free()" inside it, how to chose right ones?" problem.
In what concerns Java and .NET, there are intrics (with annotations) that jump through some of the safety restrictions for AOT code and when running on JIT, it eventually short circuits some calls after it realises them as being safe.
In any case, both platforms are pursuing alternative solutions to bring back those Delphi/Turbo Pascal like of calling into external code.
Android also has such annotations that allows ART just to direct call into NDK code.
https://gist.github.com/apangin/7a9b7062a4bd0cd41fcc
Ordinary native methods implemented by the JVM itself don't need to use JNI either.
https://en.wikipedia.org/wiki/Draft:Upgrade_Readiness
Appraiser not only consumes CPU (and HDD/SSD!) time, but is also technically quite interesting as well. For example it loads a simple kernel driver (nxquery.sys) into your Windows 7 machine to read a MSR to determine if NX has been disabled in the BIOS.
Like Longhorn, as everything .NET was hard to swallow for them. Later confirmed, from my point of view, when Joe Duffy recounts how some devs reacted at the internal success of Midori.
So we got Longhorn core stuff redone in COM instead for Vista, and by the time Windows 8 came out WinRT, with an .NET runtime incompatible with CLR, including only able to understand the MSIL that the team considered relevant for firstly MDIL (Windows 8/8.x) and then .NET Native (Windows 10 onwards).
Now we have Reunion trying to sort out the mess, brining everything back into Windows 7 like development stack, where UWP is just the COM evolution and both worlds (Win32 / UWP) share the same sandboxing and container models.
And in the process .NET 5 is focusing on the desktop side, with .NET Native having an uncertain future, and a big question mark if CoreRT will ever take its place.
Ah and then there is the whole story of them killing C++/CX via C++/WinRT, in name of ISO C++ compatibility, for a bunch of libraries that are anyway Windows specific.
Now they realised that telling everyone to just wait for ISO C++23 to gain C++/CX features wasn't the most welcoming decision to "Developers, Developers, Developers".
C++/WinRT only feels better for those that have eschewed C++/CX and used the real man WRL (ATL like) template library, which naturally was the Windows team.
Those politics really suck from the outside.
For example, the Windows way to clear memory is ZeroMemory() not memset().
OP references Illumos, but I also think the only way you get access to syscalls on macOS is through Apple's libc.
That's right. In fact this was a source of a time-related bug in Go on Mac OS. https://github.com/golang/go/issues/17490 https://github.com/golang/go/issues/16570
But more broadly, I think the policy is less "Unix took a wrong turn" and more that goroutines make C/Go interop painful.
Go 1.0 is basically Limbo with a bit of Oberon-2 syntax.
Outside the chocolate factory, it would have been just as successful, to the point that everyone forgets about Inferno and only talks about Plan 9.
Well, they invented Unix, and later its improved successor (Plan 9).
Go doesn't do this; it implements as much as possible itself, going straight down to direct system calls in assembly language.
Occasionally there are problems that ensue."
This is an interesting tidbit about Go to the perspective of an OS designer; basically an aspiring OS designer would only need to implement the subset of the Unix API syscalls that Go actually required, and only to the degree that Go needed specific functionality from them; that is,
it would be an interesting idea to code a new OS and/or OS microkernel -- which would only support Go's subset of Unix's syscalls/API...
Or, perhaps even more interesting -- code a 'bare-metal' version of Go which includes its own OS-like support code (mini internal OS functionality), implementing the Unix syscalls it makes, but on bare metal hardware..."
Obviously go devs are attempting to do the right thing here and trying to implement async version of getaddrinfo(3) because POSIX's version is not and this route is extremely messy as it ends up requiring to reimplement bind's libs, and or the whole dns standard.
But this has nothing to do with C's std lib. its posix interface is defined in C, that's all about it.
What's being attempted here is to implement a POSIX defined function in another language and with a different behavior (async).
If there exist a getaddrinfo_a() in the posix standard, go devs wouldn't have had any issue and they would have went the typical route and created a binding between go's call and the posix call provided by the OS.
In principle, if you can assume modern POSIX, then you can also spawn a POSIX thread to call getaddrinfo() and wait asynchronously for the result.
In practice getaddrinfo() isn't always thread-safe :/ But it's supposed to be.