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