mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1182516 - Add Chaos Mode environment variable MOZ_CHAOSMODE. r=roc
This commit is contained in:
parent
ce65d9290b
commit
2e648924e7
@ -7,9 +7,11 @@
|
|||||||
#include "mozilla/ChaosMode.h"
|
#include "mozilla/ChaosMode.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
Atomic<uint32_t> gChaosModeCounter(0);
|
Atomic<uint32_t> gChaosModeCounter(0);
|
||||||
|
ChaosFeature gChaosFeatures = None;
|
||||||
|
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
} /* namespace mozilla */
|
} /* namespace mozilla */
|
||||||
|
@ -15,19 +15,7 @@
|
|||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
namespace detail {
|
enum ChaosFeature {
|
||||||
extern MFBT_DATA Atomic<uint32_t> gChaosModeCounter;
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When "chaos mode" is activated, code that makes implicitly nondeterministic
|
|
||||||
* choices is encouraged to make random and extreme choices, to test more
|
|
||||||
* code paths and uncover bugs.
|
|
||||||
*/
|
|
||||||
class ChaosMode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum ChaosFeature {
|
|
||||||
None = 0x0,
|
None = 0x0,
|
||||||
// Altering thread scheduling.
|
// Altering thread scheduling.
|
||||||
ThreadScheduling = 0x1,
|
ThreadScheduling = 0x1,
|
||||||
@ -40,19 +28,32 @@ public:
|
|||||||
// Iterate over hash tables in random order.
|
// Iterate over hash tables in random order.
|
||||||
HashTableIteration = 0x10,
|
HashTableIteration = 0x10,
|
||||||
Any = 0xffffffff,
|
Any = 0xffffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
namespace detail {
|
||||||
// Change this to any non-None value to activate ChaosMode.
|
extern MFBT_DATA Atomic<uint32_t> gChaosModeCounter;
|
||||||
static const ChaosFeature sChaosFeatures = None;
|
extern MFBT_DATA ChaosFeature gChaosFeatures;
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When "chaos mode" is activated, code that makes implicitly nondeterministic
|
||||||
|
* choices is encouraged to make random and extreme choices, to test more
|
||||||
|
* code paths and uncover bugs.
|
||||||
|
*/
|
||||||
|
class ChaosMode
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
static void SetChaosFeature(ChaosFeature aChaosFeature)
|
||||||
|
{
|
||||||
|
detail::gChaosFeatures = aChaosFeature;
|
||||||
|
}
|
||||||
|
|
||||||
static bool isActive(ChaosFeature aFeature)
|
static bool isActive(ChaosFeature aFeature)
|
||||||
{
|
{
|
||||||
if (detail::gChaosModeCounter > 0) {
|
if (detail::gChaosModeCounter > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return sChaosFeatures & aFeature;
|
return detail::gChaosFeatures & aFeature;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,7 +275,7 @@ nsSocketTransportService::AddToPollList(SocketContext *sock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t newSocketIndex = mActiveCount;
|
uint32_t newSocketIndex = mActiveCount;
|
||||||
if (ChaosMode::isActive(ChaosMode::NetworkScheduling)) {
|
if (ChaosMode::isActive(ChaosFeature::NetworkScheduling)) {
|
||||||
newSocketIndex = ChaosMode::randomUint32LessThan(mActiveCount + 1);
|
newSocketIndex = ChaosMode::randomUint32LessThan(mActiveCount + 1);
|
||||||
PodMove(mActiveList + newSocketIndex + 1, mActiveList + newSocketIndex,
|
PodMove(mActiveList + newSocketIndex + 1, mActiveList + newSocketIndex,
|
||||||
mActiveCount - newSocketIndex);
|
mActiveCount - newSocketIndex);
|
||||||
|
@ -1626,7 +1626,7 @@ nsHttpConnection::OnWriteSegment(char *buf,
|
|||||||
return NS_ERROR_FAILURE; // stop iterating
|
return NS_ERROR_FAILURE; // stop iterating
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ChaosMode::isActive(ChaosMode::IOAmounts) &&
|
if (ChaosMode::isActive(ChaosFeature::IOAmounts) &&
|
||||||
ChaosMode::randomUint32LessThan(2)) {
|
ChaosMode::randomUint32LessThan(2)) {
|
||||||
// read 1...count bytes
|
// read 1...count bytes
|
||||||
count = ChaosMode::randomUint32LessThan(count) + 1;
|
count = ChaosMode::randomUint32LessThan(count) + 1;
|
||||||
|
@ -56,7 +56,7 @@ InsertTransactionSorted(nsTArray<nsHttpTransaction*> &pendingQ, nsHttpTransactio
|
|||||||
for (int32_t i=pendingQ.Length()-1; i>=0; --i) {
|
for (int32_t i=pendingQ.Length()-1; i>=0; --i) {
|
||||||
nsHttpTransaction *t = pendingQ[i];
|
nsHttpTransaction *t = pendingQ[i];
|
||||||
if (trans->Priority() >= t->Priority()) {
|
if (trans->Priority() >= t->Priority()) {
|
||||||
if (ChaosMode::isActive(ChaosMode::NetworkScheduling)) {
|
if (ChaosMode::isActive(ChaosFeature::NetworkScheduling)) {
|
||||||
int32_t samePriorityCount;
|
int32_t samePriorityCount;
|
||||||
for (samePriorityCount = 0; i - samePriorityCount >= 0; ++samePriorityCount) {
|
for (samePriorityCount = 0; i - samePriorityCount >= 0; ++samePriorityCount) {
|
||||||
if (pendingQ[i - samePriorityCount]->Priority() != trans->Priority()) {
|
if (pendingQ[i - samePriorityCount]->Priority() != trans->Priority()) {
|
||||||
|
@ -3123,7 +3123,17 @@ XREMain::XRE_mainInit(bool* aExitFlag)
|
|||||||
|
|
||||||
StartupTimeline::Record(StartupTimeline::MAIN);
|
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");
|
printf_stderr("*** You are running in chaos test mode. See ChaosMode.h. ***\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ TimerThread::Run()
|
|||||||
if (mSleeping) {
|
if (mSleeping) {
|
||||||
// Sleep for 0.1 seconds while not firing timers.
|
// Sleep for 0.1 seconds while not firing timers.
|
||||||
uint32_t milliseconds = 100;
|
uint32_t milliseconds = 100;
|
||||||
if (ChaosMode::isActive(ChaosMode::TimerScheduling)) {
|
if (ChaosMode::isActive(ChaosFeature::TimerScheduling)) {
|
||||||
milliseconds = ChaosMode::randomUint32LessThan(200);
|
milliseconds = ChaosMode::randomUint32LessThan(200);
|
||||||
}
|
}
|
||||||
waitFor = PR_MillisecondsToInterval(milliseconds);
|
waitFor = PR_MillisecondsToInterval(milliseconds);
|
||||||
@ -320,7 +320,7 @@ TimerThread::Run()
|
|||||||
// interval is so small we should not wait at all).
|
// interval is so small we should not wait at all).
|
||||||
double microseconds = (timeout - now).ToMilliseconds() * 1000;
|
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 mean value of sFractions must be 1 to ensure that
|
||||||
// the average of a long sequence of timeouts converges to the
|
// the average of a long sequence of timeouts converges to the
|
||||||
// actual sum of their times.
|
// actual sum of their times.
|
||||||
|
@ -95,7 +95,7 @@ nsEventQueue::PutEvent(already_AddRefed<nsIRunnable>&& aRunnable)
|
|||||||
// Avoid calling AddRef+Release while holding our monitor.
|
// Avoid calling AddRef+Release while holding our monitor.
|
||||||
nsCOMPtr<nsIRunnable> event(aRunnable);
|
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
|
// With probability 0.5, yield so other threads have a chance to
|
||||||
// dispatch events to this queue first.
|
// dispatch events to this queue first.
|
||||||
if (ChaosMode::randomUint32LessThan(2)) {
|
if (ChaosMode::randomUint32LessThan(2)) {
|
||||||
|
@ -284,7 +284,7 @@ private:
|
|||||||
static void
|
static void
|
||||||
SetupCurrentThreadForChaosMode()
|
SetupCurrentThreadForChaosMode()
|
||||||
{
|
{
|
||||||
if (!ChaosMode::isActive(ChaosMode::ThreadScheduling)) {
|
if (!ChaosMode::isActive(ChaosFeature::ThreadScheduling)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,7 +926,7 @@ nsThread::SetPriority(int32_t aPriority)
|
|||||||
pri = PR_PRIORITY_NORMAL;
|
pri = PR_PRIORITY_NORMAL;
|
||||||
}
|
}
|
||||||
// If chaos mode is active, retain the randomly chosen priority
|
// If chaos mode is active, retain the randomly chosen priority
|
||||||
if (!ChaosMode::isActive(ChaosMode::ThreadScheduling)) {
|
if (!ChaosMode::isActive(ChaosFeature::ThreadScheduling)) {
|
||||||
PR_SetThreadPriority(mThread, pri);
|
PR_SetThreadPriority(mThread, pri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user