Thread Native ID Access

Hohensee, Paul hohensee at amazon.com
Fri Feb 23 21:07:39 UTC 2018


Here’s a concrete proposal on which people may want to comment.

We could add a method to ThreadInfo, vis.,

long getPlatformThreadId()

Returns the platform-specific thread ID of the thread associated with this ThreadInfo. The ID has no meaning to the Java runtime and is not guaranteed to have any meaning at all.
I.e., it may be a constant value for all threads, or a native address, and may not be the same across multiple invocations.

Returns:

the platform-specific ID of the associated thread.

For a fiber, a reasonable value would be the OS thread id for the OS thread that’s running the fiber at ThreadInfo construction time. If, say, the platform used a string or some other larger-than-long value, it could be a native address or some other value that mapped to one.

If we don’t want to add a new method to ThreadInfo, we could define a com.sun.management.ThreadInfo to go with com.sun.management.ThreadMXBean.

Parenthetically, to me a fiber is enough different from a thread to warrant a separate MXBean. I.e., a thread is a species of fiber, but not vica versa. So, we shouldn’t gate changes to ThreadMXBean on having a thorough understanding of how to support fibers in JMX.

We could also add to com.sun.management.ThreadMXBean the methods getThreadId(long id), getThreadId(long [] ids), getPlatformThreadId(long id), and getPlatformThreadId(long [] ids). These presumably would be fast compared to creating ThreadInfo(s).

We don’t want to add Thread.getPlatformId(), so the way to get the current thread’s platform id would be

getThreadInfo( Thread.currentThread().getId() ).getPlatformThreadId()

which is cumbersome and slow. Instead, by analogy to ThreadMXBean.getCurrentThreadCpuTime(), we could add to com.sun.management.ThreadMXBean the methods getCurrentThreadId() and getCurrentPlatformThreadId().

All this may seem somewhat overkill, but it’s no more so than how we currently create ThreadInfo objects and the various ThreadCpu/UserTime method definitions.

Thanks,

Paul

From: serviceability-dev <serviceability-dev-bounces at openjdk.java.net> on behalf of Jeremy Manson <jeremymanson at google.com>
Date: Thursday, February 22, 2018 at 9:42 PM
To: David Holmes <david.holmes at oracle.com>
Cc: "serviceability-dev at openjdk.java.net" <serviceability-dev at openjdk.java.net>, "loom-dev at openjdk.java.net" <loom-dev at openjdk.java.net>, John Rose <john.r.rose at oracle.com>
Subject: Re: Thread Native ID Access

I think we're all pretty much agreed that fibers imply native tids can change.  I think that, as long as we document that, we're fine.

An API where there is probably a worse implementation problem is ThreadMXBean#getThreadCpuTime<https://docs.oracle.com/javase/9/docs/api/java/lang/management/ThreadMXBean.html#getThreadCpuTime-long->.  Right now, the implementation assumes a 1:1 mapping between OS thread and Java thread.  Removing that assumption implies you have to do something like track cpu time every time the scheduler switches you out, which is going to make your switches expensive.

Jeremy

On Thu, Feb 22, 2018 at 9:16 PM, David Holmes <david.holmes at oracle.com<mailto:david.holmes at oracle.com>> wrote:
On 23/02/2018 3:04 PM, John Rose wrote:
On Feb 22, 2018, at 8:49 PM, David Holmes <david.holmes at oracle.com<mailto:david.holmes at oracle.com> <mailto:david.holmes at oracle.com<mailto:david.holmes at oracle.com>>> wrote:

I don't think this request has any impact on Fibers at all. At any given time a piece of executing Java code is executing on a current Thread, and that current Thread must be running on a native thread (regardless of mapping) and the native thread has an id. The only use for exposing such an id is to allow you to correlate information obtained from inside the VM, with information observed outside, possibly by external tools.

We may or may not bind fiber identity to the legacy java.lang.Thread type.

I'm not assuming that exposing native thread ids implies anything about the binding between those entities and anything higher-level. I have no issue with a Fiber/Continuation/Task/whatever running on different java.lang.Threads over its lifetime. For that matter I don't think it matters if java.lang.Threads could execute on different native threads (they don't but they could).

David
-----

This affects the question of whether the following code can return false:

boolean testThreadShift(Runnable r) {
   Thread t0 = Thread.current();
   r.run();
   Thread t1 = Thread.current();
   return t0 == t1;
}

This method can return false if (a) Thread.current() reports the identity
of the OS thread (not the fiber currently running), and (b) the runnable
includes a blocking operation which causes the current fiber to reschedule
on a different OS thread before it returns.

Having this method return false is, perhaps, surprising enough to cause
us to inject fiber identity into java.lang.Thread, so that a java.lang.Thread
identity is 1-1 with a fiber, rather than an OS "dinosaur" thread.  (You can
only pick one!)  The alternative is to keep a 1-1 identity between OS threads
and java.lang.Thread instances, making a new type which carries fiber
identity that multiplexes in a scheduler-dependent way over OS threads.

It's an interesting trade-off, with many compatibility concerns.
I think we are leaning toward injecting fiber identity into Thread,
although this makes me shudder to think of the overheads we
will buy with this one move (ThreadLocal hash tables).

So, now if you reify the OS thread identity, you could have the same
issue again.  Can this routine return false?

boolean testNTIDShift(Runnable r) {
   long t0 = NativeThreadID.current();
   r.run();
   long t1 = NativeThreadID.current();
   return t0 == t1;
}

I think, if you are digging down all the way to the native thread ID,
this routine *must* be allowed to return false under a Loom JVM.
There's no credible way to assign unique int64_t IDs to fiber objects
in the Java heap, as if they were OS objects.

So my question is, do the proposed use cases for NTID allow
for testNTIDShift to return false?  If not, then it's pretty easy to say
that we don't want to supply NativeThreadID.current() for general
use, just to people implementing schedulers.

— John



More information about the loom-dev mailing list