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