tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 */