3 ms·
There are several advantages to using kernel syscalls directly: 1. No overhead from libc; minimizes syscall cost 2. No dependency on libc and C language ABI/t
by titzer 2y ago
There are several advantages to using kernel syscalls directly:
1. No overhead from libc; minimizes syscall cost
2. No dependency on libc and C language ABI/toolchains
3. Reduced attack surface. libc can and does have bugs and potentially ROP or Spectre gadgets.
4. Bootstrapping other languages, e.g. Virgil
- kllrnohj 2y ago> 1. No overhead from libc; minimizes syscall cost The few nanoseconds of a straight function call are absolutely irrelevant vs the 10s of microseconds of a syscall cost and you lose out on any of the optimizations a libc has that you might not or didn't think about (like memoization of getpid() ) and you need to take on keeping up with syscall evolution / best practices which a libc generally has a good handle on. > No dependency on libc and C language ABI/toolchains This obviously doesn't apply to a C syscall header, though, such as the case in OP :)
- gpderetta 2y agoA syscall can be way less than 10us. Especially if it is not doing I/O.
- kaba0 2y agoBut a kernel mode switch is definitely more expensive than a trivial (likely cached) jump instruction.
- matheusmoreira 2y ago> you lose out on any of the optimizations a libc has that you might not or didn't think about (like memoization of getpid() ) Not much of a big deal. These "optimizations" caused enough bugs that they actually got reverted. https://www.man7.org/linux/man-pages/man2/getpid.2.html https://www.man7.org/linux/man-pages/man2/getpid.2.html Because of the aforementioned problems, since glibc 2.25, the PID cache is removed: calls to getpid() always invoke the actual system call, rather than returning a cached value. Get rid of libc and you gain the ability to have zero global state in exchange. Freestanding C actually makes sense and is a very fun language to program in. No legacy nonsense to worry about. Even errno is gone.
- kllrnohj 2y ago> Get rid of libc and you gain the ability to have zero global state in exchange. No you don't, you still have the global state the kernel is maintaining on your behalf. Open FDs, memory mappings, process & thread scheduling states, limits, the command line arguments, environment variables, etc... There's a shitload of global state in /proc/self/ Also the external connections to the process (eg, stdin/out/err) are still inherently global, regardless of however your runtime is pretending to treat them. And it's not like you even managed to reduce duplicated state since every memory allocator is going to still track what regions it received from the kernel and recycle those. > Freestanding C actually makes sense [..] No legacy nonsense to worry about Except for, you know, the entire language :p