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 {
CpuLinux()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
~CpuLinux()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
CpuUsage()54 WebRtc_Word32 CpuLinux::CpuUsage()
55 {
56 WebRtc_UWord32 dummy = 0;
57 WebRtc_UWord32* dummyArray = NULL;
58 return CpuUsageMultiCore(dummy, dummyArray);
59 }
60
CpuUsageMultiCore(WebRtc_UWord32 & numCores,WebRtc_UWord32 * & coreArray)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
GetData(long long & busy,long long & idle,long long * & busyArray,long long * & idleArray)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
GetNumCores()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