Home | History | Annotate | Download | only in gpu
      1 // Copyright (c) 2012 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 
      5 #ifndef CONTENT_GPU_GPU_WATCHDOG_THREAD_H_
      6 #define CONTENT_GPU_GPU_WATCHDOG_THREAD_H_
      7 
      8 #include "base/memory/ref_counted.h"
      9 #include "base/memory/weak_ptr.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/power_monitor/power_observer.h"
     12 #include "base/threading/thread.h"
     13 #include "base/time/time.h"
     14 #include "content/common/gpu/gpu_watchdog.h"
     15 
     16 namespace content {
     17 
     18 // A thread that intermitently sends tasks to a group of watched message loops
     19 // and deliberately crashes if one of them does not respond after a timeout.
     20 class GpuWatchdogThread : public base::Thread,
     21                           public GpuWatchdog,
     22                           public base::PowerObserver,
     23                           public base::RefCountedThreadSafe<GpuWatchdogThread> {
     24  public:
     25   explicit GpuWatchdogThread(int timeout);
     26 
     27   // Accessible on watched thread but only modified by watchdog thread.
     28   bool armed() const { return armed_; }
     29   void PostAcknowledge();
     30 
     31   // Implement GpuWatchdog.
     32   virtual void CheckArmed() OVERRIDE;
     33 
     34   // Must be called after a PowerMonitor has been created. Can be called from
     35   // any thread.
     36   void AddPowerObserver();
     37 
     38  protected:
     39   virtual void Init() OVERRIDE;
     40   virtual void CleanUp() OVERRIDE;
     41 
     42  private:
     43   friend class base::RefCountedThreadSafe<GpuWatchdogThread>;
     44 
     45   // An object of this type intercepts the reception and completion of all tasks
     46   // on the watched thread and checks whether the watchdog is armed.
     47   class GpuWatchdogTaskObserver : public base::MessageLoop::TaskObserver {
     48    public:
     49     explicit GpuWatchdogTaskObserver(GpuWatchdogThread* watchdog);
     50     virtual ~GpuWatchdogTaskObserver();
     51 
     52     // Implements MessageLoop::TaskObserver.
     53     virtual void WillProcessTask(
     54         const base::PendingTask& pending_task) OVERRIDE;
     55     virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE;
     56 
     57    private:
     58     GpuWatchdogThread* watchdog_;
     59   };
     60 
     61   virtual ~GpuWatchdogThread();
     62 
     63   void OnAcknowledge();
     64   void OnCheck(bool after_suspend);
     65   void DeliberatelyTerminateToRecoverFromHang();
     66 
     67   void OnAddPowerObserver();
     68 
     69   // Implement PowerObserver.
     70   virtual void OnSuspend() OVERRIDE;
     71   virtual void OnResume() OVERRIDE;
     72 
     73 #if defined(OS_WIN)
     74   base::TimeDelta GetWatchedThreadTime();
     75 #endif
     76 
     77   base::MessageLoop* watched_message_loop_;
     78   base::TimeDelta timeout_;
     79   volatile bool armed_;
     80   GpuWatchdogTaskObserver task_observer_;
     81 
     82 #if defined(OS_WIN)
     83   void* watched_thread_handle_;
     84   base::TimeDelta arm_cpu_time_;
     85 #endif
     86 
     87   // Time after which it's assumed that the computer has been suspended since
     88   // the task was posted.
     89   base::Time suspension_timeout_;
     90 
     91   bool suspended_;
     92 
     93 #if defined(OS_CHROMEOS)
     94   FILE* tty_file_;
     95 #endif
     96 
     97   base::WeakPtrFactory<GpuWatchdogThread> weak_factory_;
     98 
     99   DISALLOW_COPY_AND_ASSIGN(GpuWatchdogThread);
    100 };
    101 
    102 }  // namespace content
    103 
    104 #endif  // CONTENT_GPU_GPU_WATCHDOG_THREAD_H_
    105