Adding bucket_width metric - naim
[dyninst.git] / paradyn / h / dyninstRPC.I
1 /*
2  * Copyright (c) 1993, 1994 Barton P. Miller, Jeff Hollingsworth,
3  *     Bruce Irvin, Jon Cargille, Krishna Kunchithapadam, Karen
4  *     Karavanic, Tia Newhall, Mark Callaghan.  All rights reserved.
5  * 
6  * This software is furnished under the condition that it may not be
7  * provided or otherwise made available to, or used by, any other
8  * person, except as provided for by the terms of applicable license
9  * agreements.  No title to or ownership of the software is hereby
10  * transferred.  The name of the principals may not be used in any
11  * advertising or publicity related to this software without specific,
12  * written prior authorization.  Any use of this software must include
13  * the above copyright notice.
14  *
15  */
16
17 /*
18  * dyninstRPC.I,v
19  *
20  * Revision 1.28  1995/10/13  14:43:55  naim
21  * Revision version update for the showErrorCallback function
22  *
23  * Revision 1.27  1995/06/02  20:58:45  newhall
24  * made code compatable with new datamanager interface
25  * replaced List and HTable container classes with STL containers
26  *
27  * Revision 1.26  1995/05/18  10:51:49  markc
28  * added mdl classes
29  * modified resource specifications in interfaces to use ids
30  *
31  * Revision 1.25  1995/02/16  08:01:42  markc
32  * Modified interfaces:
33  *   1) XDR interfaces use strings and vectors instead of igen arrays and char*'s
34  *   2) No sync upcalls are allowed by the server in xdr interfaces
35  *   3) Redefined igen arrays that were used in thread code to use manually 
36  *      defined structures rather than igen-defined, since igen did not need
37  *      to know about these structures.
38  *   4) Upped all of the version numbers since all new interface code is 
39  *      generated.
40  *   5) Async calls are no longer handled while waiting for sync responses, these
41  *      requests are buffered.
42  *
43  * Revision 1.24  1994/11/09  18:38:36  rbi
44  * the "Don't Blame Me" commit
45  *
46  * Revision 1.23  1994/11/03  16:05:31  rbi
47  * eliminated argc from addExecutable interface
48  *
49  * Revision 1.22  1994/11/02  11:41:27  markc
50  * Incremented the version.
51  *
52  * Revision 1.21  1994/09/22  00:44:26  markc
53  * Incremented version number
54  * Changed "String" to "char*"
55  * Made array declarations explicit
56  *
57  * Revision 1.20  1994/08/22  16:01:31  markc
58  * Remove my_pid which duplicated a class member
59  * Add daemon dictionary calls to dataManager interface.
60  *
61  * Revision 1.19  1994/08/17  17:55:27  markc
62  * Incremented version numbers because a new version of igen has been
63  * committed.
64  *
65  * Revision 1.18  1994/08/08  20:14:56  hollings
66  * added suppress instrumentation command.
67  *
68  * Revision 1.17  1994/07/20  16:30:40  hollings
69  * added resourceBatchMode
70  *
71  * Revision 1.16  1994/07/14  23:44:29  hollings
72  * added getCurrentHybridCost
73  *
74  * Revision 1.15  1994/07/05  03:26:54  hollings
75  * added stat printing command.
76  *
77  * Revision 1.14  1994/07/02  01:45:24  markc
78  * Removed aggregation operator from enableDataCollection call.
79  * Remove aggregation operator definitions, which are provided by
80  * util/h/aggregation.H
81  *
82  * Revision 1.13  1994/06/29  02:55:34  hollings
83  * Added copyright and log line.
84  *
85  *
86  */
87
88 #define MetStyleEventCounter    0
89 #define MetStyleSampledFunction 1
90
91 #include "util/h/Types.h"
92 #include "util/h/aggregation.h"
93 #include "paradyn/src/met/mdl.h"
94
95
96 /* used by paradynd to inform a change in the status of an application. */
97 // typedef enum { procPaused, procExited } processStatus_t;
98 #define procPaused 0
99 #define procExited 1
100 typedef u_int processStatus_t;
101
102 $remote
103 abstract class mdl_expr {
104 $ignore
105 public:
106   virtual ~mdl_expr();
107   virtual bool apply(mdl_var &ret) = 0;
108 #ifdef NO_MDL_PRINT
109   virtual void print(ostream& os) = 0;
110 #endif
111 $ignore
112 };
113
114 $remote
115 class mdl_v_expr : mdl_expr {
116   string var_;
117   vector<string> fields_;
118   vector<mdl_expr*> *args_;
119   int literal_;
120   u_int arg_;
121   mdl_expr *left_;
122   mdl_expr *right_;
123   u_int type_;
124   vector<u_int> type_walk;
125   bool do_type_walk_;
126   bool ok_;
127   u_int res_type_;
128
129 $ignore
130 public:
131   mdl_v_expr(string var, vector<string> fields);
132   mdl_v_expr(string func_name, vector<T_dyninstRPC::mdl_expr*> *args);
133   mdl_v_expr(int int_literal);
134   mdl_v_expr(string string_lit);
135   mdl_v_expr(u_int bin_op, T_dyninstRPC::mdl_expr *left, T_dyninstRPC::mdl_expr *right);
136   mdl_v_expr(string var, u_int array_index);
137   ~mdl_v_expr();
138   bool apply(mdl_var &ret);
139 #ifdef NO_MDL_PRINT
140   virtual void print(ostream& os) {
141     os << "MDL_V_EXPR: var=" << var_ << " res_type=" << res_type_ << " do_type_walk="
142       << do_type_walk_;
143     unsigned size = fields_.size(), index;
144     if (size) {
145       os << "Fields: ";
146       for (index=0; index<size; index++) {
147         os << fields_[index] << " ";
148       }
149       os << endl;
150     }
151   }
152 #endif
153
154 $ignore
155 };
156
157 $remote
158 class mdl_instr_req {
159   u_int arg_type_;
160   u_int arg_val_;
161   string arg_name_;
162   string arg_name_2_;
163   u_int type_;
164   string timer_counter_name_;
165
166 $ignore
167 public:
168   // start and stop timers, read symbol
169   mdl_instr_req(u_int type, string name);
170
171   // for counters, call_func
172   mdl_instr_req(u_int arg_type, u_int arg_val, string arg_name, string arg_name_2,
173                 u_int type, string obj_name);
174
175   ~mdl_instr_req();
176   bool apply(u_int pos, instPoint *p, u_int where_instr, metricDefinitionNode *m,
177              AstNode *pred, vector<dataReqNode*>& flags);
178 $ignore
179 };
180
181 $remote
182 class mdl_icode {
183   u_int if_op1_;
184   u_int if_val1_;
185   string if_str1_;
186
187   u_int if_op2_;
188   u_int if_val2_;
189   string if_str2_;
190
191   u_int bin_op_;
192   bool use_if_;
193   mdl_instr_req *req_;
194
195 $ignore
196 public:
197   mdl_icode(u_int iop1, u_int ival1, string str1,
198             u_int iop2, u_int ival2, string str2,
199             u_int bop, bool use, T_dyninstRPC::mdl_instr_req *r);
200   ~mdl_icode();
201   bool apply(u_int position, instPoint *p, u_int where_instr,
202              metricDefinitionNode *mn, vector<dataReqNode*>& flags);
203 $ignore
204 };
205
206 $remote
207 abstract class mdl_stmt {
208 $ignore
209 public:
210   virtual ~mdl_stmt() { }
211   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags) = 0;
212 #ifdef NO_MDL_PRINT
213   virtual void print(ostream& os) = 0;
214 #endif
215 $ignore
216 };
217
218 $remote
219 class mdl_list_stmt : mdl_stmt {
220   u_int type_;
221   string id_;
222   vector<string> *elements_;
223   bool is_lib_;
224   string flavor_;
225
226 $ignore
227 public:
228   mdl_list_stmt(u_int type, string ident, vector<string> *elems,
229                 bool is_lib, string flavor);
230   virtual ~mdl_list_stmt();
231   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
232 #ifdef NO_MDL_PRINT
233   virtual void print(ostream& os) { }
234 #endif
235
236 $ignore
237 };
238
239 $remote
240 class mdl_for_stmt : mdl_stmt {
241   mdl_stmt *for_body_;
242   string index_name_;
243   mdl_expr *list_expr_;
244
245 $ignore
246 public:
247   mdl_for_stmt(string index_name, T_dyninstRPC::mdl_expr *list_exp, mdl_stmt *body);
248   virtual ~mdl_for_stmt();
249   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
250 #ifdef NO_MDL_PRINT
251   virtual void print(ostream& os) { }
252 #endif
253
254 $ignore
255 };
256
257 $remote
258 class mdl_if_stmt : mdl_stmt {
259   mdl_expr *expr_;
260   mdl_stmt *body_;
261
262 $ignore
263 public:
264   mdl_if_stmt(mdl_expr *expr, mdl_stmt *body);
265   virtual ~mdl_if_stmt();
266   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
267 #ifdef NO_MDL_PRINT
268   virtual void print(ostream& os) { }
269 #endif
270
271 $ignore
272 };
273
274 $remote
275 class mdl_seq_stmt : mdl_stmt {
276   vector<mdl_stmt*> *stmts_;
277
278 $ignore
279 public:
280   mdl_seq_stmt(vector<mdl_stmt*> *stmts);
281   virtual ~mdl_seq_stmt();
282   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
283 #ifdef NO_MDL_PRINT
284   virtual void print(ostream& os) { }
285 #endif
286
287 $ignore
288 };
289
290 $remote
291 class mdl_instr_stmt : mdl_stmt {
292   u_int position_;
293   mdl_expr *point_expr_;
294   vector<mdl_icode*> *icode_reqs_;
295   u_int where_instr_;
296   bool constrained_;
297
298 $ignore
299 public:
300   mdl_instr_stmt(u_int pos, mdl_expr *point_expr, vector<mdl_icode*> *i_reqs,
301                  unsigned where_instr, bool constrained);
302   virtual ~mdl_instr_stmt();
303   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
304 #ifdef NO_MDL_PRINT
305   virtual void print(ostream& os) {
306     os << "MDL_INSTR_STMT: constrained=" << constrained_ << " ";
307     point_expr_->print(os);
308   }
309 #endif
310
311 $ignore
312 };
313
314 $remote 
315 class mdl_constraint {
316   string id_;
317   vector<string> *match_path_;
318   vector<mdl_stmt*> *stmts_;
319   bool replace_;
320   u_int data_type_;
321   u_int hierarchy_;
322   u_int type_;
323
324 $ignore
325 public:
326   mdl_constraint(string id, vector<string> *match_path,
327                  vector<T_dyninstRPC::mdl_stmt*> *stmts, bool replace, u_int d_type,
328                  bool& error);
329   ~mdl_constraint();
330   bool apply(metricDefinitionNode *mn, dataReqNode *&flag,
331              vector<string>& resource, process *proc);
332
333 #ifdef NO_MDL_PRINT
334    friend ostream& operator<< (ostream& os, const T_dyninstRPC::mdl_constraint& cons) {
335      os << "\nConstraint: " << cons.id_ << " ";
336      unsigned size, index;
337      if (cons.match_path_) {
338        size = cons.match_path_->size();
339        for (index=0; index<size; index++) os << (*cons.match_path_)[index] << "/";
340        os << endl;
341      }
342      os << "Replace=" << cons.replace_ << " Data_type=" << cons.data_type_ << " Hierarchy=" 
343        << cons.hierarchy_ << " Type=" << cons.type_ << endl;
344     if (cons.stmts_) {
345       size = cons.stmts_->size();
346       os << "Statements\n";
347       for (index=0; index<size; index++) {
348         (*cons.stmts_)[index]->print(os);
349         os << " ";
350       }
351     }
352    }
353 #endif
354
355 $ignore
356 };
357
358 $remote
359 class mdl_metric {
360   string id_;
361   string name_;
362   string units_;
363   u_int agg_op_;
364   u_int style_;
365   u_int type_;
366   vector<mdl_stmt*> *stmts_;
367   vector<string> *flavors_;
368   vector<mdl_constraint*> *constraints_;
369   vector<string> *temp_ctr_;
370   bool developerMode_;
371   bool normalized_;
372
373 $ignore
374 public:
375   mdl_metric(string id, string name, string units,
376              u_int agg, u_int style, u_int type,
377              vector<mdl_stmt*> *mv, vector<string> *flavs, 
378              vector<T_dyninstRPC::mdl_constraint*> *cons,
379              vector<string> *temp_c, bool developerMode,bool normalized);
380   ~mdl_metric();
381 #ifdef NO_MDL_PRINT
382   friend ostream& operator<< (ostream &os, const T_dyninstRPC::mdl_metric& met) {
383     os << "\nMetric: " << met.id_ << " " << met.name_ << " agg_op=" << met.agg_op_ << " style=" 
384       << met.style_ << " type=" << met.type_ << endl;
385     unsigned size, index;
386     if (met.stmts_) {
387       size = met.stmts_->size();
388       os << "Statements\n";
389       for (index=0; index<size; index++) {
390         (*met.stmts_)[index]->print(os);
391          os << " ";
392       }
393     }
394     if (met.constraints_) {
395       size = met.constraints_->size();
396       os << "Constraints\n";
397       for (index=0; index<size; index++) {
398         os << *((*met.constraints_)[index]) << " ";
399       }
400     }
401   }
402 #endif
403   metricDefinitionNode *apply(vector< vector<string> >&focus, string& flat_name);
404 $ignore
405 };
406
407 /* descriptive information about a metric */
408 $remote struct metricInfo { 
409     string name;
410     int style;
411     int aggregate;
412     string units;
413     bool developerMode;
414     bool normalized;
415     u_int handle;  // this is currently ignored by the daemons 
416 };
417
418 /*
419  * Create a paradynd process.
420  *
421  */
422 int createDaemon(string machine,
423                  string login,
424                  string name,
425                  vector<string> argv);
426
427
428 $remote dynRPC {
429     $base 4000;
430     $version 25;
431
432     //
433     // Define a program to run. 
434     // argv: the command and arguments
435     // dir: working directory where program will run.
436     // stopAtFirstBreak: if true, the program will stops before it executes its
437     //                   first instruction.
438     int addExecutable(vector<string> argv, string dir, bool stopAtFirstBreak);
439
440     //
441     // Connect up with a running program (not possible on all platforms).
442     //
443     bool attachProgram(int pid);
444
445     //
446     // Start an application running (This starts the actual execution).
447     //
448     bool startProgram(int program);
449
450     //
451     //   Stop a process
452     //
453     bool pauseProgram(int program);
454
455     //
456     //   Stop all processes associted with the application.
457     //
458     bool pauseApplication();
459
460     //
461     // Continue a paused process
462     //
463     void continueProgram(int program);
464
465     //
466     // Continue all of the processes
467     //
468     void continueApplication();
469
470     //
471     // Disconnect the tool from the process.
472     //    pause - leave the process in a stopped state.
473     //
474     //
475     bool detachProgram(int program, bool pause);
476
477      //
478     // Set internal metric current bucket width
479     //
480     void computeCurrentBucketWidth(double bucket);
481
482     //
483     // Set internal metric global bucket width
484     //
485     void computeGlobalBucketWidth(double bucket);
486
487     //
488     // Gets called when a new application is started that is not visible to
489     //   paradyn (e.g. pvm_spawn).
490     //
491     $upcall $async void newProgramCallbackFunc( int pid, 
492                                                 vector<string> argv, 
493                                                 string machine);
494     //
495     // Message display with "error" visual characteristics
496     // and lookup in error database for explanation. This function
497     // calls showError function in UIM class
498     //
499     $upcall $async void showErrorCallback (int errCode,
500                                            string errString,
501                                            string hostName);
502
503     //
504     // Handler that gets called when new sample data is delivered.
505     //
506     //   p - a program from addProgram
507     //   mi - a metricInstance returned by enableDataCollection
508     //   startTimeStamp - starting time of the interval covered by this sample.
509     //   endTimeStamp - ending time of the interval covered by this sample.
510     //   value - the value of this sample
511     //
512    $virtual $upcall $async void sampleDataCallbackFunc(int program, 
513                                                        int mi,
514                                                        double startTimeStamp, 
515                                                        double endTimeStamp, 
516                                                        double value);
517
518    //
519    // XXXX - Hack this should be generalized into a vector.
520    //
521    $virtual $upcall $async void cpDataCallbackFunc(int program,
522                                                       double timeStamp,
523                                                       int context,
524                                                       double total,
525                                                       double share);
526
527    // 
528    // Handler that reports the initial time for which a daemon reports a sample
529    // The earliest (absolute) initial time will become the base time (0)
530    //
531    $virtual $upcall $async void firstSampleCallback(int program,
532                                                     double time);
533
534     //
535     // Handler that gets called when a new resource is defined.
536     //
537     // resource_name    - name of resource, divided into parts
538     // abstraction      - abstraction to which it belongs     
539     //
540     $upcall $async void resourceInfoCallback(int program, 
541                                              vector<string> resource_name,
542                                              string abstraction);
543
544     // The id that will be used to represent this resource
545     $async void resourceInfoResponse(vector<string> resource_name, u_int resource_id);
546
547     $upcall $async void resourceBatchMode(bool);
548
549     //
550     // Handler that gets called when new mapping data is collected.
551     //
552     $upcall $async void mappingInfoCallback(int program, 
553                                             string abstraction, 
554                                             string type, 
555                                             string key,
556                                             string value);
557
558     // Upcall for a new metric being defined.
559     //
560     $upcall $async void newMetricCallback(metricInfo info); 
561
562     void setSampleRate(double sampleInterval);
563
564     //
565     // tell dyninst to ignore this resource for instrumentation.
566     //    Currently this only applies to programs, modules, and procedures.
567     //    False - suppress
568     //    True - enable
569     //
570     bool setTracking(u_int resource_id, bool);
571
572     //
573     // Routines to control data collection on a performanceStream.
574     //
575     // resourceList     - a list of resources
576     // metric   - what metric to collect data for
577     //
578     int enableDataCollection(vector<u_int> focus, string metric,int id);
579
580     //
581     // stop collecting data for the named mi.
582     //     mi           - a metricInstance returned by enableDataCollection.
583     //
584     void disableDataCollection(int mi);
585
586     //
587     // Return the expected cost of collecting performance data for a single
588     //    metric at a given focus.  The value returned is the fraction of
589     //    perturbation expected (i.e. 0.10 == 10% slow down expected).
590     //
591     double getPredictedDataCost(vector<u_int> focus, string metric);
592
593     //
594     // Current best guess about the cost of instrumentation.
595     //
596     double getCurrentHybridCost();
597
598     //
599     // Get the static configuration information.
600     //
601     vector<metricInfo> getAvailableMetrics();
602
603     //
604     // Create a new resource.
605     //
606     void addResource(u_int parent, u_int id, string name);
607
608     //
609     // stdio or stderr from an application.
610     //
611     $upcall $async void applicationIO(int pid, int len, string line);
612
613     //
614     // stdio or stderr from an application.
615     //
616     $virtual $upcall $async void reportStatus(string line);
617
618     //
619     // Debugger style calls.
620     //
621     //
622     string getStatus(int pid);
623     void coreProcess(int pid);
624
625     //
626     // For paradynd's that may get started, but not by paradyn
627     // This allows them to report system information
628     // flavor = programming environment {"pvm", "cm5", ... }
629     $virtual $upcall $async void reportSelf(string machine, 
630                                             string program, 
631                                             int pid,
632                                             string flavor);
633
634     //
635     // this call is used by paradynd to inform paradyn of a change in
636     // the status of a process -- the process stops (due to a signal), 
637     // or the process exits
638     //
639     $virtual $upcall $async void processStatus(int pid, u_int procstat);
640
641     // this call is used by the paradyndCM5 daemon to notify paradyn
642     // that it is ready, so that the application can be restarted.
643     $virtual $upcall $async void nodeDaemonReadyCallback();
644
645     // this call is used to notify all daemons that the CM5 node daemon is ready.
646     // Daemons that have a process waiting for the CM5 node daemon can then 
647     // resume the application.
648     $async void nodeDaemonReady();
649
650     //
651     // For timing and other measurements of paradynd
652     //
653     void printStats();
654
655     // MDL methods
656     $async void send_metrics(vector<mdl_metric*> *);
657     $async void send_constraints(vector<mdl_constraint*>*);
658     $async void send_stmts(vector<mdl_stmt*> *);
659 };