| /* |
| * 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 |