casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
HostInfoLinux.h
Go to the documentation of this file.
00001 //# HostInfo_linux.h: Linux specific memory, swap, and CPU code.
00002 //# $Id: HostInfoLinux.h 21022 2011-03-01 10:07:47Z gervandiepen $
00003 
00004  /*
00005  **  This is a greatly MODIFIED version of a "top" machine dependent file.
00006  **  The only resemblance it bears to the original is with respect to the
00007  **  mechanics of finding various system details. The copyright details
00008  **  follow.
00009  **
00010  **  --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
00011  **
00012  **  Top users/processes display for Unix
00013  **  Version 3
00014  **
00015  **  This program may be freely redistributed,
00016  **  but this entire comment MUST remain intact.
00017  **
00018  **  Copyright (c) 1984, 1989, William LeFebvre, Rice University
00019  **  Copyright (c) 1989 - 1994, William LeFebvre, Northwestern University
00020  **  Copyright (c) 1994, 1995, William LeFebvre, Argonne National Laboratory
00021  **  Copyright (c) 1996, William LeFebvre, Group sys Consulting
00022  **  Copyright (c) 2002, Associated Universities Inc.
00023  */
00024 
00025 #ifndef CASA_HOSTINFOLINUX_H
00026 #define CASA_HOSTINFOLINUX_H
00027 
00028 # if defined(HOSTINFO_DO_IMPLEMENT)
00029 
00030 /*
00031  *          AUTHOR:       Darrell Schiebel  <drs@nrao.edu>
00032  *
00033  * ORIGINAL AUTHORS:      Richard Henderson <rth@tamu.edu>
00034  *                        Alexey Klimkin    <kad@klon.tme.mcst.ru>
00035  *
00036  *
00037  */
00038 
00039 #include <string.h>
00040 #include <ctype.h>
00041 #include <sys/types.h>
00042 #include <sys/stat.h>
00043 #include <sys/vfs.h>
00044 #include <unistd.h>
00045 #include <fcntl.h>
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 
00049 // <summary>
00050 // HostInfo for Linux machines.
00051 // </summary>
00052 
00053 // <use visibility=local>
00054 
00055 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00056 // </reviewed>
00057 
00058 // <prerequisite>
00059 //   <li> <linkto class=HostInfo>HostInfo</linkto>
00060 // </prerequisite>
00061 
00062 // <synopsis> 
00063 // This file provides the Linux specific functions for HostInfo.
00064 // It is selectively included by HostInfo.cc.
00065 // </synopsis>
00066 //
00067 // <group name="HostInfo">
00068 
00069 #if 0
00070 #include <linux/proc_fs.h>      /* for PROC_SUPER_MAGIC */
00071 #else
00072 #define PROC_SUPER_MAGIC 0x9fa0
00073 #endif
00074 
00075 #define PROCFS "/proc"
00076 #define CPUINFO "/proc/cpuinfo"
00077 #define MEMINFO "/proc/meminfo"
00078 
00079 #define bytetok(x)      (((x) + 512) >> 10)
00080 
00081 namespace casa { //# NAMESPACE CASA - BEGIN
00082 
00083 class HostMachineInfo {
00084 friend class HostInfo;
00085   
00086     HostMachineInfo( );
00087     void update_info( );
00088 
00089     int valid;
00090     int cpus;
00091 
00092     ssize_t memory_total;
00093     ssize_t memory_used;
00094     ssize_t memory_free;
00095 
00096     ssize_t swap_total;
00097     ssize_t swap_used;
00098     ssize_t swap_free;
00099 };
00100 
00101 // </group>
00102 
00103 
00104 static inline char *
00105 skip_ws(const char *p)
00106 {
00107     while (isspace(*p)) p++;
00108     return (char *)p;
00109 }
00110     
00111 static inline char *
00112 skip_token(const char *p)
00113 {
00114     while (isspace(*p)) p++;
00115     while (*p && !isspace(*p)) p++;
00116     return (char *)p;
00117 }
00118 
00119 HostMachineInfo::HostMachineInfo( ) : valid(1)
00120 {
00121     char buffer[4096+1];
00122     int fd, len;
00123     char *p;
00124 
00125 #ifndef AIPS_CRAY_PGI
00126     /* make sure the proc filesystem is mounted */
00127     {
00128         struct statfs sb;
00129         if (statfs(PROCFS, &sb) < 0 || sb.f_type != PROC_SUPER_MAGIC)
00130         {
00131             fprintf( stderr, "proc filesystem not mounted on " PROCFS "\n" );
00132             valid = 0;
00133             return;
00134         }
00135     }
00136 #endif
00137 
00138     /* get number of CPUs */
00139     {
00140         cpus = 0;
00141         FILE *fptr = fopen(CPUINFO, "r");
00142         while ( (p = fgets( buffer, sizeof(buffer), fptr )) ) {
00143             if ( ! strncmp( p, "processor", 9 ) ) ++cpus;
00144         }
00145         fclose(fptr);
00146     }
00147 
00148     /* get system total memory */
00149     /* See the sprintf() statements of the file
00150        fs/proc/proc_misc.c in the kernel source tree */
00151     {
00152         fd = open(MEMINFO, O_RDONLY);
00153         len = read(fd, buffer, sizeof(buffer)-1);
00154         close(fd);
00155         buffer[len] = '\0';
00156 
00157         int ret;
00158         unsigned long mem_total, swp_total;
00159         p = strstr(buffer, "MemTotal:");
00160         if ((ret = sscanf (p, "MemTotal: %lu kB\n", &mem_total)) != 1)
00161           cerr << "Error parsing MemTotal in /proc/meminfo\n";
00162         memory_total = mem_total;
00163         p = strstr(buffer, "SwapTotal:");
00164         if ((ret = sscanf (p, "SwapTotal: %lu kB\n", &swp_total)) != 1)
00165           cerr << "Error parsing SwapTotal in /proc/meminfo\n";
00166         swap_total = swp_total;
00167     }
00168 }
00169 
00170 void HostMachineInfo::update_info( )
00171 {
00172     char buffer[4096+1];
00173     int fd, len;
00174 
00175     /* get system wide memory usage */
00176     {
00177         char *p;
00178         int ret;
00179         unsigned long mem_total, mem_free, mem_cached, swp_total, swp_free;
00180 
00181         fd = open(MEMINFO, O_RDONLY);
00182         len = read(fd, buffer, sizeof(buffer)-1);
00183         close(fd);
00184         buffer[len] = '\0';
00185 
00186         p = strstr(buffer, "MemTotal:");
00187 
00188         if ((ret = sscanf (p,"MemTotal: %lu kB\nMemFree: %lu kB\n",
00189                            &mem_total, &mem_free)) != 2)
00190           cerr << "Error parsing MemTotal and MemFree in /proc/meminfo\n";
00191 
00192         p = strstr (buffer, "Cached:");
00193         if ((ret = sscanf (p,"Cached: %lu kB\n", &mem_cached)) != 1)
00194           cerr << "Error parsing Cached in /proc/meminfo\n";
00195 
00196         memory_total = mem_total;
00197         memory_free = mem_free + mem_cached;
00198         memory_used = memory_total - memory_free;
00199 
00200         p = strstr (buffer, "SwapTotal:");
00201         if ((ret = sscanf (p, "SwapTotal: %lu kB\nSwapFree: %lu kB\n",
00202                            &swp_total, &swp_free)) != 2)
00203           cerr << "Error parsing SwapTotal and SwapFree in /proc/meminfo\n";
00204 
00205         swap_total = swp_total;
00206         swap_free = swp_free;
00207         swap_used = swap_total-swap_free;
00208     }
00209 }
00210 
00211 } //# NAMESPACE CASA - END
00212 
00213 # endif
00214 
00215 #endif