1 //
2 // regtime.h
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Curtis Janssen <cljanss@limitpt.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #ifdef __GNUC__
29 #pragma interface
30 #endif
31 
32 #ifndef _util_misc_regtime_h
33 #define _util_misc_regtime_h
34 
35 #include <iostream>
36 #include <string>
37 #include <util/class/class.h>
38 
39 namespace sc {
40 
41 class TimedRegion {
42   private:
43     char *name_;
44     TimedRegion *up_;
45     TimedRegion *subregions_;
46     TimedRegion *next_;
47     TimedRegion *prev_;
48     double cpu_time_;
49     double wall_time_;
50     double cpu_enter_;
51     double wall_enter_;
52     double flops_;
53     double flops_enter_;
54 
55     TimedRegion *insert_after(const char *name);
56     TimedRegion *insert_before(const char *name);
57   public:
58     TimedRegion(const char *name);
59     ~TimedRegion();
name()60     const char *name() const { return name_; }
61     TimedRegion *findinsubregion(const char *);
62     void cpu_enter(double);
63     void wall_enter(double);
64     void flops_enter(double);
65     void cpu_exit(double);
66     void wall_exit(double);
67     void flops_exit(double);
cpu_add(double t)68     void cpu_add(double t) { cpu_time_ += t; }
wall_add(double t)69     void wall_add(double t) { wall_time_ += t; }
flops_add(double t)70     void flops_add(double t) { flops_ += t; }
up()71     TimedRegion *up() const { return up_; }
subregions()72     TimedRegion *subregions() const { return subregions_; }
next()73     TimedRegion *next() const { return next_; }
prev()74     TimedRegion *prev() const { return prev_; }
75 
76     int nregion();
77     void get_region_names(const char *names[]);
78     void get_wall_times(double *);
79     void get_cpu_times(double *);
80     void get_flops(double *);
81     void get_depth(int *, int depth = 0);
82 };
83 
84 /** The RegionTimer class is used to record the time spent in a section of
85 code.  During the run of a code, enter and exit members are called to begin
86 and end timed sections.  The print member is used to display the obtained
87 times.  Multiple enter calls for a region with the same name aggregate the
88 timings. Nested regions are supported. */
89 class RegionTimer: public DescribedClass {
90   protected:
91     int wall_time_;
92     int cpu_time_;
93     int flops_;
94 
95     TimedRegion *top_;
96     TimedRegion *current_;
97     TimedRegion *default_;
98 
99   public:
100     RegionTimer(const char *topname = "total",
101                 int cpu_time = 0, int wall_time = 1);
102     RegionTimer(const Ref<KeyVal> &);
103     ~RegionTimer();
104     void enter(const char * = 0);
105     void change(const char *newname, const char * oldname = 0);
106     void exit(const char * = 0, bool do_not_throw = false);
107     void set_default(const char *);
108     void unset_default();
109     void enter_default();
110     void exit_default();
111     virtual void print(std::ostream& = ExEnv::out0()) const;
112 
113     void update_top() const;
114 
115     int nregion() const;
116     void get_region_names(const char *names[]) const;
117     void get_wall_times(double *) const;
118     void get_cpu_times(double *) const;
119     void get_flops(double *) const;
120     void get_depth(int *) const;
121 
122     double get_wall_time() const;
123     double get_cpu_time() const;
124     double get_flops() const;
125 
126     void add_wall_time(const char *, double);
127     void add_cpu_time(const char *, double);
128     void add_flops(const char *, double);
129 
130     static RegionTimer *default_regiontimer();
131     static void set_default_regiontimer(const Ref<RegionTimer> &);
132 };
133 
134 /** The Timer class uses RegionTimer to time intervals in an exception safe
135 manner.  It will automatically call RegionTimer::enter when its constructor
136 is called and RegionTimer::exit when its destructor is called.  The reset
137 member can also result in RegionTimer's enter and exit routines being
138 called.  The programmer is responsible for making sure that timers are
139 exited in the reverse of the order that they are entered.  */
140 class Timer {
141     Ref<RegionTimer> timer_;
142     std::string name_;
143     bool active_;
144   public:
145     /** Start timing a region using the default RegionTimer and activate
146         the timer.  If a null name pointer is given, then the
147         timer will not be activated. */
148     Timer(const char *name);
149     /** Start timing a region using the given RegionTimer. If a null name
150         pointer is given, then the timer will not be activated. */
151     Timer(const Ref<RegionTimer> &, const char *name);
152     /** Stop timing a region, if active. */
153     ~Timer();
154     /** Stop timing the current region, if active.  If a new region name is
155         passed in, start timing with that name.  If no region name is
156         given, the Timer will be deactivated.  */
157     void reset(const char * = 0);
158 };
159 
160 }
161 
162 #endif
163 
164 // Local Variables:
165 // mode: c++
166 // c-file-style: "CLJ"
167 // End:
168