Chris@49: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@0: 
Chris@0: /*
Chris@52:     Sonic Visualiser
Chris@52:     An audio file viewer and annotation editor.
Chris@52:     Centre for Digital Music, Queen Mary, University of London.
Chris@0:     
Chris@52:     This program is free software; you can redistribute it and/or
Chris@52:     modify it under the terms of the GNU General Public License as
Chris@52:     published by the Free Software Foundation; either version 2 of the
Chris@52:     License, or (at your option) any later version.  See the file
Chris@52:     COPYING included with this distribution for more information.
Chris@0: */
Chris@0: 
Chris@0: /*
Chris@0:    This is a modified version of a source file from the 
Chris@0:    Rosegarden MIDI and audio sequencer and notation editor.
Chris@202:    This file copyright 2000-2006 Chris Cannam, Guillaume Laurent,
Chris@202:    and QMUL.
Chris@0: */
Chris@0: 
Chris@0: 
Chris@1581: #ifndef SV_PROFILER_H
Chris@1581: #define SV_PROFILER_H
Chris@0: 
Chris@150: #include "system/System.h"
Chris@0: 
Chris@0: #include <map>
Chris@0: 
Chris@0: #include "RealTime.h"
Chris@0: 
Chris@183: //#define NO_TIMING 1
Chris@183: 
Chris@434: //#define WANT_TIMING 1
Chris@183: 
Chris@183: #ifdef NDEBUG
Chris@183: #ifndef WANT_TIMING
Chris@183: #define NO_TIMING 1
Chris@183: #endif
Chris@183: #endif
Chris@0: 
Chris@1216: #ifndef NO_TIMING
Chris@1216: #include <ctime>
Chris@1216: #include <sys/time.h>
Chris@1216: #endif
Chris@1216: 
Chris@0: /**
Chris@0:  * Profiling classes
Chris@0:  */
Chris@0: 
Chris@0: /**
Chris@0:  * The class holding all profiling data
Chris@0:  *
Chris@0:  * This class is a singleton
Chris@0:  */
Chris@0: class Profiles
Chris@0: {
Chris@0: public:
Chris@0:     static Profiles* getInstance();
Chris@0:     ~Profiles();
Chris@0: 
Chris@1216: #ifndef NO_TIMING
Chris@0:     void accumulate(const char* id, clock_t time, RealTime rt);
Chris@1216: #endif
Chris@183:     void dump() const;
Chris@0: 
Chris@0: protected:
Chris@0:     Profiles();
Chris@0: 
Chris@1216: #ifndef NO_TIMING
Chris@0:     typedef std::pair<clock_t, RealTime> TimePair;
Chris@0:     typedef std::pair<int, TimePair> ProfilePair;
Chris@0:     typedef std::map<const char *, ProfilePair> ProfileMap;
Chris@0:     typedef std::map<const char *, TimePair> LastCallMap;
Chris@183:     typedef std::map<const char *, TimePair> WorstCallMap;
Chris@0:     ProfileMap m_profiles;
Chris@0:     LastCallMap m_lastCalls;
Chris@183:     WorstCallMap m_worstCalls;
Chris@1216: #endif
Chris@0: 
Chris@0:     static Profiles* m_instance;
Chris@0: };
Chris@0: 
Chris@183: #ifndef NO_TIMING
Chris@183: 
Chris@183: /**
Chris@183:  * Profile point instance class.  Construct one of these on the stack
Chris@183:  * at the start of a function, in order to record the time consumed
Chris@183:  * within that function.  The profiler object should be effectively
Chris@183:  * optimised out if NO_TIMING is defined, so any overhead in a release
Chris@183:  * build should be negligible so long as you remember to define that.
Chris@183:  */
Chris@0: class Profiler
Chris@0: {
Chris@0: public:
Chris@183:     /**
Chris@183:      * Create a profile point instance that records time consumed
Chris@183:      * against the given profiling point name.  If showOnDestruct is
Chris@183:      * true, the time consumed will be printed to stderr when the
Chris@183:      * object is destroyed; otherwise, only the accumulated, mean and
Chris@183:      * worst-case times will be shown when the program exits or
Chris@183:      * Profiles::dump() is called.
Chris@183:      */
Chris@183:     Profiler(const char *name, bool showOnDestruct = false);
Chris@0:     ~Profiler();
Chris@0: 
Chris@183:     void update() const;
Chris@408:     void end(); // same action as dtor
Chris@0: 
Chris@0: protected:
Chris@0:     const char* m_c;
Chris@0:     clock_t m_startCPU;
Chris@0:     RealTime m_startTime;
Chris@0:     bool m_showOnDestruct;
Chris@408:     bool m_ended;
Chris@0: };
Chris@183: 
Chris@183: #else
Chris@183: 
Chris@183: class Profiler
Chris@183: {
Chris@183: public:
Chris@408:     Profiler(const char *, bool = false) { }
Chris@183:     ~Profiler() { }
Chris@408: 
Chris@408:     void update() const { }
Chris@408:     void end() { }
Chris@183: };
Chris@0: 
Chris@0: #endif
Chris@183: 
Chris@183: #endif