Skip to content

Conversation

@jerrinot
Copy link

@jerrinot jerrinot commented Jan 5, 2026

This PR further optimizes os::current_thread_cpu_time (used by ThreadMXBean.getCurrentThreadUserTime()) on Linux by using the kernel's fast-path for the calling thread. I see it as a continuation of #28556.

The current code in master has 2 phases:

  1. Create a timer bound to the current Thread ID (TID) + massage the timer to switch from CPUCLOCK_SCHED timer to CPUCLOCK_VIRT
  2. Use the timer in clock_gettime()

Within the kernel, a routine exists to extract the TID from the timer, followed by a radix lookup to find booking structures for the specified TID.

However, the kernel also has a fast-path: When TID is 0, then the kernel avoids the radix lookup and instead treats the timer as bound to 'the current thread' (or a process, depending on lower bits of the clock). The current thread/task has bookkeeping structures more readily available and the radix lookup is avoided. The result is around 13% faster getCurrentThreadUserTime().

Potential concerns

  1. ABI stability. I believe Linux policy on ABI stability is simple: "WE DO NOT BREAK USERSPACE!" Changing the behaviour when TID is 0 would break user-space.
  2. I am not fluent in C++ and I am not entirely sure if the expression to build the timer is UB-free. Perhaps there is a better way which does not rely on a specific size of clockid_t. Feedback here is very much appreciated.

The benchmark from #28556 (switched to nanos + more iterations + fork count):

before:
Benchmark                                             Mode      Cnt       Score   Error  Units
ThreadMXBeanBench.getCurrentThreadUserTime          sample  4347067      81.746 ± 0.510  ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.00    sample               69.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.50    sample               80.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.90    sample               90.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.95    sample               90.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.99    sample               90.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.999   sample              230.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.9999  sample             1980.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p1.00    sample           653312.000          ns/op

after:
Benchmark                                             Mode      Cnt       Score   Error  Units
ThreadMXBeanBench.getCurrentThreadUserTime          sample  5081223      70.813 ± 0.325  ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.00    sample               59.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.50    sample               70.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.90    sample               70.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.95    sample               70.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.99    sample               80.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.999   sample              170.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.9999  sample             1830.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p1.00    sample           425472.000          ns/op

@JonasNorlinder: this is what I raised on the mailing-list.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Error

 ⚠️ OCA signatory status must be verified

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/29032/head:pull/29032
$ git checkout pull/29032

Update a local copy of the PR:
$ git checkout pull/29032
$ git pull https://git.openjdk.org/jdk.git pull/29032/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 29032

View PR using the GUI difftool:
$ git pr show -t 29032

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/29032.diff

before:
Benchmark                                             Mode      Cnt       Score   Error  Units
ThreadMXBeanBench.getCurrentThreadUserTime          sample  4347067      81.746 ± 0.510  ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.00    sample               69.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.50    sample               80.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.90    sample               90.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.95    sample               90.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.99    sample               90.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.999   sample              230.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.9999  sample             1980.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p1.00    sample           653312.000          ns/op

after:
Benchmark                                             Mode      Cnt       Score   Error  Units
ThreadMXBeanBench.getCurrentThreadUserTime          sample  5081223      70.813 ± 0.325  ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.00    sample               59.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.50    sample               70.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.90    sample               70.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.95    sample               70.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.99    sample               80.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.999   sample              170.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p0.9999  sample             1830.000          ns/op
ThreadMXBeanBench.getCurrentThreadUserTime:p1.00    sample           425472.000          ns/op
@bridgekeeper bridgekeeper bot added the oca Needs verification of OCA signatory status label Jan 5, 2026
@bridgekeeper
Copy link

bridgekeeper bot commented Jan 5, 2026

Hi @jerrinot, welcome to this OpenJDK project and thanks for contributing!

We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing /signed in a comment in this pull request.

If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please use "Add GitHub user jerrinot" as summary for the issue.

If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing /covered in a comment in this pull request.

@openjdk
Copy link

openjdk bot commented Jan 5, 2026

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk bot added the hotspot-runtime hotspot-runtime-dev@openjdk.org label Jan 5, 2026
@openjdk
Copy link

openjdk bot commented Jan 5, 2026

@jerrinot The following label will be automatically applied to this pull request:

  • hotspot-runtime

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@jerrinot
Copy link
Author

jerrinot commented Jan 5, 2026

Hi @jerrinot, thanks for making a comment in an OpenJDK project!

All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user jerrinot" for the summary.

If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.

Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hotspot-runtime hotspot-runtime-dev@openjdk.org oca Needs verification of OCA signatory status

Development

Successfully merging this pull request may close these issues.

1 participant