blob: 8e8ecda6ca8856a4cca67fceb0756071b0f26c5e [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
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
18namespace webrtc {
19CpuLinux::CpuLinux()
wu@webrtc.org3d48d5b2011-08-16 00:03:36 +000020 : 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];
niklase@google.com470e71d2011-07-07 08:21:25 +000040
wu@webrtc.org3d48d5b2011-08-16 00:03:36 +000041 GetData(m_oldBusyTime, m_oldIdleTime, m_busyArray, m_idleArray);
42 }
niklase@google.com470e71d2011-07-07 08:21:25 +000043}
44
45CpuLinux::~CpuLinux()
46{
47 delete [] m_oldBusyTimeMulti;
48 delete [] m_oldIdleTimeMulti;
49 delete [] m_idleArray;
50 delete [] m_busyArray;
51 delete [] m_resultArray;
52}
53
54WebRtc_Word32 CpuLinux::CpuUsage()
55{
56 WebRtc_UWord32 dummy = 0;
57 WebRtc_UWord32* dummyArray = NULL;
58 return CpuUsageMultiCore(dummy, dummyArray);
59}
60
61WebRtc_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;
wu@webrtc.orgae53bf82011-08-23 18:56:56 +000068 if (GetData(busy, idle, m_busyArray, m_idleArray) != 0)
69 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000070
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
110int 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];
wu@webrtc.orgae53bf82011-08-23 18:56:56 +0000120 if (fgets(line, 100, fp) == NULL) {
121 fclose(fp);
122 return -1;
123 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000124 char firstWord[100];
wu@webrtc.orgae53bf82011-08-23 18:56:56 +0000125 if (sscanf(line, "%s ", firstWord) != 1) {
126 fclose(fp);
127 return -1;
128 }
129 if (strncmp(firstWord, "cpu", 3) != 0) {
130 fclose(fp);
niklase@google.com470e71d2011-07-07 08:21:25 +0000131 return -1;
132 }
133 char sUser[100];
134 char sNice[100];
135 char sSystem[100];
136 char sIdle[100];
wu@webrtc.orgae53bf82011-08-23 18:56:56 +0000137 if (sscanf(line, "%s %s %s %s %s ",
138 firstWord, sUser, sNice, sSystem, sIdle) != 5) {
139 fclose(fp);
140 return -1;
141 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000142 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 {
wu@webrtc.orgae53bf82011-08-23 18:56:56 +0000151 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 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000160 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
171int 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];
ajm@google.com825e0632011-07-16 01:04:52 +0000180 if (!fgets(line, 100, fp))
181 {
mflodman@webrtc.org67cdc222012-01-16 09:31:39 +0000182 fclose(fp);
ajm@google.com825e0632011-07-16 01:04:52 +0000183 return -1;
184 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000185 int numCores = -1;
186 char firstWord[100];
187 do
188 {
189 numCores++;
190 if (fgets(line, 100, fp))
191 {
wu@webrtc.orgae53bf82011-08-23 18:56:56 +0000192 if (sscanf(line, "%s ", firstWord) != 1) {
193 firstWord[0] = '\0';
194 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000195 } else {
196 break;
197 }
198 } while (strncmp(firstWord, "cpu", 3) == 0);
199 fclose(fp);
200 return numCores;
201}
202} // namespace webrtc