00001 /** @file rutz/trace.cc GVX_TRACE macro for user-controlled tracing and 00002 profiling */ 00003 00004 /////////////////////////////////////////////////////////////////////// 00005 // 00006 // Copyright (c) 1999-2004 California Institute of Technology 00007 // Copyright (c) 2004-2007 University of Southern California 00008 // Rob Peters <rjpeters at usc dot edu> 00009 // 00010 // created: Mon Jan 4 08:00:00 1999 00011 // commit: $Id: trace.cc 8249 2007-04-12 06:03:40Z rjpeters $ 00012 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/trace.cc $ 00013 // 00014 // -------------------------------------------------------------------- 00015 // 00016 // This file is part of GroovX. 00017 // [http://ilab.usc.edu/rjpeters/groovx/] 00018 // 00019 // GroovX is free software; you can redistribute it and/or modify it 00020 // under the terms of the GNU General Public License as published by 00021 // the Free Software Foundation; either version 2 of the License, or 00022 // (at your option) any later version. 00023 // 00024 // GroovX is distributed in the hope that it will be useful, but 00025 // WITHOUT ANY WARRANTY; without even the implied warranty of 00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00027 // General Public License for more details. 00028 // 00029 // You should have received a copy of the GNU General Public License 00030 // along with GroovX; if not, write to the Free Software Foundation, 00031 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00032 // 00033 /////////////////////////////////////////////////////////////////////// 00034 00035 #ifndef GROOVX_RUTZ_TRACE_CC_UTC20050626084020_DEFINED 00036 #define GROOVX_RUTZ_TRACE_CC_UTC20050626084020_DEFINED 00037 00038 #include "rutz/trace.h" 00039 00040 #include "rutz/backtrace.h" 00041 00042 #include <iostream> 00043 00044 /////////////////////////////////////////////////////////////////////// 00045 // 00046 // File-scope helper functions and data 00047 // 00048 /////////////////////////////////////////////////////////////////////// 00049 00050 namespace 00051 { 00052 unsigned int g_max_trace_level = 20; 00053 bool g_do_global_trace = false; 00054 00055 void print_in(const char* context_name) throw() 00056 { 00057 const unsigned int n = rutz::backtrace::current().size(); 00058 00059 if (n < g_max_trace_level) 00060 { 00061 for (unsigned int i = 0; i < n; ++i) 00062 { 00063 std::cerr << "| "; 00064 } 00065 // Test whether n has 1, 2, or >3 digits 00066 if (n < 10) 00067 std::cerr << n << "-->> "; 00068 else if (n < 100) 00069 std::cerr << n << "->> "; 00070 else 00071 std::cerr << n << ">> "; 00072 00073 std::cerr << context_name << '\n'; 00074 } 00075 } 00076 00077 void print_out(const char* context_name) throw() 00078 { 00079 const unsigned int n = rutz::backtrace::current().size(); 00080 00081 if (n < g_max_trace_level) 00082 { 00083 for (unsigned int i = 0; i < n; ++i) 00084 { 00085 std::cerr << "| "; 00086 } 00087 std::cerr << "| <<--"; 00088 00089 std::cerr << context_name << '\n'; 00090 } 00091 00092 if (n == 0) 00093 std::cerr << '\n'; 00094 } 00095 } 00096 00097 /////////////////////////////////////////////////////////////////////// 00098 // 00099 // rutz::trace member definitions 00100 // 00101 /////////////////////////////////////////////////////////////////////// 00102 00103 bool rutz::trace::get_global_trace() throw() 00104 { 00105 return g_do_global_trace; 00106 } 00107 00108 void rutz::trace::set_global_trace(bool on_off) throw() 00109 { 00110 g_do_global_trace = on_off; 00111 } 00112 00113 unsigned int rutz::trace::get_max_level() throw() 00114 { 00115 return g_max_trace_level; 00116 } 00117 00118 void rutz::trace::set_max_level(unsigned int lev) throw() 00119 { 00120 g_max_trace_level = lev; 00121 } 00122 00123 rutz::trace::trace(prof& p, bool use_msg) throw() 00124 : 00125 m_prof(p), 00126 m_start(), 00127 m_should_print_msg(g_do_global_trace || use_msg), 00128 m_should_pop(rutz::backtrace::current().push(&p)), 00129 m_timing_mode(rutz::prof::get_timing_mode()) 00130 { 00131 if (this->m_should_print_msg) 00132 print_in(this->m_prof.context_name()); 00133 00134 // We want this to be the last thing in the constructor, so that we 00135 // don't include the rest of the constructor runtime in our elapsed 00136 // time measurement: 00137 this->m_start = rutz::prof::get_now_time(this->m_timing_mode); 00138 } 00139 00140 rutz::trace::~trace() throw() 00141 { 00142 // We want this to be the first thing in the destructor, so that we 00143 // don't include the rest of the destructor runtime in our elapsed 00144 // time measurement: 00145 const rutz::time finish = rutz::prof::get_now_time(this->m_timing_mode); 00146 const rutz::time elapsed = finish - this->m_start; 00147 00148 this->m_prof.add_time(elapsed); 00149 00150 // Do a backtrace::pop() only if the corresponding backtrace::push() 00151 // succeeeded in the constructor (it could have failed due to memory 00152 // exhaustion, etc.): 00153 if (this->m_should_pop) 00154 { 00155 rutz::backtrace& c = rutz::backtrace::current(); 00156 c.pop(); 00157 rutz::prof* parent = c.top(); 00158 if (parent != 0) 00159 parent->add_child_time(elapsed); 00160 } 00161 00162 if (this->m_should_print_msg) 00163 print_out(this->m_prof.context_name()); 00164 } 00165 00166 static const char __attribute__((used)) vcid_groovx_rutz_trace_cc_utc20050626084020[] = "$Id: trace.cc 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/trace.cc $"; 00167 #endif // !GROOVX_RUTZ_TRACE_CC_UTC20050626084020_DEFINED