TextLog.C

Go to the documentation of this file.
00001 /*!@file Util/TextLog.C Functions for logging model/simulation events */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Util/TextLog.C $
00035 // $Id: TextLog.C 6528 2006-04-25 18:57:30Z rjpeters $
00036 //
00037 
00038 #ifndef UTIL_TEXTLOG_C_DEFINED
00039 #define UTIL_TEXTLOG_C_DEFINED
00040 
00041 #include "Util/TextLog.H"
00042 
00043 #include "Util/Assert.H"
00044 #include "Util/SimTime.H"
00045 #include "Util/log.H"
00046 #include "Util/sformat.H"
00047 #include "rutz/mutex.h"
00048 
00049 #include <fstream>
00050 #include <map>
00051 
00052 /* A note on the implementation strategy here for the text-logging
00053    functions: internally, we keep a map of TextLogger objects, one per
00054    filename. When one of the public functions is called, we look up
00055    the associated TextLogger object, creating it if needed, and then
00056    perform the requested logging action on that object.
00057 */
00058 
00059 namespace
00060 {
00061   // ######################################################################
00062   class TextLogger
00063   {
00064   public:
00065     TextLogger(const std::string& fname)
00066       :
00067       itsMutex(),
00068       itsStream(fname.c_str()),
00069       itsTime(SimTime::ZERO())
00070     {
00071       pthread_mutex_init(&itsMutex, 0);
00072 
00073       if (!itsStream.is_open())
00074         {
00075           LFATAL("Couldn't open text log file '%s' for writing",
00076                  fname.c_str());
00077         }
00078       else
00079         {
00080           LINFO("Opened textlog file '%s'", fname.c_str());
00081         }
00082     }
00083 
00084     void log(const std::string& event,
00085              const std::string& details)
00086     {
00087       this->log(event, details, itsTime);
00088     }
00089 
00090     void log(const std::string& event,
00091              const std::string& details,
00092              const SimTime& t)
00093     {
00094       GVX_MUTEX_LOCK(&itsMutex);
00095 
00096       itsStream
00097         << sformat("%010.02fms %-20s ", t.msecs(), event.c_str())
00098         << details << std::endl;
00099       itsStream.flush();  // don't lose messages if ctrl-C
00100     }
00101 
00102     void setTime(const SimTime& t)
00103     {
00104       GVX_MUTEX_LOCK(&itsMutex);
00105 
00106       itsTime = t;
00107     }
00108 
00109   private:
00110     pthread_mutex_t itsMutex;
00111     std::ofstream itsStream;
00112     SimTime itsTime;
00113   };
00114 
00115   // ######################################################################
00116   typedef std::map<std::string, TextLogger*> LoggerMap;
00117 
00118   LoggerMap* g_loggers;
00119   pthread_mutex_t g_loggers_mutex = PTHREAD_MUTEX_INITIALIZER;
00120 
00121   pthread_once_t g_loggers_init_once = PTHREAD_ONCE_INIT;
00122   void loggers_init()
00123   {
00124     ASSERT(g_loggers == 0);
00125     g_loggers = new LoggerMap;
00126   }
00127 
00128   // ######################################################################
00129   TextLogger* get_logger(const std::string& fname)
00130   {
00131     pthread_once(&g_loggers_init_once, loggers_init);
00132 
00133     ASSERT(g_loggers != 0);
00134 
00135     GVX_MUTEX_LOCK(&g_loggers_mutex);
00136 
00137     LoggerMap::iterator itr = g_loggers->find(fname);
00138 
00139     if (itr != g_loggers->end())
00140       {
00141         return (*itr).second;
00142       }
00143 
00144     // else, let's create a new logger for the given fname
00145     TextLogger* logger = new TextLogger(fname);
00146     g_loggers->insert(LoggerMap::value_type(fname, logger));
00147     return logger;
00148   }
00149 }
00150 
00151 // ######################################################################
00152 void textLog(const std::string& fname,
00153              const std::string& event,
00154              const std::string& details)
00155 {
00156   if (!fname.empty())
00157     get_logger(fname)->log(event, details);
00158 }
00159 
00160 // ######################################################################
00161 void textLog(const std::string& fname,
00162              const std::string& event,
00163              const std::string& details,
00164              const SimTime& t)
00165 {
00166   if (!fname.empty())
00167     get_logger(fname)->log(event, details, t);
00168 }
00169 
00170 // ######################################################################
00171 void setLogTime(const std::string& fname,
00172                 const SimTime& t)
00173 {
00174   if (!fname.empty())
00175     get_logger(fname)->setTime(t);
00176 }
00177 
00178 // ######################################################################
00179 /* So things look consistent in everyone's emacs... */
00180 /* Local Variables: */
00181 /* mode: c++ */
00182 /* indent-tabs-mode: nil */
00183 /* End: */
00184 
00185 #endif // UTIL_TEXTLOG_C_DEFINED
Generated on Sun May 8 08:42:32 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3