hang_watcher.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_THREADING_HANG_WATCHER_H_
  5. #define BASE_THREADING_HANG_WATCHER_H_
  6. #include <atomic>
  7. #include <cstdint>
  8. #include <memory>
  9. #include <type_traits>
  10. #include <vector>
  11. #include "base/atomicops.h"
  12. #include "base/bits.h"
  13. #include "base/callback.h"
  14. #include "base/callback_forward.h"
  15. #include "base/callback_helpers.h"
  16. #include "base/compiler_specific.h"
  17. #include "base/synchronization/lock.h"
  18. #include "base/thread_annotations.h"
  19. #include "base/threading/platform_thread.h"
  20. #include "base/threading/simple_thread.h"
  21. #include "base/threading/thread_checker.h"
  22. #include "base/threading/thread_local.h"
  23. #include "base/time/tick_clock.h"
  24. #include "base/time/time.h"
  25. namespace base {
  26. class HangWatchScopeEnabled;
  27. namespace internal {
  28. class HangWatchState;
  29. } // namespace internal
  30. } // namespace base
  31. namespace base {
  32. // Instantiate a HangWatchScopeEnabled in a code scope to register to be
  33. // watched for hangs of more than |timeout| by the HangWatcher.
  34. //
  35. // Example usage:
  36. //
  37. // void FooBar(){
  38. // HangWatchScopeEnabled scope(base::TimeDelta::FromSeconds(5));
  39. // DoWork();
  40. // }
  41. //
  42. // If DoWork() takes more than 5s to run and the HangWatcher
  43. // inspects the thread state before Foobar returns a hang will be
  44. // reported.
  45. //
  46. // HangWatchScopeEnableds are typically meant to live on the stack. In some
  47. // cases it's necessary to keep a HangWatchScopeEnabled instance as a class
  48. // member but special care is required when doing so as a HangWatchScopeEnabled
  49. // that stays alive longer than intended will generate non-actionable hang
  50. // reports.
  51. class BASE_EXPORT HangWatchScopeEnabled {
  52. public:
  53. // A good default value needs to be large enough to represent a significant
  54. // hang and avoid noise while being small enough to not exclude too many
  55. // hangs. The nature of the work that gets executed on the thread is also
  56. // important. We can be much stricter when monitoring a UI thread compared tp
  57. // a ThreadPool thread for example.
  58. static const base::TimeDelta kDefaultHangWatchTime;
  59. // Constructing/destructing thread must be the same thread.
  60. explicit HangWatchScopeEnabled(TimeDelta timeout);
  61. ~HangWatchScopeEnabled();
  62. HangWatchScopeEnabled(const HangWatchScopeEnabled&) = delete;
  63. HangWatchScopeEnabled& operator=(const HangWatchScopeEnabled&) = delete;
  64. private:
  65. // This object should always be constructed and destructed on the same thread.
  66. THREAD_CHECKER(thread_checker_);
  67. // The deadline set by the previous HangWatchScopeEnabled created on this
  68. // thread. Stored so it can be restored when this HangWatchScopeEnabled is
  69. // destroyed.
  70. TimeTicks previous_deadline_;
  71. // Indicates whether the kIgnoreCurrentHang flag must be set upon exiting this
  72. // HangWatchScopeEnabled. This is true if the
  73. // kIgnoreCurrentHangWatchScopeEnabled flag was set upon entering this scope,
  74. // but was cleared for this HangWatchScopeEnabled because there was no active
  75. // HangWatchScopeDisabled.
  76. bool set_hangs_ignored_on_exit_ = false;
  77. #if DCHECK_IS_ON()
  78. // The previous HangWatchScopeEnabled created on this thread.
  79. HangWatchScopeEnabled* previous_hang_watch_scope_enable_;
  80. #endif
  81. };
  82. // Scoped object that disables hang watching on the thread. The object nullifies
  83. // the effect of all live HangWatchScopeEnabled instances and also that of new
  84. // HangWatchScopeEnabled instances created during its lifetime. Use to avoid
  85. // capturing hangs for operations known to take unbounded time like waiting for
  86. // user input. This does not unregister the thread so when this object is
  87. // destroyed hang watching resumes for new HangWatchScopeEnableds.
  88. //
  89. // Example usage:
  90. // {
  91. // HangWatchScopeEnabled scope_1;
  92. // {
  93. // HangWatchScopeEnabled scope_2;
  94. // HangWatchScopeDisabled disabler;
  95. // WaitForUserInput();
  96. // HangWatchScopeEnabled scope_3;
  97. // }
  98. //
  99. // HangWatchScopeEnabled scope_4;
  100. // }
  101. //
  102. // HangWatchScopeEnabled scope_5;
  103. //
  104. // In this example hang watching is disabled for HangWatchScopeEnableds 1, 2 and
  105. // 3 since they were either active at the time of the |disabler|'s creation or
  106. // created while the disabler was still active. HangWatchScopeEnableds 4 and 5
  107. // are unaffected since they were created after the disabler was destroyed.
  108. //
  109. class BASE_EXPORT HangWatchScopeDisabled {
  110. public:
  111. HangWatchScopeDisabled();
  112. ~HangWatchScopeDisabled();
  113. HangWatchScopeDisabled(const HangWatchScopeDisabled&) = delete;
  114. HangWatchScopeDisabled& operator=(const HangWatchScopeDisabled&) = delete;
  115. };
  116. // Monitors registered threads for hangs by inspecting their associated
  117. // HangWatchStates for deadline overruns. This happens at a regular interval on
  118. // a separate thread. Only one instance of HangWatcher can exist at a time
  119. // within a single process. This instance must outlive all monitored threads.
  120. class BASE_EXPORT HangWatcher : public DelegateSimpleThread::Delegate {
  121. public:
  122. // The first invocation of the constructor will set the global instance
  123. // accessible through GetInstance(). This means that only one instance can
  124. // exist at a time.
  125. HangWatcher();
  126. // Clears the global instance for the class.
  127. ~HangWatcher() override;
  128. HangWatcher(const HangWatcher&) = delete;
  129. HangWatcher& operator=(const HangWatcher&) = delete;
  130. // Returns a non-owning pointer to the global HangWatcher instance.
  131. static HangWatcher* GetInstance();
  132. // Initializes HangWatcher. Must be called once on the main thread during
  133. // startup while single-threaded.
  134. static void InitializeOnMainThread();
  135. // Thread safe functions to verify if hang watching is activated. If called
  136. // before InitializeOnMainThread returns the default value which is false.
  137. static bool IsEnabled();
  138. static bool IsThreadPoolHangWatchingEnabled();
  139. static bool IsIOThreadHangWatchingEnabled();
  140. static bool IsUIThreadHangWatchingEnabled();
  141. // Sets up the calling thread to be monitored for threads. Returns a
  142. // ScopedClosureRunner that unregisters the thread. This closure has to be
  143. // called from the registered thread before it's joined.
  144. ScopedClosureRunner RegisterThread()
  145. LOCKS_EXCLUDED(watch_state_lock_) WARN_UNUSED_RESULT;
  146. // Choose a closure to be run at the end of each call to Monitor(). Use only
  147. // for testing. Reentering the HangWatcher in the closure must be done with
  148. // care. It should only be done through certain testing functions because
  149. // deadlocks are possible.
  150. void SetAfterMonitorClosureForTesting(base::RepeatingClosure closure);
  151. // Choose a closure to be run instead of recording the hang. Used to test
  152. // that certain conditions hold true at the time of recording. Use only
  153. // for testing. Reentering the HangWatcher in the closure must be done with
  154. // care. It should only be done through certain testing functions because
  155. // deadlocks are possible.
  156. void SetOnHangClosureForTesting(base::RepeatingClosure closure);
  157. // Set a monitoring period other than the default. Use only for
  158. // testing.
  159. void SetMonitoringPeriodForTesting(base::TimeDelta period);
  160. // Choose a callback to invoke right after waiting to monitor in Wait(). Use
  161. // only for testing.
  162. void SetAfterWaitCallbackForTesting(
  163. RepeatingCallback<void(TimeTicks)> callback);
  164. // Force the monitoring loop to resume and evaluate whether to continue.
  165. // This can trigger a call to Monitor() or not depending on why the
  166. // HangWatcher thread is sleeping. Use only for testing.
  167. void SignalMonitorEventForTesting();
  168. // Call to make sure no more monitoring takes place. The
  169. // function is thread-safe and can be called at anytime but won't stop
  170. // monitoring that is currently taking place. Use only for testing.
  171. void StopMonitoringForTesting();
  172. // Replace the clock used when calculating time spent
  173. // sleeping. Use only for testing.
  174. void SetTickClockForTesting(const base::TickClock* tick_clock);
  175. // Use to block until the hang is recorded. Allows the caller to halt
  176. // execution so it does not overshoot the hang watch target and result in a
  177. // non-actionable stack trace in the crash recorded.
  178. void BlockIfCaptureInProgress();
  179. // Begin executing the monitoring loop on the HangWatcher thread.
  180. void Start();
  181. private:
  182. // Use to assert that functions are called on the monitoring thread.
  183. THREAD_CHECKER(hang_watcher_thread_checker_);
  184. // Use to assert that functions are called on the constructing thread.
  185. THREAD_CHECKER(constructing_thread_checker_);
  186. // Invoke base::debug::DumpWithoutCrashing() insuring that the stack frame
  187. // right under it in the trace belongs to HangWatcher for easier attribution.
  188. NOINLINE static void RecordHang();
  189. using HangWatchStates =
  190. std::vector<std::unique_ptr<internal::HangWatchState>>;
  191. // Used to save a snapshots of the state of hang watching during capture.
  192. // Only the state of hung threads is retained.
  193. class BASE_EXPORT WatchStateSnapShot {
  194. public:
  195. struct WatchStateCopy {
  196. base::TimeTicks deadline;
  197. base::PlatformThreadId thread_id;
  198. };
  199. // Construct the snapshot from provided data. |snapshot_time| can be
  200. // different than now() to be coherent with other operations recently done
  201. // on |watch_states|. If any deadline in |watch_states| is before
  202. // |deadline_ignore_threshold|, the snapshot is empty.
  203. WatchStateSnapShot(const HangWatchStates& watch_states,
  204. base::TimeTicks snapshot_time,
  205. base::TimeTicks deadline_ignore_threshold);
  206. WatchStateSnapShot(const WatchStateSnapShot& other);
  207. ~WatchStateSnapShot();
  208. // Returns a string that contains the ids of the hung threads separated by a
  209. // '|'. The size of the string is capped at debug::CrashKeySize::Size256. If
  210. // no threads are hung returns an empty string. Can only be invoked if
  211. // IsActionable().
  212. std::string PrepareHungThreadListCrashKey() const;
  213. // Return the highest deadline included in this snapshot.
  214. base::TimeTicks GetHighestDeadline() const;
  215. // Returns true if the snapshot can be used to record an actionable hang
  216. // report and false if not.
  217. bool IsActionable() const;
  218. private:
  219. base::TimeTicks snapshot_time_;
  220. std::vector<WatchStateCopy> hung_watch_state_copies_;
  221. };
  222. // Return a watch state snapshot taken Now() to be inspected in tests.
  223. // NO_THREAD_SAFETY_ANALYSIS is needed because the analyzer can't figure out
  224. // that calls to this function done from |on_hang_closure_| are properly
  225. // locked.
  226. WatchStateSnapShot GrabWatchStateSnapshotForTesting() const
  227. NO_THREAD_SAFETY_ANALYSIS;
  228. // Inspects the state of all registered threads to check if they are hung and
  229. // invokes the appropriate closure if so.
  230. void Monitor() LOCKS_EXCLUDED(watch_state_lock_);
  231. // Record the hang and perform the necessary housekeeping before and after.
  232. void CaptureHang(base::TimeTicks capture_time)
  233. EXCLUSIVE_LOCKS_REQUIRED(watch_state_lock_) LOCKS_EXCLUDED(capture_lock_);
  234. // Stop all monitoring and join the HangWatcher thread.
  235. void Stop();
  236. // Wait until it's time to monitor.
  237. void Wait();
  238. // Run the loop that periodically monitors the registered thread at a
  239. // set time interval.
  240. void Run() override;
  241. base::TimeDelta monitor_period_;
  242. // Indicates whether Run() should return after the next monitoring.
  243. std::atomic<bool> keep_monitoring_{true};
  244. // Use to make the HangWatcher thread wake or sleep to schedule the
  245. // appropriate monitoring frequency.
  246. WaitableEvent should_monitor_;
  247. bool IsWatchListEmpty() LOCKS_EXCLUDED(watch_state_lock_);
  248. // Stops hang watching on the calling thread by removing the entry from the
  249. // watch list.
  250. void UnregisterThread() LOCKS_EXCLUDED(watch_state_lock_);
  251. Lock watch_state_lock_;
  252. std::vector<std::unique_ptr<internal::HangWatchState>> watch_states_
  253. GUARDED_BY(watch_state_lock_);
  254. base::DelegateSimpleThread thread_;
  255. RepeatingClosure after_monitor_closure_for_testing_;
  256. RepeatingClosure on_hang_closure_for_testing_;
  257. RepeatingCallback<void(TimeTicks)> after_wait_callback_;
  258. base::Lock capture_lock_ ACQUIRED_AFTER(watch_state_lock_);
  259. std::atomic<bool> capture_in_progress_{false};
  260. const base::TickClock* tick_clock_;
  261. // The time after which all deadlines in |watch_states_| need to be for a hang
  262. // to be reported.
  263. base::TimeTicks deadline_ignore_threshold_;
  264. FRIEND_TEST_ALL_PREFIXES(HangWatcherTest, NestedScopes);
  265. FRIEND_TEST_ALL_PREFIXES(HangWatcherSnapshotTest, HungThreadIDs);
  266. FRIEND_TEST_ALL_PREFIXES(HangWatcherSnapshotTest, NonActionableReport);
  267. };
  268. // Classes here are exposed in the header only for testing. They are not
  269. // intended to be used outside of base.
  270. namespace internal {
  271. // Threadsafe class that manages a deadline of type TimeTicks alongside hang
  272. // watching specific flags. The flags are stored in the higher bits of the
  273. // underlying TimeTicks deadline. This enables setting the flags on thread T1 in
  274. // a way that's resilient to concurrent deadline or flag changes from thread T2.
  275. // Flags can be queried separately from the deadline and users of this class
  276. // should not have to care about them when doing so.
  277. class BASE_EXPORT HangWatchDeadline {
  278. public:
  279. // Masks to set flags by flipping a single bit in the TimeTicks value. There
  280. // are two types of flags. Persistent flags remain set through a deadline
  281. // change and non-persistent flags are cleared when the deadline changes.
  282. enum class Flag : uint64_t {
  283. // Minimum value for validation purposes. Not currently used.
  284. kMinValue = bits::LeftmostBit<uint64_t>() >> 7,
  285. // Persistent because control by the lifetime of HangWatchScopeDisabled.
  286. kHasActiveHangWatchScopeDisabled = bits::LeftmostBit<uint64_t>() >> 2,
  287. // Persistent because if hang detection is disabled on a thread it should
  288. // be re-enabled manually.
  289. kIgnoreCurrentHangWatchScopeEnabled = bits::LeftmostBit<uint64_t>() >> 1,
  290. // Non-persistent because a new value means a new HangWatchScopeEnabled
  291. // started
  292. // after the beginning of capture. It can't be implicated in the hang so we
  293. // don't want it to block.
  294. kShouldBlockOnHang = bits::LeftmostBit<uint64_t>() >> 0,
  295. kMaxValue = kShouldBlockOnHang
  296. };
  297. HangWatchDeadline();
  298. ~HangWatchDeadline();
  299. // HangWatchDeadline should never be copied. To keep a copy of the deadline or
  300. // flags use the appropriate accessors.
  301. HangWatchDeadline(const HangWatchDeadline&) = delete;
  302. HangWatchDeadline& operator=(const HangWatchDeadline&) = delete;
  303. // Returns the underlying TimeTicks deadline. WARNING: The deadline and flags
  304. // can change concurrently. To inspect both, use GetFlagsAndDeadline() to get
  305. // a coherent race-free view of the state.
  306. TimeTicks GetDeadline() const;
  307. // Returns a mask containing the flags and the deadline as a pair. Use to
  308. // inspect the flags and deadline and then optionally call
  309. // SetShouldBlockOnHang() .
  310. std::pair<uint64_t, TimeTicks> GetFlagsAndDeadline() const;
  311. // Returns true if the flag is set and false if not. WARNING: The deadline and
  312. // flags can change concurrently. To inspect both, use GetFlagsAndDeadline()
  313. // to get a coherent race-free view of the state.
  314. bool IsFlagSet(Flag flag) const;
  315. // Returns true if a flag is set in |flags| and false if not. Use to inspect
  316. // the flags mask returned by GetFlagsAndDeadline(). WARNING: The deadline and
  317. // flags can change concurrently. If you need to inspect both you need to use
  318. // GetFlagsAndDeadline() to get a coherent race-free view of the state.
  319. static bool IsFlagSet(Flag flag, uint64_t flags);
  320. // Replace the deadline value. |new_value| needs to be within [0,
  321. // Max()]. This function can never fail.
  322. void SetDeadline(TimeTicks new_value);
  323. // Sets the kShouldBlockOnHang flag and returns true if current flags and
  324. // deadline are still equal to |old_flags| and |old_deadline|. Otherwise does
  325. // not set the flag and returns false.
  326. bool SetShouldBlockOnHang(uint64_t old_flags, TimeTicks old_deadline);
  327. // Sets the kHasActiveHangWatchScopeDisabled flag.
  328. void SetHasActiveHangWatchScopeDisabled();
  329. // Clears the kHasActiveHangWatchScopeDisabled flag.
  330. void UnsetHasActiveHangWatchScopeDisabled();
  331. // Sets the kIgnoreCurrentHangWatchScopeEnabled flag.
  332. void SetIgnoreCurrentHangWatchScopeEnabled();
  333. // Clears the kIgnoreCurrentHangWatchScopeEnabled flag.
  334. void UnsetIgnoreCurrentHangWatchScopeEnabled();
  335. // Use to simulate the value of |bits_| changing between the calling a
  336. // Set* function and the moment of atomically switching the values. The
  337. // callback should return a value containing the desired flags and deadline
  338. // bits. The flags that are already set will be preserved upon applying. Use
  339. // only for testing.
  340. void SetSwitchBitsClosureForTesting(
  341. RepeatingCallback<uint64_t(void)> closure);
  342. // Remove the deadline modification callback for when testing is done. Use
  343. // only for testing.
  344. void ResetSwitchBitsClosureForTesting();
  345. private:
  346. using TimeTicksInternalRepresentation =
  347. std::result_of<decltype (&TimeTicks::ToInternalValue)(TimeTicks)>::type;
  348. static_assert(std::is_same<TimeTicksInternalRepresentation, int64_t>::value,
  349. "Bit manipulations made by HangWatchDeadline need to be"
  350. "adapted if internal representation of TimeTicks changes.");
  351. // Replace the bits with the ones provided through the callback. Preserves the
  352. // flags that were already set. Returns the switched in bits. Only call if
  353. // |switch_bits_callback_for_testing_| is installed.
  354. uint64_t SwitchBitsForTesting();
  355. // Atomically sets persitent flag |flag|. Cannot fail.
  356. void SetPersistentFlag(Flag flag);
  357. // Atomically clears persitent flag |flag|. Cannot fail.
  358. void ClearPersistentFlag(Flag flag);
  359. // Converts bits to TimeTicks with some sanity checks. Use to return the
  360. // deadline outside of this class.
  361. static TimeTicks DeadlineFromBits(uint64_t bits);
  362. // Returns the largest representable deadline.
  363. static TimeTicks Max();
  364. // Extract the flag bits from |bits|.
  365. static uint64_t ExtractFlags(uint64_t bits);
  366. // Extract the deadline bits from |bits|.
  367. static uint64_t ExtractDeadline(uint64_t bits);
  368. // BitsType is uint64_t. This type is chosen for having
  369. // std::atomic<BitsType>{}.is_lock_free() true on many platforms and having no
  370. // undefined behaviors with regards to bit shift operations. Throughout this
  371. // class this is the only type that is used to store, retrieve and manipulate
  372. // the bits. When returning a TimeTicks value outside this class it's
  373. // necessary to run the proper checks to insure correctness of the conversion
  374. // that has to go through int_64t. (See DeadlineFromBits()).
  375. using BitsType = uint64_t;
  376. static_assert(std::is_same<std::underlying_type<Flag>::type, BitsType>::value,
  377. "Flag should have the same underlying type as bits_ to "
  378. "simplify thinking about bit operations");
  379. // Holds the bits of both the flags and the TimeTicks deadline.
  380. // TimeTicks values represent a count of microseconds since boot which may or
  381. // may not include suspend time depending on the platform. Using the seven
  382. // highest order bits and the sign bit to store flags still enables the
  383. // storing of TimeTicks values that can represent up to ~1142 years of uptime
  384. // in the remaining bits. Should never be directly accessed from outside the
  385. // class. Starts out at Max() to provide a base-line deadline that will not be
  386. // reached during normal execution.
  387. //
  388. // Binary format: 0xFFDDDDDDDDDDDDDDDD
  389. // F = Flags
  390. // D = Deadline
  391. std::atomic<BitsType> bits_{static_cast<uint64_t>(Max().ToInternalValue())};
  392. RepeatingCallback<uint64_t(void)> switch_bits_callback_for_testing_;
  393. THREAD_CHECKER(thread_checker_);
  394. FRIEND_TEST_ALL_PREFIXES(HangWatchDeadlineTest, BitsPreservedThroughExtract);
  395. };
  396. // Contains the information necessary for hang watching a specific
  397. // thread. Instances of this class are accessed concurrently by the associated
  398. // thread and the HangWatcher. The HangWatcher owns instances of this
  399. // class and outside of it they are accessed through
  400. // GetHangWatchStateForCurrentThread().
  401. class BASE_EXPORT HangWatchState {
  402. public:
  403. HangWatchState();
  404. ~HangWatchState();
  405. HangWatchState(const HangWatchState&) = delete;
  406. HangWatchState& operator=(const HangWatchState&) = delete;
  407. // Allocates a new state object bound to the calling thread and returns an
  408. // owning pointer to it.
  409. static std::unique_ptr<HangWatchState> CreateHangWatchStateForCurrentThread();
  410. // Retrieves the hang watch state associated with the calling thread.
  411. // Returns nullptr if no HangWatchState exists for the current thread (see
  412. // CreateHangWatchStateForCurrentThread()).
  413. static ThreadLocalPointer<HangWatchState>*
  414. GetHangWatchStateForCurrentThread();
  415. // Returns the current deadline. Use this function if you need to
  416. // store the value. To test if the deadline has expired use IsOverDeadline().
  417. // WARNING: The deadline and flags can change concurrently. If you need to
  418. // inspect both you need to use GetFlagsAndDeadline() to get a coherent
  419. // race-free view of the state.
  420. TimeTicks GetDeadline() const;
  421. // Returns a mask containing the hang watching flags and the value as a pair.
  422. // Use to inspect the flags and deadline and optionally call
  423. // SetShouldBlockOnHang(flags, deadline).
  424. std::pair<uint64_t, TimeTicks> GetFlagsAndDeadline() const;
  425. // Sets the deadline to a new value.
  426. void SetDeadline(TimeTicks deadline);
  427. // Mark this thread as ignored for hang watching. This means existing hang
  428. // watch will not trigger hangs.
  429. void SetIgnoreCurrentHangWatchScopeEnabled();
  430. // Reactivate hang watching on this thread. Should be called when all
  431. // HangWatchScopeEnabled instances that were ignored have completed.
  432. void UnsetIgnoreCurrentHangWatchScopeEnabled();
  433. // Mark hang watching as disabled on this thread. This means new
  434. // HangWatchScopeEnabled instances will not trigger hangs.
  435. void SetHasActiveHangWatchScopeDisabled();
  436. // Reactivate hang watching on this thread. New HangWatchScopeEnabled
  437. // instances will trigger hangs.
  438. void UnsetHasActiveHangWatchScopeDisabled();
  439. // Mark the current state as having to block in its destruction until hang
  440. // capture completes.
  441. bool SetShouldBlockOnHang(uint64_t old_flags, TimeTicks old_deadline);
  442. // Returns true if |flag| is set and false if not. WARNING: The deadline and
  443. // flags can change concurrently. If you need to inspect both you need to use
  444. // GetFlagsAndDeadline() to get a coherent race-free view of the state.
  445. bool IsFlagSet(HangWatchDeadline::Flag flag);
  446. // Tests whether the associated thread's execution has gone over the deadline.
  447. bool IsOverDeadline() const;
  448. #if DCHECK_IS_ON()
  449. // Saves the supplied HangWatchScopeEnabled as the currently active
  450. // HangWatchScopeEnabled.
  451. void SetCurrentHangWatchScopeEnabled(HangWatchScopeEnabled* scope);
  452. // Retrieve the currently active scope.
  453. HangWatchScopeEnabled* GetCurrentHangWatchScopeEnabled();
  454. #endif
  455. PlatformThreadId GetThreadID() const;
  456. // Retrieve the current hang watch deadline directly. For testing only.
  457. HangWatchDeadline* GetHangWatchDeadlineForTesting();
  458. // Returns the current nesting level.
  459. int nesting_level() { return nesting_level_; }
  460. // Increase the nesting level by 1;
  461. void IncrementNestingLevel();
  462. // Reduce the nesting level by 1;
  463. void DecrementNestingLevel();
  464. private:
  465. // The thread that creates the instance should be the class that updates
  466. // the deadline.
  467. THREAD_CHECKER(thread_checker_);
  468. // If the deadline fails to be updated before TimeTicks::Now() ever
  469. // reaches the value contained in it this constistutes a hang.
  470. HangWatchDeadline deadline_;
  471. const PlatformThreadId thread_id_;
  472. // Number of active HangWatchScopeEnables on this thread.
  473. int nesting_level_ = 0;
  474. #if DCHECK_IS_ON()
  475. // Used to keep track of the current HangWatchScopeEnabled and detect improper
  476. // usage. Scopes should always be destructed in reverse order from the one
  477. // they were constructed in. Example of improper use:
  478. //
  479. // {
  480. // std::unique_ptr<Scope> scope = std::make_unique<Scope>(...);
  481. // Scope other_scope;
  482. // |scope| gets deallocated first, violating reverse destruction order.
  483. // scope.reset();
  484. // }
  485. HangWatchScopeEnabled* current_hang_watch_scope_enable_{nullptr};
  486. #endif
  487. };
  488. } // namespace internal
  489. } // namespace base
  490. #endif // BASE_THREADING_HANG_WATCHER_H_