diff options
Diffstat (limited to 'ksim/systeminfo.cpp')
-rw-r--r-- | ksim/systeminfo.cpp | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/ksim/systeminfo.cpp b/ksim/systeminfo.cpp new file mode 100644 index 0000000..567477c --- /dev/null +++ b/ksim/systeminfo.cpp @@ -0,0 +1,277 @@ +/* System Information + * + * Copyright (C) 2001 Robbie Ward <linuxphreak@gmx.co.uk> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include "systeminfo.h" + +#ifdef __linux__ +#include <sys/sysinfo.h> +#include <linux/kernel.h> +#endif + +#ifdef HAVE_SYS_LOADAVG_H +#include <sys/loadavg.h> +#endif + +#ifdef __FreeBSD__ +#include <osreldate.h> +#include <kvm.h> +#include <fcntl.h> +#include <sys/time.h> +#include <sys/param.h> +#include <sys/conf.h> +#if __FreeBSD_version < 400000 +#include <sys/rlist.h> +#endif +#include <sys/vmmeter.h> +#include <sys/sysctl.h> +#include <vm/vm_param.h> +#include <iomanip> +#include <iostream> +#endif + +// Some global vars +// expand as needed for other platforms +int System::bytesToMegs( unsigned long value ) +{ +#ifdef __linux__ + return ((((value / 1024) >> 10) | 11) + 1); +#endif + +#ifdef __FreeBSD__ + return (((value) + (1 << 19)) >> 20); +#endif +} + +System * System::m_self = 0; // initialize pointer +System & System::self() +{ + if ( !m_self ) + { + m_self = new System; + atexit( System::cleanup ); + } + + m_self->updateData(); + return *m_self; +} + +void System::cleanup() +{ + if ( !m_self ) + return; + + delete m_self; + m_self = 0; +} + +double System::loadAverage( int load ) const +{ + int value = --load; + return loadAverages()[ value > 2 ? 2 : value ]; +} + +System::System() +{ + m_loads[ 0 ] = 0; + m_loads[ 1 ] = 0; + m_loads[ 2 ] = 0; + + m_uptime = 0; + m_totalram = 0; + m_usedram = 0; + m_freeram = 0; + m_sharedram = 0; + m_bufferram = 0; + m_cacheram = 0; + m_totalhigh = 0; + m_freehigh = 0; + m_totalswap = 0; + m_usedswap = 0; + m_freeswap = 0; + m_procs = 0; + + m_self = this; +} + +System::~System() +{ +} + +void System::updateData() +{ +#ifdef __linux__ + struct sysinfo system; + if (sysinfo(&system) < 0) { + fprintf(stderr, "Error calling sysinfo()\n"); + return; + } + + m_uptime = system.uptime; + m_totalram = system.totalram; + m_sharedram = system.sharedram; + m_bufferram = system.bufferram; + m_usedram = m_totalram - m_freeram; + +#ifdef HAVE_SYSINFO_HIGH + m_totalhigh = system.totalhigh; + m_freehigh = system.freehigh; +#else +#ifdef __GNUC__ +#warning "TODO: find alternative way to get total high and freehigh" +#endif +#endif + + m_totalswap = system.totalswap; + m_freeswap = system.freeswap; + m_procs = system.procs; + m_cacheram = 0; + + FILE *file = fopen("/proc/meminfo", "r"); + char buffer[70]; + if (file) { + while (fgets(buffer, sizeof(buffer), file)) { + sscanf(buffer, "Mem: %*d %*d %*d %*d %*d %lu", &m_cacheram); + if (m_cacheram != 0) + break; + } + + fclose(file); + } + + m_freeram = system.freeram; +#endif + +#ifdef __FreeBSD__ + struct timeval bootTime; + size_t size = sizeof(bootTime); + + if (sysctlbyname("kern.boottime", + &bootTime, &size, NULL, 0) != -1 && bootTime.tv_sec != 0) { + m_uptime = time(0) - bootTime.tv_sec + 30; + } + + char buf[80]; + char *used; + char *total; + FILE *pipe; + static int psize = 0, pshift = 0; + static int name2oid[2] = { 0, 3 }; + struct vmtotal vmt; + size_t vmtLength = sizeof(vmt); + static char name[] = "vfs.bufspace"; + static int oidBufspace[CTL_MAXNAME + 2]; + static size_t oidBufspaceLength = sizeof(oidBufspace); + size_t bufspaceLength = sizeof(int); + static int initialized = 0; + unsigned long memXUsed, memTotal; + size_t memLength = sizeof(memTotal); + + if (pshift == 0) { + psize = getpagesize(); + while (psize > 1) { + ++pshift; + psize >>= 1; + } + } + + unsigned long xused1, xused2; + size_t xused1Length = sizeof(xused1); + size_t xused2Length = sizeof(xused2); + if (sysctlbyname("vm.stats.vm.v_active_count", &xused1, &xused1Length, NULL, 0) == 0 + && sysctlbyname("vm.stats.vm.v_inactive_count", &xused2, &xused2Length, NULL, 0) == 0) { + memXUsed = (xused1 + xused2) << pshift; + } + + unsigned long cacheRam; + size_t cacheSize = sizeof(cacheRam); + if (sysctlbyname("vm.stats.vm.v_active_count", &cacheRam, &cacheSize, NULL, 0) == 0) { + m_cacheram = cacheRam << pshift; + } + + if (!m_totalram && sysctlbyname("hw.physmem", &memTotal, &memLength, NULL, 0) == 0) + m_totalram = memTotal; + + if (sysctlbyname("vm.meter", &vmt, &vmtLength, NULL, 0) == 0) + m_sharedram = vmt.t_rmshr << pshift; + + if (!initialized) { + if (sysctl(name2oid, 2, oidBufspace, &oidBufspaceLength, + name, strlen(name)) < 0) + return; + + oidBufspaceLength /= sizeof(int); + ++initialized; + } + + if (sysctl(oidBufspace, oidBufspaceLength, + &m_bufferram, &bufspaceLength, 0, 0) < 0) + return; + + m_usedram = memXUsed - m_bufferram - m_cacheram; + m_freeram = memTotal - m_usedram; + + //TODO: get the total and free high mem values + m_totalhigh = 0; + m_freehigh = 0; + + if ((pipe = popen("/usr/sbin/swapinfo -k", "r")) == 0) { + fprintf(stderr, "Error reading swap info\n"); + m_freeswap = m_totalswap = 1; + return; + } + + fgets(buf, sizeof(buf), pipe); + fgets(buf, sizeof(buf), pipe); + fgets(buf, sizeof(buf), pipe); + fgets(buf, sizeof(buf), pipe); + pclose(pipe); + + strtok(buf, " "); + total = strtok(NULL, " "); + used = strtok(NULL, " "); + unsigned long usedSwap = atol(used) * 1024; + + m_totalswap = atol(total) * 1024; + m_freeswap = m_totalswap - usedSwap; + + //TODO: get amount of procs + m_procs = 0; +#endif + +#ifdef HAVE_GETLOADAVG + double load[3]; + if (getloadavg(load, 3) != -1) { + m_loads[0] = load[0]; + m_loads[1] = load[1]; + m_loads[2] = load[2]; + } +#else +#warning "TODO: Find an alternative method for getloadavg" +#endif + + m_usedswap = m_totalswap - m_freeswap; +} |