1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/* 2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * 4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * Use of this source code is governed by a BSD-style license 5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * that can be found in the LICENSE file in the root of the source 6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * tree. An additional intellectual property rights grant can be found 7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * in the file PATENTS. All contributing project authors may 8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * be found in the AUTHORS file in the root of the source tree. 9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */ 10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 11e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "cpu_linux.h" 12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 13e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <stdio.h> 14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <stdlib.h> 15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <string.h> 16e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include <unistd.h> 17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentnamespace webrtc { 19e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentCpuLinux::CpuLinux() 20c55a96383497a772a307b346368133960b02ad03Eric Laurent : m_oldBusyTime(0), 21c55a96383497a772a307b346368133960b02ad03Eric Laurent m_oldIdleTime(0), 22c55a96383497a772a307b346368133960b02ad03Eric Laurent m_oldBusyTimeMulti(NULL), 23c55a96383497a772a307b346368133960b02ad03Eric Laurent m_oldIdleTimeMulti(NULL), 24c55a96383497a772a307b346368133960b02ad03Eric Laurent m_idleArray(NULL), 25c55a96383497a772a307b346368133960b02ad03Eric Laurent m_busyArray(NULL), 26c55a96383497a772a307b346368133960b02ad03Eric Laurent m_resultArray(NULL), 27c55a96383497a772a307b346368133960b02ad03Eric Laurent m_numCores(0) { 28c55a96383497a772a307b346368133960b02ad03Eric Laurent const int result = GetNumCores(); 29c55a96383497a772a307b346368133960b02ad03Eric Laurent if (result != -1) { 30c55a96383497a772a307b346368133960b02ad03Eric Laurent m_numCores = result; 31c55a96383497a772a307b346368133960b02ad03Eric Laurent m_oldBusyTimeMulti = new long long[m_numCores]; 32c55a96383497a772a307b346368133960b02ad03Eric Laurent memset(m_oldBusyTimeMulti, 0, sizeof(long long) * m_numCores); 33c55a96383497a772a307b346368133960b02ad03Eric Laurent m_oldIdleTimeMulti = new long long[m_numCores]; 34c55a96383497a772a307b346368133960b02ad03Eric Laurent memset(m_oldIdleTimeMulti, 0, sizeof(long long) * m_numCores); 35c55a96383497a772a307b346368133960b02ad03Eric Laurent m_idleArray = new long long[m_numCores]; 36c55a96383497a772a307b346368133960b02ad03Eric Laurent memset(m_idleArray, 0, sizeof(long long) * m_numCores); 37c55a96383497a772a307b346368133960b02ad03Eric Laurent m_busyArray = new long long[m_numCores]; 38c55a96383497a772a307b346368133960b02ad03Eric Laurent memset(m_busyArray, 0, sizeof(long long) * m_numCores); 39c55a96383497a772a307b346368133960b02ad03Eric Laurent m_resultArray = new WebRtc_UWord32[m_numCores]; 40c55a96383497a772a307b346368133960b02ad03Eric Laurent 41c55a96383497a772a307b346368133960b02ad03Eric Laurent GetData(m_oldBusyTime, m_oldIdleTime, m_busyArray, m_idleArray); 42c55a96383497a772a307b346368133960b02ad03Eric Laurent } 43e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentCpuLinux::~CpuLinux() 46e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete [] m_oldBusyTimeMulti; 48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete [] m_oldIdleTimeMulti; 49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete [] m_idleArray; 50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete [] m_busyArray; 51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete [] m_resultArray; 52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 53e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentWebRtc_Word32 CpuLinux::CpuUsage() 55e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32 dummy = 0; 57e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32* dummyArray = NULL; 58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return CpuUsageMultiCore(dummy, dummyArray); 59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 60e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 61e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentWebRtc_Word32 CpuLinux::CpuUsageMultiCore(WebRtc_UWord32& numCores, 62e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent WebRtc_UWord32*& coreArray) 63e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 64e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent coreArray = m_resultArray; 65e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent numCores = m_numCores; 66e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long busy = 0; 67e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long idle = 0; 68c55a96383497a772a307b346368133960b02ad03Eric Laurent if (GetData(busy, idle, m_busyArray, m_idleArray) != 0) 69c55a96383497a772a307b346368133960b02ad03Eric Laurent return -1; 70e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 71e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long deltaBusy = busy - m_oldBusyTime; 72e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long deltaIdle = idle - m_oldIdleTime; 73e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent m_oldBusyTime = busy; 74e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent m_oldIdleTime = idle; 75e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 76e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int retVal = -1; 77e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (deltaBusy + deltaIdle == 0) 78e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 79e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent retVal = 0; 80e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 81e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent else 82e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 83e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent retVal = (int)(100 * (deltaBusy) / (deltaBusy + deltaIdle)); 84e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 85e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 86e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (coreArray == NULL) 87e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 88e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return retVal; 89e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 90e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 91e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (WebRtc_UWord32 i = 0; i < m_numCores; i++) 92e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 93e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent deltaBusy = m_busyArray[i] - m_oldBusyTimeMulti[i]; 94e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent deltaIdle = m_idleArray[i] - m_oldIdleTimeMulti[i]; 95e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent m_oldBusyTimeMulti[i] = m_busyArray[i]; 96e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent m_oldIdleTimeMulti[i] = m_idleArray[i]; 97e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if(deltaBusy + deltaIdle == 0) 98e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 99e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent coreArray[i] = 0; 100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent else 102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent coreArray[i] = (int)(100 * (deltaBusy) / (deltaBusy+deltaIdle)); 104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return retVal; 107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint CpuLinux::GetData(long long& busy, long long& idle, long long*& busyArray, 111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long*& idleArray) 112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 113e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent FILE* fp = fopen("/proc/stat", "r"); 114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (!fp) 115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 117e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 118e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 119e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent char line[100]; 120c55a96383497a772a307b346368133960b02ad03Eric Laurent if (fgets(line, 100, fp) == NULL) { 121c55a96383497a772a307b346368133960b02ad03Eric Laurent fclose(fp); 122c55a96383497a772a307b346368133960b02ad03Eric Laurent return -1; 123c55a96383497a772a307b346368133960b02ad03Eric Laurent } 124e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent char firstWord[100]; 125c55a96383497a772a307b346368133960b02ad03Eric Laurent if (sscanf(line, "%s ", firstWord) != 1) { 126c55a96383497a772a307b346368133960b02ad03Eric Laurent fclose(fp); 127c55a96383497a772a307b346368133960b02ad03Eric Laurent return -1; 128c55a96383497a772a307b346368133960b02ad03Eric Laurent } 129c55a96383497a772a307b346368133960b02ad03Eric Laurent if (strncmp(firstWord, "cpu", 3) != 0) { 130c55a96383497a772a307b346368133960b02ad03Eric Laurent fclose(fp); 131e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 132e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 133e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent char sUser[100]; 134e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent char sNice[100]; 135e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent char sSystem[100]; 136e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent char sIdle[100]; 137c55a96383497a772a307b346368133960b02ad03Eric Laurent if (sscanf(line, "%s %s %s %s %s ", 138c55a96383497a772a307b346368133960b02ad03Eric Laurent firstWord, sUser, sNice, sSystem, sIdle) != 5) { 139c55a96383497a772a307b346368133960b02ad03Eric Laurent fclose(fp); 140c55a96383497a772a307b346368133960b02ad03Eric Laurent return -1; 141c55a96383497a772a307b346368133960b02ad03Eric Laurent } 142e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long luser = atoll(sUser); 143e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long lnice = atoll(sNice); 144e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long lsystem = atoll(sSystem); 145e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent long long lidle = atoll (sIdle); 146e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 147e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent busy = luser + lnice + lsystem; 148e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent idle = lidle; 149e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (WebRtc_UWord32 i = 0; i < m_numCores; i++) 150e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 151c55a96383497a772a307b346368133960b02ad03Eric Laurent if (fgets(line, 100, fp) == NULL) { 152c55a96383497a772a307b346368133960b02ad03Eric Laurent fclose(fp); 153c55a96383497a772a307b346368133960b02ad03Eric Laurent return -1; 154c55a96383497a772a307b346368133960b02ad03Eric Laurent } 155c55a96383497a772a307b346368133960b02ad03Eric Laurent if (sscanf(line, "%s %s %s %s %s ", firstWord, sUser, sNice, sSystem, 156c55a96383497a772a307b346368133960b02ad03Eric Laurent sIdle) != 5) { 157c55a96383497a772a307b346368133960b02ad03Eric Laurent fclose(fp); 158c55a96383497a772a307b346368133960b02ad03Eric Laurent return -1; 159c55a96383497a772a307b346368133960b02ad03Eric Laurent } 160e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent luser = atoll(sUser); 161e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent lnice = atoll(sNice); 162e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent lsystem = atoll(sSystem); 163e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent lidle = atoll (sIdle); 164e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent busyArray[i] = luser + lnice + lsystem; 165e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent idleArray[i] = lidle; 166e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 167e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent fclose(fp); 168e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return 0; 169e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 170e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 171e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint CpuLinux::GetNumCores() 172e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent{ 173e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent FILE* fp = fopen("/proc/stat", "r"); 174e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (!fp) 175e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 176e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return -1; 177e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 178e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Skip first line 179e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent char line[100]; 180c55a96383497a772a307b346368133960b02ad03Eric Laurent if (!fgets(line, 100, fp)) 181c55a96383497a772a307b346368133960b02ad03Eric Laurent { 182c55a96383497a772a307b346368133960b02ad03Eric Laurent return -1; 183c55a96383497a772a307b346368133960b02ad03Eric Laurent } 184e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int numCores = -1; 185e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent char firstWord[100]; 186e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent do 187e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 188e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent numCores++; 189e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (fgets(line, 100, fp)) 190e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent { 191c55a96383497a772a307b346368133960b02ad03Eric Laurent if (sscanf(line, "%s ", firstWord) != 1) { 192c55a96383497a772a307b346368133960b02ad03Eric Laurent firstWord[0] = '\0'; 193c55a96383497a772a307b346368133960b02ad03Eric Laurent } 194e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else { 195e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent break; 196e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 197e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } while (strncmp(firstWord, "cpu", 3) == 0); 198e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent fclose(fp); 199e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return numCores; 200e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 201e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} // namespace webrtc 202