<div dir="auto">Last time I've checked on the OpenJDK src there's something that could help there i.e. <a href="https://github.com/openjdk/jdk/blob/861cc671e2e4904d94f50710be99a511e2f9bb68/src/java.base/share/classes/sun/nio/ch/Util.java#L56">https://github.com/openjdk/jdk/blob/861cc671e2e4904d94f50710be99a511e2f9bb68/src/java.base/share/classes/sun/nio/ch/Util.java#L56</a><div dir="auto"><br></div><div dir="auto">but probably will need to be exposed in the right way, and currently thread local pooling is outside the scoped value purposes, meaning that we would need something "different".</div><div dir="auto">Per-carrier thread locals aren't free and due to the work stealing nature of v threads, a release of the pooled instance can land in a different carrier from the originating one, that's something to be considered.</div><div dir="auto">But still, I agree with Carl M that other solutions are worse, on the paper, due to the presence of atomic operations, likely contended (even if wait-free as xchg or others, or by using multiplicative methods to distribute the contention).</div><div dir="auto"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il mar 21 feb 2023, 00:33 robert engels <<a href="mailto:rengels@ix.netcom.com">rengels@ix.netcom.com</a>> ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space">Why do you think that VirtualThreads do not support ThreadLocal? From the docs:<div><br></div><blockquote type="cite"><span style="color:rgb(22,21,19);font-family:OracleSansVF,OracleSansVFCyGr,-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",sans-serif;font-size:14.8px;background-color:rgb(251,249,248)">Finally, another aspect that works correctly in virtual threads but deserves being revisited for better scalability is </span><span style="box-sizing:border-box;margin:0px;padding:0px;list-style:none;font-style:italic;color:rgb(22,21,19);font-family:OracleSansVF,OracleSansVFCyGr,-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",sans-serif;font-size:14.8px;background-repeat:no-repeat no-repeat">thread-local variables</span><span style="color:rgb(22,21,19);font-family:OracleSansVF,OracleSansVFCyGr,-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",sans-serif;font-size:14.8px;background-color:rgb(251,249,248)">, both regular and inheritable. Virtual threads support thread-local behavior the same way as platform threads, but because virtual threads can be very numerous, thread locals should be used only after careful consideration.</span></blockquote><div><br></div><div><div>If you expect every thread to have this trace then the memory will be used regardless.</div><div><br></div><div><br></div><div><div><blockquote type="cite"><div>On Feb 20, 2023, at 5:17 PM, Carl M <<a href="mailto:java@rkive.org" target="_blank" rel="noreferrer">java@rkive.org</a>> wrote:</div><br><div><span style="font-family:Helvetica;font-size:16px;font-style:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none;float:none;display:inline!important">Re sending without HTML</span><br style="font-family:Helvetica;font-size:16px;font-style:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"><br style="font-family:Helvetica;font-size:16px;font-style:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none"><blockquote type="cite" style="font-family:Helvetica;font-size:16px;font-style:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration:none">On 02/20/2023 3:15 PM PST Carl M <<a href="mailto:java@rkive.org" target="_blank" rel="noreferrer">java@rkive.org</a>> wrote:<br><br><br>While testing out Virtual Threads with project Loom, I encountered some challenges that I was hoping this mailing list could provide guidance on.<br><br>I have a tracing library that uses ThreadLocals for recording events and timing info. The concurrency is structured so that each thread is the sole writer to it's own trace buffer, but separate threads can come in and read that data asynchronously. I am using ThreadLocals to avoid contention between multiple tracing threads. Secondarily, I depend on threads exiting for automatic clean up of the trace data per thread.<br><br>Virtual threads present a hard to overcome challenge, because I can't find a way to tell if ThreadLocals are supported. One of the value propositions of my library is that it has a consistent and low overhead. Specifically, calling ThreadLocal.set() throws an UnsupportedOperationException in the event that they are not allowed. In the case of using Virtual threads, the likelihood of this happening is much higher, since users are now able to create threads cheaply. I have explored several work-arounds, but not being able to tell is one I can't seem to cleanly overcome. Some ideas that did not pan out:<br><br>* Use a ConcurrentHashMap to implement my own "threadlocal" like solution. Two problems come up: 1. It's easy to accidentally keep the thread alive, and 2. When Thread Locals are supported, my library doesn't get the speedup from them.<br><br>* Use an AtomicReferenceArray and hash into a fixed size of buckets. This avoids using the Thread as a Key, and pays a minor cost of synchronizing on the bucket for recording trace data. In effect it's a poor man's ThreadLocal. However, If I get unlucky there will be contention on a bucket that doesn't naturally shard itself like CHM does.<br><br>* Do Nothing. This causes callers to allocate a ton of memory since the ThreadLocal.initialValue() gets called a ton, leading to unpredictable tracer overhead. There is a small but noticeable amount of overhead for creating the initial value (like registering with the reader) so this ends up not being practical.<br><br>* A Hybrid of ThreadLocal when supported and fallback to CHM or ARA as mentioned above. This is the solution I came up with, where my ThreadLocal calls get() but has no initialValue() override. If the value is null, I attempt to set it. If there is an exception, I write the value to the CHM/ARA and then check there first for future get() calls. The problem with this is that the exception from set() causes an unacceptable amount of overhead for something that should have been very cheap. It isn't sufficient to check if the thread is virtual to see if TLs are supported, so I can't check the class name of the thread apriori. And, since multiple types of threads are calling into my library, I can't require callers to use TLs.<br><br><br>I'm kind of at a loss as to how to efficiently fallback to a slower implementation when TLs aren't supported, since I can't tell if they are or not. (e.g. can't tell if the electric fence is on without touching it). Again, I'd prefer to keep the fast ThreadLocals if they are supported though.<br><br><br>I'm looking for ideas (or just to register feedback) with this email, and have been otherwise very happy with the progress on project Loom.<br><br>Carl</blockquote></div></blockquote></div><br></div></div></div></blockquote></div>