ChaosMode.h (2943B)
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 #ifndef mozilla_ChaosMode_h 8 #define mozilla_ChaosMode_h 9 10 #include "mozilla/Assertions.h" 11 #include "mozilla/Atomics.h" 12 13 #include <cstdint> 14 15 namespace mozilla { 16 17 enum class ChaosFeature : uint32_t { 18 None = 0x0, 19 // Altering thread scheduling. 20 ThreadScheduling = 0x1, 21 // Altering network request scheduling. 22 NetworkScheduling = 0x2, 23 // Altering timer scheduling. 24 TimerScheduling = 0x4, 25 // Read and write less-than-requested amounts. 26 IOAmounts = 0x8, 27 // Iterate over hash tables in random order. 28 HashTableIteration = 0x10, 29 // Randomly refuse to use cached version of image (when allowed by spec). 30 ImageCache = 0x20, 31 // Delay dispatching threads to encourage dispatched tasks to run. 32 TaskDispatching = 0x40, 33 // Delay task running to encourage sending threads to run. 34 TaskRunning = 0x80, 35 Any = 0xffffffff, 36 }; 37 38 namespace detail { 39 extern MFBT_DATA Atomic<uint32_t, Relaxed> gChaosModeCounter; 40 extern MFBT_DATA ChaosFeature gChaosFeatures; 41 } // namespace detail 42 43 /** 44 * When "chaos mode" is activated, code that makes implicitly nondeterministic 45 * choices is encouraged to make random and extreme choices, to test more 46 * code paths and uncover bugs. 47 */ 48 class ChaosMode { 49 public: 50 static void SetChaosFeature(ChaosFeature aChaosFeature) { 51 detail::gChaosFeatures = aChaosFeature; 52 } 53 54 static bool isActive(ChaosFeature aFeature) { 55 return detail::gChaosModeCounter > 0 && 56 (uint32_t(detail::gChaosFeatures) & uint32_t(aFeature)); 57 } 58 59 /** 60 * Increase the chaos mode activation level. An equivalent number of 61 * calls to leaveChaosMode must be made in order to restore the original 62 * chaos mode state. 63 */ 64 static void enterChaosMode() { detail::gChaosModeCounter++; } 65 66 /** 67 * Decrease the chaos mode activation level. See enterChaosMode(). 68 */ 69 static void leaveChaosMode() { 70 MOZ_ASSERT(detail::gChaosModeCounter > 0); 71 detail::gChaosModeCounter--; 72 } 73 74 /** 75 * Returns a somewhat (but not uniformly) random uint32_t < aBound. 76 * Not to be used for anything except ChaosMode, since it's not very random. 77 */ 78 static uint32_t randomUint32LessThan(uint32_t aBound) { 79 MOZ_ASSERT(aBound != 0); 80 return uint32_t(rand()) % aBound; 81 } 82 83 /** 84 * Returns a somewhat (but not uniformly) random int32_t <= aLow and >= aHigh. 85 * Not to be used for anything except ChaosMode, since it's not very random. 86 */ 87 static int32_t randomInt32InRange(int32_t aLow, int32_t aHigh) { 88 MOZ_ASSERT(aHigh >= aLow); 89 return (int32_t(rand()) % (aHigh - aLow + 1)) + aLow; 90 } 91 }; 92 93 } /* namespace mozilla */ 94 95 #endif /* mozilla_ChaosMode_h */