133 lines
3.9 KiB
C++
133 lines
3.9 KiB
C++
|
/*
|
||
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license
|
||
|
* that can be found in the LICENSE file in the root of the source
|
||
|
* tree. An additional intellectual property rights grant can be found
|
||
|
* in the file PATENTS. All contributing project authors may
|
||
|
* be found in the AUTHORS file in the root of the source tree.
|
||
|
*/
|
||
|
|
||
|
#include "cpu_mac.h"
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <mach/mach.h>
|
||
|
#include <mach/mach_error.h>
|
||
|
|
||
|
#include "tick_util.h"
|
||
|
|
||
|
namespace webrtc {
|
||
|
CpuWrapperMac::CpuWrapperMac() : _cpuUsage(NULL)
|
||
|
{
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
_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;
|
||
|
}
|
||
|
vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount);
|
||
|
}
|
||
|
|
||
|
CpuWrapperMac::~CpuWrapperMac()
|
||
|
{
|
||
|
delete _cpuUsage;
|
||
|
delete _lastTickCount;
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32 CpuWrapperMac::CpuUsage()
|
||
|
{
|
||
|
WebRtc_UWord32 numCores;
|
||
|
WebRtc_UWord32* array = NULL;
|
||
|
return CpuUsageMultiCore(numCores, array);
|
||
|
}
|
||
|
|
||
|
WebRtc_Word32
|
||
|
CpuWrapperMac::CpuUsageMultiCore(WebRtc_UWord32& numCores,
|
||
|
WebRtc_UWord32*& array)
|
||
|
{
|
||
|
natural_t cpuCount;
|
||
|
processor_info_array_t infoArray;
|
||
|
mach_msg_type_number_t infoCount;
|
||
|
|
||
|
// sanity check
|
||
|
if(_cpuUsage == NULL)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
WebRtc_Word64 now = TickTime::MillisecondTimestamp();
|
||
|
WebRtc_Word64 timeDiffMS = now - _lastTime;
|
||
|
// TODO(hellner) why block here? Why not just return the old
|
||
|
// value? Is this behavior consistent across all
|
||
|
// platforms?
|
||
|
// Make sure that at least 500 ms pass between calls.
|
||
|
if(timeDiffMS < 500)
|
||
|
{
|
||
|
usleep((500-timeDiffMS)*1000);
|
||
|
return CpuUsageMultiCore(numCores, array);
|
||
|
}
|
||
|
_lastTime = now;
|
||
|
|
||
|
kern_return_t error = host_processor_info(mach_host_self(),
|
||
|
PROCESSOR_CPU_LOAD_INFO,
|
||
|
&cpuCount,
|
||
|
&infoArray,
|
||
|
&infoCount);
|
||
|
if (error)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
processor_cpu_load_info_data_t* cpuLoadInfo =
|
||
|
(processor_cpu_load_info_data_t*) infoArray;
|
||
|
|
||
|
WebRtc_Word32 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];
|
||
|
}
|
||
|
|
||
|
vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount);
|
||
|
|
||
|
numCores = cpuCount;
|
||
|
array = _cpuUsage;
|
||
|
return totalCpuUsage/cpuCount;
|
||
|
}
|
||
|
} // namespace webrtc
|