Skip to content

Commit 56b69c7

Browse files
committed
minor touchups
1 parent b0264b9 commit 56b69c7

File tree

4 files changed

+101
-45
lines changed

4 files changed

+101
-45
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ jobs:
317317
id: test-results
318318
with:
319319
json_thousands_separator: ','
320-
junit_files: '**/TEST-*.xml'
320+
files: '**/TEST-*.xml'
321321
comment_mode: off
322322
ignore_runs: true
323323
job_summary: true

caffeine/src/jcstress/java/com/github/benmanes/caffeine/cache/IntermittentNull.java

Lines changed: 75 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.openjdk.jcstress.annotations.JCStressTest;
2525
import org.openjdk.jcstress.annotations.Outcome;
2626
import org.openjdk.jcstress.annotations.State;
27+
import org.openjdk.jcstress.infra.results.II_Result;
2728
import org.openjdk.jcstress.infra.results.L_Result;
2829

2930
import com.google.errorprone.annotations.Var;
@@ -39,62 +40,93 @@
3940
* the correct visibility ordering.
4041
* <p>
4142
* {@snippet lang="shell" :
42-
* // JAVA_VERSION=?? for an alternative jdk
43-
* ./gradlew caffeine:jcstress --rerun
43+
* # use JAVA_VERSION for an alternative jdk
44+
* JAVA_VERSION=11 ./gradlew caffeine:jcstress --tests IntermittentNull --rerun
4445
* }
4546
*
4647
* @author [email protected] (Ben Manes)
4748
*/
48-
@State
49-
@JCStressTest
50-
@Outcome(id = "ok", expect = Expect.ACCEPTABLE, desc = "Reference seen and valid")
51-
@Outcome(id = "null", expect = Expect.FORBIDDEN, desc = "Reference seen but field not visible")
52-
public class IntermittentNull {
53-
private static final VarHandle VALUE;
54-
55-
volatile Value value = new Value("ok");
56-
57-
@Actor
58-
public void writer() {
59-
var oldValue = (Value) VALUE.getAcquire(this);
60-
var newValue = new Value("ok");
61-
VALUE.setRelease(this, newValue);
62-
VarHandle.storeStoreFence();
63-
oldValue.data = null;
64-
}
49+
@SuppressWarnings("PMD.MissingStaticMethodInNonInstantiatableClass")
50+
public final class IntermittentNull {
51+
52+
private IntermittentNull() {}
53+
54+
@State
55+
@JCStressTest
56+
@Outcome(id = "ok", expect = Expect.ACCEPTABLE, desc = "Reference seen and valid")
57+
@Outcome(id = "null", expect = Expect.FORBIDDEN, desc = "Reference seen but field not visible")
58+
public static class Simple {
59+
private static final VarHandle VALUE;
60+
61+
volatile Value value = new Value("ok");
62+
63+
@Actor
64+
public void writer() {
65+
var oldValue = (Value) VALUE.getAcquire(this);
66+
var newValue = new Value("ok");
67+
VALUE.setRelease(this, newValue);
68+
VarHandle.storeStoreFence();
69+
oldValue.data = null;
70+
}
71+
72+
@Actor
73+
public void reader(L_Result r) {
74+
@Var var value = (Value) VALUE.getAcquire(this);
75+
for (;;) {
76+
var data = value.data;
77+
if (data != null) {
78+
r.r1 = data;
79+
return;
80+
}
81+
VarHandle.loadLoadFence();
82+
var current = (Value) VALUE.getAcquire(this);
83+
if (value == current) {
84+
r.r1 = null;
85+
return;
86+
}
87+
value = current;
88+
}
89+
}
6590

66-
@Actor
67-
public void reader(L_Result r) {
68-
@Var var value = (Value) VALUE.getAcquire(this);
69-
for (;;) {
70-
var data = value.data;
71-
if (data != null) {
72-
r.r1 = data;
73-
return;
91+
static {
92+
try {
93+
VALUE = MethodHandles.lookup().findVarHandle(Simple.class, "value", Value.class);
94+
} catch (ReflectiveOperationException e) {
95+
throw new ExceptionInInitializerError(e);
7496
}
75-
VarHandle.loadLoadFence();
76-
var current = (Value) VALUE.getAcquire(this);
77-
if (value == current) {
78-
r.r1 = null;
79-
return;
97+
}
98+
99+
static final class Value {
100+
@Nullable String data;
101+
102+
Value(String data) {
103+
this.data = data;
80104
}
81-
value = current;
82105
}
83106
}
84107

85-
static {
86-
try {
87-
VALUE = MethodHandles.lookup().findVarHandle(IntermittentNull.class, "value", Value.class);
88-
} catch (ReflectiveOperationException e) {
89-
throw new ExceptionInInitializerError(e);
108+
@State
109+
@JCStressTest
110+
@Outcome(id = "1, 1", expect = Expect.ACCEPTABLE, desc = "Reference seen and valid")
111+
@Outcome(expect = Expect.FORBIDDEN, desc = "Reference seen but field not visible")
112+
public static class Actual {
113+
private static final String OK = "ok";
114+
115+
final Cache<String, String> cache;
116+
117+
public Actual() {
118+
cache = Caffeine.newBuilder().weakValues().build();
119+
cache.put(OK, OK);
90120
}
91-
}
92121

93-
static final class Value {
94-
@Nullable String data;
122+
@Actor
123+
public void writer(II_Result r) {
124+
r.r1 = (cache.asMap().put(OK, OK) == null) ? 0 : 1;
125+
}
95126

96-
Value(String data) {
97-
this.data = data;
127+
@Actor
128+
public void reader(II_Result r) {
129+
r.r2 = (cache.getIfPresent(OK) == null) ? 0 : 1;
98130
}
99131
}
100132
}

gradle/config/spotbugs/exclude.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@
763763
<Match>
764764
<Or>
765765
<Class name="~com\.github\.benmanes\.caffeine\.cache.*_jcstress.*"/>
766-
<Class name="com.github.benmanes.caffeine.cache.IntermittentNull"/>
766+
<Class name="~com\.github\.benmanes\.caffeine\.cache\.IntermittentNull.*"/>
767767
</Or>
768768
<Bug pattern="
769769
URF_UNREAD_FIELD,

gradle/plugins/src/main/kotlin/analyze/jcstress.caffeine.gradle.kts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ eclipse.classpath {
5454

5555
@CacheableTask
5656
abstract class JCStress : JavaExec() {
57+
@get:Input @get:Optional
58+
@get:Option(option = "mode", description = "[sanity, quick, default, tough, stress]")
59+
abstract val mode: Property<String>
60+
@get:Input @get:Optional
61+
@get:Option(option = "time", description = "Time per test iteration (milliseconds)")
62+
abstract val time: Property<String>
63+
@get:Input @get:Optional
64+
@get:Option(option = "iterations", description = "Iterations per test")
65+
abstract val iterations: Property<String>
66+
@get:Input @get:Optional
67+
@get:Option(option = "tests", description = "The tests to execute")
68+
abstract val testNames: Property<String>
5769
@get:OutputDirectory
5870
val outputDir: Provider<Directory> = project.layout.buildDirectory.dir("jcstress")
5971

@@ -65,6 +77,18 @@ abstract class JCStress : JavaExec() {
6577

6678
@TaskAction
6779
override fun exec() {
80+
if (iterations.isPresent) {
81+
args("-iters", iterations.get().replace("[_,]".toRegex(), ""))
82+
}
83+
if (time.isPresent) {
84+
args("-time", time.get().replace("[_,]".toRegex(), ""))
85+
}
86+
if (testNames.isPresent) {
87+
args("-t", testNames.get())
88+
}
89+
if (mode.isPresent) {
90+
args("-m", mode.get())
91+
}
6892
args("-r", outputDir.get().asFile.resolve("results"))
6993
outputDir.get().asFile.mkdirs()
7094
super.exec()

0 commit comments

Comments
 (0)