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#include <iomanip>
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <iostream>
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <vector>
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32.h"
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/cpumonitor.h"
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/flags.h"
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/gunit.h"
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/scoped_ptr.h"
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/thread.h"
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/timeutils.h"
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/timing.h"
26a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.org#include "webrtc/test/testsupport/gtest_disable.h"
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const int kMaxCpus = 1024;
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const int kSettleTime = 100;  // Amount of time to between tests.
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const int kIdleTime = 500;  // Amount of time to be idle in ms.
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const int kBusyTime = 1000;  // Amount of time to be busy in ms.
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const int kLongInterval = 2000;  // Interval longer than busy times
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass BusyThread : public rtc::Thread {
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  BusyThread(double load, double duration, double interval) :
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    load_(load), duration_(duration), interval_(interval) {
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ~BusyThread() {
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Stop();
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Run() {
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Timing time;
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double busy_time = interval_ * load_ / 100.0;
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    for (;;) {
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      time.BusyWait(busy_time);
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      time.IdleWait(interval_ - busy_time);
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (duration_) {
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        duration_ -= interval_;
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (duration_ <= 0) {
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          break;
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  double load_;
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  double duration_;
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  double interval_;
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass CpuLoadListener : public sigslot::has_slots<> {
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuLoadListener()
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      : current_cpus_(0),
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        cpus_(0),
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        process_load_(.0f),
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        system_load_(.0f),
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        count_(0) {
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnCpuLoad(int current_cpus, int cpus, float proc_load, float sys_load) {
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    current_cpus_ = current_cpus;
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    cpus_ = cpus;
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    process_load_ = proc_load;
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    system_load_ = sys_load;
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ++count_;
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int current_cpus() const { return current_cpus_; }
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int cpus() const { return cpus_; }
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float process_load() const { return process_load_; }
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float system_load() const { return system_load_; }
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int count() const { return count_; }
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int current_cpus_;
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int cpus_;
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float process_load_;
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float system_load_;
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int count_;
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Set affinity (which cpu to run on), but respecting FLAG_affinity:
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// -1 means no affinity - run on whatever cpu is available.
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 0 .. N means run on specific cpu.  The tool will create N threads and call
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   SetThreadAffinity on 0 to N - 1 as cpu.  FLAG_affinity sets the first cpu
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   so the range becomes affinity to affinity + N - 1
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Note that this function affects Windows scheduling, effectively giving
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   the thread with affinity for a specified CPU more priority on that CPU.
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SetThreadAffinity(BusyThread* t, int cpu, int affinity) {
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (affinity >= 0) {
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return ::SetThreadAffinityMask(t->GetHandle(),
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        1 << (cpu + affinity)) != FALSE;
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool SetThreadPriority(BusyThread* t, int prio) {
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!prio) {
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return true;
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool ok = t->SetPriority(static_cast<rtc::ThreadPriority>(prio));
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!ok) {
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    std::cout << "Error setting thread priority." << std::endl;
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ok;
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint CpuLoad(double cpuload, double duration, int numthreads,
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            int priority, double interval, int affinity) {
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int ret = 0;
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::vector<BusyThread*> threads;
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < numthreads; ++i) {
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    threads.push_back(new BusyThread(cpuload, duration, interval));
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // NOTE(fbarchard): Priority must be done before Start.
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!SetThreadPriority(threads[i], priority) ||
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org       !threads[i]->Start() ||
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org       !SetThreadAffinity(threads[i], i, affinity)) {
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ret = 1;
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Wait on each thread
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (ret == 0) {
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    for (int i = 0; i < numthreads; ++i) {
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      threads[i]->Stop();
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < numthreads; ++i) {
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete threads[i];
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ret;
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Make 2 CPUs busy
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic void CpuTwoBusyLoop(int busytime) {
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuLoad(100.0, busytime / 1000.0, 2, 1, 0.050, -1);
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Make 1 CPUs busy
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic void CpuBusyLoop(int busytime) {
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuLoad(100.0, busytime / 1000.0, 1, 1, 0.050, -1);
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Make 1 use half CPU time.
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic void CpuHalfBusyLoop(int busytime) {
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuLoad(50.0, busytime / 1000.0, 1, 1, 0.050, -1);
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestCpuSampler(bool test_proc, bool test_sys, bool force_fallback) {
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuSampler sampler;
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.set_force_fallback(force_fallback);
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sampler.Init());
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.set_load_interval(100);
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int cpus = sampler.GetMaxCpus();
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test1: CpuSampler under idle situation.
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::SleepMs(kSettleTime);
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetProcessLoad();
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetSystemLoad();
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::SleepMs(kIdleTime);
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float proc_idle = 0.f, sys_idle = 0.f;
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_proc) {
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    proc_idle = sampler.GetProcessLoad();
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_sys) {
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      sys_idle = sampler.GetSystemLoad();
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_proc) {
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "ProcessLoad Idle:      "
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setiosflags(std::ios_base::fixed)
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setprecision(2) << std::setw(6) << proc_idle;
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_GE(proc_idle, 0.f);
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_LE(proc_idle, static_cast<float>(cpus));
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_sys) {
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "SystemLoad Idle:       "
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setiosflags(std::ios_base::fixed)
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setprecision(2) << std::setw(6) << sys_idle;
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_GE(sys_idle, 0.f);
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_LE(sys_idle, static_cast<float>(cpus));
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test2: CpuSampler with main process at 50% busy.
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::SleepMs(kSettleTime);
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetProcessLoad();
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetSystemLoad();
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuHalfBusyLoop(kBusyTime);
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float proc_halfbusy = 0.f, sys_halfbusy = 0.f;
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_proc) {
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    proc_halfbusy = sampler.GetProcessLoad();
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_sys) {
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    sys_halfbusy = sampler.GetSystemLoad();
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_proc) {
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "ProcessLoad Halfbusy:  "
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setiosflags(std::ios_base::fixed)
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setprecision(2) << std::setw(6) << proc_halfbusy;
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_GE(proc_halfbusy, 0.f);
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_LE(proc_halfbusy, static_cast<float>(cpus));
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_sys) {
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "SystemLoad Halfbusy:   "
22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setiosflags(std::ios_base::fixed)
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setprecision(2) << std::setw(6) << sys_halfbusy;
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_GE(sys_halfbusy, 0.f);
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_LE(sys_halfbusy, static_cast<float>(cpus));
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test3: CpuSampler with main process busy.
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::SleepMs(kSettleTime);
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetProcessLoad();
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetSystemLoad();
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuBusyLoop(kBusyTime);
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float proc_busy = 0.f, sys_busy = 0.f;
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_proc) {
24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    proc_busy = sampler.GetProcessLoad();
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_sys) {
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    sys_busy = sampler.GetSystemLoad();
24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_proc) {
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "ProcessLoad Busy:      "
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setiosflags(std::ios_base::fixed)
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setprecision(2) << std::setw(6) << proc_busy;
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_GE(proc_busy, 0.f);
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_LE(proc_busy, static_cast<float>(cpus));
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_sys) {
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "SystemLoad Busy:       "
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setiosflags(std::ios_base::fixed)
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setprecision(2) << std::setw(6) << sys_busy;
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_GE(sys_busy, 0.f);
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_LE(sys_busy, static_cast<float>(cpus));
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test4: CpuSampler with 2 cpus process busy.
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (cpus >= 2) {
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Thread::SleepMs(kSettleTime);
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    sampler.GetProcessLoad();
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    sampler.GetSystemLoad();
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CpuTwoBusyLoop(kBusyTime);
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    float proc_twobusy = 0.f, sys_twobusy = 0.f;
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (test_proc) {
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proc_twobusy = sampler.GetProcessLoad();
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (test_sys) {
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      sys_twobusy = sampler.GetSystemLoad();
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (test_proc) {
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_INFO) << "ProcessLoad 2 CPU Busy:"
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                   << std::setiosflags(std::ios_base::fixed)
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                   << std::setprecision(2) << std::setw(6) << proc_twobusy;
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      EXPECT_GE(proc_twobusy, 0.f);
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      EXPECT_LE(proc_twobusy, static_cast<float>(cpus));
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (test_sys) {
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_INFO) << "SystemLoad 2 CPU Busy: "
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                   << std::setiosflags(std::ios_base::fixed)
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                   << std::setprecision(2) << std::setw(6) << sys_twobusy;
28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      EXPECT_GE(sys_twobusy, 0.f);
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      EXPECT_LE(sys_twobusy, static_cast<float>(cpus));
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test5: CpuSampler with idle process after being busy.
29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::SleepMs(kSettleTime);
29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetProcessLoad();
29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetSystemLoad();
29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::SleepMs(kIdleTime);
29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_proc) {
29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    proc_idle = sampler.GetProcessLoad();
30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_sys) {
30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    sys_idle = sampler.GetSystemLoad();
30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_proc) {
30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "ProcessLoad Idle:      "
30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setiosflags(std::ios_base::fixed)
30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setprecision(2) << std::setw(6) << proc_idle;
30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_GE(proc_idle, 0.f);
30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_LE(proc_idle, proc_busy);
31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (test_sys) {
31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "SystemLoad Idle:       "
31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setiosflags(std::ios_base::fixed)
31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << std::setprecision(2) << std::setw(6) << sys_idle;
31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_GE(sys_idle, 0.f);
31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_LE(sys_idle, static_cast<float>(cpus));
31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST(CpuMonitorTest, TestCpus) {
32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuSampler sampler;
32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sampler.Init());
32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int current_cpus = sampler.GetCurrentCpus();
32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int cpus = sampler.GetMaxCpus();
32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LOG(LS_INFO) << "Current Cpus:     " << std::setw(9) << current_cpus;
32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LOG(LS_INFO) << "Maximum Cpus:     " << std::setw(9) << cpus;
32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_GT(cpus, 0);
32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_LE(cpus, kMaxCpus);
32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_GT(current_cpus, 0);
33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_LE(current_cpus, cpus);
33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests overall system CpuSampler using legacy OS fallback code if applicable.
33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST(CpuMonitorTest, TestGetSystemLoadForceFallback) {
33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestCpuSampler(false, true, true);
33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests both process and system functions in use at same time.
341a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(CpuMonitorTest, DISABLED_ON_MAC(TestGetBothLoad)) {
34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TestCpuSampler(true, true, false);
34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Tests a query less than the interval produces the same value.
34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST(CpuMonitorTest, TestInterval) {
34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuSampler sampler;
34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sampler.Init());
34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test1: Set interval to large value so sampler will not update.
35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.set_load_interval(kLongInterval);
35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetProcessLoad();
35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sampler.GetSystemLoad();
35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float proc_orig = sampler.GetProcessLoad();
35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float sys_orig = sampler.GetSystemLoad();
35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::SleepMs(kIdleTime);
36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float proc_halftime = sampler.GetProcessLoad();
36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  float sys_halftime = sampler.GetSystemLoad();
36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(proc_orig, proc_halftime);
36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(sys_orig, sys_halftime);
36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST(CpuMonitorTest, TestCpuMonitor) {
36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuMonitor monitor(Thread::Current());
37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CpuLoadListener listener;
37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  monitor.SignalUpdate.connect(&listener, &CpuLoadListener::OnCpuLoad);
37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(monitor.Start(10));
37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // We have checked cpu load more than twice.
37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(listener.count() > 2, 1000);
37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_GT(listener.current_cpus(), 0);
37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_GT(listener.cpus(), 0);
37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_GE(listener.process_load(), .0f);
37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_GE(listener.system_load(), .0f);
37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  monitor.Stop();
38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Wait 20 ms to ake sure all signals are delivered.
38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::Current()->ProcessMessages(20);
38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int old_count = listener.count();
38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::Current()->ProcessMessages(20);
38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Verfy no more siganls.
38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(old_count, listener.count());
38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
390