/*
* 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()
: _cpuCount(0),
_cpuUsage(NULL),
_totalCpuUsage(0),
_lastTickCount(NULL),
_lastTime(0)
{
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;
}
_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);
}
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)
{
// sanity check
if(_cpuUsage == NULL)
{
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;
}
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;
}
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];
}
vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount);
return 0;
}
} // namespace webrtc