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