That tracks, but this does not necessarily follow:
> demonstrating that the old APIs are not ideal.
I've been around the tech industry long enough to see several cycles of practitioners going back and forth between technologies and approaches. E.g. strong type systems (C++, Java) -> loose type systems (Python, JS) -> strong type systems (Rust, TypeScript). And each time the tide shifts there are always plenty of arguments trying to show why the previous approach was objectively worse and the new one is better.
That's not to say that nothing is moving forward, but the fact that people are unhappy with a technology doesn't mean that technology is objectively inferior to a proposed replacement. Sometimes it's just fashion.
I apologise for writing so much that you couldn't read all of it, but this part, whilst buried at the end of the first paragraph was really important:
> > the non-POSIX apis are much faster than the POSIX api -- especially the ones that are harder to mix with the POSIX api.
That they are better in this objective way is why this particular kind of unhappiness demonstrates what I say, even if you're not otherwise interested in people being happy.
So POSIX as a technology may be lacking but honestly what’s impressive about it to me is that it’s also a standard, not perfect there either, of course.
I think any conversation about replacing POSIX must include an effort to update or replace the standard. Deprecate the parts that no longer work well and add things that other systems have de-facto agreed upon, at least.
I think a more accurate framing is that in the 80s POSIX was designed for a thousand or so peers, and later versions have expanded and scaled accordingly. Literally every interface has these types of growth patterns so this shouldn't be a surprise.
But your point, which is the same point I made below, is that POSIX is but one of several interfaces on a modern system: https://news.ycombinator.com/item?id=34905405
As I noted below, we have semi-standardized extensions from POSIX. We don't really need POSIX to codify a new event system because we have libev/libevent. This is another point the parent article gets wrong when it says we need to get POSIX "off our necks." Nowhere does POSIX compliance stand in the way of using libev, or even using mremap(). I don't agree with your conclusion around mremap() above but it doesn't matter because the salient point is that mremap() works absolutely fine within the paradigm offered by mmap() and POSIX. libev works just fine within the paradigm offered by the file/socket api.
"But none of those "local file databases" can handle hundreds of thousands of clients"
This is absolutely not true. Those systems work just fine with even a million reader threads.
Maybe you mean the databases don't perform well under parallel writes, but this has nothing to do with the shared memory interface (how could it?). It's purely due to the design and intent of each system as primarily read-focused systems. mmap will work just as well as any other shared memory interface when it comes to reading and writing. Pick nearly any write-performant database - it's using mmap.
"Evolving APIs are evidence that people are unhappy with these interfaces"
Not quite. The actual truth is that POSIX plays very well with extensions to its interfaces and this is yet another dimension in which the above article is demonstrated to be very, very silly.
I suppose it depends how you define a "client". If you define it as a query (or an HTTP request or something like that), then I suppose you're right, but you're also not mmap()ing all the time, which is what we're actually talking about here. But if you define it the way databases traditionally do, it is itself a full-featured application, so 100 clients doing 1m queries a second is 100m queries per second, and no, mmap() isn't fast enough to do that, and since we're talking about mmap() I didn't think I needed to explain that.
> But your point, which is the same point I made below, is that POSIX is but one of several interfaces on a modern system: https://news.ycombinator.com/item?id=34905405
I must be reading a different comment, because I don't understand exactly what that has to do with anything, but I think if you're not reading "every word" of the article, maybe I'm thinking you're not reading "every word" my comments either. I was only under the impression you thought the sockets API and mmap() were ideal interfaces.
What position do you think I have that you think I need to change?
> Not quite. The actual truth is that POSIX plays very well with extensions to its interfaces and this is yet another dimension in which the above article is demonstrated to be very, very silly.
I don't understand. That POSIX is so big is one of the first complaints in the article given by implementors of embedded systems, and the "extension-like" nature of POSIX works directly against that. Then, once you have this nice "extension" like iouring with its provided buffers and files, which is basically like a whole io-state-machine operating system in zero system calls, and you know, maybe it can be part of the POSIX standardization process and make POSIX better, or maybe it just becomes popular enough there's a kevent ring extension for the bsds and there's a libiocp4 that unifies the differences, and you think that's all basically POSIX anyway, so what's the point?
Well, the point is that shouldn't stop people from imagining a system that didn't do anything else -- how much smaller the code would be, and cheaper the hardware (less ram, less rom), and maybe if you can organise the kernel with this model in mind, how much faster it would be. These sorts of ideas you can really only explore once you've mentally prepared yourself for there not being a POSIX.
The article defines client as another thread or process - the argument is that these interfaces only support two processes and not many. There isn't any functional limit on how many processes can map the same region of memory.
"but you're also not mmap()ing all the time, which is what we're actually talking about here"
No, I don't think that's at all what we're talking about. We're talking about the ability of the architecture to scale -- not the efficiency of calling one specific syscall.
"I was only under the impression you thought the sockets API and mmap() were ideal interfaces."
I haven't said that they're ideal, only that they're demonstrably capable of enabling more than just two processes to interact.
"and you think that's all basically POSIX anyway, so what's the point?"
The point is that the article's conclusion that POSIX is preventing progress is nonsense.
As you say, standards emerge.
"how much smaller the code would be, and cheaper the hardware (less ram, less rom), and maybe if you can organise the kernel with this model in mind, how much faster it would be."
These aren't points raised by the article -- in fact so far we've been discussing the opposite (extensions and features, not cutting features).
Could things be cut from POSIX? Sure. But is implementing stuff like select() really a "yoke?" It's not exactly difficult, and I don't think you or anyone has articulated how it might hamper the inclusion of more advanced interfaces. The resources needed to implement POSIX are not significant.
What specifically do you think POSIX's architecture is preventing us from implementing?
It does no such thing. The word "client" is given once in the text, and little is said except it isn't a thread due to the fact their support is fraught with peril and often poorly provided for by programming languages
> I haven't said that they're ideal, only that they're demonstrably capable of enabling more than just two processes to interact.
So was carrier pigeon, but sometimes we want to send messages faster than that.
> These aren't points raised by the article -- in fact so far we've been discussing the opposite (extensions and features, not cutting features).
>... about the ability of the architecture to scale -- not the efficiency of calling one specific syscall.
> What specifically do you think POSIX's architecture is preventing us from implementing?
Erm, they are the points raised by the article, that's kind-of why I think you still haven't read it yet. Here's the paragraph right after the one where it defines a client as not-a-thread (and after talking about one specific syscall):
The death of any of these systems is when a user asks, "What about Posix? How can I port my XXX program to run on your system?" Providing Posix-like semantics in these systems is their death knell, because the Posix way of thinking is so narrow and providing its varied illusions requires so many hidden changes and adherences to age-old assumptions that there is no way to have a flexible innovative system and serve the Posix elephant. This means that no matter how innovative and clever a system is, once it is tainted by Posix support, it becomes just another Posix system.
> But is implementing stuff like select() really a "yoke?" It's not exactly difficult, and I don't think you or anyone has articulated how it might hamper the inclusion of more advanced interfaces
Could you show me? I don't think it's possible to implement a select() that works with Linux's fancy new iouring that uses the provided files and buffers features easily, but I'd like to be proven wrong.
It does. It says quite clearly, quote "If you look at most inter-process communication mechanisms, you can see that they are most often used by only two programs — usually a client and server." Two processes on a local machine, using shared memory or other IPC. IPC, not network calls.
"So was carrier pigeon, but sometimes we want to send messages faster than that."
Don't be disingenuous. You haven't articulated a faster mechanism and in fact there isn't one.
"Erm, they are the points raised by the article,"
No, they are not. Based on your replies it seems you may fundamentally not understand the points raised by the article.
"Could you show me? I don't think it's possible to implement a select() that works with Linux's fancy new iouring that uses the provided files and buffers features easily, but I'd like to be proven wrong."
You've already provided an example. The Linux kernel provides both select, a posix interface, and io_uring. Nothing about providing posix interfaces precludes providing specialized interfaces as well.
Two processes! Not two threads!
> Don't be disingenuous.
How would you know? You still haven't read the article, so you're arguing with a straw-man!
> You haven't articulated a faster mechanism and in fact there isn't one.
"la la la my fingers are in my ears I can't hear you!" is the best you got? You seem to admit iouring exists, isn't POSIX, but what? You just don't believe it's faster now? Bull shit.
> You've already provided an example. The Linux kernel provides both select, a posix interface, and io_uring. Nothing about providing posix interfaces precludes providing specialized interfaces as well.
If you think a reimplementation of Linux is "easy" you need to have your head examined: Microsoft has near-infinite money and eventually gave up, deciding POSIX was too hard, and just implemented another hypervisor.
And I wrote "thread or process" because, architecturally regarding IPC, the distinction is unimportant.
"How would you know?"
Due to the inaccuracy of your analogy, with regard to actual systems interfaces.
"You seem to admit iouring exists, isn't POSIX, but what? You just don't believe it's faster now? Bull shit."
io_uring is not faster than shared memory via mmap.
"If you think a reimplementation of Linux is "easy" you need to have your head examined"
I think now we're touching on the limits of your experience and expertise. Implementing select(2) on Linux is indeed quite simple. Have you ever read through select.c?
Have you ever even implemented a posix subsystem? I have.
"Microsoft has near-infinite money and eventually gave up, deciding POSIX was too hard, and just implemented another hypervisor. "
This isn't how things work on Windows.
As an aside, I've noticed that your ignorance has shifted into rudeness. Don't bother to respond again. This conversation is over.
I think "the [BSD] socket API" was designed for a thousand or so peers (FD_SETSIZE). That's why the API evolved. Now (2023) there are a lot of APIs and different choices you can make (blocking, polling readiness, sigio, aio, iocp, iouring), none of which is best at everything, but the non-POSIX apis are much faster than the POSIX api -- especially the ones that are harder to mix with the POSIX api.
> "We should be able to assume that the data we want exists in main memory without having to keep telling the system to load more of it."
> Yes, this is exactly what mmap() already does. mmap() is part of POSIX. Use it!
This is not what mmap() does, but the opposite. mmap() sets up page-tables for demand-paging. Those little page-faults actually trigger a check (demand) to see if the page is "in memory" (this is what Linux calls the "block cache"), an update to the page-tables to point to where it is and returns (or kick off a read IO operation to the backing store). These page-faults add up. What the author is looking for in Linux is mremap() and Darwin is mach_vm_remap() and definitely not in POSIX.
> * Shared memory - mmap() is about as generic of a memory sharing interface as one could hope for. It certainly works just fine with arbitrary numbers of clients. There are again countless examples of using shared memory with arbitrary participants -- for example all the various local file databases: sqlite, leveldb, berkeley db, etc.
But none of those "local file databases" can handle hundreds of thousands of clients, and aren't great even for the low hundreds(!), that's why most "big" database vendors avoid "just" using mmap(), and instead have to perform complex contortions involving things like mach_vm_remap/mremap/O_DIRECT/sigaction+SIGSEGV. userfaultfd and memfd are other examples of recent evolutions in these APIs.
You are looking for truth? Evolving APIs are evidence that people are unhappy with these interfaces, and these newer APIs are better at some things than the old, demonstrating that the old APIs are not ideal.
So we have evidence our (programming) model is not ideal, are we to be like Copernicus and look for a better model (better APIs)? Or are we to emulate Tolosani and Ingoli?