bes  Updated for version 3.20.6
BESStopWatch.cc
1 // BESStopWatch.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // ndp Nathan Potter <ndp@opendap.org>
31 // pwest Patrick West <pwest@ucar.edu>
32 // jgarcia Jose Garcia <jgarcia@ucar.edu>
33 
34 #include <cerrno>
35 #include <string>
36 #include <iostream>
37 #include <cstring>
38 
39 using std::string ;
40 using std::endl;
41 using std::ostream;
42 
43 #include "BESStopWatch.h"
44 #include "BESDebug.h"
45 
46 namespace bes_timing {
47 BESStopWatch *elapsedTimeToReadStart=0;
48 BESStopWatch *elapsedTimeToTransmitStart=0;
49 }
50 
57 bool
58 BESStopWatch::start(string name)
59 {
60  return start(name, MISSING_LOG_PARAM) ;
61 }
62 
71 bool
72 BESStopWatch::start(string name, string reqID)
73 {
74  _timer_name = name;
75  _req_id = reqID;
76  // get timing for current usage
77  if( getrusage( RUSAGE_SELF, &_start_usage ) != 0 )
78  {
79  int myerrno = errno ;
80  char *c_err = strerror( myerrno ) ;
81  string err = "getrusage failed in start: " ;
82  err += (c_err != 0) ? c_err : "unknown error";
83 #if 0
84  if( c_err )
85  {
86  err += c_err ;
87  }
88  else
89  {
90  err += "unknown error" ;
91  }
92 #endif
93  if(BESDebug::GetStrm())
94  *(BESDebug::GetStrm()) << "[" << BESDebug::GetPidStr() << "]["<< _log_name << "][" << _req_id << "][ERROR][" << _timer_name << "][" << err << "]" << endl;
95  _started = false ;
96  }
97  else
98  {
99  _started = true ;
100  struct timeval &start = _start_usage.ru_utime ;
101  double starttime = start.tv_sec*1000.0 + start.tv_usec/1000.0;
102 
103  if(BESDebug::GetStrm())
104  *(BESDebug::GetStrm()) << "[" << BESDebug::GetPidStr() << "]["<< _log_name << "][" << _req_id << "][STARTED][" << starttime << "][ms]["<< _timer_name << "]" << endl;
105  }
106 
107  // either we started the stop watch, or failed to start it. Either way,
108  // no timings are available, so set stopped to false.
109  _stopped = false ;
110 
111 
112  return _started ;
113 }
114 
115 
124 {
125  // if we have started, then stop and update the log.
126  if( _started )
127  {
128  // get timing for current usage
129  if( getrusage( RUSAGE_SELF, &_stop_usage ) != 0 )
130  {
131  int myerrno = errno ;
132  char *c_err = strerror( myerrno ) ;
133  string err = "getrusage failed in stop: " ;
134  err += (c_err != 0) ? c_err : "unknown error";
135 #if 0
136  if( c_err )
137  {
138  err += c_err ;
139  }
140  else
141  {
142  err += "unknown error" ;
143  }
144 #endif
145  if(BESDebug::GetStrm())
146  *(BESDebug::GetStrm()) << "[" << BESDebug::GetPidStr() << "]["<< _log_name << "][" << _req_id << "][ERROR][" << _timer_name << "][" << err << "]" << endl;
147  _started = false ;
148  _stopped = false ;
149  }
150  else
151  {
152  // get the difference between the _start_usage and the
153  // _stop_usage and save the difference in _result.
154  bool success = timeval_subtract() ;
155  if( !success )
156  {
157  if(BESDebug::GetStrm())
158  *(BESDebug::GetStrm()) << "[" << BESDebug::GetPidStr() << "]["<< _log_name << "][" << _req_id << "][ERROR][" << _timer_name << "][Failed to get timing.]" << endl;
159  _started = false ;
160  _stopped = false ;
161  }
162  else
163  {
164  _stopped = true ;
165 
166  struct timeval &stop = _stop_usage.ru_utime ;
167  double stoptime = stop.tv_sec*1000.0 + stop.tv_usec/1000.0;
168  double elapsed = _result.tv_sec*1000.0 + _result.tv_usec/1000.0;
169 
170  if(BESDebug::GetStrm())
171  *(BESDebug::GetStrm()) << "[" << BESDebug::GetPidStr() << "]["<< _log_name << "][" << _req_id << "][STOPPED][" << stoptime << "][ms][" << _timer_name << "][ELAPSED][" << elapsed << "][ms]" << endl;
172 
173  }
174  }
175  }
176 }
177 
178 bool
179 BESStopWatch::timeval_subtract()
180 {
181  struct timeval &start = _start_usage.ru_utime ;
182  struct timeval &stop = _stop_usage.ru_utime ;
183 
184  /* Perform the carry for the later subtraction by updating y. */
185  if( stop.tv_usec < start.tv_usec )
186  {
187  int nsec = (start.tv_usec - stop.tv_usec) / 1000000 + 1 ;
188  start.tv_usec -= 1000000 * nsec ;
189  start.tv_sec += nsec ;
190  }
191  if( stop.tv_usec - start.tv_usec > 1000000 )
192  {
193  int nsec = (start.tv_usec - stop.tv_usec) / 1000000 ;
194  start.tv_usec += 1000000 * nsec ;
195  start.tv_sec -= nsec ;
196  }
197 
198  /* Compute the time remaining to wait.
199  tv_usec is certainly positive. */
200  _result.tv_sec = stop.tv_sec - start.tv_sec ;
201  _result.tv_usec = stop.tv_usec - start.tv_usec ;
202 
203  /* Return 1 if result is negative. */
204  return !(stop.tv_sec < start.tv_sec) ;
205 }
206 
213 void
214 BESStopWatch::dump( ostream &strm ) const
215 {
216  strm << BESIndent::LMarg << "BESStopWatch::dump - ("
217  << (void *)this << ")" << endl ;
218 }
219 
220 
221 
222 
223 
BESStopWatch::start
virtual bool start(std::string name)
Definition: BESStopWatch.cc:58
BESDebug::GetPidStr
static std::string GetPidStr()
return the pid as a string
Definition: BESDebug.cc:124
BESStopWatch::~BESStopWatch
virtual ~BESStopWatch()
Definition: BESStopWatch.cc:123
BESStopWatch
Definition: BESStopWatch.h:55
BESDebug::GetStrm
static std::ostream * GetStrm()
return the debug stream
Definition: BESDebug.h:176
BESStopWatch::dump
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESStopWatch.cc:214