Skip to content

Commit fe0eec0

Browse files
committed
Support generation of VarHandle variant
1 parent cc36d74 commit fe0eec0

File tree

7 files changed

+322
-38
lines changed

7 files changed

+322
-38
lines changed

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ which is then transformed to a regular `classes` directory to be used later by t
124124
</goals>
125125
<configuration>
126126
<output>${project.build.directory}/classes-pre-atomicfu</output>
127+
<!-- "VH" to use Java 9 VarHandle, "BOTH" to produce multi-version code -->
128+
<variant>FU</variant>
127129
</configuration>
128130
</execution>
129131
</executions>
@@ -150,7 +152,8 @@ which is then transformed to a regular `classes` directory to be used later by t
150152

151153
## Gradle build setup
152154

153-
Add and apply AtmoicFU plugin:
155+
You will need Gradle 4.0 or later for the following snippets to work.
156+
Add and apply AtomicFU plugin:
154157

155158
```groovy
156159
buildscript {
@@ -182,6 +185,7 @@ atomicFU {
182185
inputFiles = sourceSets.main.output.classesDirs
183186
outputDir = CLASSES_POST_ATOMICFU
184187
classPath = sourceSets.main.runtimeClasspath
188+
variant = "FU" // "VH" to use Java 9 VarHandle, "BOTH" to produce multi-version code
185189
}
186190
187191
atomicFU.dependsOn compileKotlin
@@ -193,6 +197,17 @@ jar {
193197
}
194198
```
195199

200+
## VarHandles with Java 9 (optional)
201+
202+
AtomicFU can produce code that is using Java 9
203+
[VarHandle](http://download.java.net/java/jdk9/docs/api/java/lang/invoke/VarHandle.html)
204+
instead of `AtomicXXXFieldUpdater`. Set `variant` configuration option to `VH`.
205+
206+
You can also create [JEP 238](http://openjdk.java.net/jeps/238) multi-release jar with both
207+
`AtomicXXXFieldUpdater` baseline and `VarHandle` version for Java 9+.
208+
Set `variant` configuration option to `BOTH` and configure `Multi-Release: true` attribute
209+
in the resulting jar manifest.
210+
196211
## Testing lock-free data structures (optional)
197212

198213
You can optionally test lock-freedomness of lock-free data structures using `LockFreedomTestEnvironment` class.

atomicfu-gradle-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/gradle/AtomicFUGradlePlugin.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package kotlinx.atomicfu.plugin.gradle
22

33
import kotlinx.atomicfu.transformer.AtomicFUTransformer
4+
import kotlinx.atomicfu.transformer.Variant
45
import org.gradle.api.DefaultTask
56
import org.gradle.api.Plugin
67
import org.gradle.api.Project
@@ -27,12 +28,15 @@ open class AtomicFUTransformTask : DefaultTask() {
2728
@InputFiles
2829
var classPath: FileCollection = project.files()
2930
@Input
30-
var verbose: Boolean = false
31+
var verbose = false
32+
@Input
33+
var variant= Variant.FU
3134

3235
@TaskAction
3336
fun transform() {
3437
inputFiles.files.forEach {
35-
val t = AtomicFUTransformer(classPath.files.map { it.absolutePath }, it, outputDir)
38+
val t = AtomicFUTransformer(
39+
classPath.files.map { it.absolutePath }, it, outputDir, variant)
3640
t.verbose = verbose
3741
t.transform()
3842
}

atomicfu-maven-plugin/src/main/kotlin/kotlinx/atomicfu/plugin/TransformMojo.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package kotlinx.atomicfu.plugin
1818

1919
import kotlinx.atomicfu.transformer.AtomicFUTransformer
20+
import kotlinx.atomicfu.transformer.Variant
2021
import org.apache.maven.plugin.AbstractMojo
2122
import org.apache.maven.plugins.annotations.LifecyclePhase
2223
import org.apache.maven.plugins.annotations.Mojo
@@ -46,14 +47,20 @@ class TransformMojo : AbstractMojo() {
4647
@Parameter(defaultValue = "\${project.build.outputDirectory}", property = "output", required = true)
4748
lateinit var output: File
4849

50+
/**
51+
* Transformation variant: "FU", "VH", or "BOTH".
52+
*/
53+
@Parameter(defaultValue = "FU", property = "variant", required = true)
54+
lateinit var variant: Variant
55+
4956
/**
5057
* Verbose debug info.
5158
*/
5259
@Parameter(defaultValue = "false", property = "verbose", required = false)
5360
var verbose: Boolean = false
5461

5562
override fun execute() {
56-
val t = AtomicFUTransformer(classpath, input, output)
63+
val t = AtomicFUTransformer(classpath, input, output, variant)
5764
t.verbose = verbose
5865
t.transform()
5966
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package kotlinx.atomicfu.test
18+
19+
import kotlinx.atomicfu.atomic
20+
21+
class IntArithmetic {
22+
private val _x = atomic(0)
23+
val x get() = _x.value
24+
25+
fun lazySet(v: Int) = _x.lazySet(v)
26+
fun getAndSet(v: Int) = _x.getAndSet(v)
27+
fun getAndIncrement() = _x.getAndIncrement()
28+
fun getAndDecrement() = _x.getAndDecrement()
29+
fun getAndAdd(v: Int) = _x.getAndAdd(v)
30+
fun addAndGet(v: Int) = _x.addAndGet(v)
31+
fun incrementAndGet() = _x.incrementAndGet()
32+
fun decrementAndGet() = _x.decrementAndGet()
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package kotlinx.atomicfu.test
18+
19+
import kotlinx.atomicfu.atomic
20+
21+
class LongArithmetic {
22+
private val _x = atomic(0L)
23+
val x get() = _x.value
24+
25+
fun lazySet(v: Long) = _x.lazySet(v)
26+
fun getAndSet(v: Long) = _x.getAndSet(v)
27+
fun getAndIncrement() = _x.getAndIncrement()
28+
fun getAndDecrement() = _x.getAndDecrement()
29+
fun getAndAdd(v: Long) = _x.getAndAdd(v)
30+
fun addAndGet(v: Long) = _x.addAndGet(v)
31+
fun incrementAndGet() = _x.incrementAndGet()
32+
fun decrementAndGet() = _x.decrementAndGet()
33+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package kotlinx.atomicfu.test
18+
19+
import org.junit.Test
20+
21+
class ArithmeticTest {
22+
@Test
23+
fun testInt() {
24+
val a = IntArithmetic()
25+
check(a.x == 0)
26+
a.lazySet(1)
27+
check(a.x == 1)
28+
check(a.getAndSet(2) == 1)
29+
check(a.x == 2)
30+
check(a.getAndIncrement() == 2)
31+
check(a.x == 3)
32+
check(a.getAndDecrement() == 3)
33+
check(a.x == 2)
34+
check(a.getAndAdd(2) == 2)
35+
check(a.x == 4)
36+
check(a.addAndGet(3) == 7)
37+
check(a.x == 7)
38+
check(a.incrementAndGet() == 8)
39+
check(a.x == 8)
40+
check(a.decrementAndGet() == 7)
41+
check(a.x == 7)
42+
}
43+
44+
@Test
45+
fun testLong() {
46+
val a = LongArithmetic()
47+
check(a.x == 0L)
48+
a.lazySet(1)
49+
check(a.x == 1L)
50+
check(a.getAndSet(2) == 1L)
51+
check(a.x == 2L)
52+
check(a.getAndIncrement() == 2L)
53+
check(a.x == 3L)
54+
check(a.getAndDecrement() == 3L)
55+
check(a.x == 2L)
56+
check(a.getAndAdd(2) == 2L)
57+
check(a.x == 4L)
58+
check(a.addAndGet(3) == 7L)
59+
check(a.x == 7L)
60+
check(a.incrementAndGet() == 8L)
61+
check(a.x == 8L)
62+
check(a.decrementAndGet() == 7L)
63+
check(a.x == 7L)
64+
}
65+
}

0 commit comments

Comments
 (0)