Home | History | Annotate | Download | only in trace_event
      1 // Copyright 2017 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 BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H
      6 #define BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H
      7 
      8 #include <memory>
      9 
     10 #include "base/base_export.h"
     11 #include "base/gtest_prod_util.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/timer/timer.h"
     14 #include "base/trace_event/memory_dump_request_args.h"
     15 
     16 namespace base {
     17 class SingleThreadTaskRunner;
     18 
     19 namespace trace_event {
     20 
     21 class MemoryDumpManager;
     22 
     23 // Schedules global dump requests based on the triggers added. The methods of
     24 // this class are NOT thread safe and the client has to take care of invoking
     25 // all the methods of the class safely.
     26 class BASE_EXPORT MemoryDumpScheduler {
     27  public:
     28   static MemoryDumpScheduler* GetInstance();
     29 
     30   // Initializes the scheduler. NOT thread safe.
     31   void Setup(MemoryDumpManager* mdm_,
     32              scoped_refptr<SingleThreadTaskRunner> polling_task_runner);
     33 
     34   // Adds triggers for scheduling global dumps. Both periodic and peak triggers
     35   // cannot be added together. At the moment the periodic support is limited to
     36   // at most one periodic trigger per dump mode and peak triggers are limited to
     37   // at most one. All intervals should be an integeral multiple of the smallest
     38   // interval specified. NOT thread safe.
     39   void AddTrigger(MemoryDumpType trigger_type,
     40                   MemoryDumpLevelOfDetail level_of_detail,
     41                   uint32_t min_time_between_dumps_ms);
     42 
     43   // Starts periodic dumps. NOT thread safe and triggers must be added before
     44   // enabling.
     45   void EnablePeriodicTriggerIfNeeded();
     46 
     47   // Starts polling memory total. NOT thread safe and triggers must be added
     48   // before enabling.
     49   void EnablePollingIfNeeded();
     50 
     51   // Resets time for triggering dump to account for minimum time between the
     52   // dumps. NOT thread safe.
     53   void NotifyDumpTriggered();
     54 
     55   // Disables all triggers. NOT thread safe. This should be called before
     56   // polling thread is stopped to stop polling cleanly.
     57   void DisableAllTriggers();
     58 
     59  private:
     60   friend class MemoryDumpManagerTest;
     61   friend class MemoryDumpSchedulerPollingTest;
     62   FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest, TestPollingOnDumpThread);
     63   FRIEND_TEST_ALL_PREFIXES(MemoryDumpSchedulerPollingTest, NotifyDumpTriggered);
     64 
     65   // Helper class to schdule periodic memory dumps.
     66   struct BASE_EXPORT PeriodicTriggerState {
     67     PeriodicTriggerState();
     68     ~PeriodicTriggerState();
     69 
     70     bool is_configured;
     71 
     72     RepeatingTimer timer;
     73     uint32_t dump_count;
     74     uint32_t min_timer_period_ms;
     75     uint32_t light_dumps_rate;
     76     uint32_t heavy_dumps_rate;
     77 
     78     uint32_t light_dump_period_ms;
     79     uint32_t heavy_dump_period_ms;
     80 
     81     DISALLOW_COPY_AND_ASSIGN(PeriodicTriggerState);
     82   };
     83 
     84   struct BASE_EXPORT PollingTriggerState {
     85     enum State {
     86       CONFIGURED,  // Polling trigger was added.
     87       ENABLED,     // Polling is running.
     88       DISABLED     // Polling is disabled.
     89     };
     90 
     91     static const uint32_t kMaxNumMemorySamples = 50;
     92 
     93     PollingTriggerState();
     94     ~PollingTriggerState();
     95 
     96     // Helper to clear the tracked memory totals and poll count from last dump.
     97     void ResetTotals();
     98 
     99     State current_state;
    100     MemoryDumpLevelOfDetail level_of_detail;
    101 
    102     uint32_t polling_interval_ms;
    103 
    104     // Minimum numer of polls after the last dump at which next dump can be
    105     // triggered.
    106     int min_polls_between_dumps;
    107     int num_polls_from_last_dump;
    108 
    109     uint64_t last_dump_memory_total;
    110     int64_t memory_increase_threshold;
    111     uint64_t last_memory_totals_kb[kMaxNumMemorySamples];
    112     uint32_t last_memory_totals_kb_index;
    113 
    114     DISALLOW_COPY_AND_ASSIGN(PollingTriggerState);
    115   };
    116 
    117   MemoryDumpScheduler();
    118   ~MemoryDumpScheduler();
    119 
    120   // Helper to set polling disabled.
    121   void DisablePollingOnPollingThread();
    122 
    123   // Periodically called by the timer.
    124   void RequestPeriodicGlobalDump();
    125 
    126   // Called for polling memory usage and trigger dumps if peak is detected.
    127   void PollMemoryOnPollingThread();
    128 
    129   // Returns true if peak memory value is detected.
    130   bool ShouldTriggerDump(uint64_t current_memory_total);
    131 
    132   // Helper to detect peaks in memory usage.
    133   bool IsCurrentSamplePeak(uint64_t current_memory_total);
    134 
    135   // Must be set before enabling tracing.
    136   static void SetPollingIntervalForTesting(uint32_t interval);
    137 
    138   // True if periodic dumping is enabled.
    139   bool IsPeriodicTimerRunningForTesting();
    140 
    141   MemoryDumpManager* mdm_;
    142 
    143   // Accessed on the thread of the client before enabling and only accessed on
    144   // the thread that called "EnablePeriodicTriggersIfNeeded()" after enabling.
    145   std::unique_ptr<PeriodicTriggerState> periodic_state_;
    146 
    147   // Accessed on the thread of the client before enabling and only accessed on
    148   // the polling thread after enabling.
    149   std::unique_ptr<PollingTriggerState> polling_state_;
    150 
    151   // Accessed on the thread of the client only.
    152   scoped_refptr<SingleThreadTaskRunner> polling_task_runner_;
    153 
    154   // True when the scheduler is setup. Accessed on the thread of client only.
    155   bool is_setup_;
    156 
    157   DISALLOW_COPY_AND_ASSIGN(MemoryDumpScheduler);
    158 };
    159 
    160 }  // namespace trace_event
    161 }  // namespace base
    162 
    163 #endif  // BASE_TRACE_EVENT_MEMORY_DUMP_SCHEDULER_H
    164