8158039: VarHandle float/double field/array access should support CAS/set/add atomics

Reviewed-by: shade, vlivanov, darcy
This commit is contained in:
Paul Sandoz 2016-06-20 13:06:33 +02:00
parent cc10eca0b0
commit 152f87ef6c
3 changed files with 238 additions and 2 deletions

View File

@ -173,7 +173,125 @@ public class JdkInternalMiscUnsafeAccessTestDouble {
}
UNSAFE.putDouble(base, offset, 1.0d);
// Compare
{
boolean r = UNSAFE.compareAndSwapDouble(base, offset, 1.0d, 2.0d);
assertEquals(r, true, "success compareAndSwap double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 2.0d, "success compareAndSwap double value");
}
{
boolean r = UNSAFE.compareAndSwapDouble(base, offset, 1.0d, 3.0d);
assertEquals(r, false, "failing compareAndSwap double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 2.0d, "failing compareAndSwap double value");
}
// Advanced compare
{
double r = UNSAFE.compareAndExchangeDoubleVolatile(base, offset, 2.0d, 1.0d);
assertEquals(r, 2.0d, "success compareAndExchangeVolatile double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 1.0d, "success compareAndExchangeVolatile double value");
}
{
double r = UNSAFE.compareAndExchangeDoubleVolatile(base, offset, 2.0d, 3.0d);
assertEquals(r, 1.0d, "failing compareAndExchangeVolatile double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 1.0d, "failing compareAndExchangeVolatile double value");
}
{
double r = UNSAFE.compareAndExchangeDoubleAcquire(base, offset, 1.0d, 2.0d);
assertEquals(r, 1.0d, "success compareAndExchangeAcquire double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 2.0d, "success compareAndExchangeAcquire double value");
}
{
double r = UNSAFE.compareAndExchangeDoubleAcquire(base, offset, 1.0d, 3.0d);
assertEquals(r, 2.0d, "failing compareAndExchangeAcquire double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 2.0d, "failing compareAndExchangeAcquire double value");
}
{
double r = UNSAFE.compareAndExchangeDoubleRelease(base, offset, 2.0d, 1.0d);
assertEquals(r, 2.0d, "success compareAndExchangeRelease double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 1.0d, "success compareAndExchangeRelease double value");
}
{
double r = UNSAFE.compareAndExchangeDoubleRelease(base, offset, 2.0d, 3.0d);
assertEquals(r, 1.0d, "failing compareAndExchangeRelease double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 1.0d, "failing compareAndExchangeRelease double value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = UNSAFE.weakCompareAndSwapDouble(base, offset, 1.0d, 2.0d);
}
assertEquals(success, true, "weakCompareAndSwap double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 2.0d, "weakCompareAndSwap double value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = UNSAFE.weakCompareAndSwapDoubleAcquire(base, offset, 2.0d, 1.0d);
}
assertEquals(success, true, "weakCompareAndSwapAcquire double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 1.0d, "weakCompareAndSwapAcquire double");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = UNSAFE.weakCompareAndSwapDoubleRelease(base, offset, 1.0d, 2.0d);
}
assertEquals(success, true, "weakCompareAndSwapRelease double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 2.0d, "weakCompareAndSwapRelease double");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = UNSAFE.weakCompareAndSwapDoubleVolatile(base, offset, 2.0d, 1.0d);
}
assertEquals(success, true, "weakCompareAndSwapVolatile double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 1.0d, "weakCompareAndSwapVolatile double");
}
UNSAFE.putDouble(base, offset, 2.0d);
// Compare set and get
{
double o = UNSAFE.getAndSetDouble(base, offset, 1.0d);
assertEquals(o, 2.0d, "getAndSet double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, 1.0d, "getAndSet double value");
}
UNSAFE.putDouble(base, offset, 1.0d);
// get and add, add and get
{
double o = UNSAFE.getAndAddDouble(base, offset, 2.0d);
assertEquals(o, 1.0d, "getAndAdd double");
double x = UNSAFE.getDouble(base, offset);
assertEquals(x, (double)(1.0d + 2.0d), "getAndAdd double");
}
}
static void testAccess(long address) {

View File

@ -173,7 +173,125 @@ public class JdkInternalMiscUnsafeAccessTestFloat {
}
UNSAFE.putFloat(base, offset, 1.0f);
// Compare
{
boolean r = UNSAFE.compareAndSwapFloat(base, offset, 1.0f, 2.0f);
assertEquals(r, true, "success compareAndSwap float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 2.0f, "success compareAndSwap float value");
}
{
boolean r = UNSAFE.compareAndSwapFloat(base, offset, 1.0f, 3.0f);
assertEquals(r, false, "failing compareAndSwap float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 2.0f, "failing compareAndSwap float value");
}
// Advanced compare
{
float r = UNSAFE.compareAndExchangeFloatVolatile(base, offset, 2.0f, 1.0f);
assertEquals(r, 2.0f, "success compareAndExchangeVolatile float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 1.0f, "success compareAndExchangeVolatile float value");
}
{
float r = UNSAFE.compareAndExchangeFloatVolatile(base, offset, 2.0f, 3.0f);
assertEquals(r, 1.0f, "failing compareAndExchangeVolatile float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 1.0f, "failing compareAndExchangeVolatile float value");
}
{
float r = UNSAFE.compareAndExchangeFloatAcquire(base, offset, 1.0f, 2.0f);
assertEquals(r, 1.0f, "success compareAndExchangeAcquire float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 2.0f, "success compareAndExchangeAcquire float value");
}
{
float r = UNSAFE.compareAndExchangeFloatAcquire(base, offset, 1.0f, 3.0f);
assertEquals(r, 2.0f, "failing compareAndExchangeAcquire float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 2.0f, "failing compareAndExchangeAcquire float value");
}
{
float r = UNSAFE.compareAndExchangeFloatRelease(base, offset, 2.0f, 1.0f);
assertEquals(r, 2.0f, "success compareAndExchangeRelease float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 1.0f, "success compareAndExchangeRelease float value");
}
{
float r = UNSAFE.compareAndExchangeFloatRelease(base, offset, 2.0f, 3.0f);
assertEquals(r, 1.0f, "failing compareAndExchangeRelease float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 1.0f, "failing compareAndExchangeRelease float value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = UNSAFE.weakCompareAndSwapFloat(base, offset, 1.0f, 2.0f);
}
assertEquals(success, true, "weakCompareAndSwap float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 2.0f, "weakCompareAndSwap float value");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = UNSAFE.weakCompareAndSwapFloatAcquire(base, offset, 2.0f, 1.0f);
}
assertEquals(success, true, "weakCompareAndSwapAcquire float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 1.0f, "weakCompareAndSwapAcquire float");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = UNSAFE.weakCompareAndSwapFloatRelease(base, offset, 1.0f, 2.0f);
}
assertEquals(success, true, "weakCompareAndSwapRelease float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 2.0f, "weakCompareAndSwapRelease float");
}
{
boolean success = false;
for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
success = UNSAFE.weakCompareAndSwapFloatVolatile(base, offset, 2.0f, 1.0f);
}
assertEquals(success, true, "weakCompareAndSwapVolatile float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 1.0f, "weakCompareAndSwapVolatile float");
}
UNSAFE.putFloat(base, offset, 2.0f);
// Compare set and get
{
float o = UNSAFE.getAndSetFloat(base, offset, 1.0f);
assertEquals(o, 2.0f, "getAndSet float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, 1.0f, "getAndSet float value");
}
UNSAFE.putFloat(base, offset, 1.0f);
// get and add, add and get
{
float o = UNSAFE.getAndAddFloat(base, offset, 2.0f);
assertEquals(o, 1.0f, "getAndAdd float");
float x = UNSAFE.getFloat(base, offset);
assertEquals(x, (float)(1.0f + 2.0f), "getAndAdd float");
}
}
static void testAccess(long address) {

View File

@ -55,12 +55,12 @@ function generate {
if [ "$package" == "jdk.internal.misc" ]; then
case $type in
boolean|byte|char|short)
boolean|byte|char|short|float|double)
args="$args -KCAS"
;;
esac
case $type in
byte|char|short)
byte|char|short|float|double)
args="$args -KAtomicAdd"
;;
esac