-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make regular files switch context #158
Comments
Combining libmill with threads is something I would not recommend. While it may work with some pthread implementations it may not with others. In more concrete terms, pthreads may make assumptions about the layout of the call stack which are violated by libmill's 'hand-crafted' stacks. Another option would be using aio + signals, but I don't have much experience with that. For example, what happens if the signal queue is full? Are signals dropped or what? |
How was the thread here different? Is it something like kernel vs user space thread? |
It's not different. That's why I've replaced the code with something more sane. If you want to give the thread approach a try, go for it. It may not work on all platforms though. |
I'll give it a shot, then. (: |
@raedwulf have any suggestions about this? |
A coincidence! I read up on this yesterday. Currently the best way for this is a thread pool sadly. I think there was some lwn article on this (I'll find a link when i finish my job interview). Tldr; linux and posix offer aio so can be used for non blocking but they have caveats in platform compatibility and Linux aio can still block in some cases. We'll need to test the alternatives (posix or otherwise) but we might have to use kernel threads some of the supported platforms. |
I read that |
I don't recall seeing any implementation of file i/o context switching. I suspect that they use separate threads to read files and then cache it. Lwan has manual coroutines mixed with pthreads. |
I was wrong - lwan uses mmap for small files. https://tia.mat.br/posts/2012/10/14/vectored_i_o_with_mmap___to_serve_files.html |
Are we talking about offloading regular file operations to worker threads? If anyone is interested, I can upload the code to my github account. I have no plan to work on this anytime soon, and I suspect it isn't quite suitable in its current state for inclusion in libmill. (I don't have access to the computer with the code now, but hope to get it back sometime this weekend.) |
Yeah, my ideas is that the threads would be used just to offload regular file operations to worker threads. You think there wouldn't be a problem with the stack in this scenario? Btw, I'd love to see the code. |
The start_routine uses the stack (created by pthread_create) of the new thread. |
Relevant for Linux: https://lwn.net/Articles/671649/ |
yeah, looks like Linus really hates the aio interface. in the future we might have kernel support for this. but meanwhile, which approach should we use? @johneh let us know when you find the code. |
I was thinking what about a mfork-based design with a POSIX shm-backed channel (synchronised using POSIX sem) to communicate with a separate I/O process. Thoughts on this @sustrik? |
|
In the end we need to have a proper real-world benchmark program where the different approaches can be compared because it's all theoretical at the moment. We don't know if asynchronous file I/O in a different thread would give a significant advantage. For instance, lwan's mmap approach bypasses the issue through OS caching. So are blocking/non-blocking files actually important for real-world applications apart simply making sure libmill semantics are consistent? A side note, has anyone tested shm-based channel IPC performance? I recall it was one of the goals of nanomsg? EDIT: "libmill semantics are correct" -> "libmill semantics are consistent". I think the first order to be correct is to correct the documentation so that users know file I/O is never non-blocking in the current state. |
I have uploaded my experiment here: See the files worker.c and pipe.c; pipe.c code is an abstraction using regular pipe to create an inter-thread communication channel. Examples/tests are in the examples sub-directoy. Other than the files fsop.c, mcp.c and du3.c (translation of a go program from the book by Kernighan et al.), the rest can be ignored. Please use this recipe: The default configure prefix is pwd, the libs will be installed under /lib in the source directory. |
@readwulf: Right, the docs should be updated. I am working 12hr shifts this week so I'll probably won't have time to do that, but patches are welcome. |
johneh@: It looks like pipe can be made into an actual publicly visible object exported by libmill? |
@sustrik: That was the original intention. |
Warning added to the docs. |
It seems closing the write end of a pipe can be a difficult business. If the fd is closed in one thread |
Regular files don't switch context the way they're implemented now. The reason is because regular files ignore O_NONBLOCK. So they never return EAGAIN or EWOULDBLOCK. So since we can't use O_NONBLOCK, an approach we could take is to create a thread pool, dispatch the work and then when the work is done we deliver the result. We need a way to
fdwait
so for that we can useeventfd
as it was used for dns resolution in the past. What do you think about this approach?The text was updated successfully, but these errors were encountered: