00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "memsensor.h"
00011 #include <qfile.h>
00012 #include <qglobal.h>
00013 #include <qtextstream.h>
00014 #include <qstring.h>
00015 #include <qregexp.h>
00016
00017 #ifdef Q_OS_FREEBSD
00018 #include <sys/time.h>
00019 #include <sys/param.h>
00020 #include <sys/sysctl.h>
00021 #include <sys/resource.h>
00022 #include <unistd.h>
00023 #include <kvm.h>
00024 #include <sys/file.h>
00025 #include <osreldate.h>
00026 #endif
00027
00028 #if defined(Q_OS_NETBSD)
00029 #include <sys/param.h>
00030 #include <sys/sysctl.h>
00031 #include <sys/sched.h>
00032 #include <sys/swap.h>
00033 #endif
00034
00035 #if defined Q_OS_FREEBSD || defined(Q_OS_NETBSD)
00036
00037 #define pagetok(size) ((size) << pageshift)
00038 #endif
00039
00040 MemSensor::MemSensor(int msec) : Sensor(msec)
00041 {
00042 #if defined Q_OS_FREEBSD || defined(Q_OS_NETBSD)
00043
00044 int pagesize = getpagesize();
00045 pageshift = 0;
00046 while (pagesize > 1)
00047 {
00048 pageshift++;
00049 pagesize >>= 1;
00050 }
00051
00052
00053 pageshift -= 10;
00054 # if (defined(Q_OS_FREEBSD) && __FreeBSD_version < 500018)
00055 connect(&ksp, SIGNAL(receivedStdout(KProcess *, char *, int )),
00056 this,SLOT(receivedStdout(KProcess *, char *, int )));
00057 connect(&ksp, SIGNAL(processExited(KProcess *)),
00058 this,SLOT(processExited( KProcess * )));
00059
00060 swapTotal = swapUsed = 0;
00061
00062 MaxSet = false;
00063
00064 readValues();
00065 # elif defined Q_OS_FREEBSD
00066 kd = kvm_open("/dev/null", "/dev/null", "/dev/null", O_RDONLY, "kvm_open");
00067 # endif
00068 #else
00069 readValues();
00070 #endif
00071 }
00072
00073 MemSensor::~MemSensor()
00074 {}
00075
00076 #ifdef Q_OS_FREEBSD
00077 void MemSensor::receivedStdout(KProcess *, char *buffer, int len )
00078 {
00079 buffer[len] = 0;
00080 sensorResult += QString( QCString(buffer) );
00081 }
00082 #else
00083 void MemSensor::receivedStdout(KProcess *, char *, int)
00084 {
00085 }
00086 #endif
00087
00088 void MemSensor::processExited(KProcess *)
00089 {
00090 #ifdef Q_OS_FREEBSD
00091 QStringList stringList = QStringList::split('\n',sensorResult);
00092 sensorResult = "";
00093 QStringList itemsList = QStringList::split(' ', stringList[1]);
00094
00095 swapUsed = itemsList[2].toInt();
00096 swapTotal = itemsList[1].toInt();
00097 #endif
00098 }
00099
00100 int MemSensor::getMemTotal()
00101 {
00102 #if defined Q_OS_FREEBSD || defined(Q_OS_NETBSD)
00103 static int mem = 0;
00104 size_t size = sizeof(mem);
00105
00106 sysctlbyname("hw.physmem", &mem, &size, NULL, 0);
00107 return (mem / 1024);
00108 #else
00109 QRegExp rx( "MemTotal:\\s*(\\d+)" );
00110 rx.search( meminfo );
00111 return ( rx.cap(1).toInt() );
00112 #endif
00113 }
00114
00115 int MemSensor::getMemFree()
00116 {
00117 #ifdef Q_OS_FREEBSD
00118 static int mem = 0;
00119 size_t size = sizeof(mem);
00120
00121 sysctlbyname("vm.stats.vm.v_free_count", &mem, &size, NULL, 0);
00122 return (pagetok(mem));
00123 #elif defined(Q_OS_NETBSD)
00124 struct uvmexp_sysctl uvmexp;
00125 int mib[2];
00126 size_t ssize;
00127 mib[0] = CTL_VM;
00128 mib[1] = VM_UVMEXP2;
00129 ssize = sizeof(uvmexp);
00130 sysctl(mib,2,&uvmexp,&ssize,NULL,0);
00131 return pagetok(uvmexp.free);
00132 #else
00133 QRegExp rx( "MemFree:\\s*(\\d+)" );
00134 rx.search( meminfo );
00135 return ( rx.cap(1).toInt() );
00136 #endif
00137 }
00138
00139 int MemSensor::getBuffers()
00140 {
00141 #ifdef Q_OS_FREEBSD
00142 static int mem = 0;
00143 size_t size = sizeof(mem);
00144
00145 sysctlbyname("vfs.bufspace", &mem, &size, NULL, 0);
00146 return (mem / 1024);
00147 #elif defined(Q_OS_NETBSD)
00148 static int buf_mem = 0;
00149 size_t size = sizeof(buf_mem);
00150
00151 sysctlbyname("vm.bufmem", &buf_mem, &size, NULL, 0);
00152 return (buf_mem / 1024);
00153 #else
00154 QRegExp rx( "Buffers:\\s*(\\d+)" );
00155 rx.search( meminfo );
00156 return ( rx.cap(1).toInt() );
00157 #endif
00158 }
00159
00160 int MemSensor::getCached()
00161 {
00162 #ifdef Q_OS_FREEBSD
00163 static int mem = 0;
00164 size_t size = sizeof(mem);
00165
00166 sysctlbyname("vm.stats.vm.v_cache_count", &mem, &size, NULL, 0);
00167 return (pagetok(mem));
00168 #elif defined(Q_OS_NETBSD)
00169 return 0;
00170 #else
00171 QRegExp rx1( "Cached:\\s*(\\d+)" );
00172 QRegExp rx2( "SwapCached:\\s*(\\d+)" );
00173 rx1.search( meminfo );
00174 rx2.search( meminfo );
00175 return ( rx1.cap(1).toInt() + rx2.cap(1).toInt() );
00176 #endif
00177 }
00178
00179
00180 int MemSensor::getSwapTotal()
00181 {
00182 #ifdef Q_OS_FREEBSD
00183 # if __FreeBSD_version < 500018
00184 return(swapTotal);
00185 # else
00186 int n = -1;
00187 int pagesize = getpagesize();
00188 int retavail = 0;
00189
00190 if (kd != NULL)
00191 n = kvm_getswapinfo(kd, &swapinfo, 1, 0);
00192
00193 if (n < 0 || swapinfo.ksw_total == 0)
00194 return(0);
00195
00196 retavail = swapinfo.ksw_total * pagesize / 1024;
00197
00198 return(retavail);
00199 # endif
00200 #elif defined(Q_OS_NETBSD)
00201 struct uvmexp_sysctl uvmexp;
00202 int STotal = 0;
00203 int pagesize = 1;
00204 int mib[2];
00205 size_t ssize;
00206 mib[0] = CTL_VM;
00207 mib[1] = VM_UVMEXP;
00208 ssize = sizeof(uvmexp);
00209
00210 if (sysctl(mib,2,&uvmexp,&ssize,NULL,0) != -1) {
00211 pagesize = uvmexp.pagesize;
00212 STotal = (pagesize*uvmexp.swpages) >> 10;
00213 }
00214 return STotal;
00215 #else
00216 QRegExp rx( "SwapTotal:\\s*(\\d+)" );
00217 rx.search( meminfo );
00218 return ( rx.cap(1).toInt() );
00219 #endif
00220 }
00221
00222 int MemSensor::getSwapFree()
00223 {
00224 #ifdef Q_OS_FREEBSD
00225 # if __FreeBSD_version < 500018
00226 return(swapTotal - swapUsed);
00227 # else
00228 int n = -1;
00229 int pagesize = getpagesize();
00230 int retfree = 0;
00231
00232 if (kd != NULL)
00233 n = kvm_getswapinfo(kd, &swapinfo, 1, 0);
00234 if (n < 0 || swapinfo.ksw_total == 0)
00235 return(0);
00236
00237 retfree = (swapinfo.ksw_total - swapinfo.ksw_used) * pagesize / 1024;
00238
00239 return(retfree);
00240 # endif
00241 #elif defined(Q_OS_NETBSD)
00242 struct uvmexp_sysctl uvmexp;
00243 int STotal = 0;
00244 int SFree = 0;
00245 int SUsed = 0;
00246 int pagesize = 1;
00247 int mib[2];
00248 size_t ssize;
00249 mib[0] = CTL_VM;
00250 mib[1] = VM_UVMEXP;
00251 ssize = sizeof(uvmexp);
00252
00253 if (sysctl(mib,2,&uvmexp,&ssize,NULL,0) != -1) {
00254 pagesize = uvmexp.pagesize;
00255 STotal = (pagesize*uvmexp.swpages) >> 10;
00256 SUsed = (pagesize*uvmexp.swpginuse) >> 10;
00257 SFree = STotal - SUsed;
00258 }
00259 return SFree;
00260 #else
00261 QRegExp rx( "SwapFree:\\s*(\\d+)" );
00262 rx.search( meminfo );
00263 return ( rx.cap(1).toInt() );
00264 #endif
00265 }
00266
00267 void MemSensor::readValues()
00268 {
00269 #if defined Q_OS_FREEBSD || defined(Q_OS_NETBSD)
00270 # if (defined(Q_OS_FREEBSD) && __FreeBSD_version < 500018)
00271 ksp.clearArguments();
00272 ksp << "swapinfo";
00273 ksp.start( KProcess::NotifyOnExit,KProcIO::Stdout);
00274 # endif
00275 #else
00276 QFile file("/proc/meminfo");
00277 QString line;
00278 if ( file.open(IO_ReadOnly | IO_Translate) )
00279 {
00280 QTextStream t( &file );
00281 meminfo = t.read();
00282 file.close();
00283 }
00284 #endif
00285 }
00286
00287 void MemSensor::update()
00288 {
00289 readValues();
00290 QString format;
00291 SensorParams *sp;
00292 Meter *meter;
00293 QObjectListIt it( *objList );
00294 #if (defined(Q_OS_FREEBSD) && __FreeBSD_version < 500018)
00295 bool set = false;
00296 #endif
00297 int totalMem = getMemTotal();
00298 int usedMem = totalMem - getMemFree();
00299 int usedMemNoBuffers = usedMem - getBuffers() - getCached();
00300 int totalSwap = getSwapTotal();
00301 int usedSwap = totalSwap - getSwapFree();
00302
00303 while (it != 0)
00304 {
00305 sp = (SensorParams*)(*it);
00306 #if (defined(Q_OS_FREEBSD) && __FreeBSD_version < 500018)
00307 if ( (!MaxSet) && (totalSwap > 0) ) {
00308 setMaxValue(sp);
00309 bool set = true;
00310 }
00311 #endif
00312 meter = sp->getMeter();
00313 format = sp->getParam("FORMAT");
00314 if (format.length() == 0 )
00315 {
00316 format = "%um";
00317 }
00318
00319 format.replace( QRegExp("%fmb", false), QString::number( (int)(( totalMem - usedMemNoBuffers)/1024.0+0.5)));
00320 format.replace( QRegExp("%fm", false), QString::number( (int)( ( totalMem - usedMem )/1024.0+0.5) ));
00321
00322 format.replace( QRegExp("%umb", false), QString::number( (int)((usedMemNoBuffers)/1024.0+0.5)));
00323 format.replace( QRegExp("%um", false), QString::number( (int)((usedMem)/1024.0+0.5 )));
00324
00325 format.replace( QRegExp("%tm", false), QString::number( (int)( (totalMem)/1024.0+0.5)));
00326
00327 format.replace( QRegExp("%fs", false), QString::number( (int)((totalSwap - usedSwap)/1024.0+0.5)));
00328 format.replace( QRegExp("%us", false), QString::number( (int)(usedSwap/1024.0+0.5)));
00329 format.replace( QRegExp("%ts", false), QString::number( (int)(totalSwap/1024.0+0.5)));
00330
00331 meter->setValue(format);
00332 ++it;
00333 }
00334 #if (defined(Q_OS_FREEBSD) && __FreeBSD_version < 500018)
00335 if (set)
00336 MaxSet = true;
00337 #endif
00338 }
00339
00340 void MemSensor::setMaxValue( SensorParams *sp )
00341 {
00342 Meter *meter;
00343 meter = sp->getMeter();
00344 QString f;
00345 f = sp->getParam("FORMAT");
00346
00347 if (f.length() == 0 )
00348 {
00349 f = "%um";
00350 }
00351 if( f=="%fm" || f== "%um" || f=="%fmb" || f=="%umb" )
00352 meter->setMax( getMemTotal() / 1024 );
00353 if( f=="%fs" || f== "%us" )
00354 meter->setMax( getSwapTotal() / 1024 );
00355 }
00356
00357 #include "memsensor.moc"