• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_THREADING_HANG_WATCHER_H_
6 #define BASE_THREADING_HANG_WATCHER_H_
7 
8 #include <atomic>
9 #include <cstdint>
10 #include <memory>
11 #include <type_traits>
12 #include <vector>
13 
14 #include "base/atomicops.h"
15 #include "base/auto_reset.h"
16 #include "base/base_export.h"
17 #include "base/bits.h"
18 #include "base/compiler_specific.h"
19 #include "base/dcheck_is_on.h"
20 #include "base/debug/crash_logging.h"
21 #include "base/functional/callback.h"
22 #include "base/functional/callback_forward.h"
23 #include "base/functional/callback_helpers.h"
24 #include "base/gtest_prod_util.h"
25 #include "base/memory/memory_pressure_listener.h"
26 #include "base/memory/raw_ptr.h"
27 #include "base/synchronization/lock.h"
28 #include "base/synchronization/waitable_event.h"
29 #include "base/thread_annotations.h"
30 #include "base/threading/platform_thread.h"
31 #include "base/threading/simple_thread.h"
32 #include "base/threading/thread_checker.h"
33 #include "base/time/tick_clock.h"
34 #include "base/time/time.h"
35 #include "build/build_config.h"
36 
37 namespace base {
38 class WatchHangsInScope;
39 namespace internal {
40 class HangWatchState;
41 }  // namespace internal
42 }  // namespace base
43 
44 namespace base {
45 
46 // Instantiate a WatchHangsInScope in a code scope to register to be
47 // watched for hangs of more than |timeout| by the HangWatcher.
48 //
49 // Example usage:
50 //
51 //  void FooBar(){
52 //    WatchHangsInScope scope(base::Seconds(5));
53 //    DoWork();
54 //  }
55 //
56 // If DoWork() takes more than 5s to run and the HangWatcher
57 // inspects the thread state before Foobar returns a hang will be
58 // reported.
59 //
60 // WatchHangsInScopes are typically meant to live on the stack. In some
61 // cases it's necessary to keep a WatchHangsInScope instance as a class
62 // member but special care is required when doing so as a WatchHangsInScope
63 // that stays alive longer than intended will generate non-actionable hang
64 // reports.
65 class BASE_EXPORT [[maybe_unused, nodiscard]] WatchHangsInScope {
66  public:
67   // A good default value needs to be large enough to represent a significant
68   // hang and avoid noise while being small enough to not exclude too many
69   // hangs. The nature of the work that gets executed on the thread is also
70   // important. We can be much stricter when monitoring a UI thread compared to
71   // a ThreadPool thread for example.
72   static constexpr base::TimeDelta kDefaultHangWatchTime = base::Seconds(10);
73 
74   // Constructing/destructing thread must be the same thread.
75   explicit WatchHangsInScope(TimeDelta timeout = kDefaultHangWatchTime);
76   ~WatchHangsInScope();
77 
78   WatchHangsInScope(const WatchHangsInScope&) = delete;
79   WatchHangsInScope& operator=(const WatchHangsInScope&) = delete;
80 
81  private:
82   // Will be true if the object actually set a deadline and false if not.
83   bool took_effect_ = true;
84 
85   // This object should always be constructed and destructed on the same thread.
86   THREAD_CHECKER(thread_checker_);
87 
88   // The deadline set by the previous WatchHangsInScope created on this
89   // thread. Stored so it can be restored when this WatchHangsInScope is
90   // destroyed.
91   TimeTicks previous_deadline_;
92 
93   // Indicates whether the kIgnoreCurrentWatchHangsInScope flag must be set upon
94   // exiting this WatchHangsInScope if a call to InvalidateActiveExpectations()
95   // previously suspended hang watching.
96   bool set_hangs_ignored_on_exit_ = false;
97 
98 #if DCHECK_IS_ON()
99   // The previous WatchHangsInScope created on this thread.
100   raw_ptr<WatchHangsInScope> previous_watch_hangs_in_scope_;
101 #endif
102 };
103 
104 // Monitors registered threads for hangs by inspecting their associated
105 // HangWatchStates for deadline overruns. This happens at a regular interval on
106 // a separate thread. Only one instance of HangWatcher can exist at a time
107 // within a single process. This instance must outlive all monitored threads.
108 class BASE_EXPORT HangWatcher : public DelegateSimpleThread::Delegate {
109  public:
110   // Describes the type of a process for logging purposes.
111   enum class ProcessType {
112     kUnknownProcess = 0,
113     kBrowserProcess = 1,
114     kGPUProcess = 2,
115     kRendererProcess = 3,
116     kUtilityProcess = 4,
117     kMax = kUtilityProcess
118   };
119 
120   // Describes the type of a thread for logging purposes.
121   enum class ThreadType {
122     kIOThread = 0,
123     kMainThread = 1,
124     kThreadPoolThread = 2,
125     kMax = kThreadPoolThread
126   };
127 
128   // Notes on lifetime:
129   //   1) The first invocation of the constructor will set the global instance
130   //      accessible through GetInstance().
131   //   2) In production HangWatcher is always purposefuly leaked.
132   //   3) If not leaked HangWatcher is always constructed and destructed from
133   //      the same thread.
134   //   4) There can never be more than one instance of HangWatcher at a time.
135   //      The class is not base::Singleton derived because it needs to destroyed
136   //      in tests.
137   HangWatcher();
138 
139   // Clears the global instance for the class.
140   ~HangWatcher() override;
141 
142   HangWatcher(const HangWatcher&) = delete;
143   HangWatcher& operator=(const HangWatcher&) = delete;
144 
145   static void CreateHangWatcherInstance();
146 
147   // Returns a non-owning pointer to the global HangWatcher instance.
148   static HangWatcher* GetInstance();
149 
150   // Initializes HangWatcher. Must be called once on the main thread during
151   // startup while single-threaded.
152   static void InitializeOnMainThread(ProcessType process_type,
153                                      bool emit_crashes);
154 
155   // Returns the values that were set through InitializeOnMainThread() to their
156   // default value. Used for testing since in prod initialization should happen
157   // only once.
158   static void UnitializeOnMainThreadForTesting();
159 
160   // Thread safe functions to verify if hang watching is activated. If called
161   // before InitializeOnMainThread returns the default value which is false.
162   static bool IsEnabled();
163   static bool IsThreadPoolHangWatchingEnabled();
164   static bool IsIOThreadHangWatchingEnabled();
165 
166   // Returns true if crash dump reporting is configured for any thread type.
167   static bool IsCrashReportingEnabled();
168 
169   // Use to avoid capturing hangs for operations known to take unbounded time
170   // like waiting for user input. WatchHangsInScope objects created after this
171   // call will take effect. To resume watching for hangs create a new
172   // WatchHangsInScope after the unbounded operation finishes.
173   //
174   // Example usage:
175   //  {
176   //    WatchHangsInScope scope_1;
177   //    {
178   //      WatchHangsInScope scope_2;
179   //      InvalidateActiveExpectations();
180   //      WaitForUserInput();
181   //    }
182   //
183   //    WatchHangsInScope scope_4;
184   //  }
185   //
186   // WatchHangsInScope scope_5;
187   //
188   // In this example hang watching is disabled for WatchHangsInScopes 1 and 2
189   // since they were both active at the time of the invalidation.
190   // WatchHangsInScopes 4 and 5 are unaffected since they were created after the
191   // end of the WatchHangsInScope that was current at the time of invalidation.
192   //
193   static void InvalidateActiveExpectations();
194 
195   // Marks the current process as "shutting down". This changes the histograms
196   // emitted every interval for all threads.
197   static void SetShuttingDown();
198 
199   // Sets up the calling thread to be monitored for threads. Returns a
200   // ScopedClosureRunner that unregisters the thread. This closure has to be
201   // called from the registered thread before it's joined. Returns a null
202   // closure in the case where there is no HangWatcher instance to register the
203   // thread with.
204   [[nodiscard]] static ScopedClosureRunner RegisterThread(
205       ThreadType thread_type);
206 
207   // Choose a closure to be run at the end of each call to Monitor(). Use only
208   // for testing. Reentering the HangWatcher in the closure must be done with
209   // care. It should only be done through certain testing functions because
210   // deadlocks are possible.
211   void SetAfterMonitorClosureForTesting(base::RepeatingClosure closure);
212 
213   // Choose a closure to be run instead of recording the hang. Used to test
214   // that certain conditions hold true at the time of recording. Use only
215   // for testing. Reentering the HangWatcher in the closure must be done with
216   // care. It should only be done through certain testing functions because
217   // deadlocks are possible.
218   void SetOnHangClosureForTesting(base::RepeatingClosure closure);
219 
220   // Set a monitoring period other than the default. Use only for
221   // testing.
222   void SetMonitoringPeriodForTesting(base::TimeDelta period);
223 
224   // Choose a callback to invoke right after waiting to monitor in Wait(). Use
225   // only for testing.
226   void SetAfterWaitCallbackForTesting(
227       RepeatingCallback<void(TimeTicks)> callback);
228 
229   // Force the monitoring loop to resume and evaluate whether to continue.
230   // This can trigger a call to Monitor() or not depending on why the
231   // HangWatcher thread is sleeping. Use only for testing.
232   void SignalMonitorEventForTesting();
233 
234   // Call to make sure no more monitoring takes place. The
235   // function is thread-safe and can be called at anytime but won't stop
236   // monitoring that is currently taking place. Use only for testing.
237   static void StopMonitoringForTesting();
238 
239   // Replace the clock used when calculating time spent
240   // sleeping. Use only for testing.
241   void SetTickClockForTesting(const base::TickClock* tick_clock);
242 
243   // Use to block until the hang is recorded. Allows the caller to halt
244   // execution so it does not overshoot the hang watch target and result in a
245   // non-actionable stack trace in the crash recorded.
246   void BlockIfCaptureInProgress();
247 
248   // Begin executing the monitoring loop on the HangWatcher thread.
249   void Start();
250 
251   // Returns true if Start() has been called and Stop() has not been called
252   // since.
IsStarted()253   bool IsStarted() const { return thread_started_; }
254 
255   // Returns the value of the crash key with the time since last system power
256   // resume.
257   std::string GetTimeSinceLastSystemPowerResumeCrashKeyValue() const;
258 
259  private:
260   // See comment of ::RegisterThread() for details.
261   [[nodiscard]] ScopedClosureRunner RegisterThreadInternal(
262       ThreadType thread_type) LOCKS_EXCLUDED(watch_state_lock_);
263 
264   // Use to assert that functions are called on the monitoring thread.
265   THREAD_CHECKER(hang_watcher_thread_checker_);
266 
267   // Use to assert that functions are called on the constructing thread.
268   THREAD_CHECKER(constructing_thread_checker_);
269 
270   // Invoked on memory pressure signal.
271   void OnMemoryPressure(
272       base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
273 
274 #if !BUILDFLAG(IS_NACL)
275   // Returns a ScopedCrashKeyString that sets the crash key with the time since
276   // last critical memory pressure signal.
277   [[nodiscard]] debug::ScopedCrashKeyString
278   GetTimeSinceLastCriticalMemoryPressureCrashKey();
279 #endif
280 
281   // Invoke base::debug::DumpWithoutCrashing() insuring that the stack frame
282   // right under it in the trace belongs to HangWatcher for easier attribution.
283   NOINLINE static void RecordHang();
284 
285   using HangWatchStates =
286       std::vector<std::unique_ptr<internal::HangWatchState>>;
287 
288   // Used to save a snapshots of the state of hang watching during capture.
289   // Only the state of hung threads is retained.
290   class BASE_EXPORT WatchStateSnapShot {
291    public:
292     struct WatchStateCopy {
293       base::TimeTicks deadline;
294       base::PlatformThreadId thread_id;
295     };
296 
297     WatchStateSnapShot();
298     WatchStateSnapShot(const WatchStateSnapShot& other);
299     ~WatchStateSnapShot();
300 
301     // Initialize the snapshot from provided data. |snapshot_time| can be
302     // different than now() to be coherent with other operations recently done
303     // on |watch_states|. |hung_watch_state_copies_| can be empty after
304     // initialization for a number of reasons:
305     // 1. If any deadline in |watch_states| is before
306     // |deadline_ignore_threshold|.
307     // 2. If some of the hung threads could not be marked as blocking on
308     // capture.
309     // 3. If none of the hung threads are of a type configured to trigger a
310     // crash dump.
311     //
312     // This function cannot be called more than once without an associated call
313     // to Clear().
314     void Init(const HangWatchStates& watch_states,
315               base::TimeTicks deadline_ignore_threshold,
316               base::TimeDelta monitoring_period);
317 
318     // Reset the snapshot object to be reused. Can only be called after Init().
319     void Clear();
320 
321     // Returns a string that contains the ids of the hung threads separated by a
322     // '|'. The size of the string is capped at debug::CrashKeySize::Size256. If
323     // no threads are hung returns an empty string. Can only be invoked if
324     // IsActionable(). Can only be called after Init().
325     std::string PrepareHungThreadListCrashKey() const;
326 
327     // Return the highest deadline included in this snapshot. Can only be called
328     // if IsActionable(). Can only be called after Init().
329     base::TimeTicks GetHighestDeadline() const;
330 
331     // Returns true if the snapshot can be used to record an actionable hang
332     // report and false if not. Can only be called after Init().
333     bool IsActionable() const;
334 
335    private:
336     bool initialized_ = false;
337     std::vector<WatchStateCopy> hung_watch_state_copies_;
338   };
339 
340   // Return a watch state snapshot taken Now() to be inspected in tests.
341   // NO_THREAD_SAFETY_ANALYSIS is needed because the analyzer can't figure out
342   // that calls to this function done from |on_hang_closure_| are properly
343   // locked.
344   WatchStateSnapShot GrabWatchStateSnapshotForTesting() const
345       NO_THREAD_SAFETY_ANALYSIS;
346 
347   // Inspects the state of all registered threads to check if they are hung and
348   // invokes the appropriate closure if so.
349   void Monitor() LOCKS_EXCLUDED(watch_state_lock_);
350 
351   // Record the hang crash dump and perform the necessary housekeeping before
352   // and after.
353   void DoDumpWithoutCrashing(const WatchStateSnapShot& watch_state_snapshot)
354       EXCLUSIVE_LOCKS_REQUIRED(watch_state_lock_) LOCKS_EXCLUDED(capture_lock_);
355 
356   // Stop all monitoring and join the HangWatcher thread.
357   void Stop();
358 
359   // Wait until it's time to monitor.
360   void Wait();
361 
362   // Run the loop that periodically monitors the registered thread at a
363   // set time interval.
364   void Run() override;
365 
366   base::TimeDelta monitoring_period_;
367 
368   // Use to make the HangWatcher thread wake or sleep to schedule the
369   // appropriate monitoring frequency.
370   WaitableEvent should_monitor_;
371 
372   bool IsWatchListEmpty() LOCKS_EXCLUDED(watch_state_lock_);
373 
374   // Stops hang watching on the calling thread by removing the entry from the
375   // watch list.
376   void UnregisterThread() LOCKS_EXCLUDED(watch_state_lock_);
377 
378   Lock watch_state_lock_;
379 
380   std::vector<std::unique_ptr<internal::HangWatchState>> watch_states_
381       GUARDED_BY(watch_state_lock_);
382 
383   // Snapshot to be reused across hang captures. The point of keeping it
384   // around is reducing allocations during capture.
385   WatchStateSnapShot watch_state_snapshot_
386       GUARDED_BY_CONTEXT(hang_watcher_thread_checker_);
387 
388   base::DelegateSimpleThread thread_;
389   bool thread_started_ = false;
390 
391   RepeatingClosure after_monitor_closure_for_testing_;
392   RepeatingClosure on_hang_closure_for_testing_;
393   RepeatingCallback<void(TimeTicks)> after_wait_callback_;
394 
395   base::Lock capture_lock_ ACQUIRED_AFTER(watch_state_lock_);
396   std::atomic<bool> capture_in_progress_{false};
397 
398   raw_ptr<const base::TickClock> tick_clock_;
399 
400   // Registration to receive memory pressure signals.
401   base::MemoryPressureListener memory_pressure_listener_;
402 
403   // The last time at which a critical memory pressure signal was received, or
404   // null if no signal was ever received. Atomic because it's set and read from
405   // different threads.
406   std::atomic<base::TimeTicks> last_critical_memory_pressure_{
407       base::TimeTicks()};
408 
409   // The time after which all deadlines in |watch_states_| need to be for a hang
410   // to be reported.
411   base::TimeTicks deadline_ignore_threshold_;
412 
413   FRIEND_TEST_ALL_PREFIXES(HangWatcherTest, NestedScopes);
414   FRIEND_TEST_ALL_PREFIXES(HangWatcherSnapshotTest, HungThreadIDs);
415   FRIEND_TEST_ALL_PREFIXES(HangWatcherSnapshotTest, NonActionableReport);
416 };
417 
418 // Classes here are exposed in the header only for testing. They are not
419 // intended to be used outside of base.
420 namespace internal {
421 
422 // Threadsafe class that manages a deadline of type TimeTicks alongside hang
423 // watching specific flags. The flags are stored in the higher bits of the
424 // underlying TimeTicks deadline. This enables setting the flags on thread T1 in
425 // a way that's resilient to concurrent deadline or flag changes from thread T2.
426 // Flags can be queried separately from the deadline and users of this class
427 // should not have to care about them when doing so.
428 class BASE_EXPORT HangWatchDeadline {
429  public:
430   // Masks to set flags by flipping a single bit in the TimeTicks value. There
431   // are two types of flags. Persistent flags remain set through a deadline
432   // change and non-persistent flags are cleared when the deadline changes.
433   enum class Flag : uint64_t {
434     // Minimum value for validation purposes. Not currently used.
435     kMinValue = bits::LeftmostBit<uint64_t>() >> 7,
436     // Persistent because if hang detection is disabled on a thread it should
437     // be re-enabled manually.
438     kIgnoreCurrentWatchHangsInScope = bits::LeftmostBit<uint64_t>() >> 1,
439     // Non-persistent because a new value means a new WatchHangsInScope started
440     // after the beginning of capture. It can't be implicated in the hang so we
441     // don't want it to block.
442     kShouldBlockOnHang = bits::LeftmostBit<uint64_t>() >> 0,
443     kMaxValue = kShouldBlockOnHang
444   };
445 
446   HangWatchDeadline();
447   ~HangWatchDeadline();
448 
449   // HangWatchDeadline should never be copied. To keep a copy of the deadline or
450   // flags use the appropriate accessors.
451   HangWatchDeadline(const HangWatchDeadline&) = delete;
452   HangWatchDeadline& operator=(const HangWatchDeadline&) = delete;
453 
454   // Returns the underlying TimeTicks deadline. WARNING: The deadline and flags
455   // can change concurrently. To inspect both, use GetFlagsAndDeadline() to get
456   // a coherent race-free view of the state.
457   TimeTicks GetDeadline() const;
458 
459   // Returns a mask containing the flags and the deadline as a pair. Use to
460   // inspect the flags and deadline and then optionally call
461   // SetShouldBlockOnHang() .
462   std::pair<uint64_t, TimeTicks> GetFlagsAndDeadline() const;
463 
464   // Returns true if the flag is set and false if not. WARNING: The deadline and
465   // flags can change concurrently. To inspect both, use GetFlagsAndDeadline()
466   // to get a coherent race-free view of the state.
467   bool IsFlagSet(Flag flag) const;
468 
469   // Returns true if a flag is set in |flags| and false if not. Use to inspect
470   // the flags mask returned by GetFlagsAndDeadline(). WARNING: The deadline and
471   // flags can change concurrently. If you need to inspect both you need to use
472   // GetFlagsAndDeadline() to get a coherent race-free view of the state.
473   static bool IsFlagSet(Flag flag, uint64_t flags);
474 
475   // Replace the deadline value. |new_value| needs to be within [0,
476   // Max()]. This function can never fail.
477   void SetDeadline(TimeTicks new_value);
478 
479   // Sets the kShouldBlockOnHang flag and returns true if current flags and
480   // deadline are still equal to |old_flags| and  |old_deadline|. Otherwise does
481   // not set the flag and returns false.
482   bool SetShouldBlockOnHang(uint64_t old_flags, TimeTicks old_deadline);
483 
484   // Sets the kIgnoreCurrentWatchHangsInScope flag.
485   void SetIgnoreCurrentWatchHangsInScope();
486 
487   // Clears the kIgnoreCurrentWatchHangsInScope flag.
488   void UnsetIgnoreCurrentWatchHangsInScope();
489 
490   // Use to simulate the value of |bits_| changing between the calling a
491   // Set* function and the moment of atomically switching the values. The
492   // callback should return a value containing the desired flags and deadline
493   // bits. The flags that are already set will be preserved upon applying. Use
494   // only for testing.
495   void SetSwitchBitsClosureForTesting(
496       RepeatingCallback<uint64_t(void)> closure);
497 
498   // Remove the deadline modification callback for when testing is done. Use
499   // only for testing.
500   void ResetSwitchBitsClosureForTesting();
501 
502  private:
503   using TimeTicksInternalRepresentation =
504       std::invoke_result<decltype(&TimeTicks::ToInternalValue),
505                          TimeTicks>::type;
506   static_assert(std::is_same_v<TimeTicksInternalRepresentation, int64_t>,
507                 "Bit manipulations made by HangWatchDeadline need to be"
508                 "adapted if internal representation of TimeTicks changes.");
509 
510   // Replace the bits with the ones provided through the callback. Preserves the
511   // flags that were already set. Returns the switched in bits. Only call if
512   // |switch_bits_callback_for_testing_| is installed.
513   uint64_t SwitchBitsForTesting();
514 
515   // Atomically sets persitent flag |flag|. Cannot fail.
516   void SetPersistentFlag(Flag flag);
517 
518   // Atomically clears persitent flag |flag|. Cannot fail.
519   void ClearPersistentFlag(Flag flag);
520 
521   // Converts bits to TimeTicks with some sanity checks. Use to return the
522   // deadline outside of this class.
523   static TimeTicks DeadlineFromBits(uint64_t bits);
524 
525   // Returns the largest representable deadline.
526   static TimeTicks Max();
527 
528   // Extract the flag bits from |bits|.
529   static uint64_t ExtractFlags(uint64_t bits);
530 
531   // Extract the deadline bits from |bits|.
532   static uint64_t ExtractDeadline(uint64_t bits);
533 
534   // BitsType is uint64_t. This type is chosen for having
535   // std::atomic<BitsType>{}.is_lock_free() true on many platforms and having no
536   // undefined behaviors with regards to bit shift operations. Throughout this
537   // class this is the only type that is used to store, retrieve and manipulate
538   // the bits. When returning a TimeTicks value outside this class it's
539   // necessary to run the proper checks to insure correctness of the conversion
540   // that has to go through int_64t. (See DeadlineFromBits()).
541   using BitsType = uint64_t;
542   static_assert(std::is_same_v<std::underlying_type<Flag>::type, BitsType>,
543                 "Flag should have the same underlying type as bits_ to "
544                 "simplify thinking about bit operations");
545 
546   // Holds the bits of both the flags and the TimeTicks deadline.
547   // TimeTicks values represent a count of microseconds since boot which may or
548   // may not include suspend time depending on the platform. Using the seven
549   // highest order bits and the sign bit to store flags still enables the
550   // storing of TimeTicks values that can represent up to ~1142 years of uptime
551   // in the remaining bits. Should never be directly accessed from outside the
552   // class. Starts out at Max() to provide a base-line deadline that will not be
553   // reached during normal execution.
554   //
555   // Binary format: 0xFFDDDDDDDDDDDDDDDD
556   // F = Flags
557   // D = Deadline
558   std::atomic<BitsType> bits_{static_cast<uint64_t>(Max().ToInternalValue())};
559 
560   RepeatingCallback<uint64_t(void)> switch_bits_callback_for_testing_;
561 
562   THREAD_CHECKER(thread_checker_);
563 
564   FRIEND_TEST_ALL_PREFIXES(HangWatchDeadlineTest, BitsPreservedThroughExtract);
565 };
566 
567 // Contains the information necessary for hang watching a specific
568 // thread. Instances of this class are accessed concurrently by the associated
569 // thread and the HangWatcher. The HangWatcher owns instances of this
570 // class and outside of it they are accessed through
571 // GetHangWatchStateForCurrentThread().
572 class BASE_EXPORT HangWatchState {
573  public:
574   // |thread_type| is the type of thread the watch state will
575   // be associated with. It's the responsibility of the creating
576   // code to choose the correct type.
577   explicit HangWatchState(HangWatcher::ThreadType thread_type);
578   ~HangWatchState();
579 
580   HangWatchState(const HangWatchState&) = delete;
581   HangWatchState& operator=(const HangWatchState&) = delete;
582 
583   // Allocates a new state object bound to the calling thread and returns an
584   // owning pointer to it.
585   static std::unique_ptr<HangWatchState> CreateHangWatchStateForCurrentThread(
586       HangWatcher::ThreadType thread_type);
587 
588   // Retrieves the hang watch state associated with the calling thread.
589   // Returns nullptr if no HangWatchState exists for the current thread (see
590   // CreateHangWatchStateForCurrentThread()).
591   static HangWatchState* GetHangWatchStateForCurrentThread();
592 
593   // Returns the current deadline. Use this function if you need to
594   // store the value. To test if the deadline has expired use IsOverDeadline().
595   // WARNING: The deadline and flags can change concurrently. If you need to
596   // inspect both you need to use GetFlagsAndDeadline() to get a coherent
597   // race-free view of the state.
598   TimeTicks GetDeadline() const;
599 
600   // Returns a mask containing the hang watching flags and the value as a pair.
601   // Use to inspect the flags and deadline and optionally call
602   // SetShouldBlockOnHang(flags, deadline).
603   std::pair<uint64_t, TimeTicks> GetFlagsAndDeadline() const;
604 
605   // Sets the deadline to a new value.
606   void SetDeadline(TimeTicks deadline);
607 
608   // Mark this thread as ignored for hang watching. This means existing
609   // WatchHangsInScope will not trigger hangs.
610   void SetIgnoreCurrentWatchHangsInScope();
611 
612   // Reactivate hang watching on this thread. Should be called when all
613   // WatchHangsInScope instances that were ignored have completed.
614   void UnsetIgnoreCurrentWatchHangsInScope();
615 
616   // Mark the current state as having to block in its destruction until hang
617   // capture completes.
618   bool SetShouldBlockOnHang(uint64_t old_flags, TimeTicks old_deadline);
619 
620   // Returns true if |flag| is set and false if not. WARNING: The deadline and
621   // flags can change concurrently. If you need to inspect both you need to use
622   // GetFlagsAndDeadline() to get a coherent race-free view of the state.
623   bool IsFlagSet(HangWatchDeadline::Flag flag);
624 
625   // Tests whether the associated thread's execution has gone over the deadline.
626   bool IsOverDeadline() const;
627 
628 #if DCHECK_IS_ON()
629   // Saves the supplied WatchHangsInScope as the currently active
630   // WatchHangsInScope.
631   void SetCurrentWatchHangsInScope(WatchHangsInScope* scope);
632 
633   // Retrieve the currently active scope.
634   WatchHangsInScope* GetCurrentWatchHangsInScope();
635 #endif
636 
637   PlatformThreadId GetThreadID() const;
638 
639   // Retrieve the current hang watch deadline directly. For testing only.
640   HangWatchDeadline* GetHangWatchDeadlineForTesting();
641 
642   // Returns the current nesting level.
nesting_level()643   int nesting_level() { return nesting_level_; }
644 
645   // Increase the nesting level by 1;
646   void IncrementNestingLevel();
647 
648   // Reduce the nesting level by 1;
649   void DecrementNestingLevel();
650 
651   // Returns the type of the thread under watch.
thread_type()652   HangWatcher::ThreadType thread_type() const { return thread_type_; }
653 
654  private:
655   // The thread that creates the instance should be the class that updates
656   // the deadline.
657   THREAD_CHECKER(thread_checker_);
658 
659   const AutoReset<HangWatchState*> resetter_;
660 
661   // If the deadline fails to be updated before TimeTicks::Now() ever
662   // reaches the value contained in it this constistutes a hang.
663   HangWatchDeadline deadline_;
664 
665   // A unique ID of the thread under watch. Used for logging in crash reports
666   // only.
667   PlatformThreadId thread_id_;
668 
669   // Number of active HangWatchScopeEnables on this thread.
670   int nesting_level_ = 0;
671 
672   // The type of the thread under watch.
673   const HangWatcher::ThreadType thread_type_;
674 
675 #if DCHECK_IS_ON()
676   // Used to keep track of the current WatchHangsInScope and detect improper
677   // usage. Scopes should always be destructed in reverse order from the one
678   // they were constructed in. Example of improper use:
679   //
680   // {
681   //   std::unique_ptr<Scope> scope = std::make_unique<Scope>(...);
682   //   Scope other_scope;
683   //   |scope| gets deallocated first, violating reverse destruction order.
684   //   scope.reset();
685   // }
686   raw_ptr<WatchHangsInScope> current_watch_hangs_in_scope_{nullptr};
687 #endif
688 };
689 
690 }  // namespace internal
691 }  // namespace base
692 
693 #endif  // BASE_THREADING_HANG_WATCHER_H_
694