blob: 74783b9b42629086e0c1c24e95dee3bb81b084ad [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
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000011#include "system_wrappers/source/cpu_linux.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17
18namespace webrtc {
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000019
niklase@google.com470e71d2011-07-07 08:21:25 +000020CpuLinux::CpuLinux()
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000021 : old_busy_time_(0),
22 old_idle_time_(0),
23 old_busy_time_multi_(NULL),
24 old_idle_time_multi_(NULL),
25 idle_array_(NULL),
26 busy_array_(NULL),
27 result_array_(NULL),
28 num_cores_(0) {
29 const int result = GetNumCores();
30 if (result != -1) {
31 num_cores_ = result;
32 old_busy_time_multi_ = new long long[num_cores_];
33 memset(old_busy_time_multi_, 0, sizeof(long long) * num_cores_);
34 old_idle_time_multi_ = new long long[num_cores_];
35 memset(old_idle_time_multi_, 0, sizeof(long long) * num_cores_);
36 idle_array_ = new long long[num_cores_];
37 memset(idle_array_, 0, sizeof(long long) * num_cores_);
38 busy_array_ = new long long[num_cores_];
39 memset(busy_array_, 0, sizeof(long long) * num_cores_);
40 result_array_ = new WebRtc_UWord32[num_cores_];
niklase@google.com470e71d2011-07-07 08:21:25 +000041
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000042 GetData(old_busy_time_, old_idle_time_, busy_array_, idle_array_);
43 }
niklase@google.com470e71d2011-07-07 08:21:25 +000044}
45
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000046CpuLinux::~CpuLinux() {
47 delete [] old_busy_time_multi_;
48 delete [] old_idle_time_multi_;
49 delete [] idle_array_;
50 delete [] busy_array_;
51 delete [] result_array_;
niklase@google.com470e71d2011-07-07 08:21:25 +000052}
53
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000054WebRtc_Word32 CpuLinux::CpuUsage() {
55 WebRtc_UWord32 dummy = 0;
56 WebRtc_UWord32* dummy_array = NULL;
57 return CpuUsageMultiCore(dummy, dummy_array);
niklase@google.com470e71d2011-07-07 08:21:25 +000058}
59
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000060WebRtc_Word32 CpuLinux::CpuUsageMultiCore(WebRtc_UWord32& num_cores,
61 WebRtc_UWord32*& core_array) {
62 core_array = result_array_;
63 num_cores = num_cores_;
64 long long busy = 0;
65 long long idle = 0;
66 if (GetData(busy, idle, busy_array_, idle_array_) != 0)
67 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +000068
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000069 long long delta_busy = busy - old_busy_time_;
70 long long delta_idle = idle - old_idle_time_;
71 old_busy_time_ = busy;
72 old_idle_time_ = idle;
niklase@google.com470e71d2011-07-07 08:21:25 +000073
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000074 int ret_val = -1;
75 if (delta_busy + delta_idle == 0) {
76 ret_val = 0;
77 } else {
78 ret_val = (int)(100 * (delta_busy) / (delta_busy + delta_idle));
79 }
niklase@google.com470e71d2011-07-07 08:21:25 +000080
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000081 if (core_array == NULL) {
82 return ret_val;
83 }
niklase@google.com470e71d2011-07-07 08:21:25 +000084
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000085 for (WebRtc_UWord32 i = 0; i < num_cores_; ++i) {
86 delta_busy = busy_array_[i] - old_busy_time_multi_[i];
87 delta_idle = idle_array_[i] - old_idle_time_multi_[i];
88 old_busy_time_multi_[i] = busy_array_[i];
89 old_idle_time_multi_[i] = idle_array_[i];
90 if (delta_busy + delta_idle == 0) {
91 core_array[i] = 0;
92 } else {
93 core_array[i] = (int)(100 * (delta_busy) / (delta_busy + delta_idle));
niklase@google.com470e71d2011-07-07 08:21:25 +000094 }
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000095 }
96 return ret_val;
niklase@google.com470e71d2011-07-07 08:21:25 +000097}
98
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +000099int CpuLinux::GetData(long long& busy, long long& idle, long long*& busy_array,
100 long long*& idle_array) {
101 FILE* fp = fopen("/proc/stat", "r");
102 if (!fp) {
103 return -1;
104 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000105
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +0000106 char line[100];
107 if (fgets(line, 100, fp) == NULL) {
108 fclose(fp);
109 return -1;
110 }
111 char first_word[100];
112 if (sscanf(line, "%s ", first_word) != 1) {
113 fclose(fp);
114 return -1;
115 }
116 if (strncmp(first_word, "cpu", 3) != 0) {
117 fclose(fp);
118 return -1;
119 }
120 char s_user[100];
121 char s_nice[100];
122 char s_system[100];
123 char s_idle[100];
124 if (sscanf(line, "%s %s %s %s %s ",
125 first_word, s_user, s_nice, s_system, s_idle) != 5) {
126 fclose(fp);
127 return -1;
128 }
129 long long luser = atoll(s_user);
130 long long lnice = atoll(s_nice);
131 long long lsystem = atoll(s_system);
132 long long lidle = atoll(s_idle);
niklase@google.com470e71d2011-07-07 08:21:25 +0000133
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +0000134 busy = luser + lnice + lsystem;
135 idle = lidle;
136 for (WebRtc_UWord32 i = 0; i < num_cores_; ++i) {
wu@webrtc.orgae53bf82011-08-23 18:56:56 +0000137 if (fgets(line, 100, fp) == NULL) {
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +0000138 fclose(fp);
139 return -1;
wu@webrtc.orgae53bf82011-08-23 18:56:56 +0000140 }
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +0000141 if (sscanf(line, "%s %s %s %s %s ", first_word, s_user, s_nice, s_system,
142 s_idle) != 5) {
143 fclose(fp);
144 return -1;
wu@webrtc.orgae53bf82011-08-23 18:56:56 +0000145 }
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +0000146 luser = atoll(s_user);
147 lnice = atoll(s_nice);
148 lsystem = atoll(s_system);
149 lidle = atoll(s_idle);
150 busy_array[i] = luser + lnice + lsystem;
151 idle_array[i] = lidle;
152 }
153 fclose(fp);
154 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000155}
156
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +0000157int CpuLinux::GetNumCores() {
158 FILE* fp = fopen("/proc/stat", "r");
159 if (!fp) {
160 return -1;
161 }
162 // Skip first line
163 char line[100];
164 if (!fgets(line, 100, fp)) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000165 fclose(fp);
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +0000166 return -1;
167 }
168 int num_cores = -1;
169 char first_word[100];
170 do {
171 num_cores++;
172 if (fgets(line, 100, fp)) {
173 if (sscanf(line, "%s ", first_word) != 1) {
174 first_word[0] = '\0';
175 }
176 } else {
177 break;
178 }
179 } while (strncmp(first_word, "cpu", 3) == 0);
180 fclose(fp);
181 return num_cores;
niklase@google.com470e71d2011-07-07 08:21:25 +0000182}
phoglund@webrtc.orgb15d2852012-11-21 08:02:57 +0000183
niklase@google.com470e71d2011-07-07 08:21:25 +0000184} // namespace webrtc