StopWatch.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _SUPPORT_STOP_WATCH_H_
00014 #define _SUPPORT_STOP_WATCH_H_
00015 
00021 #include <support/SupportDefs.h>
00022 
00023 #ifndef _INCLUDES_PERFORMANCE_INSTRUMENTATION
00024 #define _INCLUDES_PERFORMANCE_INSTRUMENTATION 0
00025 #endif
00026 
00027 #if _SUPPORTS_NAMESPACE
00028 namespace palmos {
00029 namespace support {
00030 #endif // _SUPPORTS_NAMESPACE
00031 
00036 // Flags that can be passed in to constructor.
00037 enum {
00038     B_STOP_WATCH_SILENT         = (1<<0),       // Don't print anything.
00039     B_STOP_WATCH_NESTING        = (1<<1),       // Peform nesting, print all results when top is done.
00040     B_STOP_WATCH_CLEAR_CACHE    = (1<<2),       // Clear caches before starting.
00041     B_STOP_WATCH_RAW            = (1<<3),       // Don't try to adjust values for overhead.
00042     B_STOP_WATCH_HIGH_PRIORITY  = (1<<4),       // Run thread at a high priority.
00043     B_STOP_WATCH_QUANTIFY       = (1<<5),       // Enable Quantify instrumentation during the stop watch.
00044     B_STOP_WATCH_NO_TIME        = (1<<6)        // Don't measure elapsed time.
00045 };
00046 
00047 // Flags for StartProfiling()
00048 enum {
00049     B_PROFILE_KEEP_SAMPLES      = (1<<0),       // If set, any existing samples are kept -- not cleared.
00050     B_PROFILE_UPLOAD_SAMPLES    = (1<<1)        // Dump results to POD when profiling has finished.
00051 };
00052 
00053 // Available performance counters.  These are just the DPXA255 performance
00054 // counter values, there is no abstraction here (yet).
00055 enum perf_counter_t {
00056     B_COUNT_ICACHE_MISS             = 0,
00057     B_COUNT_DATA_STALL              = 2,
00058     B_COUNT_ITLB_MISS               = 3,
00059     B_COUNT_DTLB_MISS               = 4,
00060     B_COUNT_BRANCH_INSTRUCTION      = 5,
00061     B_COUNT_BRANCH_MISPREDICTED     = 6,
00062     B_COUNT_INSTRUCTION             = 7,
00063     B_COUNT_DBUFFER_STALL_DURATION  = 8,
00064     B_COUNT_DBUFFER_STALL           = 9,
00065     B_COUNT_DCACHE_ACCESS           = 10,
00066     B_COUNT_DCACHE_MISS             = 11,
00067     B_COUNT_DCACHE_WRITEBACK        = 12,
00068     B_COUNT_PC_CHANGE               = 13
00069 };
00070 
00071 // Flags for StartPerformance();
00072 enum {
00073     B_COUNT_HIGH_PRECISION      = (1<<0)        // Use high precision (low range) access to counters.
00074 };
00075 
00076 // Counter registers, used for building ratios.
00077 enum perf_counter_reg_t {
00078     B_COUNT_REGISTER_CYCLES         = 0,        // Special register, always available, of cycle count
00079     B_COUNT_REGISTER_A              = 1,
00080     B_COUNT_REGISTER_B              = 2
00081 };
00082 
00083 // Standard performance node weights.
00084 enum {
00085     B_PERFORMANCE_WEIGHT_EMPTY  = 100,          // Function does nothing.
00086     B_PERFORMANCE_WEIGHT_LIGHT  = 200,          // Function does very little -- get or set a few basic variables.
00087     B_PERFORMANCE_WEIGHT_MEDIUM = 300,          // Function does about the same work as the instrumentation.
00088     B_PERFORMANCE_WEIGHT_HEAVY  = 400           // Function does significantly more work than instrumentation.
00089 };
00090 
00091 // This macro inserts a performance instrumentation node at the current location.  It is usually
00092 // used at the top of a function to instrument that function.  The weight is the
00093 #if _INCLUDES_PERFORMANCE_INSTRUMENTATION
00094 #define B_PERFORMANCE_NODE(weight, name) SStopWatch __performance_node__(weight, name)
00095 #else
00096 #define B_PERFORMANCE_NODE(weight, name)
00097 #endif
00098 
00099 /*-------------------------------------------------------------*/
00100 /*----- SStopWatch class --------------------------------------*/
00101 
00102 class SStopWatch
00103 {
00104 public:
00105             // Normal constructor.  'name' is the label for this stop watch;
00106             // the memory it points to must be valid for the lifetime of
00107             // of the object (or root if nested).  Flags are as above.
00108             // minWeight is the minimum weight stopwatch to instrument when
00109             // nesting.  maxItems is the maximum number of nested stop watches
00110             // that can be stored.
00111                         SStopWatch(const char *name, uint32_t flags = 0, int32_t minWeight = 0, size_t maxItems = 0);
00112 
00113             // Constructor for B_PERFORMANCE_NODE.
00114                         SStopWatch(int32_t weight, const char *name);
00115 
00116                         ~SStopWatch();
00117 
00118     static  void        FlushICache();
00119 
00120             const char* Name() const;
00121 
00122             // The following functions enable additional features in the
00123             // stop watch.  Calling one of these functions implicitly does a
00124             // Restart() of the stop watch.
00125 
00126             // Call this to run the profiler.
00127             void        StartProfiling(uint32_t flags = 0);
00128 
00129             // Call this to run the performance counters.  You can optionally
00130             // call AddPerformanceRatio() (multiple times) to generate additional
00131             // statistics to display.
00132             void        AddPerformanceRatio(perf_counter_reg_t numerator, perf_counter_reg_t denominator);
00133             void        StartPerformance(perf_counter_t cntA, perf_counter_t cntB, uint32_t flags = 0);
00134 
00135             // Completely restart the stop-watching, as if it had been re-created.
00136             // This means flushing caches, re-computing overhead, and finally
00137             // calling Mark().
00138             void        Restart();
00139 
00140             // Mark the current location as the start time of the stop watch.  All
00141             // metrics will be reported with this as the baseline.
00142             void        Mark();
00143 
00144             // Start and stop the stop watch timer.  Currently only start and stops
00145             // time and quantify -- does NOT control profiling or performance counters.
00146             void        Suspend();
00147             void        Resume();
00148 
00149             // Return current elapsed  time.  Can be called while stop watch is
00150             // running.
00151             nsecs_t     ElapsedTime() const;
00152 
00153             // Stop measurement.  Can not be restarted.
00154             void        Stop();
00155             void        StopFast();
00156 
00157             // Retrieve final measurements.  Only valid after Stop() has been
00158             // called.
00159             nsecs_t     TotalTime() const;
00160             int64_t     TotalPerformance(perf_counter_reg_t reg) const;
00161 
00162             struct      Node;
00163             struct      Root;
00164 
00165 /*----- Private or reserved ---------------*/
00166 private:
00167 
00168                         SStopWatch(const SStopWatch &);
00169             SStopWatch  &operator=(const SStopWatch &);
00170             
00171             void        InitChild(Root* root, const char* name);
00172             void        MarkInternal(Root* root);
00173             void        RestartInternal(Root* root);
00174             void        StopInternal(Root* root);
00175 
00176             Root*       m_root;
00177             Node*       m_node;
00178             Node*       m_parent;
00179             int32_t     m_type;
00180 };
00181 
00182 /*-------------------------------------------------------------*/
00183 /*----- SPerformanceSample class ------------------------------*/
00184 
00185 class SPerformanceSample
00186 {
00187 public:
00188                         SPerformanceSample();
00189                         ~SPerformanceSample();
00190 
00191 private:
00192             uint32_t    m_counters[3];
00193 };
00194 
00195 /*-------------------------------------------------------------*/
00196 /*-------------------------------------------------------------*/
00197 
00198 #if _SUPPORTS_NAMESPACE
00199 } } // namespace palmos::support
00200 #endif
00201 
00204 #endif /* _SUPPORT_STOP_WATCH_H_ */