Minor spelling mistake.
[system_status.git] / data_engine / cpu_monitor.cpp
blob620e633794da21099d0ebe299b5a93795476cb15
1 /***********************************************************************************
2 * System Monitor: Plasmoid and data engines to monitor CPU/Memory/Swap Usage.
3 * Copyright (C) 2008 Matthew Dawson
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 ***********************************************************************************/
21 #include "cpu_monitor.h"
22 #include <QList>
23 #include <QVector>
24 #include <QFile>
25 #include <QTextStream>
27 struct cpu_jiffies{
29 unsigned long user;
30 unsigned long sys;
31 unsigned long nice;
32 unsigned long disk;
33 unsigned long idle;
35 ///Simply 0 inits all values.
36 cpu_jiffies():user(0),sys(0),nice(0),disk(0),idle(0){}
40 CPUMonitor::CPUMonitor(QObject* parent, const QVariantList& args):
41 Plasma::DataEngine(parent),
42 average(new cpu_jiffies()),
43 procstat(new QFile("/proc/stat")),
44 m_numcpus(1){
46 Q_UNUSED(args)
48 setMinimumPollingInterval(500);
52 CPUMonitor::~CPUMonitor(){
54 cpuTimeVector.clear();
55 delete average;
59 void CPUMonitor::init(){
61 setData("Average CPU Usage", DataEngine::Data());
62 setData("Number of CPUs", m_numcpus);
64 cpuTimeVector.push_back(cpu_jiffies());
68 bool CPUMonitor::sourceRequestEvent(const QString &proc){
70 // setData(proc, DataEngine::Data());
72 /// @todo:When solid gets proc support, use that
73 bool ok;
75 int procNum = proc.toInt(&ok);
77 kDebug() << ok << " " << proc;
79 if(!ok){
81 if(proc == "Average CPU Usage"){
82 setData(proc, "User", 0.0);
83 setData(proc, "Sys", 0.0);
84 setData(proc, "Nice", 0.0);
85 setData(proc, "Disk", 0.0);
86 setData(proc, "Idle", 0.0);
87 return true;
88 }else if(proc == "Number of CPUs"){
89 setData(proc, m_numcpus);
90 return true;
91 }else {
92 return false;
95 }else if(procNum < m_numcpus){
97 if(cpuTimeVector.count() < procNum){cpuTimeVector.resize(procNum + 1);}
99 setData(proc, "User", 0.0);
100 setData(proc, "Sys", 0.0);
101 setData(proc, "Nice", 0.0);
102 setData(proc, "Disk", 0.0);
103 setData(proc, "Idle", 0.0);
105 return true;
107 }else{
109 return false;
115 bool CPUMonitor::updateProc(QString ProcessorNumber, cpu_jiffies &old_jiffies, cpu_jiffies &diff){
117 cpu_jiffies temp;
118 bool ok;
119 QString input;
120 QTextStream readin;
122 if(procstat->openMode() == QIODevice::NotOpen){
124 if(!procstat->open(QIODevice::ReadOnly | QIODevice::Text)){
126 return false;
132 readin.setDevice(procstat);
133 readin.seek(0);
135 do {
137 readin >> input;
138 if(input == QString("cpu%1").arg(ProcessorNumber) ){
139 break;
142 }while(!readin.atEnd());
144 if(readin.status() & QTextStream::ReadPastEnd){
145 return false;
148 readin >> input;
149 temp.user = input.toLong();
150 readin >> input;
151 temp.nice = input.toLong();
152 readin >> input;
153 temp.sys = input.toLong();
154 readin >> input;
155 temp.idle = input.toLong();
156 readin >> input;
157 temp.disk = input.toLong(&ok);
158 ///Neccessary as some kernels may not support IOWait.
159 if(!ok){
160 temp.disk = 0;
163 diff.user = temp.user - old_jiffies.user;
164 diff.sys = temp.sys - old_jiffies.sys;
165 diff.nice = temp.nice - old_jiffies.nice;
166 diff.disk = temp.disk - old_jiffies.disk;
167 diff.idle = temp.idle - old_jiffies.idle;
169 old_jiffies = temp;
171 return true;
175 bool CPUMonitor::updateProcessor(QString ProcessorNumber, cpu_jiffies &diff){
177 if(ProcessorNumber.toInt() >= cpuTimeVector.count()){
179 cpuTimeVector.resize(ProcessorNumber.toInt() + 1);
183 if(!updateProc(ProcessorNumber, cpuTimeVector[ProcessorNumber.toInt()], diff)){
185 return false;
187 }else {
189 return true;
197 bool CPUMonitor::updateSourceEvent(const QString& source){
199 unsigned long total_diff;
200 cpu_jiffies diff;
201 bool ok;
202 int procNumber = source.toInt(&ok);
204 if(ok){
206 if(procNumber < cpuTimeVector.count()){
208 if(!updateProcessor(source, diff)){
210 return false;
214 total_diff = diff.user + diff.sys + diff.nice + diff.disk + diff.idle;
216 if(total_diff == 0){
218 total_diff = 1;
222 setData(source, "User", (double)diff.user / (double)total_diff);
223 setData(source, "Sys", diff.sys / (double)total_diff);
224 setData(source, "Nice", diff.nice / (double)total_diff);
225 setData(source, "Disk", diff.disk / (double)total_diff);
226 setData(source, "Idle", diff.idle / (double)total_diff);
228 return true;
230 }else{
232 return false;
236 }else if(source == "Number of CPUs"){
238 setData(source, m_numcpus);
239 return true;
241 }else if(source == "Average CPU Usage"){
242 ///@todo Implement Properly
243 cpu_jiffies diff;
245 updateProc("", *average, diff);
247 total_diff = diff.user + diff.sys + diff.nice + diff.disk + diff.idle;
249 if(total_diff == 0){
251 total_diff = 1;
255 setData(source, "User", (double)diff.user / (double)total_diff);
256 setData(source, "Sys", diff.sys / (double)total_diff);
257 setData(source, "Nice", diff.nice / (double)total_diff);
258 setData(source, "Disk", diff.disk / (double)total_diff);
259 setData(source, "Idle", diff.idle / (double)total_diff);
261 return true;
265 return false;
269 #include "cpu_monitor.moc"