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_linux.h"
     12 
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include <string.h>
     16 #include <unistd.h>
     17 
     18 namespace webrtc {
     19 CpuLinux::CpuLinux()
     20     : m_oldBusyTime(0),
     21       m_oldIdleTime(0),
     22       m_oldBusyTimeMulti(NULL),
     23       m_oldIdleTimeMulti(NULL),
     24       m_idleArray(NULL),
     25       m_busyArray(NULL),
     26       m_resultArray(NULL),
     27       m_numCores(0) {
     28     const int result = GetNumCores();
     29     if (result != -1) {
     30       m_numCores = result;
     31       m_oldBusyTimeMulti = new long long[m_numCores];
     32       memset(m_oldBusyTimeMulti, 0, sizeof(long long) * m_numCores);
     33       m_oldIdleTimeMulti = new long long[m_numCores];
     34       memset(m_oldIdleTimeMulti, 0, sizeof(long long) * m_numCores);
     35       m_idleArray = new long long[m_numCores];
     36       memset(m_idleArray, 0, sizeof(long long) * m_numCores);
     37       m_busyArray = new long long[m_numCores];
     38       memset(m_busyArray, 0, sizeof(long long) * m_numCores);
     39       m_resultArray = new WebRtc_UWord32[m_numCores];
     40 
     41       GetData(m_oldBusyTime, m_oldIdleTime, m_busyArray, m_idleArray);
     42     }
     43 }
     44 
     45 CpuLinux::~CpuLinux()
     46 {
     47     delete [] m_oldBusyTimeMulti;
     48     delete [] m_oldIdleTimeMulti;
     49     delete [] m_idleArray;
     50     delete [] m_busyArray;
     51     delete [] m_resultArray;
     52 }
     53 
     54 WebRtc_Word32 CpuLinux::CpuUsage()
     55 {
     56     WebRtc_UWord32 dummy = 0;
     57     WebRtc_UWord32* dummyArray = NULL;
     58     return CpuUsageMultiCore(dummy, dummyArray);
     59 }
     60 
     61 WebRtc_Word32 CpuLinux::CpuUsageMultiCore(WebRtc_UWord32& numCores,
     62                                           WebRtc_UWord32*& coreArray)
     63 {
     64     coreArray = m_resultArray;
     65     numCores = m_numCores;
     66     long long busy = 0;
     67     long long idle = 0;
     68     if (GetData(busy, idle, m_busyArray, m_idleArray) != 0)
     69         return -1;
     70 
     71     long long deltaBusy = busy - m_oldBusyTime;
     72     long long deltaIdle = idle - m_oldIdleTime;
     73     m_oldBusyTime = busy;
     74     m_oldIdleTime = idle;
     75 
     76     int retVal = -1;
     77     if (deltaBusy + deltaIdle == 0)
     78     {
     79         retVal = 0;
     80     }
     81     else
     82     {
     83         retVal = (int)(100 * (deltaBusy) / (deltaBusy + deltaIdle));
     84     }
     85 
     86     if (coreArray == NULL)
     87     {
     88       return retVal;
     89     }
     90 
     91     for (WebRtc_UWord32 i = 0; i < m_numCores; i++)
     92     {
     93         deltaBusy = m_busyArray[i] - m_oldBusyTimeMulti[i];
     94         deltaIdle = m_idleArray[i] - m_oldIdleTimeMulti[i];
     95         m_oldBusyTimeMulti[i] = m_busyArray[i];
     96         m_oldIdleTimeMulti[i] = m_idleArray[i];
     97         if(deltaBusy + deltaIdle == 0)
     98         {
     99             coreArray[i] = 0;
    100         }
    101         else
    102         {
    103             coreArray[i] = (int)(100 * (deltaBusy) / (deltaBusy+deltaIdle));
    104         }
    105     }
    106     return retVal;
    107 }
    108 
    109 
    110 int CpuLinux::GetData(long long& busy, long long& idle, long long*& busyArray,
    111                       long long*& idleArray)
    112 {
    113     FILE* fp = fopen("/proc/stat", "r");
    114     if (!fp)
    115     {
    116         return -1;
    117     }
    118 
    119     char line[100];
    120     if (fgets(line, 100, fp) == NULL) {
    121         fclose(fp);
    122         return -1;
    123     }
    124     char firstWord[100];
    125     if (sscanf(line, "%s ", firstWord) != 1) {
    126         fclose(fp);
    127         return -1;
    128     }
    129     if (strncmp(firstWord, "cpu", 3) != 0) {
    130         fclose(fp);
    131         return -1;
    132     }
    133     char sUser[100];
    134     char sNice[100];
    135     char sSystem[100];
    136     char sIdle[100];
    137     if (sscanf(line, "%s %s %s %s %s ",
    138                firstWord, sUser, sNice, sSystem, sIdle) != 5) {
    139         fclose(fp);
    140         return -1;
    141     }
    142     long long luser = atoll(sUser);
    143     long long lnice = atoll(sNice);
    144     long long lsystem = atoll(sSystem);
    145     long long lidle = atoll (sIdle);
    146 
    147     busy = luser + lnice + lsystem;
    148     idle = lidle;
    149     for (WebRtc_UWord32 i = 0; i < m_numCores; i++)
    150     {
    151         if (fgets(line, 100, fp) == NULL) {
    152             fclose(fp);
    153             return -1;
    154         }
    155         if (sscanf(line, "%s %s %s %s %s ", firstWord, sUser, sNice, sSystem,
    156                    sIdle) != 5) {
    157             fclose(fp);
    158             return -1;
    159         }
    160         luser = atoll(sUser);
    161         lnice = atoll(sNice);
    162         lsystem = atoll(sSystem);
    163         lidle = atoll (sIdle);
    164         busyArray[i] = luser + lnice + lsystem;
    165         idleArray[i] = lidle;
    166     }
    167     fclose(fp);
    168     return 0;
    169 }
    170 
    171 int CpuLinux::GetNumCores()
    172 {
    173     FILE* fp = fopen("/proc/stat", "r");
    174     if (!fp)
    175     {
    176         return -1;
    177     }
    178     // Skip first line
    179     char line[100];
    180     if (!fgets(line, 100, fp))
    181     {
    182         fclose(fp);
    183         return -1;
    184     }
    185     int numCores = -1;
    186     char firstWord[100];
    187     do
    188     {
    189         numCores++;
    190         if (fgets(line, 100, fp))
    191         {
    192             if (sscanf(line, "%s ", firstWord) != 1) {
    193                 firstWord[0] = '\0';
    194             }
    195         } else {
    196             break;
    197         }
    198     } while (strncmp(firstWord, "cpu", 3) == 0);
    199     fclose(fp);
    200     return numCores;
    201 }
    202 } // namespace webrtc
    203