147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2010 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_CPUMONITOR_H_
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_CPUMONITOR_H_
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/basictypes.h"
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/messagehandler.h"
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/scoped_ptr.h"
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/sigslot.h"
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_LINUX)
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stream.h"
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // defined(WEBRTC_LINUX)
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass Thread;
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass SystemInfo;
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct CpuStats {
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuStats()
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      : prev_total_times_(0),
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        prev_cpu_times_(0),
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        prev_load_(0.f),
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        prev_load_time_(0u) {
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint64 prev_total_times_;
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint64 prev_cpu_times_;
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float prev_load_;  // Previous load value.
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 prev_load_time_;  // Time previous load value was taken.
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// CpuSampler samples the process and system load.
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass CpuSampler {
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuSampler();
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ~CpuSampler();
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Initialize CpuSampler.  Returns true if successful.
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool Init();
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Set minimum interval in ms between computing new load values.
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Default 950 ms.  Set to 0 to disable interval.
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void set_load_interval(int min_load_interval);
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Return CPU load of current process as a float from 0 to 1.
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float GetProcessLoad();
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Return CPU load of current process as a float from 0 to 1.
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float GetSystemLoad();
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Return number of cpus. Includes hyperthreads.
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int GetMaxCpus() const;
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Return current number of cpus available to this process.
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int GetCurrentCpus();
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // For testing. Allows forcing of fallback to using NTDLL functions.
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void set_force_fallback(bool fallback) {
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    force_fallback_ = fallback;
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float UpdateCpuLoad(uint64 current_total_times,
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      uint64 current_cpu_times,
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      uint64 *prev_total_times,
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      uint64 *prev_cpu_times);
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuStats process_;
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuStats system_;
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int cpus_;
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int min_load_interval_;  // Minimum time between computing new load.
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<SystemInfo> sysinfo_;
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void* get_system_times_;
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void* nt_query_system_information_;
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool force_fallback_;
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_LINUX)
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // File for reading /proc/stat
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<FileStream> sfile_;
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // defined(WEBRTC_LINUX)
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// CpuMonitor samples and signals the CPU load periodically.
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass CpuMonitor
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : public rtc::MessageHandler, public sigslot::has_slots<> {
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  explicit CpuMonitor(Thread* thread);
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ~CpuMonitor();
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void set_thread(Thread* thread);
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool Start(int period_ms);
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Stop();
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Signal parameters are current cpus, max cpus, process load and system load.
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sigslot::signal4<int, int, float, float> SignalUpdate;
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected:
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Override virtual method of parent MessageHandler.
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void OnMessage(rtc::Message* msg);
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Clear the monitor thread and stop sending it messages if the thread goes
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // away before our lifetime.
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnMessageQueueDestroyed() { monitor_thread_ = NULL; }
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread* monitor_thread_;
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuSampler sampler_;
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int period_ms_;
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DISALLOW_COPY_AND_ASSIGN(CpuMonitor);
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_BASE_CPUMONITOR_H_
124