Bug 1075644 - Reduce Gecko thread priority at very start; r=snorp r=bnicholson
☠☠ backed out by 8f1758ce53f0 ☠ ☠
authorJim Chen <nchen@mozilla.com>
Mon, 06 Oct 2014 13:23:53 -0400
changeset 209056 4fee6e1f1ad29c5a711ce3ab521b17fdd1539e49
parent 209055 f5db0dae14347be0f0c6c266e08ba8600f9714e8
child 209057 c5c3dbaf007e60c43daf651ec21270c1bc86ffc4
push id27602
push userkwierso@gmail.com
push dateTue, 07 Oct 2014 02:30:49 +0000
treeherdermozilla-central@9ee9e193fc48 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp, bnicholson
bugs1075644
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1075644 - Reduce Gecko thread priority at very start; r=snorp r=bnicholson
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoThread.java
mobile/android/base/home/TopSitesPanel.java
mobile/android/base/util/ThreadUtils.java
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1224,16 +1224,21 @@ public abstract class GeckoApp
                 @Override
                 public void run() {
                     GeckoThread.setLaunchState(GeckoThread.LaunchState.Launched);
                     GeckoThread.createAndStart();
                 }
             }, 1000 * 5 /* 5 seconds */);
         }
 
+        // Heavy load on the Gecko thread can slow down the time it takes for UI to appear on
+        // single-core devices. By minimizing the Gecko thread priority, we ensure that the UI
+        // appears quickly. The priority is reset to normal once thumbnails are loaded.
+        ThreadUtils.reduceGeckoPriority();
+
         MemoryMonitor.getInstance().init(getApplicationContext());
 
         Tabs.getInstance().attachToContext(this);
         try {
             Favicons.initializeWithContext(this);
         } catch (Exception e) {
             Log.e(LOGTAG, "Exception starting favicon cache. Corrupt resources?", e);
         }
@@ -1600,16 +1605,20 @@ public abstract class GeckoApp
             GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Viewport:Flush", null));
         }
 
         if (ACTION_ALERT_CALLBACK.equals(action)) {
             processAlertCallback(intent);
         } else if (NotificationHelper.HELPER_BROADCAST_ACTION.equals(action)) {
             NotificationHelper.getInstance(getApplicationContext()).handleNotificationIntent(intent);
         }
+
+        // Reset Gecko to normal priority. We may reduce the
+        // priority again later, e.g. for loading thumbnails.
+        ThreadUtils.resetGeckoPriority();
     }
 
     private String restoreSessionTabs(final boolean isExternalURL) throws SessionRestoreException {
         try {
             String sessionString = getProfile().readSessionFile(false);
             if (sessionString == null) {
                 throw new SessionRestoreException("Could not read from session file");
             }
--- a/mobile/android/base/GeckoThread.java
+++ b/mobile/android/base/GeckoThread.java
@@ -46,16 +46,17 @@ public class GeckoThread extends Thread 
     private final String mAction;
     private final String mUri;
 
     public static boolean ensureInit() {
         ThreadUtils.assertOnUiThread();
         if (isCreated())
             return false;
         sGeckoThread = new GeckoThread(sArgs, sAction, sUri);
+        ThreadUtils.sGeckoThread = sGeckoThread;
         return true;
     }
 
     public static String sArgs;
     public static String sAction;
     public static String sUri;
 
     public static void setArgs(String args) {
@@ -159,17 +160,16 @@ public class GeckoThread extends Thread 
         }
 
         return (args != null ? args : "") + profileArg + guestArg;
     }
 
     @Override
     public void run() {
         Looper.prepare();
-        ThreadUtils.sGeckoThread = this;
         ThreadUtils.sGeckoHandler = new Handler();
         ThreadUtils.sGeckoQueue = Looper.myQueue();
 
         String path = initGeckoEnvironment();
 
         // This can only happen after the call to initGeckoEnvironment
         // above, because otherwise the JNI code hasn't been loaded yet.
         ThreadUtils.postToUiThread(new Runnable() {
--- a/mobile/android/base/home/TopSitesPanel.java
+++ b/mobile/android/base/home/TopSitesPanel.java
@@ -93,19 +93,16 @@ public class TopSitesPanel extends HomeF
     private ThumbnailsLoaderCallbacks mThumbnailsLoaderCallbacks;
 
     // Listener for editing pinned sites.
     private EditPinnedSiteListener mEditPinnedSiteListener;
 
     // Max number of entries shown in the grid from the cursor.
     private int mMaxGridEntries;
 
-    // Time in ms until the Gecko thread is reset to normal priority.
-    private static final long PRIORITY_RESET_TIMEOUT = 10000;
-
     public static TopSitesPanel newInstance() {
         return new TopSitesPanel();
     }
 
     private static boolean logDebug = Log.isLoggable(LOGTAG, Log.DEBUG);
     private static boolean logVerbose = Log.isLoggable(LOGTAG, Log.VERBOSE);
 
     private static void debug(final String message) {
@@ -342,17 +339,17 @@ public class TopSitesPanel extends HomeF
         getLoaderManager().initLoader(LOADER_ID_TOP_SITES, null, mCursorLoaderCallbacks);
 
         // Since this is the primary fragment that loads whenever about:home is
         // visited, we want to load it as quickly as possible. Heavy load on
         // the Gecko thread can slow down the time it takes for thumbnails to
         // appear, especially during startup (bug 897162). By minimizing the
         // Gecko thread priority, we ensure that the UI appears quickly. The
         // priority is reset to normal once thumbnails are loaded.
-        ThreadUtils.reduceGeckoPriority(PRIORITY_RESET_TIMEOUT);
+        ThreadUtils.reduceGeckoPriority();
     }
 
     /**
      * Listener for editing pinned sites.
      */
     private class EditPinnedSiteListener implements OnEditPinnedSiteListener,
                                                     OnSiteSelectedListener {
         // Tag for the PinSiteDialog fragment.
--- a/mobile/android/base/util/ThreadUtils.java
+++ b/mobile/android/base/util/ThreadUtils.java
@@ -12,16 +12,19 @@ import java.util.Map;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.util.Log;
 
 public final class ThreadUtils {
     private static final String LOGTAG = "ThreadUtils";
 
+    // Time in ms until the Gecko thread is reset to normal priority.
+    private static final long PRIORITY_RESET_TIMEOUT = 10000;
+
     /**
      * Controls the action taken when a method like
      * {@link ThreadUtils#assertOnUiThread(AssertBehavior)} detects a problem.
      */
     public static enum AssertBehavior {
         NONE,
         THROW,
     }
@@ -204,30 +207,28 @@ public final class ThreadUtils {
     }
 
     /**
      * Reduces the priority of the Gecko thread, allowing other operations
      * (such as those related to the UI and database) to take precedence.
      *
      * Note that there are no guards in place to prevent multiple calls
      * to this method from conflicting with each other.
-     *
-     * @param timeout Timeout in ms after which the priority will be reset
      */
-    public static void reduceGeckoPriority(long timeout) {
+    public static void reduceGeckoPriority() {
         if (Runtime.getRuntime().availableProcessors() > 1) {
             // Don't reduce priority for multicore devices. We use availableProcessors()
             // for its fast performance. It may give false negatives (i.e. multicore
             // detected as single-core), but we can tolerate this behavior.
             return;
         }
         if (!sIsGeckoPriorityReduced && sGeckoThread != null) {
             sIsGeckoPriorityReduced = true;
             sGeckoThread.setPriority(Thread.MIN_PRIORITY);
-            getUiHandler().postDelayed(sPriorityResetRunnable, timeout);
+            getUiHandler().postDelayed(sPriorityResetRunnable, PRIORITY_RESET_TIMEOUT);
         }
     }
 
     /**
      * Resets the priority of a thread whose priority has been reduced
      * by reduceGeckoPriority.
      */
     public static void resetGeckoPriority() {