test: Make 079-phantom less flakey.
Definitely block the main thread until the GC has cleared out the native
data objects.
Introduces new happens-before orderings which weren't there
previously:
* freeNativeStorage(dataA) happens-before printing "nulling 2"
* freeNativeStorage(dataB) happens-before bitmap shutdown
This removes the races that occurred between the printing of
"nulling 2" and "freeNativeStorage".
Bug: b/22287285
Test: art/test/run-test --host --optimizing 079-phantom
Change-Id: I04a4ecc2d3ac68470010b61d3eb1c2fedac55cca
diff --git a/test/079-phantom/src/Bitmap.java b/test/079-phantom/src/Bitmap.java
index ff43749..0d6e2d8 100644
--- a/test/079-phantom/src/Bitmap.java
+++ b/test/079-phantom/src/Bitmap.java
@@ -17,6 +17,7 @@
import java.lang.ref.ReferenceQueue;
import java.lang.ref.PhantomReference;
import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
public class Bitmap {
String mName; /* for debugging */
@@ -76,11 +77,14 @@
PhantomWrapper phan = new PhantomWrapper(wrapper, sPhantomQueue,
nativeData);
sPhantomList.add(phan);
+ wrapper.mPhantomWrapper = phan;
return wrapper;
}
- static void freeNativeStorage(int nativeDataPtr) {
+ static void freeNativeStorage(int nativeDataPtr, CountDownLatch freeSignal) {
System.out.println("freeNativeStorage: " + nativeDataPtr);
+ // Wake up the main thread that is [or will be] blocked until this native data is freed.
+ freeSignal.countDown();
}
/*
@@ -93,6 +97,9 @@
}
public int mNativeData;
+ // The PhantomWrapper corresponding to this NativeWrapper.
+ public PhantomWrapper mPhantomWrapper;
+
/*
@Override
protected void finalize() throws Throwable {
@@ -118,6 +125,8 @@
}
public int mNativeData;
+ // This will be signaled once mNativeData has been freed.
+ public CountDownLatch mFreeSignal = new CountDownLatch(1);
}
/*
@@ -137,8 +146,7 @@
PhantomWrapper ref = (PhantomWrapper) mQueue.remove();
//System.out.println("dequeued ref " + ref.mNativeData +
// " - " + ref);
- Bitmap.freeNativeStorage(ref.mNativeData);
- //ref.clear();
+ Bitmap.freeNativeStorage(ref.mNativeData, ref.mFreeSignal);
} catch (InterruptedException ie) {
System.out.println("intr");
break;
diff --git a/test/079-phantom/src/Main.java b/test/079-phantom/src/Main.java
index daead2e..ae2c688 100644
--- a/test/079-phantom/src/Main.java
+++ b/test/079-phantom/src/Main.java
@@ -14,8 +14,11 @@
* limitations under the License.
*/
+import java.util.concurrent.CountDownLatch;
+
public class Main {
Bitmap mBitmap1, mBitmap2, mBitmap3, mBitmap4;
+ CountDownLatch mFreeSignalA, mFreeSignalB;
public static void sleep(int ms) {
try {
@@ -31,7 +34,6 @@
Main main = new Main();
main.run();
- sleep(1000);
System.out.println("done");
}
@@ -46,22 +48,30 @@
System.out.println("nulling 1");
mBitmap1 = null;
Runtime.getRuntime().gc();
- sleep(500);
+ try {
+ mFreeSignalA.await(); // Block until dataA is definitely freed.
+ } catch (InterruptedException e) {
+ System.out.println("got unexpected InterruptedException e: " + e);
+ }
System.out.println("nulling 2");
mBitmap2 = null;
Runtime.getRuntime().gc();
- sleep(500);
+ sleep(200);
System.out.println("nulling 3");
mBitmap3 = null;
Runtime.getRuntime().gc();
- sleep(500);
+ sleep(200);
System.out.println("nulling 4");
mBitmap4 = null;
Runtime.getRuntime().gc();
- sleep(500);
+ try {
+ mFreeSignalB.await(); // Block until dataB is definitely freed.
+ } catch (InterruptedException e) {
+ System.out.println("got unexpected InterruptedException e: " + e);
+ }
Bitmap.shutDown();
}
@@ -77,7 +87,10 @@
*/
public void createBitmaps() {
Bitmap.NativeWrapper dataA = Bitmap.allocNativeStorage(10, 10);
+ mFreeSignalA = dataA.mPhantomWrapper.mFreeSignal;
Bitmap.NativeWrapper dataB = Bitmap.allocNativeStorage(20, 20);
+ mFreeSignalB = dataB.mPhantomWrapper.mFreeSignal;
+
mBitmap1 = new Bitmap("one", 10, 10, dataA);
mBitmap2 = new Bitmap("two", 20, 20, dataB);
mBitmap3 = mBitmap4 = new Bitmap("three/four", 20, 20, dataB);