RFR: 8373118: Test java/lang/Thread/virtual/Starvation.java timed out [v32]

Doug Lea dl at openjdk.org
Mon Feb 9 21:31:41 UTC 2026


On Thu, 5 Feb 2026 12:17:20 GMT, Viktor Klang <vklang at openjdk.org> wrote:

>> Doug Lea has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains 45 additional commits since the last revision:
>> 
>>  - Merge branch 'openjdk:master' into JDK-8373118
>>  - setup for helpJoin
>>  - Merge branch 'openjdk:master' into JDK-8373118
>>  - reduce interference after stalls
>>  - Avoid yield, for performance test
>>  - Don't oversignal LIFO
>>  - Try out different approach
>>  - Simplify scan mode control by moving and reworking topLevelExec and throwing on trim
>>  - Another set of contend vs deactivate vs park tradeoffs
>>  - Fix missing undo
>>  - ... and 35 more: https://git.openjdk.org/jdk/compare/ce27d5c9...1b9272b3
>
> src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java line 1988:
> 
>> 1986:                                 ran = 1;
>> 1987:                                 ++taken;
>> 1988:                                 if (propagate && U.getReferenceAcquire(a, np) != null)
> 
> At this point, it might even make sense to fold the propagate logic into the if-clause itself. Something like:
> 
> 
>                                 ran = 1;
>                                 ++taken;
>                                 if ((rnt != null) &&
>                                     (ps < 0 ||
>                                      ((qid & 1) == 0 &&
>                                       (fifo != 0 || taken == 1))) && U.getReferenceAcquire(a, np) != null)

Thanks. I changed to something similar.

> src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java line 2030:
> 
>> 2028:                 int phase = U.getInt(w, WorkQueue.PHASE);
>> 2029:                 long sp = (phase + NEXTIDLE) & LMASK, pc = ctl;
>> 2030:                 U.putInt(w, WorkQueue.PHASE, phase | IDLE);
> 
> So the idea here is to potentially delay the store?

main idea is that if shadowed "idle" is 0, it can't be wrong, so just plain-read to get full value

> src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java line 2811:
> 
>> 2809:                     if (q.base == b && t != null &&
>> 2810:                         U.compareAndSetReference(a, k, t, null)) {
>> 2811:                         q.base = b + 1;
> 
> Doesn't this mean that this write might end up not safely published? 🤔

That one can't matter, but for consistency I added storeFence

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/28797#discussion_r2779732120
PR Review Comment: https://git.openjdk.org/jdk/pull/28797#discussion_r2779742532
PR Review Comment: https://git.openjdk.org/jdk/pull/28797#discussion_r2779732881


More information about the core-libs-dev mailing list