Home | History | Annotate | Download | only in source
      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 
     19 namespace webrtc {
     20 CpuWrapperMac::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 
     61 CpuWrapperMac::~CpuWrapperMac()
     62 {
     63     delete[] _cpuUsage;
     64     delete[] _lastTickCount;
     65 }
     66 
     67 WebRtc_Word32 CpuWrapperMac::CpuUsage()
     68 {
     69     WebRtc_UWord32 numCores;
     70     WebRtc_UWord32* array = NULL;
     71     return CpuUsageMultiCore(numCores, array);
     72 }
     73 
     74 WebRtc_Word32
     75 CpuWrapperMac::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 
    100 WebRtc_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