Bug 1959561: Implemented new TimerThread chaos mode wait time adjustment r=smaug

Previously we would scale the wait time by a randomly selected factor,
which meant that small waits would only ever get small (probably
ineffective) adjustments. Now we randomly pick an adjustment in a known
range and build our adjustment from that. This is simple, and doesn't
require the costly, and otherwise unnecessary, conversion of a TimeStamp
to microseconds.

Differential Revision: https://phabricator.services.mozilla.com/D245678
This commit is contained in:
Justin Link
2025-04-22 15:59:06 +00:00
parent 669ebd6797
commit 57afb7f6e6
2 changed files with 17 additions and 15 deletions

View File

@@ -80,6 +80,15 @@ class ChaosMode {
MOZ_ASSERT(aBound != 0);
return uint32_t(rand()) % aBound;
}
/**
* Returns a somewhat (but not uniformly) random int32_t <= aLow and >= aHigh.
* Not to be used for anything except ChaosMode, since it's not very random.
*/
static int32_t randomInt32InRange(int32_t aLow, int32_t aHigh) {
MOZ_ASSERT(aHigh >= aLow);
return (int32_t(rand()) % (aHigh - aLow + 1)) + aLow;
}
};
} /* namespace mozilla */

View File

@@ -878,11 +878,6 @@ TimerThread::Run() {
// interval is so small we should not wait at all).
const TimeDuration timeToNextTimer = timeout - now;
// The mean value of sFractions must be 1 to ensure that the average of
// a long sequence of timeouts converges to the actual sum of their
// times.
static constexpr double sChaosFractions[] = {0.0, 0.25, 0.5, 0.75,
1.0, 1.75, 2.75};
if (timeToNextTimer < allowedEarlyFiring) {
goto next; // round down; execute event now
}
@@ -903,16 +898,14 @@ TimerThread::Run() {
// should have fired.
MOZ_ASSERT(!waitFor.IsZero());
if (chaosModeActive) {
// If chaos mode is active then mess with the amount of time that we
// request to sleep (without changing what we record as our expected
// wake-up time). This will simulate unintended early/late wake-ups.
const double waitInMs = waitFor.ToMilliseconds();
const double chaosWaitInMs =
waitInMs * sChaosFractions[ChaosMode::randomUint32LessThan(
std::size(sChaosFractions))];
waitFor = TimeDuration::FromMilliseconds(chaosWaitInMs);
}
// If chaos mode is active then we will add a random amount to the
// calculated wait (sleep) time to simulate early/late wake-ups.
const TimeDuration chaosWaitDelay =
!chaosModeActive
? TimeDuration::Zero()
: TimeDuration::FromMicroseconds(
ChaosMode::randomInt32InRange(-10000, 10000));
waitFor = std::max(TimeDuration::Zero(), waitFor + chaosWaitDelay);
mIntendedWakeupTime = wakeupTime;
} else {