Scope.Thread and @Setup bug?
Lev Serebryakov
lev at serebryakov.spb.ru
Wed Sep 28 13:44:19 UTC 2016
On 28.09.2016 16:08, Aleksey Shipilev wrote:
> On 09/28/2016 03:02 PM, Lev Serebryakov wrote:
>> I'll try to compile minimal example where I got this.
>
> If that reproduces only with your payload, I would appreciate if you can
> publish that, if MCVE does not reproduce the failure. I'll stare at
> generated code for a while...
Now I have minimal code, which hangs in JMH sometimes (interruption
doesn't work) and throw this exception sometimes! Windows 7, JDK
1.8.0_102/x64. It hangs more often, than throws exception, but I got
exceptions sometimes too, like this:
==============================================================
# Timeout: 1 s per iteration, ***WARNING: The timeout might be too low!***
# Threads: 2 threads (1 group; 1x "reader", 1x "writer" in each group),
will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: benchmarks.PCExample.buf
# Run progress: 0,00% complete, ETA 00:16:45
# Fork: 1 of 1
# Warmup Iteration 1: 433836,108 ops/s
# Warmup Iteration 2: 473749,466 ops/s
# Warmup Iteration 3: <failure>
java.lang.IllegalStateException: Writer thread has been set to
Thread[benchmarks.PCExample.buf-jmh-worker-2,5,main] but
registerWriter() is called again with
Thread[benchmarks.PCExample.buf-jmh-worker-1,5,main]
at benchmarks.PCExample$GroupState.registerWriter(PCExample.java:60)
at benchmarks.PCExample$WriterState.setup(PCExample.java:80)
at
benchmarks.generated.PCExample_buf_jmhTest._jmh_tryInit_f_writerstate3_3(PCExample_buf_jmhTest.java:754)
at
benchmarks.generated.PCExample_buf_jmhTest.buf_Throughput(PCExample_buf_jmhTest.java:136)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:444)
at
org.openjdk.jmh.runner.BenchmarkHandler$BenchmarkTask.call(BenchmarkHandler.java:426)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown
Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
Source)
at java.lang.Thread.run(Unknown Source)
==============================================================
==============================================================
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;
import org.openjdk.jmh.annotations.*;
@Fork(1)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 1000, time = 1)
@Timeout(time = 1)
public class PCExample {
@State(Scope.Group)
public static class GroupState {
AtomicReference<Object> bucket = null;
Object ball = null;
Thread reader = null;
Thread writer = null;
@Setup
public synchronized void setup() {
bucket = new AtomicReference<>();
ball = new Object();
}
synchronized void registerReader(Thread t) {
if (reader != null)
throw new IllegalStateException("Reader thread has been set to " +
reader + " but registerReader() is called again with " + t);
reader = t;
}
synchronized public void registerWriter(Thread t) {
if (writer != null)
throw new IllegalStateException("Writer thread has been set to " +
writer + " but registerWriter() is called again with " + t);
writer = t;
}
}
@State(Scope.Thread)
public static class ReaderState {
GroupState gs = null;
@Setup
public void setup(GroupState gs) {
gs.registerReader(Thread.currentThread());
this.gs = gs;
}
}
@State(Scope.Thread)
public static class WriterState {
GroupState gs = null;
@Setup
public void setup(GroupState gs) {
gs.registerWriter(Thread.currentThread());
this.gs = gs;
}
}
@Benchmark
@Group("buf")
public void writer(WriterState s) throws InterruptedException {
// Wait for empty bucket
while (!s.gs.bucket.compareAndSet(null, s.gs.ball)) {
LockSupport.park();
if (Thread.interrupted())
throw new InterruptedException();
}
// Wake up reader
LockSupport.unpark(s.gs.reader);
}
@Benchmark
@Group("buf")
public void reader(ReaderState s) throws InterruptedException {
Object o;
// Wait for ball
while ((o = s.gs.bucket.get()) == null) {
LockSupport.park();
if (Thread.interrupted())
throw new InterruptedException();
}
if (o != s.gs.ball)
throw new IllegalStateException("Wrong ball!");
// Remove ball from bucket
s.gs.bucket.set(null);
// Wake up writer
LockSupport.unpark(s.gs.writer);
}
}
==============================================================
--
// Black Lion AKA Lev Serebryakov
More information about the jmh-dev
mailing list