Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8334774

~ThreadBlockInVMPreprocess should not set thread state to _thread_in_vm before process

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Won't Fix
    • Icon: P4 P4
    • tbd
    • None
    • hotspot
    • generic
    • generic

      The construct ThreadBlockInVMPreprocess set thread to _thread_blocked and frame to be walkable, this make the thread safepoint safe.

      The code in ~ThreadBlockInVMPreprocess will eventually block the thread at barrier by calling SafepointMechanism::process_if_requested, SafepointMechanism::process_if_requested requires the thread sate to be _thread_in_vm, therefore ~ThreadBlockInVMPreprocess set the sate to _thread_in_vm before calling SafepointMechanism::process_if_requested.

      It results in less efficiency in safepoint when SafepointSynchronize::synchronize_threads to synchronize all threads to safepoint (https://github.com/openjdk/jdk/blob/master/src/hotspot/share/runtime/safepoint.cpp#L198)
      SafepointSynchronize::synchronize_threads may see a thread at sate _thread_in_vm after ~ThreadBlockInVMPreprocess set it, it will need to do another interaction to the check the thread state in such case.

      The issue won't have critical impact but slow down VM to reach safepoint, we could observe TTSP in safepoint logs, also by adding one line log like this https://github.com/openjdk/jdk/compare/master...pengxiaolong:jdk:log-sp-synchronize-iterations?expand=1, we could observe the impact on iterations in SafepointMechanism::synchronize_threads

      Sample code I used in my test:
      ```
      public class Alloc {
              static final int THREADS = 384;
              static final Object[] sinks = new Object[64*THREADS];
              static volatile boolean start;
              static volatile boolean stop;

              public static void main(String... args) throws Throwable {
                      for (int t = 0; t < THREADS; t++) {
                              int ft = t;
                              new Thread(() -> work(ft * 64)).start();
                      }

                      start = true;
                      Thread.sleep(10_000);
                      stop = true;
              }

              public static void work(int idx) {
                      while (!start) { Thread.onSpinWait(); }
                      while (!stop) {
                              sinks[idx] = new byte[128];
                      }
              }
      }

      ```

      Run it with command:
      ```
      java -Xms256m -Xmx256m -XX:+UseShenandoahGC -XX:-UseTLAB -Xlog:safepoint Alloc.java
      ```

      Simple fix I have tested: https://github.com/openjdk/jdk/compare/master...pengxiaolong:tbivm-fix

      On a MacBook Pro with 12 CPU cores, avg TTSP is 66153ns, with a fix avg TTSP is 56027ns

            xpeng Xiaolong Peng
            xpeng Xiaolong Peng
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: