Reformatted most of the CPU stuff in system_wrappers.

BUG=

Review URL: https://webrtc-codereview.appspot.com/930025

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3142 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
phoglund@webrtc.org 2012-11-21 08:02:57 +00:00
parent 5835adfef0
commit b15d285458
12 changed files with 400 additions and 419 deletions

View File

@ -32,13 +32,15 @@ enum {
};
typedef int (*WebRtc_CPUInfo)(CPUFeature feature);
// returns true if the CPU supports the feature.
// Returns true if the CPU supports the feature.
extern WebRtc_CPUInfo WebRtc_GetCPUInfo;
// No CPU feature is available => straight C path.
extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM;
// Return the features in an ARM device.
// It detects the features in the hardware platform, and returns supported
// It detects the features in the hardware platform, and returns supported
// values in the above enum definition as a bitmask.
extern uint64_t WebRtc_GetCPUFeaturesARM(void);

View File

@ -14,14 +14,16 @@
#include "typedefs.h"
namespace webrtc {
class CpuInfo
{
public:
static WebRtc_UWord32 DetectNumberOfCores();
private:
CpuInfo() {}
static WebRtc_UWord32 _numberOfCores;
class CpuInfo {
public:
static WebRtc_UWord32 DetectNumberOfCores();
private:
CpuInfo() {}
static WebRtc_UWord32 number_of_cores_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_INFO_H_

View File

@ -14,40 +14,42 @@
#include "typedefs.h"
namespace webrtc {
class CpuWrapper
{
public:
static CpuWrapper* CreateCpu();
virtual ~CpuWrapper() {}
// Returns the average CPU usage for all processors. The CPU usage can be
// between and including 0 to 100 (%)
virtual WebRtc_Word32 CpuUsage() = 0;
virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* processName,
WebRtc_UWord32 length) = 0;
virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 dwProcessID) = 0;
class CpuWrapper {
public:
static CpuWrapper* CreateCpu();
virtual ~CpuWrapper() {}
// The CPU usage per core is returned in cpu_usage. The CPU can be between
// and including 0 to 100 (%)
// Note that the pointer passed as cpu_usage is redirected to a local member
// of the CPU wrapper.
// numCores is the number of cores in the cpu_usage array.
// The return value is -1 for failure or 0-100, indicating the average
// CPU usage across all cores.
// Note: on some OSs this class is initialized lazy. This means that it
// might not yet be possible to retrieve any CPU metrics. When this happens
// the return value will be zero (indicating that there is not a failure),
// numCores will be 0 and cpu_usage will be set to NULL (indicating that
// no metrics are available yet). Once the initialization is completed,
// which can take in the order of seconds, CPU metrics can be retrieved.
virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores,
WebRtc_UWord32*& cpu_usage) = 0;
// Returns the average CPU usage for all processors. The CPU usage can be
// between and including 0 to 100 (%)
virtual WebRtc_Word32 CpuUsage() = 0;
virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* process_name,
WebRtc_UWord32 length) = 0;
virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 process_id) = 0;
virtual void Reset() = 0;
virtual void Stop() = 0;
// The CPU usage per core is returned in cpu_usage. The CPU can be between
// and including 0 to 100 (%)
// Note that the pointer passed as cpu_usage is redirected to a local member
// of the CPU wrapper.
// num_cores is the number of cores in the cpu_usage array.
// The return value is -1 for failure or 0-100, indicating the average
// CPU usage across all cores.
// Note: on some OSs this class is initialized lazy. This means that it
// might not yet be possible to retrieve any CPU metrics. When this happens
// the return value will be zero (indicating that there is not a failure),
// num_cores will be 0 and cpu_usage will be set to NULL (indicating that
// no metrics are available yet). Once the initialization is completed,
// which can take in the order of seconds, CPU metrics can be retrieved.
virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& num_cores,
WebRtc_UWord32*& cpu_usage) = 0;
protected:
CpuWrapper() {}
virtual void Reset() = 0;
virtual void Stop() = 0;
protected:
CpuWrapper() {}
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_WRAPPER_H_

View File

@ -8,29 +8,29 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "cpu_wrapper.h"
#include "system_wrappers/interface/cpu_wrapper.h"
#if defined(_WIN32)
#include "cpu_win.h"
#include "cpu_win.h"
#elif defined(WEBRTC_MAC)
#include "cpu_mac.h"
#include "cpu_mac.h"
#elif defined(WEBRTC_ANDROID)
// Not implemented yet, might be possible to use Linux implementation
// Not implemented yet, might be possible to use Linux implementation
#else // defined(WEBRTC_LINUX)
#include "cpu_linux.h"
#include "cpu_linux.h"
#endif
namespace webrtc {
CpuWrapper* CpuWrapper::CreateCpu()
{
CpuWrapper* CpuWrapper::CreateCpu() {
#if defined(_WIN32)
return new CpuWindows();
return new CpuWindows();
#elif defined(WEBRTC_MAC)
return new CpuWrapperMac();
return new CpuWrapperMac();
#elif defined(WEBRTC_ANDROID)
return 0;
return 0;
#else
return new CpuLinux();
return new CpuLinux();
#endif
}
} // namespace webrtc
} // namespace webrtc

View File

@ -10,15 +10,13 @@
// Parts of this file derived from Chromium's base/cpu.cc.
#include "cpu_features_wrapper.h"
#include "system_wrappers/interface/cpu_features_wrapper.h"
#include "typedefs.h"
#if defined(WEBRTC_ARCH_X86_FAMILY)
#if defined(_MSC_VER)
#if defined(WEBRTC_ARCH_X86_FAMILY) && defined(_MSC_VER)
#include <intrin.h>
#endif
#endif
#include "typedefs.h"
// No CPU feature is available => straight C path.
int GetCPUInfoNoASM(CPUFeature feature) {
@ -31,7 +29,7 @@ int GetCPUInfoNoASM(CPUFeature feature) {
// Intrinsic for "cpuid".
#if defined(__pic__) && defined(__i386__)
static inline void __cpuid(int cpu_info[4], int info_type) {
__asm__ volatile (
__asm__ volatile(
"mov %%ebx, %%edi\n"
"cpuid\n"
"xchg %%edi, %%ebx\n"
@ -40,7 +38,7 @@ static inline void __cpuid(int cpu_info[4], int info_type) {
}
#else
static inline void __cpuid(int cpu_info[4], int info_type) {
__asm__ volatile (
__asm__ volatile(
"cpuid\n"
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
: "a"(info_type));

View File

@ -8,13 +8,13 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "cpu_info.h"
#include "system_wrappers/interface/cpu_info.h"
#if defined(_WIN32)
#include <Windows.h>
#elif defined(WEBRTC_MAC)
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#elif defined(WEBRTC_ANDROID)
// Not implemented yet, might be possible to use Linux implementation
#else // defined(WEBRTC_LINUX)
@ -25,46 +25,42 @@
namespace webrtc {
WebRtc_UWord32 CpuInfo::_numberOfCores = 0;
WebRtc_UWord32 CpuInfo::number_of_cores_ = 0;
WebRtc_UWord32 CpuInfo::DetectNumberOfCores()
{
if (!_numberOfCores)
{
WebRtc_UWord32 CpuInfo::DetectNumberOfCores() {
if (!number_of_cores_) {
#if defined(_WIN32)
SYSTEM_INFO si;
GetSystemInfo(&si);
_numberOfCores = static_cast<WebRtc_UWord32>(si.dwNumberOfProcessors);
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
"Available number of cores:%d", _numberOfCores);
SYSTEM_INFO si;
GetSystemInfo(&si);
number_of_cores_ = static_cast<WebRtc_UWord32>(si.dwNumberOfProcessors);
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
"Available number of cores:%d", number_of_cores_);
#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
_numberOfCores = get_nprocs();
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
"Available number of cores:%d", _numberOfCores);
number_of_cores_ = get_nprocs();
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
"Available number of cores:%d", number_of_cores_);
#elif defined(WEBRTC_MAC)
int name[] = {CTL_HW, HW_AVAILCPU};
int ncpu;
size_t size = sizeof(ncpu);
if(0 == sysctl(name, 2, &ncpu, &size, NULL, 0))
{
_numberOfCores = static_cast<WebRtc_UWord32>(ncpu);
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
"Available number of cores:%d", _numberOfCores);
} else
{
WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
"Failed to get number of cores");
_numberOfCores = 1;
int name[] = {CTL_HW, HW_AVAILCPU};
int ncpu;
size_t size = sizeof(ncpu);
if (0 == sysctl(name, 2, &ncpu, &size, NULL, 0)) {
number_of_cores_ = static_cast<WebRtc_UWord32>(ncpu);
WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
"Available number of cores:%d", number_of_cores_);
} else {
WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
"Failed to get number of cores");
number_of_cores_ = 1;
}
#else
WEBRTC_TRACE(kTraceWarning, kTraceUtility, -1,
"No function to get number of cores");
_numberOfCores = 1;
WEBRTC_TRACE(kTraceWarning, kTraceUtility, -1,
"No function to get number of cores");
number_of_cores_ = 1;
#endif
}
return _numberOfCores;
}
return number_of_cores_;
}
} // namespace webrtc

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "cpu_linux.h"
#include "system_wrappers/source/cpu_linux.h"
#include <stdio.h>
#include <stdlib.h>
@ -16,187 +16,169 @@
#include <unistd.h>
namespace webrtc {
CpuLinux::CpuLinux()
: m_oldBusyTime(0),
m_oldIdleTime(0),
m_oldBusyTimeMulti(NULL),
m_oldIdleTimeMulti(NULL),
m_idleArray(NULL),
m_busyArray(NULL),
m_resultArray(NULL),
m_numCores(0) {
const int result = GetNumCores();
if (result != -1) {
m_numCores = result;
m_oldBusyTimeMulti = new long long[m_numCores];
memset(m_oldBusyTimeMulti, 0, sizeof(long long) * m_numCores);
m_oldIdleTimeMulti = new long long[m_numCores];
memset(m_oldIdleTimeMulti, 0, sizeof(long long) * m_numCores);
m_idleArray = new long long[m_numCores];
memset(m_idleArray, 0, sizeof(long long) * m_numCores);
m_busyArray = new long long[m_numCores];
memset(m_busyArray, 0, sizeof(long long) * m_numCores);
m_resultArray = new WebRtc_UWord32[m_numCores];
: old_busy_time_(0),
old_idle_time_(0),
old_busy_time_multi_(NULL),
old_idle_time_multi_(NULL),
idle_array_(NULL),
busy_array_(NULL),
result_array_(NULL),
num_cores_(0) {
const int result = GetNumCores();
if (result != -1) {
num_cores_ = result;
old_busy_time_multi_ = new long long[num_cores_];
memset(old_busy_time_multi_, 0, sizeof(long long) * num_cores_);
old_idle_time_multi_ = new long long[num_cores_];
memset(old_idle_time_multi_, 0, sizeof(long long) * num_cores_);
idle_array_ = new long long[num_cores_];
memset(idle_array_, 0, sizeof(long long) * num_cores_);
busy_array_ = new long long[num_cores_];
memset(busy_array_, 0, sizeof(long long) * num_cores_);
result_array_ = new WebRtc_UWord32[num_cores_];
GetData(m_oldBusyTime, m_oldIdleTime, m_busyArray, m_idleArray);
}
GetData(old_busy_time_, old_idle_time_, busy_array_, idle_array_);
}
}
CpuLinux::~CpuLinux()
{
delete [] m_oldBusyTimeMulti;
delete [] m_oldIdleTimeMulti;
delete [] m_idleArray;
delete [] m_busyArray;
delete [] m_resultArray;
CpuLinux::~CpuLinux() {
delete [] old_busy_time_multi_;
delete [] old_idle_time_multi_;
delete [] idle_array_;
delete [] busy_array_;
delete [] result_array_;
}
WebRtc_Word32 CpuLinux::CpuUsage()
{
WebRtc_UWord32 dummy = 0;
WebRtc_UWord32* dummyArray = NULL;
return CpuUsageMultiCore(dummy, dummyArray);
WebRtc_Word32 CpuLinux::CpuUsage() {
WebRtc_UWord32 dummy = 0;
WebRtc_UWord32* dummy_array = NULL;
return CpuUsageMultiCore(dummy, dummy_array);
}
WebRtc_Word32 CpuLinux::CpuUsageMultiCore(WebRtc_UWord32& numCores,
WebRtc_UWord32*& coreArray)
{
coreArray = m_resultArray;
numCores = m_numCores;
long long busy = 0;
long long idle = 0;
if (GetData(busy, idle, m_busyArray, m_idleArray) != 0)
return -1;
WebRtc_Word32 CpuLinux::CpuUsageMultiCore(WebRtc_UWord32& num_cores,
WebRtc_UWord32*& core_array) {
core_array = result_array_;
num_cores = num_cores_;
long long busy = 0;
long long idle = 0;
if (GetData(busy, idle, busy_array_, idle_array_) != 0)
return -1;
long long deltaBusy = busy - m_oldBusyTime;
long long deltaIdle = idle - m_oldIdleTime;
m_oldBusyTime = busy;
m_oldIdleTime = idle;
long long delta_busy = busy - old_busy_time_;
long long delta_idle = idle - old_idle_time_;
old_busy_time_ = busy;
old_idle_time_ = idle;
int retVal = -1;
if (deltaBusy + deltaIdle == 0)
{
retVal = 0;
}
else
{
retVal = (int)(100 * (deltaBusy) / (deltaBusy + deltaIdle));
}
int ret_val = -1;
if (delta_busy + delta_idle == 0) {
ret_val = 0;
} else {
ret_val = (int)(100 * (delta_busy) / (delta_busy + delta_idle));
}
if (coreArray == NULL)
{
return retVal;
}
if (core_array == NULL) {
return ret_val;
}
for (WebRtc_UWord32 i = 0; i < m_numCores; i++)
{
deltaBusy = m_busyArray[i] - m_oldBusyTimeMulti[i];
deltaIdle = m_idleArray[i] - m_oldIdleTimeMulti[i];
m_oldBusyTimeMulti[i] = m_busyArray[i];
m_oldIdleTimeMulti[i] = m_idleArray[i];
if(deltaBusy + deltaIdle == 0)
{
coreArray[i] = 0;
}
else
{
coreArray[i] = (int)(100 * (deltaBusy) / (deltaBusy+deltaIdle));
}
for (WebRtc_UWord32 i = 0; i < num_cores_; ++i) {
delta_busy = busy_array_[i] - old_busy_time_multi_[i];
delta_idle = idle_array_[i] - old_idle_time_multi_[i];
old_busy_time_multi_[i] = busy_array_[i];
old_idle_time_multi_[i] = idle_array_[i];
if (delta_busy + delta_idle == 0) {
core_array[i] = 0;
} else {
core_array[i] = (int)(100 * (delta_busy) / (delta_busy + delta_idle));
}
return retVal;
}
return ret_val;
}
int CpuLinux::GetData(long long& busy, long long& idle, long long*& busy_array,
long long*& idle_array) {
FILE* fp = fopen("/proc/stat", "r");
if (!fp) {
return -1;
}
int CpuLinux::GetData(long long& busy, long long& idle, long long*& busyArray,
long long*& idleArray)
{
FILE* fp = fopen("/proc/stat", "r");
if (!fp)
{
return -1;
}
char line[100];
if (fgets(line, 100, fp) == NULL) {
fclose(fp);
return -1;
}
char first_word[100];
if (sscanf(line, "%s ", first_word) != 1) {
fclose(fp);
return -1;
}
if (strncmp(first_word, "cpu", 3) != 0) {
fclose(fp);
return -1;
}
char s_user[100];
char s_nice[100];
char s_system[100];
char s_idle[100];
if (sscanf(line, "%s %s %s %s %s ",
first_word, s_user, s_nice, s_system, s_idle) != 5) {
fclose(fp);
return -1;
}
long long luser = atoll(s_user);
long long lnice = atoll(s_nice);
long long lsystem = atoll(s_system);
long long lidle = atoll(s_idle);
char line[100];
busy = luser + lnice + lsystem;
idle = lidle;
for (WebRtc_UWord32 i = 0; i < num_cores_; ++i) {
if (fgets(line, 100, fp) == NULL) {
fclose(fp);
return -1;
fclose(fp);
return -1;
}
char firstWord[100];
if (sscanf(line, "%s ", firstWord) != 1) {
fclose(fp);
return -1;
if (sscanf(line, "%s %s %s %s %s ", first_word, s_user, s_nice, s_system,
s_idle) != 5) {
fclose(fp);
return -1;
}
if (strncmp(firstWord, "cpu", 3) != 0) {
fclose(fp);
return -1;
}
char sUser[100];
char sNice[100];
char sSystem[100];
char sIdle[100];
if (sscanf(line, "%s %s %s %s %s ",
firstWord, sUser, sNice, sSystem, sIdle) != 5) {
fclose(fp);
return -1;
}
long long luser = atoll(sUser);
long long lnice = atoll(sNice);
long long lsystem = atoll(sSystem);
long long lidle = atoll (sIdle);
busy = luser + lnice + lsystem;
idle = lidle;
for (WebRtc_UWord32 i = 0; i < m_numCores; i++)
{
if (fgets(line, 100, fp) == NULL) {
fclose(fp);
return -1;
}
if (sscanf(line, "%s %s %s %s %s ", firstWord, sUser, sNice, sSystem,
sIdle) != 5) {
fclose(fp);
return -1;
}
luser = atoll(sUser);
lnice = atoll(sNice);
lsystem = atoll(sSystem);
lidle = atoll (sIdle);
busyArray[i] = luser + lnice + lsystem;
idleArray[i] = lidle;
}
fclose(fp);
return 0;
luser = atoll(s_user);
lnice = atoll(s_nice);
lsystem = atoll(s_system);
lidle = atoll(s_idle);
busy_array[i] = luser + lnice + lsystem;
idle_array[i] = lidle;
}
fclose(fp);
return 0;
}
int CpuLinux::GetNumCores()
{
FILE* fp = fopen("/proc/stat", "r");
if (!fp)
{
return -1;
}
// Skip first line
char line[100];
if (!fgets(line, 100, fp))
{
fclose(fp);
return -1;
}
int numCores = -1;
char firstWord[100];
do
{
numCores++;
if (fgets(line, 100, fp))
{
if (sscanf(line, "%s ", firstWord) != 1) {
firstWord[0] = '\0';
}
} else {
break;
}
} while (strncmp(firstWord, "cpu", 3) == 0);
int CpuLinux::GetNumCores() {
FILE* fp = fopen("/proc/stat", "r");
if (!fp) {
return -1;
}
// Skip first line
char line[100];
if (!fgets(line, 100, fp)) {
fclose(fp);
return numCores;
return -1;
}
int num_cores = -1;
char first_word[100];
do {
num_cores++;
if (fgets(line, 100, fp)) {
if (sscanf(line, "%s ", first_word) != 1) {
first_word[0] = '\0';
}
} else {
break;
}
} while (strncmp(first_word, "cpu", 3) == 0);
fclose(fp);
return num_cores;
}
} // namespace webrtc

View File

@ -11,41 +11,50 @@
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_
#include "cpu_wrapper.h"
#include "system_wrappers/interface/cpu_wrapper.h"
namespace webrtc {
class CpuLinux : public CpuWrapper
{
public:
CpuLinux();
virtual ~CpuLinux();
virtual WebRtc_Word32 CpuUsage();
virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/,
WebRtc_UWord32 /*length*/) {return 0;}
virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 /*dwProcessID*/) {return 0;}
class CpuLinux : public CpuWrapper {
public:
CpuLinux();
virtual ~CpuLinux();
virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores,
WebRtc_UWord32*& array);
virtual WebRtc_Word32 CpuUsage();
virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* process_name,
WebRtc_UWord32 length) {
return 0;
}
virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 process_id) {
return 0;
}
virtual void Reset() {return;}
virtual void Stop() {return;}
private:
int GetData(long long& busy, long long& idle, long long*& busyArray,
long long*& idleArray);
int GetNumCores();
virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& num_cores,
WebRtc_UWord32*& array);
long long m_oldBusyTime;
long long m_oldIdleTime;
virtual void Reset() {
return;
}
virtual void Stop() {
return;
}
private:
int GetData(long long& busy, long long& idle, long long*& busy_array,
long long*& idle_array);
int GetNumCores();
long long* m_oldBusyTimeMulti;
long long* m_oldIdleTimeMulti;
long long old_busy_time_;
long long old_idle_time_;
long long* m_idleArray;
long long* m_busyArray;
WebRtc_UWord32* m_resultArray;
WebRtc_UWord32 m_numCores;
long long* old_busy_time_multi_;
long long* old_idle_time_multi_;
long long* idle_array_;
long long* busy_array_;
WebRtc_UWord32* result_array_;
WebRtc_UWord32 num_cores_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_

View File

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "cpu_mac.h"
#include "system_wrappers/source/cpu_mac.h"
#include <iostream>
#include <mach/mach.h>
@ -17,127 +17,114 @@
#include "tick_util.h"
namespace webrtc {
CpuWrapperMac::CpuWrapperMac()
: _cpuCount(0),
_cpuUsage(NULL),
_totalCpuUsage(0),
_lastTickCount(NULL),
_lastTime(0)
{
natural_t cpuCount;
processor_info_array_t infoArray;
mach_msg_type_number_t infoCount;
: cpu_count_(0),
cpu_usage_(NULL),
total_cpu_usage_(0),
last_tick_count_(NULL),
last_time_(0) {
natural_t cpu_count;
processor_info_array_t info_array;
mach_msg_type_number_t info_count;
kern_return_t error = host_processor_info(mach_host_self(),
PROCESSOR_CPU_LOAD_INFO,
&cpuCount,
&infoArray,
&infoCount);
if (error)
{
return;
kern_return_t error = host_processor_info(mach_host_self(),
PROCESSOR_CPU_LOAD_INFO,
&cpu_count,
&info_array,
&info_count);
if (error) {
return;
}
cpu_count_ = cpu_count;
cpu_usage_ = new WebRtc_UWord32[cpu_count];
last_tick_count_ = new WebRtc_Word64[cpu_count];
last_time_ = TickTime::MillisecondTimestamp();
processor_cpu_load_info_data_t* cpu_load_info =
(processor_cpu_load_info_data_t*) info_array;
for (unsigned int cpu = 0; cpu < cpu_count; ++cpu) {
WebRtc_Word64 ticks = 0;
for (int state = 0; state < 2; ++state) {
ticks += cpu_load_info[cpu].cpu_ticks[state];
}
_cpuCount = cpuCount;
_cpuUsage = new WebRtc_UWord32[cpuCount];
_lastTickCount = new WebRtc_Word64[cpuCount];
_lastTime = TickTime::MillisecondTimestamp();
processor_cpu_load_info_data_t* cpuLoadInfo =
(processor_cpu_load_info_data_t*) infoArray;
for (unsigned int cpu= 0; cpu < cpuCount; cpu++)
{
WebRtc_Word64 ticks = 0;
for (int state = 0; state < 2; state++)
{
ticks += cpuLoadInfo[cpu].cpu_ticks[state];
}
_lastTickCount[cpu] = ticks;
_cpuUsage[cpu] = 0;
}
vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount);
last_tick_count_[cpu] = ticks;
cpu_usage_[cpu] = 0;
}
vm_deallocate(mach_task_self(), (vm_address_t)info_array, info_count);
}
CpuWrapperMac::~CpuWrapperMac()
{
delete[] _cpuUsage;
delete[] _lastTickCount;
CpuWrapperMac::~CpuWrapperMac() {
delete[] cpu_usage_;
delete[] last_tick_count_;
}
WebRtc_Word32 CpuWrapperMac::CpuUsage()
{
WebRtc_UWord32 numCores;
WebRtc_UWord32* array = NULL;
return CpuUsageMultiCore(numCores, array);
WebRtc_Word32 CpuWrapperMac::CpuUsage() {
WebRtc_UWord32 num_cores;
WebRtc_UWord32* array = NULL;
return CpuUsageMultiCore(num_cores, array);
}
WebRtc_Word32
CpuWrapperMac::CpuUsageMultiCore(WebRtc_UWord32& numCores,
WebRtc_UWord32*& array)
{
// sanity check
if(_cpuUsage == NULL)
{
return -1;
CpuWrapperMac::CpuUsageMultiCore(WebRtc_UWord32& num_cores,
WebRtc_UWord32*& array) {
// sanity check
if (cpu_usage_ == NULL) {
return -1;
}
WebRtc_Word64 now = TickTime::MillisecondTimestamp();
WebRtc_Word64 time_diff_ms = now - last_time_;
if (time_diff_ms >= 500) {
if (Update(time_diff_ms) != 0) {
return -1;
}
WebRtc_Word64 now = TickTime::MillisecondTimestamp();
WebRtc_Word64 timeDiffMS = now - _lastTime;
if(timeDiffMS >= 500)
{
if(Update(timeDiffMS) != 0)
{
return -1;
}
_lastTime = now;
}
numCores = _cpuCount;
array = _cpuUsage;
return _totalCpuUsage / _cpuCount;
last_time_ = now;
}
num_cores = cpu_count_;
array = cpu_usage_;
return total_cpu_usage_ / cpu_count_;
}
WebRtc_Word32 CpuWrapperMac::Update(WebRtc_Word64 timeDiffMS)
{
natural_t cpuCount;
processor_info_array_t infoArray;
mach_msg_type_number_t infoCount;
kern_return_t error = host_processor_info(mach_host_self(),
PROCESSOR_CPU_LOAD_INFO,
&cpuCount,
&infoArray,
&infoCount);
if (error)
{
return -1;
WebRtc_Word32 CpuWrapperMac::Update(WebRtc_Word64 time_diff_ms) {
natural_t cpu_count;
processor_info_array_t info_array;
mach_msg_type_number_t info_count;
kern_return_t error = host_processor_info(mach_host_self(),
PROCESSOR_CPU_LOAD_INFO,
&cpu_count,
&info_array,
&info_count);
if (error) {
return -1;
}
processor_cpu_load_info_data_t* cpu_load_info =
(processor_cpu_load_info_data_t*) info_array;
total_cpu_usage_ = 0;
for (unsigned int cpu = 0; cpu < cpu_count; ++cpu) {
WebRtc_Word64 ticks = 0;
for (int state = 0; state < 2; ++state) {
ticks += cpu_load_info[cpu].cpu_ticks[state];
}
processor_cpu_load_info_data_t* cpuLoadInfo =
(processor_cpu_load_info_data_t*) infoArray;
_totalCpuUsage = 0;
for (unsigned int cpu = 0; cpu < cpuCount; cpu++)
{
WebRtc_Word64 ticks = 0;
for (int state = 0; state < 2; state++)
{
ticks += cpuLoadInfo[cpu].cpu_ticks[state];
}
if(timeDiffMS <= 0)
{
_cpuUsage[cpu] = 0;
}else {
_cpuUsage[cpu] = (WebRtc_UWord32)((1000 *
(ticks - _lastTickCount[cpu])) /
timeDiffMS);
}
_lastTickCount[cpu] = ticks;
_totalCpuUsage += _cpuUsage[cpu];
if (time_diff_ms <= 0) {
cpu_usage_[cpu] = 0;
} else {
cpu_usage_[cpu] = (WebRtc_UWord32)((1000 *
(ticks - last_tick_count_[cpu])) /
time_diff_ms);
}
last_tick_count_[cpu] = ticks;
total_cpu_usage_ += cpu_usage_[cpu];
}
vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount);
vm_deallocate(mach_task_self(), (vm_address_t)info_array, info_count);
return 0;
return 0;
}
} // namespace webrtc

View File

@ -11,38 +11,43 @@
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_
#include "cpu_wrapper.h"
#include "system_wrappers/interface/cpu_wrapper.h"
namespace webrtc {
class CpuWrapperMac : public CpuWrapper
{
public:
CpuWrapperMac();
virtual ~CpuWrapperMac();
virtual WebRtc_Word32 CpuUsage();
virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/,
WebRtc_UWord32 /*length*/) {return -1;}
virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 /*dwProcessID*/) {return -1;}
class CpuWrapperMac : public CpuWrapper {
public:
CpuWrapperMac();
virtual ~CpuWrapperMac();
// Note: this class will block the call and sleep if called too fast
// This function blocks the calling thread if the thread is calling it more
// often than every 500 ms.
virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores,
WebRtc_UWord32*& array);
virtual WebRtc_Word32 CpuUsage();
virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* process_name,
WebRtc_UWord32 length) {
return -1;
}
virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 process_id) {
return -1;
}
virtual void Reset() {}
virtual void Stop() {}
// Note: this class will block the call and sleep if called too fast
// This function blocks the calling thread if the thread is calling it more
// often than every 500 ms.
virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& num_cores,
WebRtc_UWord32*& array);
private:
WebRtc_Word32 Update(WebRtc_Word64 timeDiffMS);
WebRtc_UWord32 _cpuCount;
WebRtc_UWord32* _cpuUsage;
WebRtc_Word32 _totalCpuUsage;
WebRtc_Word64* _lastTickCount;
WebRtc_Word64 _lastTime;
virtual void Reset() {}
virtual void Stop() {}
private:
WebRtc_Word32 Update(WebRtc_Word64 time_diffMS);
WebRtc_UWord32 cpu_count_;
WebRtc_UWord32* cpu_usage_;
WebRtc_Word32 total_cpu_usage_;
WebRtc_Word64* last_tick_count_;
WebRtc_Word64 last_time_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_MAC_H_

View File

@ -8,15 +8,14 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include <stddef.h>
#include "system_wrappers/interface/cpu_wrapper.h"
#include "cpu_wrapper.h"
#include <stddef.h>
namespace webrtc {
CpuWrapper* CpuWrapper::CreateCpu()
{
return NULL;
CpuWrapper* CpuWrapper::CreateCpu() {
return NULL;
}
} // namespace webrtc

View File

@ -8,10 +8,9 @@
* be found in the AUTHORS file in the root of the source tree.
*/
#include "system_wrappers/interface/cpu_wrapper.h"
#include "gtest/gtest.h"
#include "system_wrappers/interface/cpu_info.h"
#include "system_wrappers/interface/cpu_wrapper.h"
#include "system_wrappers/interface/event_wrapper.h"
#include "system_wrappers/interface/scoped_ptr.h"
#include "system_wrappers/interface/trace.h"
@ -33,7 +32,7 @@ using webrtc::Trace;
TEST(CpuWrapperTest, MAYBE_Usage) {
Trace::CreateTrace();
std::string trace_file = webrtc::test::OutputPath() +
"cpu_wrapper_unittest.txt";
"cpu_wrapper_unittest.txt";
Trace::SetTraceFile(trace_file.c_str());
Trace::SetLevelFilter(webrtc::kTraceAll);
printf("Number of cores detected:%u\n", CpuInfo::DetectNumberOfCores());