Timer.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 // $Id: Timer.C,v 1.19 2007/05/30 19:20:16 legendre Exp $
00032 
00033 #include "common/h/Timer.h"
00034 
00035 timer::timer()
00036 : usecs_(0), ssecs_(0), wsecs_(0), cu_(0), cs_(0), cw_(0),
00037   activation_count_(0),
00038 #if defined(os_windows)
00039   CYCLES_PER_SEC_(CLK_TCK), // TODO: is this right?
00040 #else
00041   CYCLES_PER_SEC_(sysconf(_SC_CLK_TCK)), 
00042 #endif
00043   MICROSECS_PER_SEC_(1.0e6),
00044   NANOSECS_PER_SEC_(1.0e9)
00045 {
00046 }
00047 
00048 timer::timer(const timer& t)
00049     : usecs_(t.usecs_), ssecs_(t.ssecs_), wsecs_(t.wsecs_),
00050     cu_(t.cu_), cs_(t.cs_), cw_(t.cw_), activation_count_(t.activation_count_),
00051     CYCLES_PER_SEC_(t.CYCLES_PER_SEC_), MICROSECS_PER_SEC_(t.MICROSECS_PER_SEC_),
00052     NANOSECS_PER_SEC_(t.NANOSECS_PER_SEC_)
00053 {
00054 }
00055 
00056 timer::~timer() {}
00057 
00058 timer&
00059 timer::operator=(const timer& t) {
00060     if (this != &t) {
00061         usecs_ = t.usecs_; ssecs_ = t.ssecs_; wsecs_ = t.wsecs_;
00062         cu_    = t.cu_;    cs_    = t.cs_;    cw_    = t.cw_;
00063         activation_count_ = t.activation_count_;
00064     }
00065     return *this;
00066 }
00067 
00068 timer&
00069 timer::operator+=(const timer& t) {
00070     timer st = t; st.stop();
00071     usecs_ += st.usecs_;
00072     ssecs_ += st.ssecs_;
00073     wsecs_ += st.wsecs_;
00074     return *this;
00075 }
00076 
00077 timer
00078 timer::operator+(const timer& t) const {
00079     timer ret = *this;
00080     return ret += t;
00081 }
00082 
00083 void
00084 timer::clear() {
00085     usecs_ = ssecs_ = wsecs_ = 0;
00086     cu_    = cs_    = cw_    = 0;
00087     activation_count_ = 0;
00088 }
00089 
00090 void
00091 timer::start() {
00092     if (activation_count_ == 0)
00093         get_current(cu_, cs_, cw_);
00094     activation_count_++;
00095 }
00096 
00097 void
00098 timer::stop() {
00099     if (activation_count_ == 0) return;
00100 
00101     activation_count_--;
00102     if (activation_count_ == 0) {
00103         double cu, cs, cw;
00104         get_current(cu, cs, cw);
00105         
00106         usecs_ += (cu - cu_);
00107         ssecs_ += (cs - cs_);
00108         wsecs_ += (cw - cw_);
00109     }
00110 }
00111 
00112 double
00113 timer::usecs() const {
00114     return usecs_;
00115 }
00116 
00117 double
00118 timer::ssecs() const {
00119     return ssecs_;
00120 }
00121 
00122 double
00123 timer::wsecs() const {
00124     return wsecs_;
00125 }
00126 
00127 bool
00128 timer::is_running() const {
00129     return (activation_count_ > 0);
00130 }
00131 
00132 
00133 
00134 
00135 /************************************************************************
00136  * architecture/operating system specific timer functions.
00137 ************************************************************************/
00138 
00139 
00140 
00141 
00142 
00143 #undef HAVE_GET_CURRENT_DEFINITION
00144 
00145 
00146 
00147 
00148 #if defined(os_windows)
00149 #if !defined(HAVE_GET_CURRENT_DEFINITION)
00150 #define HAVE_GET_CURRENT_DEFINITION
00151 
00152 #include <sys/timeb.h>
00153 #include <time.h>
00154 #include <winbase.h>
00155 #include <limits.h>
00156 
00157 void
00158 timer::get_current(double& u, double& s, double& w) {
00159   /*
00160     u = user time
00161     s = system time
00162     w = wall time
00163   */
00164 
00165   struct _timeb tb;
00166   _ftime(&tb);
00167   w = (double)tb.time + (double)tb.millitm/1000.0;
00168 
00169   FILETIME kernelT, userT, creatT, exitT;
00170   if (GetProcessTimes(GetCurrentProcess(), &creatT, &exitT, &kernelT, &userT)) {
00171     timer t;
00172     s = ((double)kernelT.dwHighDateTime * ((double)_UI32_MAX + 1.0)
00173         + (double)kernelT.dwLowDateTime)*100.0 / t.NANOSECS_PER_SEC();
00174     u = ((double)userT.dwHighDateTime * ((double)_UI32_MAX + 1.0)
00175         + (double)userT.dwLowDateTime)*100.0 / t.NANOSECS_PER_SEC();
00176   } else {
00177     u = 0;
00178     s = 0;
00179   }
00180 }
00181 
00182 #endif /* !defined(HAVE_GET_CURRENT_DEFINITION) */
00183 #endif /* defined(os_windows) */
00184 
00185 
00186 
00187 
00188 
00189 #if !defined(HAVE_GET_CURRENT_DEFINITION)
00190 #define HAVE_GET_CURRENT_DEFINITION
00191 
00192 #include <sys/types.h>
00193 #include <sys/time.h>
00194 #include <sys/times.h>
00195 
00196 #if !defined(os_aix) && !defined(os_linux)
00197 extern "C" int gettimeofday(struct timeval *tp, struct timezone *tzp);
00198 #endif
00199 
00200 void
00201 timer::get_current(double& u, double& s, double& w) {
00202     struct tms     tb;
00203     struct timeval tv;
00204     if (times(&tb) == -1) {
00205         perror("times");
00206         abort();
00207     }
00208     if (gettimeofday(&tv, 0) == -1) {
00209       perror("gettimeofday");
00210       abort();
00211     }
00212 
00213     timer t;
00214     u = tb.tms_utime / t.CYCLES_PER_SEC();
00215     s = tb.tms_stime / t.CYCLES_PER_SEC();
00216     w = (tv.tv_sec + tv.tv_usec/t.MICROSECS_PER_SEC());
00217 }
00218 #endif /* !defined(HAVE_GET_CURRENT_DEFINITION) */
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1