added observed cost model.
[dyninst.git] / paradyn / src / DMthread / DMinternals.h
1
2 /*
3  * Define the classes used in the implementation of the data manager.
4  *
5  * $Log: DMinternals.h,v $
6  * Revision 1.21  1994/07/05 03:27:16  hollings
7  * added observed cost model.
8  *
9  * Revision 1.20  1994/07/02  01:43:09  markc
10  * Removed all uses of type aggregation from enableDataCollection.
11  * The metricInfo structure now contains the aggregation operator.
12  *
13  * Revision 1.19  1994/06/29  02:55:57  hollings
14  * fixed code to remove instrumenation when done with it.
15  *
16  * Revision 1.18  1994/06/27  21:23:22  rbi
17  * Abstraction-specific resources and mapping info
18  *
19  * Revision 1.17  1994/06/17  22:07:58  hollings
20  * Added code to provide upcall for resource batch mode when a large number
21  * of resources is about to be added.
22  *
23  * Revision 1.16  1994/06/14  15:22:19  markc
24  * Added support for aggregation.
25  *
26  * Revision 1.15  1994/06/02  23:25:18  markc
27  * Added virtual function 'handle_error' to pardynDaemon class which uses the
28  * error handling features that igen provides.
29  *
30  * Revision 1.14  1994/05/10  03:57:36  hollings
31  * Changed data upcall to return array of buckets.
32  *
33  * Revision 1.13  1994/05/09  20:56:19  hollings
34  * added changeState callback.
35  *
36  * Revision 1.12  1994/04/19  22:08:37  rbi
37  * Added getTotValue method to get non-normalized metric data.
38  *
39  * Revision 1.11  1994/03/31  01:40:37  markc
40  * Added pauseProcess, continueProcess member functions.
41  *
42  * Revision 1.10  1994/03/25  22:59:31  hollings
43  * Made the data manager tolerate paraynd's dying.
44  *
45  * Revision 1.9  1994/03/24  16:41:19  hollings
46  * Added support for multiple paradynd's at once.
47  *
48  * Revision 1.8  1994/03/22  21:02:54  hollings
49  * Made it possible to add new processes (& paradynd's) via addExecutable.
50  *
51  * Revision 1.7  1994/03/21  20:32:47  hollings
52  * Changed the mid to mi mapping to be per paradyn daemon.  This is required
53  * because mids are asigned by the paradynd's, and are not globally unique.
54  *
55  * Revision 1.6  1994/03/20  01:49:47  markc
56  * Gave process structure a buffer to allow multiple writers.  Added support
57  * to register name of paradyn daemon.  Changed addProcess to return type int.
58  *
59  * Revision 1.5  1994/03/08  17:39:32  hollings
60  * Added foldCallback and getResourceListName.
61  *
62  * Revision 1.4  1994/02/24  04:36:30  markc
63  * Added an upcall to dyninstRPC.I to allow paradynd's to report information at
64  * startup.  Added a data member to the class that igen generates.
65  * Make depend differences due to new header files that igen produces.
66  * Added support to allow asynchronous starts of paradynd's.  The dataManager has
67  * an advertised port that new paradynd's can connect to.
68  *
69  * Revision 1.3  1994/02/03  23:26:57  hollings
70  * Changes to work with g++ version 2.5.2.
71  *
72  * Revision 1.2  1994/02/02  00:42:32  hollings
73  * Changes to the Data manager to reflect the file naming convention and
74  * to support the integration of the Performance Consultant.
75  *
76  *
77  */
78 #include "util/h/list.h"
79 #include "util/h/hist.h"
80 #include "util/h/aggregateSample.h"
81 #include "DMresource.h"
82 #include "dataManager.h"
83 #include <string.h>
84
85 //
86 // A handle to a running paradynd* somewhere.
87 //
88 class paradynDaemon: public dynRPCUser {
89     public:
90         paradynDaemon(char *m, char *u, char *p, xdrIOFunc r, xdrIOFunc w):
91             dynRPCUser(m, u, p, r, w, args) {
92                 if (!m) m = "";
93                 if (!u) u = "";
94
95                 machine = m;
96                 login = u;
97                 program = p;
98
99                 allDaemons.add(this);
100         }
101         // TODO setup machine, login, program
102         paradynDaemon(int f, xdrIOFunc r, xdrIOFunc w):
103             dynRPCUser(f, r, w) {
104               // machine = m;
105               // login = u;
106               // program = p;
107
108                 allDaemons.add(this);
109         }
110
111         ~paradynDaemon();
112         
113         Boolean dead;                   // has there been an error on the link.
114         void reportSelf (String m, String p, int pd);
115         char *machine;
116         char *login;
117         char *program;
118         // these args are passed to the paradynd when started
119         // for paradyndPVM these args contain the info to connect to the
120         // "well known" socket for new paradynd's
121         static char **args;
122         static List<paradynDaemon*> allDaemons;
123
124         void paradynDaemon::sampleDataCallbackFunc(int program,
125                                                    int mid,
126                                                    double startTimeStamp,
127                                                    double endTimeStamp,
128                                                    double value);
129
130         // all active metrics ids for this daemon.
131         HTable<metricInstance*> activeMids;
132
133         // replace the igen provided error handler
134         virtual void handle_error();
135 };
136
137
138 //
139 // a binary running somewhere under the control of a paradynd*.
140 //
141 class executable {
142     public:
143         executable(int id, int c, char **av, paradynDaemon *p) {
144             pid = id;
145             argc = c;
146             argv = av;
147             controlPath = p;
148         }
149         int pid;
150         int argc;
151         char **argv;
152         paradynDaemon *controlPath;
153 };
154
155 class applicationContext {
156     public:
157         void tellDaemonsOfResource(char *parent, char *name) {
158             List<paradynDaemon*> curr;
159             for (curr = daemons; *curr; curr++) {
160                 (*curr)->addResource(parent, name);
161             }
162         }
163
164         void startResourceBatchMode();
165         void endResourceBatchMode();
166
167         applicationContext(errorHandler ef)     {
168             errorFunc = ef;
169         }
170         addDaemon (int new_fd);
171         void removeDaemon(paradynDaemon *d, Boolean informUser);
172         addExecutable(char  *machine,
173                       char *login,
174                       char *name,
175                       int argc,
176                       char **argv);
177         addRunningProgram(int pid,
178                           int argc,
179                           char **argv, 
180                           paradynDaemon *daemon);       
181         Boolean applicationDefined();
182         Boolean startApplication();
183         Boolean pauseApplication();     
184         Boolean continueApplication();
185         Boolean pauseProcess(int pid);  
186         Boolean continueProcess(int pid);
187         Boolean detachApplication(Boolean);
188         void printStatus();
189         void coreProcess(int pid);
190         String_Array getAvailableMetrics();
191         metric *findMetric(char *name);
192         metricInstance *enableDataCollection(resourceList*, metric*);
193         float getPredictedDataCost(resourceList*, metric*);
194         void disableDataCollection(metricInstance*);
195
196         static List<performanceStream*> streams;
197     private:
198         List<executable*>        programs;
199         List<paradynDaemon*>     daemons;
200         errorHandler             errorFunc;
201 };
202
203 //
204 // A consumer of performance data.
205 //
206 class performanceStream {
207         friend void addMetric(metricInfo info);
208     public:
209         performanceStream(applicationContext *a, 
210                           dataType t,
211                           abstractionType ab,
212                           dataCallback dc,
213                           controlCallback cc,
214                           int tid) {
215             appl = a;
216             type = t;
217             abstraction = ab;
218             dataFunc = dc;
219             controlFunc = cc;
220             sampleRate = 10000;
221             threadId = tid;
222         }
223         void setSampleRate(timeStamp rate) { sampleRate = rate; }
224
225         metricInstance *enableDataCollection(resourceList*, metric*);
226         void disableDataCollection(metricInstance*);
227         void enableResourceCreationNotification(resource*);
228         void disableResourceCreationNotification(resource*);
229         void callSampleFunc(metricInstance *, sampleValue*, int, int);
230         void callResourceFunc(resource *p, resource *c, char *name);
231         void callResourceBatchFunc(batchMode mode);
232         void callFoldFunc(timeStamp width);
233         void callStateFunc(appState state);
234         abstractionType getAbstraction() { return abstraction; }
235     private:
236         applicationContext      *appl;
237         dataType                type;
238         abstractionType         abstraction;
239         dataCallback            dataFunc;
240         controlCallback         controlFunc;
241         int threadId;
242         // List<metricInstance*>   enabledMetrics;
243         timeStamp               sampleRate;     /* sample sampleRate usec */
244 };
245
246 //
247 // a part of an mi.
248 //
249 class component {
250     public:
251         component(paradynDaemon *d, int i, metricInstance *mi) {
252             daemon = d;
253             id = i;
254             d->activeMids.add(mi, (void *) id);
255         }
256         ~component() {
257             daemon->disableDataCollection(id);
258         }
259         sampleInfo sample;
260     private:
261         paradynDaemon *daemon;
262         int id;
263 };
264
265 class metric {
266     public:
267         metric(metricInfo i) {
268           info.style = i.style;
269           info.units = strdup (i.units);
270           info.name = strdup (i.name);
271           info.aggregate = i.aggregate;
272         }
273         metricInfo *getInfo() { return(&info); }
274         String getName() { return(info.name); }
275         metricStyle getStyle() { return((metricStyle) info.style); }
276         int getAggregate() { return info.aggregate;}
277         List<metricInstance*> enabledCombos;
278         static stringPool names;
279         static HTable<metric*> allMetrics;
280     private:
281         metricInfo info;
282 };
283
284
285 class metricInstance {
286     public:
287         ~metricInstance() {
288             if (data) delete(data);
289         }
290         metricInstance(resourceList *rl, metric *m) {
291             met = m;
292             focus = rl;
293             count = 0;
294             enabledTime = 0.0;
295             sample.aggOp = m->getAggregate();
296             data = NULL;
297         }
298         float getValue() {
299             float ret;
300
301             if (!data) abort();
302             ret = data->getValue();
303             ret /= enabledTime;
304             return(ret);
305         }
306         float getTotValue() {
307             float ret;
308
309             if (!data) abort();
310             ret = data->getValue();
311             return(ret);
312         }
313         int count;              // active users (perfStreams)
314         resourceList *focus;
315         metric *met;
316         sampleInfo sample;
317         List<sampleInfo*> parts;
318         List<component*> components;
319         List<performanceStream*> users;
320         Histogram *data;
321         float enabledTime;
322     private:
323 };
324