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);