1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "MainThreadIdlePeriod.h" 8 9 #include "mozilla/Maybe.h" 10 #include "mozilla/Preferences.h" 11 #include "mozilla/StaticPrefs_idle_period.h" 12 #include "mozilla/dom/Document.h" 13 #include "VRManagerChild.h" 14 #include "nsRefreshDriver.h" 15 #include "nsThreadUtils.h" 16 17 // The amount of idle time (milliseconds) reserved for a long idle period. 18 static const double kLongIdlePeriodMS = 50.0; 19 20 // The minimum amount of time (milliseconds) required for an idle period to be 21 // scheduled on the main thread. N.B. layout.idle_period.time_limit adds 22 // padding at the end of the idle period, which makes the point in time that we 23 // expect to become busy again be: 24 // now + idle_period.min + layout.idle_period.time_limit 25 // or during page load 26 // now + idle_period.during_page_load.min + layout.idle_period.time_limit 27 28 static const uint32_t kMaxTimerThreadBound = 5; // milliseconds 29 static const uint32_t kMaxTimerThreadBoundClamp = 15; // milliseconds 30 31 namespace mozilla { 32 33 NS_IMETHODIMP GetIdlePeriodHint(TimeStamp * aIdleDeadline)34MainThreadIdlePeriod::GetIdlePeriodHint(TimeStamp* aIdleDeadline) { 35 MOZ_ASSERT(NS_IsMainThread()); 36 MOZ_ASSERT(aIdleDeadline); 37 38 TimeStamp now = TimeStamp::Now(); 39 TimeStamp currentGuess = 40 now + TimeDuration::FromMilliseconds(kLongIdlePeriodMS); 41 42 currentGuess = nsRefreshDriver::GetIdleDeadlineHint(currentGuess); 43 if (XRE_IsContentProcess()) { 44 currentGuess = gfx::VRManagerChild::GetIdleDeadlineHint(currentGuess); 45 } 46 currentGuess = NS_GetTimerDeadlineHintOnCurrentThread(currentGuess, 47 kMaxTimerThreadBound); 48 49 // If the idle period is too small, then just return a null time 50 // to indicate we are busy. Otherwise return the actual deadline. 51 TimeDuration minIdlePeriod = 52 TimeDuration::FromMilliseconds(StaticPrefs::idle_period_min()); 53 bool busySoon = currentGuess.IsNull() || 54 (now >= (currentGuess - minIdlePeriod)) || 55 currentGuess < mLastIdleDeadline; 56 57 // During page load use higher minimum idle period. 58 if (!busySoon && XRE_IsContentProcess() && 59 mozilla::dom::Document::HasRecentlyStartedForegroundLoads()) { 60 TimeDuration minIdlePeriod = TimeDuration::FromMilliseconds( 61 StaticPrefs::idle_period_during_page_load_min()); 62 busySoon = (now >= (currentGuess - minIdlePeriod)); 63 } 64 65 if (!busySoon) { 66 *aIdleDeadline = mLastIdleDeadline = currentGuess; 67 } 68 69 return NS_OK; 70 } 71 72 /* static */ GetLongIdlePeriod()73float MainThreadIdlePeriod::GetLongIdlePeriod() { return kLongIdlePeriodMS; } 74 75 } // namespace mozilla 76