JDK-8274051 : Remove supports_vtime()/elapsedVTime()
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 18
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2021-09-21
  • Updated: 2025-07-03
  • Resolved: 2025-06-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 26
26 b05Fixed
Related Reports
Causes :  
Duplicate :  
Duplicate :  
Description
os::supports_vtime() and os::elapsedVTime() can be replaced by the os::[current_]thread_cpu_time() API. These APIs get user+sys times, which the new API does too.

Note that the os::thread_cpu_time() API is supported by all platforms*, so the only user of the old _vtime() API, G1, can just require it.

*) While in mainline it is not supported on *BSD except OSX, the (in)official externally maintained port at https://github.com/freebsd/openjdk/blob/jdk24u-freebsd/src/hotspot/os/bsd/os_bsd.cpp#L2609 does. There are efforts in progress to upstream the changes (https://mail.openjdk.org/pipermail/bsd-port-dev/2025-June/003231.html)
Comments
> We see now crashes / asserts on Linux Alpine x86_64 and AIX, do you think they are related On AIX, we even have some additional output. We see in the output "pthread_getthrds_np failed." This comes from thread_cpu_time_unchecked https://github.com/openjdk/jdk/blob/7583a7b857da053c5e3770b680ab3494f1a6b66a/src/hotspot/os/aix/os_aix.cpp#L2404 . Not sure if a failing thread_cpu_time_unchecked / os::thread_cpu_time is well handled currently.
01-07-2025

We see now crashes / asserts on Linux Alpine x86_64 and AIX, do you think they are related? Should I open a new JBS issue ? Linux Alpine x86_64 : runtime/logging/DefaultLogDecoratorsTest # SIGSEGV (0xb) at pc=0x00007f2c19d91b18, pid=11443, tid=11452 # # JRE version: OpenJDK Runtime Environment (26.0) (fastdebug build 26-internal-adhoc.jenkinsi.jdk) # Java VM: OpenJDK 64-Bit Server VM (fastdebug 26-internal-adhoc.jenkinsi.jdk, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64) # Problematic frame: # C [ld-musl-x86_64.so.1+0x66b18] pthread_getcpuclockid+0x0 Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) C [ld-musl-x86_64.so.1+0x66b18] pthread_getcpuclockid+0x0 V [libjvm.so+0xf13496] G1RemSetSummary::update()::CollectData::do_thread(Thread*)+0x16 (g1RemSetSummary.cpp:47) V [libjvm.so+0xe60585] G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure*)+0x55 (g1ConcurrentRefine.cpp:125) V [libjvm.so+0xf14499] G1RemSetSummary::G1RemSetSummary(bool)+0x89 (g1RemSetSummary.cpp:53) V [libjvm.so+0xef6173] G1RemSet::print_summary_info()+0x73 (g1RemSet.cpp:1688) V [libjvm.so+0xe16b78] G1CollectedHeap::print_tracing_info() const+0x18 (g1CollectedHeap.cpp:2174) V [libjvm.so+0x107dc70] before_exit(JavaThread*, bool)+0x420 (java.cpp:516) V [libjvm.so+0x1cde887] Threads::destroy_vm()+0x1a7 (threads.cpp:974) V [libjvm.so+0x11ca7cc] jni_DestroyJavaVM+0xac (jni.cpp:3741) C [libjli.so+0x3fee] JavaMain+0x3ee (java.c:668) C [libjli.so+0x7a49] ThreadJavaMain+0x9 (java_md.c:646) siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x00007f2bf4df7b68 AIX : gc/g1/TestRemsetLoggingThreads # Internal Error (/priv/jenkins/client-home/workspace/openjdk-jdk-aix_ppc64-dbg/jdk/src/hotspot/os/aix/os_aix.cpp:2394), pid=7012706, tid=258 # assert(n >= 0) failed: negative CPU time # No context given, using current context. Native frame: iar: 0x0900000006124e2c libjvm.so::AixNativeCallstack::print_callstack_for_context(outputStream*, ucontext_t const*, bool, char*, unsigned long)+0x4ec (C++ uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:5 parmsonstk:1) lr: 0x0900000005eb0bbc libjvm.so::CompressedOops::decode_not_null(narrowOop)+0xbc (C++ uses_alloca saves_lr stores_bc gpr_saved:2 fixedparms:1 parmsonstk:1) sp: 0x000000011023ba00 (base - 0x1E88) rtoc: 0x08001000a0462e30 |---stackaddr----| |----lrsave------|: <function name> 0x000000011023bdf0 - 0x09000000061248c4 libjvm.so::os::Aix::platform_print_native_stack(outputStream*, void const*, char*, int, unsigned char*&)+0x24 (C++ uses_alloca saves_lr stores_bc gpr_saved:1 fixedparms:5 parmsonstk:1) 0x000000011023be70 - 0x0900000006124778 libjvm.so::NativeStackPrinter::print_stack(outputStream*, char*, int, unsigned char*&, bool, int)+0x58 (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:6 fixedparms:7 parmsonstk:1) 0x000000011023bf80 - 0x09000000068bc034 libjvm.so::VMError::report(outputStream*, bool)+0x1cf4 (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:18 fixedparms:2 parmsonstk:1) 0x000000011023ca70 - 0x0900000005e96030 libjvm.so::VMError::report_and_die(int, char const*, char const*, char*, Thread*, unsigned char*, void const*, void const*, char const*, int, unsigned long)+0x870 (C++ uses_alloca saves_lr stores_bc gpr_saved:18 fixedparms:8 parmsonstk:1) 0x000000011023cc50 - 0x0900000005e954e0 libjvm.so::report_vm_error(char const*, int, char const*, char const*, ...)+0xa0 (C++ uses_alloca saves_lr stores_bc gpr_saved:5 fixedparms:4 parmsonstk:1) 0x000000011023cd10 - 0x0900000005eb5a68 libjvm.so::os::thread_cpu_time(Thread*)+0x68 (C++ uses_alloca saves_lr stores_bc gpr_saved:1 fixedparms:1 parmsonstk:1) 0x000000011023cd90 - 0x090000000635e898 libjvm.so::G1ConcurrentRefineThread::cpu_time()+0x18 (C++ uses_alloca saves_lr stores_bc gpr_saved:1 fixedparms:1 parmsonstk:1) 0x000000011023ce10 - 0x090000000635e774 libjvm.so::G1RemSetSummary::update()::CollectData::do_thread(Thread*)+0x34 (C++ uses_alloca saves_lr stores_bc gpr_saved:4 fixedparms:2 parmsonstk:1) 0x000000011023cea0 - 0x090000000635ea28 libjvm.so::G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure*)+0xa8 (C++ uses_alloca saves_lr stores_bc gpr_saved:7 fixedparms:2 parmsonstk:1) 0x000000011023cf50 - 0x090000000635e91c libjvm.so::G1ConcurrentRefine::threads_do(ThreadClosure*)+0x1c (C++ uses_alloca saves_lr stores_bc gpr_saved:1 fixedparms:2 parmsonstk:1) 0x000000011023cfd0 - 0x090000000635e68c libjvm.so::G1RemSetSummary::G1RemSetSummary(bool)+0xec (C++ uses_alloca saves_lr stores_bc gpr_saved:4 fixedparms:2 parmsonstk:1) 0x000000011023d080 - 0x0900000006646f38 libjvm.so::G1RemSet::print_summary_info()+0x78 (C++ uses_alloca saves_lr stores_bc gpr_saved:6 fixedparms:1 parmsonstk:1) 0x000000011023d1e0 - 0x0900000006646e44 libjvm.so::G1CollectedHeap::print_tracing_info() const+0x24 (C++ uses_alloca saves_lr stores_bc gpr_saved:2 fixedparms:1 parmsonstk:1) 0x000000011023d260 - 0x0900000006094510 libjvm.so::before_exit(JavaThread*, bool)+0x450 (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:11 fixedparms:2 parmsonstk:1) 0x000000011023d4b0 - 0x09000000060f7734 libjvm.so::Threads::destroy_vm()+0x254 (C++ fp_present uses_alloca saves_cr saves_lr stores_bc gpr_saved:6 parmsonstk:1) 0x000000011023d590 - 0x09000000060f7434 libjvm.so::jni_DestroyJavaVM+0x114 (C++ uses_alloca saves_lr stores_bc gpr_saved:4 fixedparms:1 parmsonstk:1) 0x000000011023d640 - 0x000000010001114c java::JavaMain+0x68c (C++ saves_lr stores_bc gpr_saved:11 fixedparms:1 parmsonstk:1) 0x000000011023d730 - 0x0000000100010a70 java::ThreadJavaMain+0x10 (C++ saves_lr stores_bc fixedparms:1 parmsonstk:1) 0x000000011023d7a0 - 0x090000000056204c libpthreads.a::_pthread_body+0xec (C saves_lr stores_bc gpr_saved:1 fixedparms:1 ) 0x000000011023d820 - 0x0000000000000000 *** end of backchain *** -----------------------
01-07-2025

Changeset: 00adbbe5 Branch: master Author: Thomas Schatzl <tschatzl@openjdk.org> Date: 2025-06-30 11:22:46 +0000 URL: https://git.openjdk.org/jdk/commit/00adbbe5538ec5c26dc5bd17ca94cc29db9bc478
30-06-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/26001 Date: 2025-06-26 12:53:37 +0000
26-06-2025

[~mbaesken] based on previous comments I suspect the effort involved in figuring out exactly what to do with this renders it a somewhat low priority task.
07-05-2025

So should we remove it or keep it for some reason?
23-04-2025

I've reassigned it to gc component and reset things for triage by gc folks. gc team needs to decide whether to keep this functionality, and if so, should be responsible for cleaning up the usage (that is all in gc-code), either by deleting usage or switching to current_thread_cpu_time (with appropriate conditionalization).
09-09-2024

[~kbarrett] yes G1 uses this for logging the amount of time its threads spend working on things. If this is not actually important then GC folk need to make that decision. Should I re-assign this to GC component?
09-09-2024

All of the "properly" implemented versions of elapsedVTime (e.g. all but BSD, which uses elapsedTime) return user+sys, so I suggest we believe that's the intent. I think elapsedVTime is only used to get timing information for logging. I think we ought to consider whether we even need this before making the effort to clean up the implementation and usage.
05-09-2024

Unfortunately things are even more complicated than first thought. The Posix CPU time functions return user+sys, but the JMM API's also need a means to return user-time only, which requires continued use of the platform specific mechanisms. If elapsedVTime is supposed to be user+sys then we can just refactor to use the shared Posix implementation, but if it were just user time then we would need the platform specific logic, which again leaves us with some unimplemented platforms (i.e. BSD).
04-09-2024

If Open/FreeBSD have the needed clock_gettime support, then I really like that approach and getting rid of the (not properly used) conditional support, whichever API(s) we end up using. Given how it's used by G1, a fallback that just always returns 0 if we detect lack of support would also be fine I think. The current reporting plausible looking but incorrect values is nearly the worst option (error with no way to control would be worse).
26-08-2024

I started switching the G1 code to use os::current_thread_cpu_time but we still need to check os::thread_cpu_time_supported, which is true everywhere except non-macOS BSD, so all the missing guards need to be added to G1 anyway, unless we implement a fallback that provides thread_cpu_time on BSD. (Or we kill off non-macOS BSD support once-and-for-all given there is no supported port effort.) FTR the implementations of current_thread_cpu_time are as follows: - AIX: getthrds64 - Linux: fast-path: clock_gettime using clock of CLOCK_THREAD_CPUTIME_ID (for each thread) - Linux: slow-path: /proc/self/task/<thread>/stat - macOS: thread_info - BSD: NOT IMPLEMENTED - Windows: GetThreadTimes But I note that FreeBSD and OpenBSD both claim to support the same code as the Linux fastpath using clock_gettime - so we could make that the Posix-based implementation (possibly getting rid of the slowpath complexity. ?? It seems all quite a mess no matter which way we go. Also we could keep the elapsedVTime API to provide the cpu-time-as-double-in-seconds abstraction to mirror the os::elapsedTime API - that isolates most of the changes to the OS code.
26-08-2024

I did some digging into this and I think the reason vtime was introduced for G1 was that to get good values for the CPU time you had turn on micro-state accounting on Solaris versions 8 and 9 (in 10 it was enabled by default). So we originally had the enable_vtime function to turn on MSA. I suspect gethrvtime was not as good on Solaris no matter which version so the two sets of API remained (there is a comment that it only returns user time not sys time). I would think that now we only need the one API for thread CPU time and so G1 should be switched to it, and then all the vtime code removed.
18-07-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/17125 Date: 2023-12-15 15:34:50 +0000
15-12-2023

> Unless we really think this functionality can be provided on all platforms, which seems unlikely since there isn't a reliably available portable API. Currently it is missing in os_bsd . Looking at https://www.freebsd.org/cgi/man.cgi?query=getrusage&sektion=2&n=1 getrusage + RUSAGE_THREAD would be available on FreeBSD. On macOS we have thread_info .
24-09-2021

Given how vtime is being used, I'm not sure that "better than nothing" comment is correct; it might be better to really admit vtime isn't supported. I think that there being buggy usage that doesn't properly handle os::supports_vtime() returning false or doesn't even check it doesn't mean we should remove the function. We should instead fix the uses. Unless we really think this functionality can be provided on all platforms, which seems unlikely since there isn't a reliably available portable API.
23-09-2021

I had a look at JDK-8160887; yes it is true, most elapsedVTime calls (they are in G1 coding) are not guarded anyway by os::supports_vtime(). But currently os::supports_vtime() returns true on all platforms so it makes no difference in the current coding. On macOS/BSD we currently just return elapsedTime in elapsedVTime (the comment says "better than nothing, but not much"). I think on macOS we could use the thread_info function (unfortunately it is not well documented) instead of getrusage + RUSAGE_THREAD .
22-09-2021

vtime stuff has some problems - see JDK-8160887.
22-09-2021