Line data Source code
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 "nsRefreshDriver.h"
12 : #include "nsThreadUtils.h"
13 :
14 : #define DEFAULT_LONG_IDLE_PERIOD 50.0f
15 : #define DEFAULT_MIN_IDLE_PERIOD 3.0f
16 : #define DEFAULT_MAX_TIMER_THREAD_BOUND 5
17 :
18 : const uint32_t kMaxTimerThreadBoundClamp = 15;
19 :
20 : namespace mozilla {
21 :
22 : NS_IMETHODIMP
23 159 : MainThreadIdlePeriod::GetIdlePeriodHint(TimeStamp* aIdleDeadline)
24 : {
25 159 : MOZ_ASSERT(NS_IsMainThread());
26 159 : MOZ_ASSERT(aIdleDeadline);
27 :
28 159 : TimeStamp now = TimeStamp::Now();
29 : TimeStamp currentGuess =
30 159 : now + TimeDuration::FromMilliseconds(GetLongIdlePeriod());
31 :
32 159 : currentGuess = nsRefreshDriver::GetIdleDeadlineHint(currentGuess);
33 159 : currentGuess = NS_GetTimerDeadlineHintOnCurrentThread(currentGuess, GetMaxTimerThreadBound());
34 :
35 : // If the idle period is too small, then just return a null time
36 : // to indicate we are busy. Otherwise return the actual deadline.
37 : TimeDuration minIdlePeriod =
38 159 : TimeDuration::FromMilliseconds(GetMinIdlePeriod());
39 477 : bool busySoon = currentGuess.IsNull() ||
40 949 : (now >= (currentGuess - minIdlePeriod)) ||
41 313 : currentGuess < mLastIdleDeadline;
42 :
43 159 : if (!busySoon) {
44 154 : *aIdleDeadline = mLastIdleDeadline = currentGuess;
45 : }
46 :
47 159 : return NS_OK;
48 : }
49 :
50 : /* static */ float
51 159 : MainThreadIdlePeriod::GetLongIdlePeriod()
52 : {
53 159 : MOZ_ASSERT(NS_IsMainThread());
54 :
55 : static float sLongIdlePeriod = DEFAULT_LONG_IDLE_PERIOD;
56 : static bool sInitialized = false;
57 :
58 159 : if (!sInitialized && Preferences::IsServiceAvailable()) {
59 2 : sInitialized = true;
60 : Preferences::AddFloatVarCache(&sLongIdlePeriod, "idle_queue.long_period",
61 2 : DEFAULT_LONG_IDLE_PERIOD);
62 : }
63 :
64 159 : return sLongIdlePeriod;
65 : }
66 :
67 : /* static */ float
68 159 : MainThreadIdlePeriod::GetMinIdlePeriod()
69 : {
70 159 : MOZ_ASSERT(NS_IsMainThread());
71 :
72 : static float sMinIdlePeriod = DEFAULT_MIN_IDLE_PERIOD;
73 : static bool sInitialized = false;
74 :
75 159 : if (!sInitialized && Preferences::IsServiceAvailable()) {
76 2 : sInitialized = true;
77 : Preferences::AddFloatVarCache(&sMinIdlePeriod, "idle_queue.min_period",
78 2 : DEFAULT_MIN_IDLE_PERIOD);
79 : }
80 :
81 159 : return sMinIdlePeriod;
82 : }
83 :
84 : /* static */ uint32_t
85 159 : MainThreadIdlePeriod::GetMaxTimerThreadBound()
86 : {
87 159 : MOZ_ASSERT(NS_IsMainThread());
88 :
89 : static uint32_t sMaxTimerThreadBound = DEFAULT_MAX_TIMER_THREAD_BOUND;
90 : static bool sInitialized = false;
91 :
92 159 : if (!sInitialized && Preferences::IsServiceAvailable()) {
93 2 : sInitialized = true;
94 : Preferences::AddUintVarCache(&sMaxTimerThreadBound, "idle_queue.max_timer_thread_bound",
95 2 : DEFAULT_MAX_TIMER_THREAD_BOUND);
96 : }
97 :
98 159 : return std::max(sMaxTimerThreadBound, kMaxTimerThreadBoundClamp);
99 : }
100 :
101 : } // namespace mozilla
|