"Fossies" - the Fresh Open Source Software Archive

Member "xosview-1.23/irix65/sarmeter.cc" (11 Jul 2020, 4876 Bytes) of package /linux/misc/xosview-1.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sarmeter.cc" see the Fossies "Dox" file reference documentation.

    1 //  
    2 //  Initial port performed by Stefan Eilemann (eilemann@gmail.com)
    3 //
    4 
    5 #include "sarmeter.h"
    6 
    7 #include <fcntl.h>
    8 
    9 SarMeter *SarMeter::_instance = NULL;
   10 
   11 SarMeter *SarMeter::Instance()
   12 {
   13     if( _instance == NULL )
   14         _instance = new SarMeter();
   15 
   16     return _instance;
   17 }
   18 
   19 SarMeter::SarMeter( void )
   20     : _bufSize(0)
   21 {
   22     _input = setupSadc();
   23     
   24     _gi.last.gswapbuf = 0;
   25     _gi.info.swapBuf = 0;
   26     
   27     for( int i=0; i<MAX_DISKS; i++ )
   28     {
   29         _di.last[i].stat.io_bcnt  = 0;
   30         _di.last[i].stat.io_wbcnt = 0;
   31         
   32         _di.info.nDevices = 0;
   33         _di.info.read[i] = 0;
   34         _di.info.write[i] = 0;
   35     }
   36 }
   37 
   38 bool SarMeter::readLine( void )
   39 {
   40     while( _bufSize < BUFSIZE-100 )
   41     {
   42         int ret = read( _input, &_buf[_bufSize], 100);
   43 
   44         if( ret < 0 )
   45             return false; // error equals eof in our case
   46 
   47         _bufSize += ret;
   48 
   49         if( ret < 100 ) // eof reached
   50             return false;
   51     }
   52 
   53     // buffer full
   54     return true;
   55 }
   56 
   57 void SarMeter::checkSadc( void )
   58 {
   59     bool dataInPipe = true;
   60 
   61     while( dataInPipe )
   62     {
   63         dataInPipe = readLine();
   64         parseBuffer();
   65     }
   66 }
   67 
   68 void SarMeter::parseBuffer( void )
   69 {
   70     while( _bufSize > 100 )
   71     {
   72         // look for 'S' (starting of Sarmagic)
   73         char *ptr = (char *)memchr( _buf, 'S', _bufSize );
   74         
   75         // not found -- discard this buffer
   76         if( ptr == NULL )
   77         {
   78             _bufSize = 0;
   79             return;
   80         }
   81 
   82         // not enough data read
   83         if( (ptr+100) > (_buf+_bufSize) )
   84             return;
   85 
   86 
   87         // check for SarmagicGFX
   88         if( memcmp( ptr, "SarmagicGFX", 11 ) == 0 )
   89         {
   90             forwardBufferTo( ptr );
   91 
   92             // data is not complete in buffer
   93             if( _bufSize < 24 + sizeof( gfxinfo ))
   94                 return;
   95 
   96             // retrieve gfxinfo structure
   97             ptr = _buf + 24;
   98             memcpy( &_gi.current, ptr, sizeof( gfxinfo ));
   99             ptr += sizeof( gfxinfo );
  100 
  101             forwardBufferTo( ptr );
  102             newGfxInfo();
  103         }
  104         // check for SarmagicNEODISK
  105         else if( memcmp( ptr, "SarmagicNEODISK", 15 ) == 0 )
  106         {
  107             forwardBufferTo( ptr );
  108 
  109             ptr = _buf + 20;
  110 
  111             // number of records [devices]
  112             int num;
  113             memcpy( &num, ptr, 4 );
  114             ptr += 4;
  115 
  116             if( num > MAX_DISKS ) num = MAX_DISKS;
  117 
  118             // data is not complete in buffer
  119             if( _bufSize < 24 + num*sizeof( diskinfo ))
  120                 return;
  121 
  122             _di.info.nDevices = num;
  123 
  124             // read disk info
  125             for( int i=0; i<num; i++ )
  126             {
  127                 memcpy( &_di.current[i], ptr, sizeof( diskinfo ));
  128                 ptr += sizeof( diskinfo );
  129             }
  130             
  131             forwardBufferTo( ptr );
  132             newDiskInfo();
  133         }
  134         else // no known Sarmagic record
  135             forwardBufferTo( ptr+1 );
  136     }
  137 }
  138 
  139 void SarMeter::newGfxInfo( void )
  140 {
  141     if( _gi.last.gswapbuf == 0 )
  142     {
  143         _gi.last.gswapbuf = _gi.current.gswapbuf;
  144         return;
  145     }
  146 
  147     _gi.info.swapBuf = _gi.current.gswapbuf - _gi.last.gswapbuf;
  148     _gi.last.gswapbuf = _gi.current.gswapbuf;
  149 }
  150 
  151 void SarMeter::newDiskInfo( void )
  152 {
  153     for( int i=0; i<_di.info.nDevices; i++ )
  154     {
  155         _di.info.read[i]  = 
  156             (_di.current[i].stat.io_bcnt - _di.current[i].stat.io_wbcnt) - 
  157             (_di.last[i].stat.io_bcnt    - _di.last[i].stat.io_wbcnt) ;
  158 
  159         _di.info.write[i] = 
  160             _di.current[i].stat.io_wbcnt - _di.last[i].stat.io_wbcnt;
  161 
  162         _di.info.read[i] *= 512;
  163         _di.info.write[i] *= 512;
  164 
  165         _di.last[i].stat.io_bcnt  = _di.current[i].stat.io_bcnt;
  166         _di.last[i].stat.io_wbcnt = _di.current[i].stat.io_wbcnt;        
  167     }
  168 }
  169 
  170 void SarMeter::forwardBufferTo( char *ptr )
  171 {
  172     size_t moveBytes = ptr-_buf;
  173     size_t bytesLeft = _bufSize - moveBytes;
  174     memmove( _buf, ptr, bytesLeft );
  175     _bufSize = bytesLeft;
  176 };
  177 
  178 
  179 // starts /usr/bin/sar, from where data is read
  180 int SarMeter::setupSadc( void )
  181 {
  182     char    sarPath[] = "/usr/lib/sa/sadc";
  183     int fd[2];
  184     int input = 0;
  185 
  186     if (pipe(fd) == -1)
  187     {
  188         perror("setupSar: pipe");
  189         return 0;
  190     }
  191 
  192     if ( fork()==0 )    // child
  193     {
  194         close(1);       // move fd[write] to stdout
  195         dup(fd[1]);
  196         close(fd[1]);
  197         close(fd[0]);   // close other end of the pipe
  198         close(2);       // close stderr
  199         setbuf(stdout,NULL); // unbuffered stdout
  200 
  201         // sar wants number of loops: 31536000 is one year
  202         if (execlp (sarPath, sarPath, "1", "31536000", 0) == -1)
  203             perror("setupSar: exec sar");
  204 
  205         // not reached
  206         exit(0);
  207     }
  208 
  209     input = fd[0];
  210     close(fd[1]);   // Close other end of the pipe
  211 
  212     fcntl( input, F_SETFL, FNONBLK );
  213 
  214     return input;
  215 }