"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 }