#!/usr/bin/env bash # Regenerates every file in output/. Requires: # - JDK25_HOME pointing at a JDK 24+ install (this repo used Temurin 25.0.4.1+1) # - JDK21_HOME pointing at a pre-JDK-24 install (this repo used OpenJDK 21.0.10), for the # before/after comparisons against JEP 491 # - gcc on PATH (builds the JNI native library) set -euo pipefail cd "$(dirname "$0")/.." : "${JDK25_HOME:?Set JDK25_HOME to a JDK 24+ install}" : "${JDK21_HOME:?Set JDK21_HOME to a pre-JDK-24 install}" JAVA_HOME="$JDK21_HOME" ./scripts/build-native.sh mkdir -p target/classes target/classes-21 "$JDK25_HOME/bin/javac" --release 25 -d target/classes $(find src/main/java -name "*.java") "$JDK21_HOME/bin/javac" --release 21 -d target/classes-21 $(find src/main/java -name "*.java") NATLIB=target/native echo "--- 01: monitor pinning, JDK21 vs JDK25 (JEP 491) ---" { echo '$ java -Djdk.tracePinnedThreads=full MonitorPinningDemo (pre-JDK-24 runtime)' echo "" "$JDK21_HOME/bin/java" -Djdk.tracePinnedThreads=full -cp target/classes-21 \ com.ankurm.vtpinning.MonitorPinningDemo 2>&1 | grep -v "Picked up" echo "" echo '$ java -Djdk.tracePinnedThreads=full MonitorPinningDemo (JDK 24+ runtime)' echo "" "$JDK25_HOME/bin/java" -Djdk.tracePinnedThreads=full -cp target/classes \ com.ankurm.vtpinning.MonitorPinningDemo 2>&1 | grep -v "Picked up" } > output/01-monitor-pinning-jdk21-vs-jdk25.txt echo "--- 02: native pinning, JDK21 vs JDK25 (still real on both) ---" { echo '$ java -Djdk.tracePinnedThreads=full NativePinningDemo (pre-JDK-24 runtime)' echo "" "$JDK21_HOME/bin/java" -Djdk.tracePinnedThreads=full -Djava.library.path=$NATLIB -cp target/classes-21 \ com.ankurm.vtpinning.NativePinningDemo 2>&1 | grep -v "Picked up" echo "" echo '$ java -Djdk.tracePinnedThreads=full NativePinningDemo (JDK 24+ runtime - flag is inert)' echo "" "$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djdk.tracePinnedThreads=full -Djava.library.path=$NATLIB -cp target/classes \ com.ankurm.vtpinning.NativePinningDemo 2>&1 | grep -v "Picked up\|WARNING" } > output/02-native-pinning-jdk21-vs-jdk25.txt echo "--- 03: jdk.VirtualThreadPinned JFR event on JDK25 ---" rm -f target/native-pin.jfr { echo '$ java -XX:StartFlightRecording=...,jdk.VirtualThreadPinned#enabled=true,threshold=0ms NativePinningDemo' echo "" "$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED \ "-XX:StartFlightRecording=filename=target/native-pin.jfr,settings=profile,jdk.VirtualThreadPinned#enabled=true,jdk.VirtualThreadPinned#threshold=0ms,jdk.VirtualThreadPinned#stackTrace=true" \ -Djava.library.path=$NATLIB -cp target/classes com.ankurm.vtpinning.NativePinningDemo 2>&1 \ | grep -v "Picked up\|WARNING\|jfr,startup\|^\[" echo "" echo '$ jfr print --events jdk.VirtualThreadPinned --stack-depth 10 target/native-pin.jfr' echo "" "$JDK25_HOME/bin/jfr" print --events jdk.VirtualThreadPinned --stack-depth 10 target/native-pin.jfr 2>&1 | grep -v "Picked up" } > output/03-jfr-virtualthreadpinned-event.txt echo "--- 04: jcmd Thread.dump_to_file, pinned vs unpinned virtual thread ---" rm -f target/threaddump.json target/threaddump_out.txt "$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djava.library.path=$NATLIB -cp target/classes \ com.ankurm.vtpinning.ThreadDumpPinnedDemo > target/threaddump_out.txt 2>&1 & PID=$! sleep 1.5 "$JDK25_HOME/bin/jcmd" "$PID" Thread.dump_to_file -format=json target/threaddump.json > target/jcmd_out.txt 2>&1 wait $PID { echo '$ java ThreadDumpPinnedDemo &' grep -v "Picked up" target/threaddump_out.txt echo "" echo '$ jcmd Thread.dump_to_file -format=json threaddump.json (taken mid-flight)' grep -v "Picked up" target/jcmd_out.txt echo "" echo '--- the two virtual thread entries from that dump ---' python3 - <<'PYEOF' import json with open('target/threaddump.json') as f: data = json.load(f) for c in data['threadDump']['threadContainers']: for t in c.get('threads', []): if t.get('virtual'): print(json.dumps(t, indent=2)) print() PYEOF } > output/04-jcmd-thread-dump-pinned-vs-unpinned.txt echo "--- 05: throughput cost of native pinning vs plain blocking (capped carriers) ---" { echo '$ java -Djdk.virtualThreadScheduler.parallelism=2 PinningThroughputDemo native 4 1000' "$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djdk.virtualThreadScheduler.parallelism=2 -Djava.library.path=$NATLIB -cp target/classes \ com.ankurm.vtpinning.PinningThroughputDemo native 4 1000 2>&1 | grep -v "Picked up\|WARNING" echo "" echo '$ java -Djdk.virtualThreadScheduler.parallelism=2 PinningThroughputDemo plain 4 1000' "$JDK25_HOME/bin/java" -Djdk.virtualThreadScheduler.parallelism=2 -Djava.library.path=$NATLIB -cp target/classes \ com.ankurm.vtpinning.PinningThroughputDemo plain 4 1000 2>&1 | grep -v "Picked up\|WARNING" } > output/05-pinning-throughput-cost.txt echo "--- 06: bounding the blast radius with a dedicated executor ---" { echo '$ java -Djdk.virtualThreadScheduler.parallelism=2 BoundedNativeCallDemo direct' "$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djdk.virtualThreadScheduler.parallelism=2 -Djava.library.path=$NATLIB -cp target/classes \ com.ankurm.vtpinning.BoundedNativeCallDemo direct 2>&1 | grep -v "Picked up\|WARNING" echo "" echo '$ java -Djdk.virtualThreadScheduler.parallelism=2 BoundedNativeCallDemo bounded' "$JDK25_HOME/bin/java" --enable-native-access=ALL-UNNAMED -Djdk.virtualThreadScheduler.parallelism=2 -Djava.library.path=$NATLIB -cp target/classes \ com.ankurm.vtpinning.BoundedNativeCallDemo bounded 2>&1 | grep -v "Picked up\|WARNING" } > output/06-bounded-executor-fix.txt echo "Done. See output/."