summaryrefslogtreecommitdiffstats
path: root/ksysguard/ksysguardd/Linux/Memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'ksysguard/ksysguardd/Linux/Memory.c')
-rw-r--r--ksysguard/ksysguardd/Linux/Memory.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/ksysguard/ksysguardd/Linux/Memory.c b/ksysguard/ksysguardd/Linux/Memory.c
new file mode 100644
index 000000000..93c8d9edb
--- /dev/null
+++ b/ksysguard/ksysguardd/Linux/Memory.c
@@ -0,0 +1,293 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <[email protected]>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ 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.
+
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "Command.h"
+#include "ksysguardd.h"
+
+#include "Memory.h"
+
+#define MEMINFOBUFSIZE (2 * 1024)
+
+static char MemInfoBuf[ MEMINFOBUFSIZE ];
+static int Dirty = 1;
+
+static unsigned long Total = 0;
+static unsigned long MFree = 0;
+static unsigned long Appl = 0;
+static unsigned long Used = 0;
+static unsigned long Buffers = 0;
+static unsigned long Cached = 0;
+static unsigned long STotal = 0;
+static unsigned long SFree = 0;
+static unsigned long SUsed = 0;
+
+static void scan_one( const char* buff, const char *key, unsigned long int* val )
+{
+ int o;
+ char *b = strstr( buff, key );
+ if ( b )
+ o = sscanf( b + strlen( key ), ": %lu", val );
+}
+
+static void processMemInfo()
+{
+ scan_one( MemInfoBuf, "MemTotal", &Total );
+ scan_one( MemInfoBuf, "MemFree", &MFree );
+ scan_one( MemInfoBuf, "Buffers", &Buffers );
+ scan_one( MemInfoBuf, "Cached", &Cached );
+ scan_one( MemInfoBuf, "SwapTotal", &STotal );
+ scan_one( MemInfoBuf, "SwapFree", &SFree );
+ Used = Total - MFree;
+ Appl = ( Used - ( Buffers + Cached ) );
+
+ if ( STotal == 0 ) /* no swap activated */
+ SUsed = 0;
+ else
+ SUsed = STotal - SFree;
+
+ Dirty = 0;
+}
+
+/*
+================================ public part =================================
+*/
+
+void initMemory( struct SensorModul* sm )
+{
+ /**
+ Make sure that /proc/meminfo exists and is readable. If not we do
+ not register any monitors for memory.
+ */
+ if ( updateMemory() < 0 )
+ return;
+
+ registerMonitor( "mem/physical/free", "integer", printMFree, printMFreeInfo, sm );
+ registerMonitor( "mem/physical/used", "integer", printUsed, printUsedInfo, sm );
+ registerMonitor( "mem/physical/application", "integer", printAppl, printApplInfo, sm );
+ registerMonitor( "mem/physical/buf", "integer", printBuffers, printBuffersInfo, sm );
+ registerMonitor( "mem/physical/cached", "integer", printCached, printCachedInfo, sm );
+ registerMonitor( "mem/swap/used", "integer", printSwapUsed, printSwapUsedInfo, sm );
+ registerMonitor( "mem/swap/free", "integer", printSwapFree, printSwapFreeInfo, sm );
+}
+
+void exitMemory( void )
+{
+}
+
+int updateMemory( void )
+{
+ /**
+ The amount of total and used memory is read from the /proc/meminfo.
+ It also contains the information about the swap space.
+ The 'file' looks like this:
+
+ MemTotal: 516560 kB
+ MemFree: 7812 kB
+ MemShared: 0 kB
+ Buffers: 80312 kB
+ Cached: 236432 kB
+ SwapCached: 468 kB
+ Active: 291992 kB
+ Inactive: 133556 kB
+ HighTotal: 0 kB
+ HighFree: 0 kB
+ LowTotal: 516560 kB
+ LowFree: 7812 kB
+ SwapTotal: 899632 kB
+ SwapFree: 898932 kB
+ Dirty: 2736 kB
+ Writeback: 0 kB
+ Mapped: 155996 kB
+ Slab: 73920 kB
+ Committed_AS: 315588 kB
+ PageTables: 1764 kB
+ ReverseMaps: 103458
+ */
+
+ int fd;
+ size_t n;
+
+ if ( ( fd = open( "/proc/meminfo", O_RDONLY ) ) < 0 ) {
+ print_error( "Cannot open \'/proc/meminfo\'!\n"
+ "The kernel needs to be compiled with support\n"
+ "for /proc filesystem enabled!\n" );
+ return -1;
+ }
+
+ if ( ( n = read( fd, MemInfoBuf, MEMINFOBUFSIZE - 1 ) ) == MEMINFOBUFSIZE - 1 ) {
+ log_error( "Internal buffer too small to read \'/proc/mem\'" );
+ close( fd );
+ return -1;
+ }
+
+ close( fd );
+ MemInfoBuf[ n ] = '\0';
+ Dirty = 1;
+
+ return 0;
+}
+
+void printMFree( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", MFree );
+}
+
+void printMFreeInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Free Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printUsed( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", Used );
+}
+
+void printUsedInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Used Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printAppl( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", Appl );
+}
+
+void printApplInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Application Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printBuffers( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", Buffers );
+}
+
+void printBuffersInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Buffer Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printCached( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", Cached );
+}
+
+void printCachedInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Cached Memory\t0\t%ld\tKB\n", Total );
+}
+
+void printSwapUsed( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", SUsed );
+}
+
+void printSwapUsedInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Used Swap Memory\t0\t%ld\tKB\n", STotal );
+}
+
+void printSwapFree( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "%ld\n", SFree );
+}
+
+void printSwapFreeInfo( const char* cmd )
+{
+ (void)cmd;
+
+ if ( Dirty )
+ processMemInfo();
+
+ fprintf( CurrentClient, "Free Swap Memory\t0\t%ld\tKB\n", STotal );
+}