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"
25 #include <QTextStream>
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")),
48 setMinimumPollingInterval(500);
52 CPUMonitor::~CPUMonitor(){
54 cpuTimeVector
.clear();
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
75 int procNum
= proc
.toInt(&ok
);
77 kDebug() << ok
<< " " << proc
;
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);
88 }else if(proc
== "Number of CPUs"){
89 setData(proc
, m_numcpus
);
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);
115 bool CPUMonitor::updateProc(QString ProcessorNumber
, cpu_jiffies
&old_jiffies
, cpu_jiffies
&diff
){
122 if(procstat
->openMode() == QIODevice::NotOpen
){
124 if(!procstat
->open(QIODevice::ReadOnly
| QIODevice::Text
)){
132 readin
.setDevice(procstat
);
138 if(input
== QString("cpu%1").arg(ProcessorNumber
) ){
142 }while(!readin
.atEnd());
144 if(readin
.status() & QTextStream::ReadPastEnd
){
149 temp
.user
= input
.toLong();
151 temp
.nice
= input
.toLong();
153 temp
.sys
= input
.toLong();
155 temp
.idle
= input
.toLong();
157 temp
.disk
= input
.toLong(&ok
);
158 ///Neccessary as some kernels may not support IOWait.
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
;
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
)){
197 bool CPUMonitor::updateSourceEvent(const QString
& source
){
199 unsigned long total_diff
;
202 int procNumber
= source
.toInt(&ok
);
206 if(procNumber
< cpuTimeVector
.count()){
208 if(!updateProcessor(source
, diff
)){
214 total_diff
= diff
.user
+ diff
.sys
+ diff
.nice
+ diff
.disk
+ diff
.idle
;
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
);
236 }else if(source
== "Number of CPUs"){
238 setData(source
, m_numcpus
);
241 }else if(source
== "Average CPU Usage"){
242 ///@todo Implement Properly
245 updateProc("", *average
, diff
);
247 total_diff
= diff
.user
+ diff
.sys
+ diff
.nice
+ diff
.disk
+ diff
.idle
;
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
);
269 #include "cpu_monitor.moc"