In various parts of the runtime and in compiler generated code we need to get a reference to the (VM-level) Thread* of the currently executing thread. This is what Thread::current() returns. For performance reasons we also have a fast-path on 64-bit where the Thread* is stashed away in a register (g7 on sparc, r15 on x64).
So Thread::current() is actually a slow-path mechanism and it delegates to ThreadLocalStorage::thread().
On some systems ThreadLocalStorage::thread utilizes a caching mechanism to try and speed up access to the current thread. Otherwise it calls into yet another "slow" path which uses the available platform thread-specific-storage APIs.
Compiled code also has a slow-path get_thread() method which uses assembly code to invoke the same platform thread-specific-storage APIs (in some cases - on sparc it simply calls ThreadLocalStorage::thread()).
8130212 had to fix a problem with the caching mechanism on Solaris and in doing so highlighted that this old ThreadLocalStorage code was put in place to deal with inadequacies of the system provided thread-specific-storage API. In fact on Solaris we even by-pass the public API (thr_getspecific/thr_setspecific) when we can and implement our own version using lower-level APIs available in the T1/T2 threading libraries!
In mid-2015 things have changed considerably and we have reliable and performant support for thread-local variables at the C++ language-level. So the way to maintain the current thread is simply using (current Solaris version):
// Declaration of thread-local variable
static __thread Thread * _thr_current
inline Thread* ThreadLocalStorage::thread() {
return _thr_current;
}
inline void ThreadLocalStorage::set_thread(Thread* thread) {
_thr_current = thread;
}
But we can go further, by using language-level thread-locals we can completely remove the ThreadLocalStorage class and define things directly in the Thread class itself, and remove the notion of get_thread_slow.
So Thread::current() is actually a slow-path mechanism and it delegates to ThreadLocalStorage::thread().
On some systems ThreadLocalStorage::thread utilizes a caching mechanism to try and speed up access to the current thread. Otherwise it calls into yet another "slow" path which uses the available platform thread-specific-storage APIs.
Compiled code also has a slow-path get_thread() method which uses assembly code to invoke the same platform thread-specific-storage APIs (in some cases - on sparc it simply calls ThreadLocalStorage::thread()).
8130212 had to fix a problem with the caching mechanism on Solaris and in doing so highlighted that this old ThreadLocalStorage code was put in place to deal with inadequacies of the system provided thread-specific-storage API. In fact on Solaris we even by-pass the public API (thr_getspecific/thr_setspecific) when we can and implement our own version using lower-level APIs available in the T1/T2 threading libraries!
In mid-2015 things have changed considerably and we have reliable and performant support for thread-local variables at the C++ language-level. So the way to maintain the current thread is simply using (current Solaris version):
// Declaration of thread-local variable
static __thread Thread * _thr_current
inline Thread* ThreadLocalStorage::thread() {
return _thr_current;
}
inline void ThreadLocalStorage::set_thread(Thread* thread) {
_thr_current = thread;
}
But we can go further, by using language-level thread-locals we can completely remove the ThreadLocalStorage class and define things directly in the Thread class itself, and remove the notion of get_thread_slow.
- duplicates
-
JDK-8024829 Cache Thread::current()->resource_area() in class Phase
- Closed
- relates to
-
JDK-8154715 Missing destructor and/or TLS clearing calls for terminating threads
- Resolved
-
JDK-8282469 Allow considered use of C++ thread_local in Hotspot
- Resolved
-
JDK-8176442 [aix] assert(_thr_current == 0L) failed: Thread::current already initialized
- Resolved
-
JDK-8029928 pthread_key_t is casted down into int from long
- Resolved
-
JDK-8184339 Thread::current_or_null() shall not assert if Posix TLS is not yet initialized
- Resolved
(1 relates to)