Question about the blocking syscalls within virtual thread
Alan Bateman
Alan.Bateman at oracle.com
Wed Dec 1 09:13:57 UTC 2021
On 30/11/2021 21:18, Almas Abdrazak wrote:
> Good day, thanks for giving me an opportunity to ask this question.
> The question I have is about performing syscalls from a virtual thread. My
> main OS is Linux so I would talk in terms of Linux. When I use InputStream
> class from jdk, internally it uses read() syscall, according to man pages,
> read() syscall is blocking so it will lock the OS thread until data won't
> be available. So with this in mind I read JEP Virtual Threads (Preview)
> According to JEP
> "The implementations of these APIs are heavily synchronized and require
> changes to avoid pinning when using these APIs from virtual threads."
> So InputStream implementation was changed to avoid synchronized keyword,
> but still it uses read() syscall right ?
> Later on in the JEP there is a paragraph
> "When a virtual thread tries to park, say, by performing a blocking I/O
> operation, while pinned, rather than released, its underlying OS thread
> will be blocked"
> As far as I understand, using InputStream would still block the OS thread,
> which means I can't increase the throughput of my backend if it uses JDBC
> which uses InputStream under the hood(Tomcat with 200 OS threads would be
> better than amount of threads equals to CPU cores all waiting on IO because
> virtual threads were using InputStreams). Did I understand it correctly ?
> My other assumption is that the JVM runtime detects that blocking read()
> would be called and replaces it with non blocking epoll() syscall from
> Linux. Please clarify this to me because I can't find any information.
The draft JEP is lengthy and I think you've picked out sentences from
different sections so hopefully we can clarify it here.
Your example is a JDBC connection. This is a network connection and the
"Networking API" section is where we try to explain that all blocking
operations have been updated to release the underlying thread (if you
are strace-ing syscalls then you won''t see read blocking, you may see
calls to epoll).
An input stream to a Socket will typically be wrapped in a buffered
input stream or a reader that bridges it to a character stream. This is
the "java.io APIs" section (that you quote from) which we try to explain
how the byte/character stream classes are changed to avoid using
monitors and workaround the temporarily limitation with pinning.
The "Limitations" section near the end (I think one of the sentences you
quote is from here) tries to summarize the general issues with pinning.
In the case of the JDBC connection then it may be an issue, it may not
be. So while every effort has been made to avoid pinning in the standard
APIs, it is possible that the JDBC driver is holding monitors when it
does blocking read/write operations. There is diagnostic options to help
identify these cases. I'm aware of several JDBC drivers that have
already done some preparation work to avoid the issue but you may have
to try it out to see if you have an issue or not.
-Alan
More information about the loom-dev
mailing list