mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1182516 - Add Chaos Mode environment variable MOZ_CHAOSMODE. r=roc
--HG-- extra : commitid : qfYBMvxZ7k extra : rebase_source : 4c7098464712d7e5fa88ba1d8fba7c044772b0d6
This commit is contained in:
parent
9b10736358
commit
fe3dfcf5b2
@ -7,9 +7,11 @@
|
||||
#include "mozilla/ChaosMode.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace detail {
|
||||
|
||||
Atomic<uint32_t> gChaosModeCounter(0);
|
||||
ChaosFeature gChaosFeatures = None;
|
||||
|
||||
} /* namespace detail */
|
||||
} /* namespace mozilla */
|
||||
|
@ -15,8 +15,24 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
enum ChaosFeature {
|
||||
None = 0x0,
|
||||
// Altering thread scheduling.
|
||||
ThreadScheduling = 0x1,
|
||||
// Altering network request scheduling.
|
||||
NetworkScheduling = 0x2,
|
||||
// Altering timer scheduling.
|
||||
TimerScheduling = 0x4,
|
||||
// Read and write less-than-requested amounts.
|
||||
IOAmounts = 0x8,
|
||||
// Iterate over hash tables in random order.
|
||||
HashTableIteration = 0x10,
|
||||
Any = 0xffffffff,
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
extern MFBT_DATA Atomic<uint32_t> gChaosModeCounter;
|
||||
extern MFBT_DATA ChaosFeature gChaosFeatures;
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
@ -27,32 +43,17 @@ extern MFBT_DATA Atomic<uint32_t> gChaosModeCounter;
|
||||
class ChaosMode
|
||||
{
|
||||
public:
|
||||
enum ChaosFeature {
|
||||
None = 0x0,
|
||||
// Altering thread scheduling.
|
||||
ThreadScheduling = 0x1,
|
||||
// Altering network request scheduling.
|
||||
NetworkScheduling = 0x2,
|
||||
// Altering timer scheduling.
|
||||
TimerScheduling = 0x4,
|
||||
// Read and write less-than-requested amounts.
|
||||
IOAmounts = 0x8,
|
||||
// Iterate over hash tables in random order.
|
||||
HashTableIteration = 0x10,
|
||||
Any = 0xffffffff,
|
||||
};
|
||||
static void SetChaosFeature(ChaosFeature aChaosFeature)
|
||||
{
|
||||
detail::gChaosFeatures = aChaosFeature;
|
||||
}
|
||||
|
||||
private:
|
||||
// Change this to any non-None value to activate ChaosMode.
|
||||
static const ChaosFeature sChaosFeatures = None;
|
||||
|
||||
public:
|
||||
static bool isActive(ChaosFeature aFeature)
|
||||
{
|
||||
if (detail::gChaosModeCounter > 0) {
|
||||
return true;
|
||||
}
|
||||
return sChaosFeatures & aFeature;
|
||||
return detail::gChaosFeatures & aFeature;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,7 +275,7 @@ nsSocketTransportService::AddToPollList(SocketContext *sock)
|
||||
}
|
||||
|
||||
uint32_t newSocketIndex = mActiveCount;
|
||||
if (ChaosMode::isActive(ChaosMode::NetworkScheduling)) {
|
||||
if (ChaosMode::isActive(ChaosFeature::NetworkScheduling)) {
|
||||
newSocketIndex = ChaosMode::randomUint32LessThan(mActiveCount + 1);
|
||||
PodMove(mActiveList + newSocketIndex + 1, mActiveList + newSocketIndex,
|
||||
mActiveCount - newSocketIndex);
|
||||
|
@ -1626,7 +1626,7 @@ nsHttpConnection::OnWriteSegment(char *buf,
|
||||
return NS_ERROR_FAILURE; // stop iterating
|
||||
}
|
||||
|
||||
if (ChaosMode::isActive(ChaosMode::IOAmounts) &&
|
||||
if (ChaosMode::isActive(ChaosFeature::IOAmounts) &&
|
||||
ChaosMode::randomUint32LessThan(2)) {
|
||||
// read 1...count bytes
|
||||
count = ChaosMode::randomUint32LessThan(count) + 1;
|
||||
|
@ -56,7 +56,7 @@ InsertTransactionSorted(nsTArray<nsHttpTransaction*> &pendingQ, nsHttpTransactio
|
||||
for (int32_t i=pendingQ.Length()-1; i>=0; --i) {
|
||||
nsHttpTransaction *t = pendingQ[i];
|
||||
if (trans->Priority() >= t->Priority()) {
|
||||
if (ChaosMode::isActive(ChaosMode::NetworkScheduling)) {
|
||||
if (ChaosMode::isActive(ChaosFeature::NetworkScheduling)) {
|
||||
int32_t samePriorityCount;
|
||||
for (samePriorityCount = 0; i - samePriorityCount >= 0; ++samePriorityCount) {
|
||||
if (pendingQ[i - samePriorityCount]->Priority() != trans->Priority()) {
|
||||
|
@ -3123,7 +3123,17 @@ XREMain::XRE_mainInit(bool* aExitFlag)
|
||||
|
||||
StartupTimeline::Record(StartupTimeline::MAIN);
|
||||
|
||||
if (ChaosMode::isActive(ChaosMode::Any)) {
|
||||
if (PR_GetEnv("MOZ_CHAOSMODE")) {
|
||||
ChaosFeature feature = ChaosFeature::Any;
|
||||
long featureInt = strtol(PR_GetEnv("MOZ_CHAOSMODE"), nullptr, 16);
|
||||
if (featureInt) {
|
||||
// NOTE: MOZ_CHAOSMODE=0 or a non-hex value maps to Any feature.
|
||||
feature = static_cast<ChaosFeature>(featureInt);
|
||||
}
|
||||
ChaosMode::SetChaosFeature(feature);
|
||||
}
|
||||
|
||||
if (ChaosMode::isActive(ChaosFeature::Any)) {
|
||||
printf_stderr("*** You are running in chaos test mode. See ChaosMode.h. ***\n");
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ TimerThread::Run()
|
||||
if (mSleeping) {
|
||||
// Sleep for 0.1 seconds while not firing timers.
|
||||
uint32_t milliseconds = 100;
|
||||
if (ChaosMode::isActive(ChaosMode::TimerScheduling)) {
|
||||
if (ChaosMode::isActive(ChaosFeature::TimerScheduling)) {
|
||||
milliseconds = ChaosMode::randomUint32LessThan(200);
|
||||
}
|
||||
waitFor = PR_MillisecondsToInterval(milliseconds);
|
||||
@ -320,7 +320,7 @@ TimerThread::Run()
|
||||
// interval is so small we should not wait at all).
|
||||
double microseconds = (timeout - now).ToMilliseconds() * 1000;
|
||||
|
||||
if (ChaosMode::isActive(ChaosMode::TimerScheduling)) {
|
||||
if (ChaosMode::isActive(ChaosFeature::TimerScheduling)) {
|
||||
// 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.
|
||||
|
@ -95,7 +95,7 @@ nsEventQueue::PutEvent(already_AddRefed<nsIRunnable>&& aRunnable)
|
||||
// Avoid calling AddRef+Release while holding our monitor.
|
||||
nsCOMPtr<nsIRunnable> event(aRunnable);
|
||||
|
||||
if (ChaosMode::isActive(ChaosMode::ThreadScheduling)) {
|
||||
if (ChaosMode::isActive(ChaosFeature::ThreadScheduling)) {
|
||||
// With probability 0.5, yield so other threads have a chance to
|
||||
// dispatch events to this queue first.
|
||||
if (ChaosMode::randomUint32LessThan(2)) {
|
||||
|
@ -284,7 +284,7 @@ private:
|
||||
static void
|
||||
SetupCurrentThreadForChaosMode()
|
||||
{
|
||||
if (!ChaosMode::isActive(ChaosMode::ThreadScheduling)) {
|
||||
if (!ChaosMode::isActive(ChaosFeature::ThreadScheduling)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -926,7 +926,7 @@ nsThread::SetPriority(int32_t aPriority)
|
||||
pri = PR_PRIORITY_NORMAL;
|
||||
}
|
||||
// If chaos mode is active, retain the randomly chosen priority
|
||||
if (!ChaosMode::isActive(ChaosMode::ThreadScheduling)) {
|
||||
if (!ChaosMode::isActive(ChaosFeature::ThreadScheduling)) {
|
||||
PR_SetThreadPriority(mThread, pri);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user