Added check to see if the begin "\7f(start_counter) call doesn't occure twice.
[charm.git] / src / ck-perf / trace-counter.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**
9  * \addtogroup CkPerf
10 */
11 /*@{*/
12
13 #ifndef __trace_counter_h__
14 #define __trace_counter_h__
15
16 #include <stdio.h>
17 #include <errno.h>
18 #include "trace.h"
19 #include "ck.h"
20 #include "trace-common.h"
21 #include "conv-mach.h"
22 #ifdef CMK_ORIGIN2000
23 #include <sys/hwperftypes.h>
24 #endif
25
26 #define MAX_ENTRIES 500
27
28 //! track statistics for all entry points
29 class StatTable {
30   public:
31     StatTable(char** args, int argc);
32     ~StatTable();
33     //! one entry is called for 'time' seconds, value is counter reading 
34     void setEp(int epidx, int stat, long long value, double time);
35     //! write three lines for each stat:
36     //!   1. number of calls for each entry
37     //!   2. average count for each entry
38     //!   3. total time in us spent for each entry
39     void write(FILE* fp);
40     void clear();
41
42   private:
43     //! struct to maintain statistics
44     struct Statistics {
45       char*  name;                  // name of stat being tracked
46       UInt   count[MAX_ENTRIES];    // total number times called
47       double average[MAX_ENTRIES];  // track average of value
48       double totTime[MAX_ENTRIES];  // total time associated with this counter
49
50       Statistics(): name(NULL) { }
51     };
52
53     Statistics* stats_;             // track stats for each entry point
54     int         numStats_;          // size of statistics being tracked
55     // bool        error_;             // will be set to true if error writing info
56 };
57
58 // counter log pool
59 class CountLogPool {
60   public:
61     CountLogPool(char* pgm, char** args, int argc);
62     ~CountLogPool();
63     void write(void) ;
64     void writeSts(void);
65     void setEp(int epidx, long long count1, long long count2, double time);
66     void clearEps() { stats_.clear(); }
67
68   private:
69     FILE*     fp_;
70     StatTable stats_;
71 };
72
73 //! For each processor, TraceCounter calculates mean, stdev, etc of 
74 //! CPU performance counters for each entry point.
75 class TraceCounter : public Trace {
76   public:
77     TraceCounter();
78     ~TraceCounter();
79     void userEvent(int e) { }
80     void creation(envelope *e, int num=1) { }
81     void beginExecute(envelope *e);
82     void beginExecute(int event, int msgType, int ep, int srcPe, int mlen=0);
83     void endExecute(void);
84     void beginIdle(void) { }
85     void endIdle(void) { }
86     void beginPack(void);
87     void endPack(void);
88     void beginUnpack(void);
89     void endUnpack(void);
90     void beginCharmInit(void) { }
91     void endCharmInit(void) { }
92     void enqueue(envelope *e) { }
93     void dequeue(envelope *e) { }
94     void beginComputation(void);
95     void endComputation(void) { }
96
97     void traceInit(char **argv);
98     int traceRegisterUserEvent(const char*) { return 0; }
99     void traceClearEps();
100     void traceWriteSts();
101     void traceClose();
102     void traceBegin() { }
103     void traceEnd() { }
104
105     //! CounterArg is a linked list of strings that allows
106     //! processing of command line args
107     struct CounterArg {
108       int         code;
109       char*       arg;
110       char*       desc;
111       CounterArg* next;
112
113       CounterArg(): code(-1), arg(NULL), desc(NULL), next(NULL) { }
114       CounterArg(int c, char* a, char* d):
115         code(c), arg(a), desc(d), next(NULL) { }
116       void setValues(int _code, char* _arg, char* _desc) {
117         code = _code;  arg = _arg;  desc = _desc;
118       }
119     };
120
121   private:
122     int         execEP_;       // id currently executing entry point
123     double      startEP_;      // start time of currently executing ep
124     double      startPack_;    // start time of pack operation
125     double      startUnpack_;  // start time of unpack operation
126     CounterArg* firstArg_;     // pointer to start of linked list of args
127     CounterArg* lastArg_;      // pointer to end of linked list of args
128     int         argStrSize_;   // size of maximum arg string (formatted output)
129
130     int         counter1_;     // 1st counter to track
131     int         counter2_;     // 2nd counter to track
132
133     #ifdef CMK_ORIGIN2000
134     enum Status { IDLE, WORKING };
135     Status      status_;       // to prevent errors
136     int         genStart_;     // track value of start_counters
137     int         fileDesc_;     // file descriptor for accessing hw counters
138     hwperf_profevctrarg_t evctrArgs_;  // tells what type of counter to profile
139     hwperf_cntr_t         cnts_;       // reads the counters values
140     // starts hw profiling for these counters
141     // returns -1 if error, generation number if no error
142     int startCounter(int counter1, int counter2);
143     // gets hw profile values for these counters
144     // returns -1 if error, generation number if no error
145     int readCounters
146     (
147       int        counter1,
148       long long* value1,
149       int        counter2,
150       long long* value2
151     );
152     #endif // CMK_ORIGIN2000
153
154     //! add the argument parameters to the linked list of args choices
155     void registerArg(CounterArg* arg);
156     //! see if the arg (str or code) matches any in the linked list of choices
157     //! and sets arg->code to the SGI code
158     //! return true if arg matches, false otherwise
159     bool matchArg(CounterArg* arg);
160     //! print out all arguments in the linked-list of choices
161     void printHelp();
162 };
163
164 #endif  // __trace_counter_h__
165
166 /*@}*/
167
168