1/* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "cpu_mac.h" 12 13#include <iostream> 14#include <mach/mach.h> 15#include <mach/mach_error.h> 16 17#include "tick_util.h" 18 19namespace webrtc { 20CpuWrapperMac::CpuWrapperMac() 21 : _cpuCount(0), 22 _cpuUsage(NULL), 23 _totalCpuUsage(0), 24 _lastTickCount(NULL), 25 _lastTime(0) 26{ 27 natural_t cpuCount; 28 processor_info_array_t infoArray; 29 mach_msg_type_number_t infoCount; 30 31 kern_return_t error = host_processor_info(mach_host_self(), 32 PROCESSOR_CPU_LOAD_INFO, 33 &cpuCount, 34 &infoArray, 35 &infoCount); 36 if (error) 37 { 38 return; 39 } 40 41 _cpuCount = cpuCount; 42 _cpuUsage = new WebRtc_UWord32[cpuCount]; 43 _lastTickCount = new WebRtc_Word64[cpuCount]; 44 _lastTime = TickTime::MillisecondTimestamp(); 45 46 processor_cpu_load_info_data_t* cpuLoadInfo = 47 (processor_cpu_load_info_data_t*) infoArray; 48 for (unsigned int cpu= 0; cpu < cpuCount; cpu++) 49 { 50 WebRtc_Word64 ticks = 0; 51 for (int state = 0; state < 2; state++) 52 { 53 ticks += cpuLoadInfo[cpu].cpu_ticks[state]; 54 } 55 _lastTickCount[cpu] = ticks; 56 _cpuUsage[cpu] = 0; 57 } 58 vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount); 59} 60 61CpuWrapperMac::~CpuWrapperMac() 62{ 63 delete[] _cpuUsage; 64 delete[] _lastTickCount; 65} 66 67WebRtc_Word32 CpuWrapperMac::CpuUsage() 68{ 69 WebRtc_UWord32 numCores; 70 WebRtc_UWord32* array = NULL; 71 return CpuUsageMultiCore(numCores, array); 72} 73 74WebRtc_Word32 75CpuWrapperMac::CpuUsageMultiCore(WebRtc_UWord32& numCores, 76 WebRtc_UWord32*& array) 77{ 78 // sanity check 79 if(_cpuUsage == NULL) 80 { 81 return -1; 82 } 83 84 WebRtc_Word64 now = TickTime::MillisecondTimestamp(); 85 WebRtc_Word64 timeDiffMS = now - _lastTime; 86 if(timeDiffMS >= 500) 87 { 88 if(Update(timeDiffMS) != 0) 89 { 90 return -1; 91 } 92 _lastTime = now; 93 } 94 95 numCores = _cpuCount; 96 array = _cpuUsage; 97 return _totalCpuUsage / _cpuCount; 98} 99 100WebRtc_Word32 CpuWrapperMac::Update(WebRtc_Word64 timeDiffMS) 101{ 102 natural_t cpuCount; 103 processor_info_array_t infoArray; 104 mach_msg_type_number_t infoCount; 105 106 kern_return_t error = host_processor_info(mach_host_self(), 107 PROCESSOR_CPU_LOAD_INFO, 108 &cpuCount, 109 &infoArray, 110 &infoCount); 111 if (error) 112 { 113 return -1; 114 } 115 116 processor_cpu_load_info_data_t* cpuLoadInfo = 117 (processor_cpu_load_info_data_t*) infoArray; 118 119 _totalCpuUsage = 0; 120 for (unsigned int cpu = 0; cpu < cpuCount; cpu++) 121 { 122 WebRtc_Word64 ticks = 0; 123 for (int state = 0; state < 2; state++) 124 { 125 ticks += cpuLoadInfo[cpu].cpu_ticks[state]; 126 } 127 if(timeDiffMS <= 0) 128 { 129 _cpuUsage[cpu] = 0; 130 }else { 131 _cpuUsage[cpu] = (WebRtc_UWord32)((1000 * 132 (ticks - _lastTickCount[cpu])) / 133 timeDiffMS); 134 } 135 _lastTickCount[cpu] = ticks; 136 _totalCpuUsage += _cpuUsage[cpu]; 137 } 138 139 vm_deallocate(mach_task_self(), (vm_address_t)infoArray, infoCount); 140 141 return 0; 142} 143} // namespace webrtc 144