On 6 Jul 2014 at 16:20, Niklas Angare wrote:
"Niall Douglas" wrote:
For me personally, how QNX (and I assume Hurd) do async i/o is the gold standard.
As a QNX user I'm curious about what you're referring to here.
All micro kernel OSs act as if all syscalls are non-blocking, even async. I cannot speak for the Hurd, but for QNX the central scheduler works by dispatching coroutines which when they block due to a message send they are saved and the next unblocked coroutine is continued. For example, if you try writing a byte to a fd, under the bonnet in the write() implementation that turns into a MsgSend which sends the byte to the channel corresponding to that fd which will appear in the resource manager's channel for that fd. The sending coroutine is then marked as blocked on message send, is suspended and the next coroutine executed for the next message arriving or in the queue. What this turns into is that you can pretty much skip threads entirely in most QNX programs - you use threads solely for having work executed on multiple CPU cores concurrently, not for concurrency in kernel space as you get for free concurrency in "kernel space" all the time (there is almost no kernel space in QNX, device drivers or handling page faults or interrupt handling are just another message dispatch and handle). As all syscalls can be scheduled and completed later on the same thread via coroutines, that means you can issue a read gather across multiple fds and as the results complete you'll receive messages with the results which appear to your code as the API returning (note you can bypass this or override it to your heart's content, QNX lets you hack the message dispatch very easily). Obviously such a facility would be extremely useful to something like ASIO because one can dispense entirely with the select()/epoll() machinery at the heart of the io_service which dispatches completions to the next available thread worker. In QNX an ASIO equivalent is already there at the heart of the OS - in fact, in QNX, the message passing infrastructure is pretty much the only thing there is, as everything from handling page faults in memory mapped files through to device drivers is implemented with the same core message passing infrastructure. QNX is a neat system. Once you've written a device driver for it you'll never enjoy writing one for Linux ever again. Linux looks quite stone age and backwards in comparison, though in fairness QNX struggles to scale as Android can. In particular, QNX copies a *tremendous* amount of memory around and will eliminate any advantages of L1/L2 caches very quickly indeed. BB10 runs at main memory speed a lot of the time as the L2 cache might as well not be there under message passing load. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/