"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "gmemusage-0.2/proc.c" of archive gmemusage-0.2.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /*
    2  * proc.c:
    3  * interface to process table entry in /proc
    4  *
    5  * Copyright (C) 1997, 1998 by Raju Mathur (raju@sgi.com)
    6  *
    7  * See file COPYING (included in this distribution) for copyright information.
    8  */
    9 #include <stdio.h>
   10 #include <string.h>
   11 #include <sys/types.h>
   12 #include <dirent.h>
   13 #include <sys/stat.h>
   14 #include "common.h"
   15 /*
   16  * memory (in Kbytes)
   17  */
   18 int
   19    sysmem = 0 ,
   20    kernelmem = 0 ,
   21    freemem = 0 ,
   22    buffermem = 0 ;
   23 /*
   24  * Set values for various memory usages
   25  */
   26 static void
   27 SetMemInfo ( void )
   28 {
   29    struct stat
   30       s ;
   31    char
   32       buf [128] ;
   33    FILE
   34       *meminfo ;
   35    int
   36       totalmem ;
   37    const char
   38       *MemLine = "Mem:" ;
   39    const int
   40       MemLineLen = strlen ( MemLine ) ;
   41 /*
   42  * Cheap way to get amount of installed mem in the computer -- get size of
   43  * /proc/kcore.
   44  */
   45    if ( stat ( "/proc/kcore" , &s ) < 0 )
   46    {
   47       fprintf ( stderr , "%s: cannot stat /proc/kcore" , progname ) ;
   48       perror ( "" ) ;
   49       exit ( 1 ) ;
   50    }
   51    sysmem = s . st_size ; /* in Kilobytes */
   52 /*
   53  * Read /proc/meminfo to get usable memory and buffers. Presumably buffers
   54  * should be considered a part of the kernel memory.
   55  */
   56    if ( ( meminfo = fopen ( "/proc/meminfo" , "r" ) ) == NULL )
   57    {
   58       fprintf ( stderr , "%s: cannot open /proc/meminfo" , progname ) ;
   59       perror ( "" ) ;
   60       exit ( 1 ) ;
   61    }
   62    while ( fgets ( buf , sizeof ( buf ) , meminfo ) )
   63    {
   64       if ( !strncmp ( buf , MemLine , MemLineLen ) )
   65       {
   66 	 /* Mem: total used free shared buffers cached */
   67 	 sscanf ( buf , "%*s %d %*d %d %*d %d" , &totalmem , &freemem ,
   68 		  &buffermem ) ;
   69 	 break ;
   70       }
   71    }
   72    sysmem /= 1024 ;
   73    totalmem /= 1024 ;
   74    freemem /= 1024 ;
   75    buffermem /= 1024 ;
   76    kernelmem = sysmem - totalmem ;
   77    fclose ( meminfo ) ;
   78    return ;
   79 }
   80 /*
   81  * Read /proc to get info about processes.
   82  * As a side effect :-) also set variables related to main memory.
   83  */
   84 void
   85 makeProcs ( void )
   86 {
   87    DIR
   88       *proc ;
   89    struct dirent
   90       *procdir ;
   91    FILE
   92       *StatusFile ;
   93    char
   94       buf [128] ;
   95    char
   96       procName [14] ;
   97    int
   98       procSize ,
   99       procRSS ,
  100       procData ,
  101       procStk ,
  102       procExe ;
  103    const char
  104       *NameLine = "Name:" ,
  105       *VmSizeLine = "VmSize:" ,
  106       *VmRSSLine = "VmRSS" ,
  107       *VmDataLine = "VmData" ,
  108       *VmStkLine = "VmStk" ,
  109       *VmExeLine = "VmExe" ;
  110    const int
  111       NameLineLen = strlen ( NameLine ) ,
  112       VmSizeLineLen = strlen ( VmSizeLine ) ,
  113       VmDataLineLen = strlen ( VmDataLine ) ,
  114       VmStkLineLen = strlen ( VmStkLine ) ,
  115       VmExeLineLen = strlen ( VmExeLine ) ,
  116       VmRSSLineLen = strlen ( VmRSSLine ) ;
  117 
  118    if ( ( proc = opendir ( "/proc" ) ) == NULL )
  119    {
  120       fprintf ( stderr , "%s: unable to open /proc" , progname ) ;
  121       perror ( "" ) ;
  122       exit ( 1 ) ;
  123    }
  124    ClearProcs () ;
  125 /*
  126  * Get memory info
  127  */
  128    SetMemInfo () ;
  129 /*
  130  * Make sure that the first process is the kernel. We'll be slightly off,
  131  * but the alternatives (adding this after the rest of the process list
  132  * has been made) are too terrible to contemplate.
  133  */
  134    addProc ( kernelname , kernelmem + buffermem , kernelmem + buffermem ) ;
  135 /*
  136  * NASTY HACK!
  137  * Some screwy feature (or my screwy understanding of /proc) causes the
  138  * sum(RSS) for all the procs + kernel + buffers + freemem to become > system
  139  * memory. Hence we recalculate system memory based on the actual figures
  140  * we get from sum(RSS)+kernel+buffers+freemem
  141  */
  142    sysmem = 0 ;
  143    while ( procdir = readdir ( proc ) )
  144    {
  145       if ( !index ( "1234567890" , procdir -> d_name [0] ) )
  146       {
  147 	 continue ;
  148       }
  149       sprintf ( buf , "/proc/%s/status" , procdir -> d_name ) ;
  150       if ( ( StatusFile = fopen ( buf , "r" ) ) == NULL )
  151       {
  152 	 fprintf ( stderr , "%s: cannot open %s for reading" ,
  153 		   progname , buf ) ;
  154 	 perror ( "" ) ;
  155 	 continue ;
  156       }
  157       procRSS = procSize = procData = procStk = procExe = 0 ;
  158       while ( fgets ( buf , sizeof ( buf ) , StatusFile ) )
  159       {
  160 /*
  161  * I hate sscanf's, but am too lazy to replace them with a more elegant,
  162  * more efficient method right now. Don't you just love TODO lists?
  163  */
  164 	 if ( !strncmp ( buf , NameLine , NameLineLen ) )
  165 	 {
  166 	    /* Name: procName */
  167 	    sscanf ( buf , "%*s %s" , procName ) ;
  168 	 }
  169 	 else if ( !strncmp ( buf , VmSizeLine , VmSizeLineLen ) )
  170 	 {
  171 	    /* VmSize: procSize kB */
  172 	    sscanf ( buf , "%*s %d" , &procSize ) ;
  173 	 }
  174 	 else if ( !strncmp ( buf , VmRSSLine , VmRSSLineLen ) )
  175 	 {
  176 	    /* VmRSS: procRSS kB */
  177 	    sscanf ( buf , "%*s %d" , &procRSS ) ;
  178 	 }
  179 	 else if ( !strncmp ( buf , VmDataLine , VmDataLineLen ) )
  180 	 {
  181 	    /* VmData: procData kB */
  182 	    sscanf ( buf , "%*s %d" , &procData ) ;
  183 	 }
  184 	 else if ( !strncmp ( buf , VmStkLine , VmStkLineLen ) )
  185 	 {
  186 	    /* VmStk: procStk kB */
  187 	    sscanf ( buf , "%*s %d" , &procStk ) ;
  188 	 }
  189 	 else if ( !strncmp ( buf , VmExeLine , VmExeLineLen ) )
  190 	 {
  191 	    /* VmExe: procExe kB */
  192 	    sscanf ( buf , "%*s %d" , &procExe ) ;
  193 	 }
  194       }
  195       fclose ( StatusFile ) ;
  196       addProc ( procName , procSize , procData + procStk + procExe ) ;
  197       sysmem += procData + procStk + procExe ;
  198    }
  199    closedir ( proc ) ;
  200    sysmem += kernelmem + buffermem + freemem ;
  201    addProc ( freename , freemem , freemem ) ;
  202    return ;
  203 }	/* makeProcs */
  204 
  205 #ifdef DEBUG
  206 void
  207 printProcs ( void )
  208 {
  209    struct ProcInfo
  210       *pi ,
  211       *procs ;
  212    int
  213       nprocs ,
  214       nprocs2 ,
  215       totmem ;
  216    register int
  217       i ;
  218    printf ( "%-20s%8s%8s%8s\n" , "Name" , "Memory" , "RSS" , "Number" ) ;
  219    totmem = nprocs2 = 0 ;
  220    procs = AllProcs ( &nprocs ) ;
  221    for ( i = 0 ; i < nprocs ; i++ )
  222    {
  223       pi = &procs[i] ;
  224       printf ( "%-20s%8d%8d%8d\n" , pi -> procname , pi -> totMem ,
  225 	       pi -> totRSS , pi -> nProcs ) ;
  226       nprocs2 += pi -> nProcs ;
  227       if ( strcmp ( pi -> procname , kernelname ) )
  228       {
  229 	 totmem += pi -> totRSS ;
  230       }
  231    }
  232    printf ( "%d procs\n" , nprocs ) ;
  233    printf ( "Mem: %d procs, %d total, %d kernel, %d buffers, %d free\n" ,
  234 	    totmem , sysmem , kernelmem , buffermem , freemem ) ;
  235 }
  236 char *progname ;
  237 void
  238 main ( int argc , char **argv )
  239 {
  240    register int i = 0 ;
  241    progname = *argv ;
  242 
  243    while ( 1 )
  244    {
  245       makeProcs () ;
  246       printProcs () ;
  247       printf ( "\n" ) ;
  248       sleep ( 5 ) ;
  249    }
  250 }
  251 #endif /* DEBUG */