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