root/juggler/tags/1.0.5/Performance/vjPerfDataBuffer.cpp

Revision 7539, 7.9 kB (checked in by anonymous, 7 years ago)

This commit was manufactured by cvs2svn to create tag
'RELENG_1_0_5_RELEASE'.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
2  *
3  * VR Juggler is (C) Copyright 1998, 1999, 2000 by Iowa State University
4  *
5  * Original Authors:
6  *   Allen Bierbaum, Christopher Just,
7  *   Patrick Hartling, Kevin Meinert,
8  *   Carolina Cruz-Neira, Albert Baker
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the
22  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  * -----------------------------------------------------------------
26  * File:          $RCSfile$
27  * Date modified: $Date$
28  * Version:       $Revision$
29  * -----------------------------------------------------------------
30  *
31  *************** <auto-copyright.pl END do not edit this line> ***************/
32
33
34 #include <Performance/vjPerfDataBuffer.h>
35 #include <Kernel/vjDebug.h>
36
37
38 void vjPerfDataBuffer::init (const char* _name, int _numbufs,
39                                     int _nindex) {
40     name = strdup (_name);
41     numbufs = _numbufs;
42     buffer = new buf_entry[numbufs];
43     read_begin = 0;
44     write_pos = 1;
45     lost = 0;
46     active = 0;
47     nindex = _nindex;
48 }
49
50
51
52 //: destructor
53 //: POST: all memory & buffers have been freed.
54 vjPerfDataBuffer::~vjPerfDataBuffer () {
55     active = 0;
56     delete []buffer;
57     delete name;
58 }
59
60
61
62 //: activates the buffer
63 //! POST: once this call is made, the buffer will start
64 //+       storing data whenever a set() is made and
65 //+       writing available data when requested.
66 void vjPerfDataBuffer::activate() {
67     active = 1;
68     vjDEBUG(vjDBG_PERFORMANCE,1) << "Performance Buffer " << name <<
69         " activated.\n" << vjDEBUG_FLUSH;
70 }
71
72
73
74 //: deactivates the buffer
75 //! POST: once this call is made, the buffer will,
76 //+       essentially, do nothing.  set() will not store
77 //+       any information and the write calls won't
78 //+       write anything.
79 void vjPerfDataBuffer::deactivate() {
80     active = 0;
81     /* deactivate maybe should reset the buffer so it's reactivated
82      * with a clean slate, thusly:
83      */
84     read_begin = 0;
85     write_pos = 1;
86     lost = 0;
87     vjDEBUG(vjDBG_PERFORMANCE,1) << "Performance Buffer " << name <<
88         " deactivated.\n" << vjDEBUG_FLUSH;
89
90 }
91
92
93
94 bool vjPerfDataBuffer::isActive() {
95     return active;
96 }
97
98
99
100 //: writes a new time entry to the buffer
101 //! POST: if a buffer is available, it is stamped with
102 //+       the current time and _phase.  If not, the
103 //+       'lost' counter is incremented.
104 //! ARGS: _phase - an integer index used to differentiate
105 //+       between different stamping points in the process
106 //+       that calls set. e.g. 1 = point right before
107 //+       entering some big computation, and 2 = point
108 //+       right after.
109 void vjPerfDataBuffer::set(int _phase) {
110     int tw;
111
112     if (!active)
113         return;
114
115     if (write_pos == read_begin) {
116         if (lost_lock.acquire() != -1) {
117             lost++;
118             lost_lock.release();
119         }
120         else
121             vjDEBUG(vjDBG_ALL,2) << "vjPerfDataBuffer: lock acquire "
122                        << "failed\n" << vjDEBUG_FLUSH;
123         tw = (write_pos + numbufs - 1) % numbufs;
124         buffer[tw].phase = _phase;
125         buffer[tw].ts.set();
126     }
127     else {
128         buffer[write_pos].phase = _phase;
129         buffer[write_pos].ts.set();
130         write_pos = (write_pos+1)%numbufs;
131     }
132 }
133
134
135 void vjPerfDataBuffer::set (int _phase, vjTimeStamp& _value) {
136     int tw;
137
138     if (!active)
139         return;
140
141     if (write_pos == read_begin) {
142         lost_lock.acquire();
143         lost++;
144         lost_lock.release();
145
146         // overwrite last buffer pos with most recent
147         tw = (write_pos + numbufs - 1) % numbufs;
148         buffer[tw].phase = _phase;
149         buffer[tw].ts = _value;
150     }
151     else {
152         buffer[write_pos].phase = _phase;
153         buffer[write_pos].ts = _value;
154         write_pos = (write_pos+1)%numbufs;
155     }
156 }
157
158
159     // for below: need a version w/ max # buffers to write
160
161     //: writes buffer contents to an ostream
162     //! POST: As many buffers as available are written to
163     //+       the ostream out and released so they can be
164     //+       used again by the writer.
165     //! ARGS: out - an ostream to write contents to.
166     //! NOTE: The format for a buffer is 'ind timestamp\n',
167     //+       e.g.: (for four buffers, say we have 3 indices)
168     //+       <br>1 15
169     //+       <br>2 25
170     //+       <br>3 27
171     //+       <br>1 42
172 void vjPerfDataBuffer::write (std::ostream& out) {
173     // the only tricky part of this is that the region we
174     // want to print out might wrap back around to the
175     // beginning of the list.  That's what the 2nd big
176     // case is for.
177     int begin, end, i, tlost;
178     buf_entry* b;
179
180     //out.width(13);
181
182     if (!active)
183         return;
184
185     //out << "PerfData " << name << "\n";
186     begin = read_begin;
187     end = (write_pos - 1 + numbufs)%numbufs;
188     //cout << "begin/end are " << begin <<' '<< end << endl;
189     if (begin == end)
190         return;
191     out << "PerfData1 \"" << name << "\" " << nindex << std::endl;
192     if (begin < end) {
193         for (i = begin; i < end; i++) {
194             b = &(buffer[i]);
195             out << b->phase << ' '
196                 << std::setiosflags(std::ios::fixed) << b->ts << '\n';
197         }
198     }
199     else { /* wraparound */
200         for (i = begin; i < numbufs; i++) {
201             b = &(buffer[i]);
202             out << b->phase << ' ' << std::setiosflags(std::ios::fixed)
203                 << b->ts << '\n';
204         }
205         for (i = 0; i < end; i++) {
206             b = &(buffer[i]);
207             out << b->phase << ' ' << std::setiosflags(std::ios::fixed)
208                 << b->ts << '\n';
209         }
210     }
211        
212     lost_lock.acquire();
213     tlost = lost;
214     lost = 0;
215     lost_lock.release();
216     read_begin = end;
217
218     out << -1 << ' ' << tlost << std::endl;
219
220 }
221
222
223
224 // this probably isn't safe in a multitasking environment
225 void vjPerfDataBuffer::writeTotal(std::ostream& out, int preskip, int postskip, float discrep) {
226     int begin = read_begin;
227     int end = (write_pos - 1 + numbufs)%numbufs;
228     int last = (end + numbufs-1) %numbufs;
229     float retval;
230     int nump;
231     int i;
232     float diff, avg;
233
234     retval = buffer[(end-postskip)%numbufs].ts - buffer[(begin+preskip)%numbufs].ts;
235     /*
236     cout << "begin is " << begin
237          << "\nend is " << end
238          << "\nlast is " << last << endl;
239     */
240     if (last > begin)
241         nump = last - begin;
242     else
243         nump = last + (numbufs - begin);
244
245     avg = retval/(nump - preskip - postskip);
246
247     out << "Dumping buffer: " << nump << " samples, total: "
248         << retval << " us, avg: " << avg << "us\n";
249     if (discrep > 0) {
250         out << "Reporting Discrepencies:\n";
251     }
252     end = (end-postskip)%numbufs;
253     begin = (begin + preskip)%numbufs;
254
255         if (begin == end)
256             return;
257         else if (begin < end) {
258             for (i = begin+1; i < end; i++) {
259                 diff = buffer[i].ts - buffer[i-1].ts;
260                 if (fabsf(diff - avg) > avg * discrep) {
261                     out << "    " << diff << " us at time "
262                         << buffer[i-1].ts << " us\n";
263                 }
264             }
265         }
266         else { /* wraparound */
267             for (i = begin+1; i < numbufs; i++) {
268                 diff = buffer[i].ts - buffer[i-1].ts;
269                 if (fabsf(diff - avg) > avg * discrep) {
270                     out << "    " << diff << " us at time "
271                         << buffer[i-1].ts << " us\n";
272
273                 }
274             }
275             diff = buffer[0].ts - buffer[numbufs].ts;
276             if (fabsf(diff - avg) > avg * discrep) {
277                 out << "    " << diff << " us at time "
278                     << buffer[numbufs].ts << " us\n";
279             }
280             for (i = 1; i < end; i++) {
281                 diff = buffer[i].ts - buffer[i-1].ts;
282                 if (fabsf(diff - avg) > avg * discrep) {
283                     out << "    " << diff << " us at time "
284                         << buffer[i-1].ts << " us\n";
285                 }
286             }
287        
288         }
289
290
291     lost_lock.acquire();
292     lost = 0;
293     lost_lock.release();
294     read_begin = end;
295
296 }
297
298
299 void vjPerfDataBuffer::dumpData() {
300
301     lost_lock.acquire();
302     read_begin = 0;
303     write_pos = 1;
304     lost = 0;
305     lost_lock.release();
306
307 }
Note: See TracBrowser for help on using the browser.