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); 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; extern WebRtc_CPUInfo WebRtc_GetCPUInfo;
// No CPU feature is available => straight C path. // No CPU feature is available => straight C path.
extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM; extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM;
// Return the features in an ARM device. // 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. // values in the above enum definition as a bitmask.
extern uint64_t WebRtc_GetCPUFeaturesARM(void); extern uint64_t WebRtc_GetCPUFeaturesARM(void);

View File

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

View File

@ -14,40 +14,42 @@
#include "typedefs.h" #include "typedefs.h"
namespace webrtc { namespace webrtc {
class CpuWrapper
{
public:
static CpuWrapper* CreateCpu();
virtual ~CpuWrapper() {}
// Returns the average CPU usage for all processors. The CPU usage can be class CpuWrapper {
// between and including 0 to 100 (%) public:
virtual WebRtc_Word32 CpuUsage() = 0; static CpuWrapper* CreateCpu();
virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* processName, virtual ~CpuWrapper() {}
WebRtc_UWord32 length) = 0;
virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 dwProcessID) = 0;
// The CPU usage per core is returned in cpu_usage. The CPU can be between // Returns the average CPU usage for all processors. The CPU usage can be
// and including 0 to 100 (%) // between and including 0 to 100 (%)
// Note that the pointer passed as cpu_usage is redirected to a local member virtual WebRtc_Word32 CpuUsage() = 0;
// of the CPU wrapper. virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* process_name,
// numCores is the number of cores in the cpu_usage array. WebRtc_UWord32 length) = 0;
// The return value is -1 for failure or 0-100, indicating the average virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 process_id) = 0;
// 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;
virtual void Reset() = 0; // The CPU usage per core is returned in cpu_usage. The CPU can be between
virtual void Stop() = 0; // 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: virtual void Reset() = 0;
CpuWrapper() {} virtual void Stop() = 0;
protected:
CpuWrapper() {}
}; };
} // namespace webrtc } // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CPU_WRAPPER_H_ #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. * 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) #if defined(_WIN32)
#include "cpu_win.h" #include "cpu_win.h"
#elif defined(WEBRTC_MAC) #elif defined(WEBRTC_MAC)
#include "cpu_mac.h" #include "cpu_mac.h"
#elif defined(WEBRTC_ANDROID) #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) #else // defined(WEBRTC_LINUX)
#include "cpu_linux.h" #include "cpu_linux.h"
#endif #endif
namespace webrtc { namespace webrtc {
CpuWrapper* CpuWrapper::CreateCpu() CpuWrapper* CpuWrapper::CreateCpu() {
{
#if defined(_WIN32) #if defined(_WIN32)
return new CpuWindows(); return new CpuWindows();
#elif defined(WEBRTC_MAC) #elif defined(WEBRTC_MAC)
return new CpuWrapperMac(); return new CpuWrapperMac();
#elif defined(WEBRTC_ANDROID) #elif defined(WEBRTC_ANDROID)
return 0; return 0;
#else #else
return new CpuLinux(); return new CpuLinux();
#endif #endif
} }
} // namespace webrtc
} // namespace webrtc

View File

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

View File

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

View File

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

View File

@ -11,41 +11,50 @@
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_ #ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CPU_LINUX_H_
#define 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 { namespace webrtc {
class CpuLinux : public CpuWrapper
{
public:
CpuLinux();
virtual ~CpuLinux();
virtual WebRtc_Word32 CpuUsage(); class CpuLinux : public CpuWrapper {
virtual WebRtc_Word32 CpuUsage(WebRtc_Word8* /*pProcessName*/, public:
WebRtc_UWord32 /*length*/) {return 0;} CpuLinux();
virtual WebRtc_Word32 CpuUsage(WebRtc_UWord32 /*dwProcessID*/) {return 0;} virtual ~CpuLinux();
virtual WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& numCores, virtual WebRtc_Word32 CpuUsage();
WebRtc_UWord32*& array); 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 WebRtc_Word32 CpuUsageMultiCore(WebRtc_UWord32& num_cores,
virtual void Stop() {return;} WebRtc_UWord32*& array);
private:
int GetData(long long& busy, long long& idle, long long*& busyArray,
long long*& idleArray);
int GetNumCores();
long long m_oldBusyTime; virtual void Reset() {
long long m_oldIdleTime; 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 old_busy_time_;
long long* m_oldIdleTimeMulti; long long old_idle_time_;
long long* m_idleArray; long long* old_busy_time_multi_;
long long* m_busyArray; long long* old_idle_time_multi_;
WebRtc_UWord32* m_resultArray;
WebRtc_UWord32 m_numCores; long long* idle_array_;
long long* busy_array_;
WebRtc_UWord32* result_array_;
WebRtc_UWord32 num_cores_;
}; };
} // namespace webrtc } // 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. * 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 <iostream>
#include <mach/mach.h> #include <mach/mach.h>
@ -17,127 +17,114 @@
#include "tick_util.h" #include "tick_util.h"
namespace webrtc { namespace webrtc {
CpuWrapperMac::CpuWrapperMac() CpuWrapperMac::CpuWrapperMac()
: _cpuCount(0), : cpu_count_(0),
_cpuUsage(NULL), cpu_usage_(NULL),
_totalCpuUsage(0), total_cpu_usage_(0),
_lastTickCount(NULL), last_tick_count_(NULL),
_lastTime(0) last_time_(0) {
{ natural_t cpu_count;
natural_t cpuCount; processor_info_array_t info_array;
processor_info_array_t infoArray; mach_msg_type_number_t info_count;
mach_msg_type_number_t infoCount;
kern_return_t error = host_processor_info(mach_host_self(), kern_return_t error = host_processor_info(mach_host_self(),
PROCESSOR_CPU_LOAD_INFO, PROCESSOR_CPU_LOAD_INFO,
&cpuCount, &cpu_count,
&infoArray, &info_array,
&infoCount); &info_count);
if (error) if (error) {
{ return;
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];
} }
last_tick_count_[cpu] = ticks;
_cpuCount = cpuCount; cpu_usage_[cpu] = 0;
_cpuUsage = new WebRtc_UWord32[cpuCount]; }
_lastTickCount = new WebRtc_Word64[cpuCount]; vm_deallocate(mach_task_self(), (vm_address_t)info_array, info_count);
_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);
} }
CpuWrapperMac::~CpuWrapperMac() CpuWrapperMac::~CpuWrapperMac() {
{ delete[] cpu_usage_;
delete[] _cpuUsage; delete[] last_tick_count_;
delete[] _lastTickCount;
} }
WebRtc_Word32 CpuWrapperMac::CpuUsage() WebRtc_Word32 CpuWrapperMac::CpuUsage() {
{ WebRtc_UWord32 num_cores;
WebRtc_UWord32 numCores; WebRtc_UWord32* array = NULL;
WebRtc_UWord32* array = NULL; return CpuUsageMultiCore(num_cores, array);
return CpuUsageMultiCore(numCores, array);
} }
WebRtc_Word32 WebRtc_Word32
CpuWrapperMac::CpuUsageMultiCore(WebRtc_UWord32& numCores, CpuWrapperMac::CpuUsageMultiCore(WebRtc_UWord32& num_cores,
WebRtc_UWord32*& array) WebRtc_UWord32*& array) {
{ // sanity check
// sanity check if (cpu_usage_ == NULL) {
if(_cpuUsage == NULL) return -1;
{ }
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;
} }
last_time_ = now;
WebRtc_Word64 now = TickTime::MillisecondTimestamp(); }
WebRtc_Word64 timeDiffMS = now - _lastTime;
if(timeDiffMS >= 500) num_cores = cpu_count_;
{ array = cpu_usage_;
if(Update(timeDiffMS) != 0) return total_cpu_usage_ / cpu_count_;
{
return -1;
}
_lastTime = now;
}
numCores = _cpuCount;
array = _cpuUsage;
return _totalCpuUsage / _cpuCount;
} }
WebRtc_Word32 CpuWrapperMac::Update(WebRtc_Word64 timeDiffMS) WebRtc_Word32 CpuWrapperMac::Update(WebRtc_Word64 time_diff_ms) {
{ natural_t cpu_count;
natural_t cpuCount; processor_info_array_t info_array;
processor_info_array_t infoArray; mach_msg_type_number_t info_count;
mach_msg_type_number_t infoCount;
kern_return_t error = host_processor_info(mach_host_self(),
kern_return_t error = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO,
PROCESSOR_CPU_LOAD_INFO, &cpu_count,
&cpuCount, &info_array,
&infoArray, &info_count);
&infoCount); if (error) {
if (error) return -1;
{ }
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];
} }
if (time_diff_ms <= 0) {
processor_cpu_load_info_data_t* cpuLoadInfo = cpu_usage_[cpu] = 0;
(processor_cpu_load_info_data_t*) infoArray; } else {
cpu_usage_[cpu] = (WebRtc_UWord32)((1000 *
_totalCpuUsage = 0; (ticks - last_tick_count_[cpu])) /
for (unsigned int cpu = 0; cpu < cpuCount; cpu++) time_diff_ms);
{
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];
} }
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 } // namespace webrtc

View File

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

View File

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