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