*** empty log message ***
[dyninst.git] / paradyn / h / dyninstRPC.I
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /* $Id: dyninstRPC.I,v 1.80 1999/05/24 17:09:29 cain Exp $
43  */
44
45 #define MetStyleEventCounter    0
46 #define MetStyleSampledFunction 1
47
48 #include "util/h/Types.h"
49 #include "util/h/aggregation.h"
50 #include "paradyn/src/met/mdl.h"
51
52 $remote
53 struct batch_buffer_entry {
54    int mid;
55    double startTimeStamp;
56    double endTimeStamp;
57    double value;
58    u_int weight;
59    bool  internal_met; 
60
61 $ignore
62    batch_buffer_entry &operator=(const batch_buffer_entry &src) {
63       mid = src.mid;
64       startTimeStamp = src.startTimeStamp;
65       endTimeStamp = src.endTimeStamp;
66       value = src.value;
67       weight = src.weight;
68       internal_met = src.internal_met;
69       return *this;
70    }
71 $ignore
72 };
73
74 // trace data streams
75 $remote
76 struct trace_batch_buffer_entry {
77    int mid;
78    u_int length;
79    byteArray traceRecord;
80
81 $ignore
82    trace_batch_buffer_entry &operator=(const trace_batch_buffer_entry &src) {
83       mid = src.mid;
84       length = src.length;
85       traceRecord = src.traceRecord;
86       return *this;
87    }
88 $ignore
89 };
90
91 /* used by paradynd to inform a change in the status of an application. */
92 // typedef enum { procPaused, procExited } processStatus_t;
93 #define procPaused 0
94 #define procExited 1
95 typedef u_int processStatus_t;
96
97 $remote
98 abstract class mdl_expr {
99 $ignore
100 public:
101   virtual ~mdl_expr();
102   virtual bool apply(mdl_var &ret) = 0;
103   virtual bool apply(AstNode*& ast) = 0;
104   virtual bool mk_list(vector<string> &funcs) = 0;
105 #ifdef NO_MDL_PRINT
106   virtual void print(ostream& os) = 0;
107 #endif
108 $ignore
109 };
110
111 $remote
112 class mdl_v_expr : mdl_expr {
113   u_int type_;
114   int int_literal_;
115   string str_literal_;
116   string var_;
117   u_int bin_op_;
118   u_int u_op_;
119   // these two are misnomer in cases other than MDL_RVAL_BINOP. when
120   // it's a unary expression or when there's only one arg expression,
121   // left_ is used and right_ is set to NULL, but in those cases,
122   // there's really no "left" or "right" expressions. --chun
123   mdl_expr *left_;
124   mdl_expr *right_;
125   vector<mdl_expr*> *args_;
126   vector<string> fields_;
127
128   // for fields. set in paradyn's mdl.C and used in paradynd's mdl.C
129   // --chun.
130   vector<u_int> type_walk;
131   bool do_type_walk_;
132
133   bool ok_;
134
135 $ignore
136 public:
137   mdl_v_expr(int int_literal);
138   mdl_v_expr(string a_str, bool is_literal);
139   mdl_v_expr(mdl_expr* expr, vector<string> fields);
140   mdl_v_expr(string func_name, vector<mdl_expr*> *args);
141   mdl_v_expr(u_int bin_op, mdl_expr *left, mdl_expr *right);
142   mdl_v_expr(string var, u_int assign_op, mdl_expr* expr);
143   mdl_v_expr(u_int u_op, mdl_expr *expr, bool is_preop);
144   mdl_v_expr(string var, mdl_expr *index_expr);
145   ~mdl_v_expr();
146   bool apply(mdl_var &ret); // non-code-gen version
147   bool apply(AstNode*& mn); // code-gen version
148   bool mk_list(vector<string> &funcs);
149 #ifdef NO_MDL_PRINT
150   virtual void print(ostream& os) 
151   {
152     os << "MDL_V_EXPR: var=" << var_ << " do_type_walk=" << do_type_walk_;
153     unsigned size = fields_.size(), index;
154     if (size) 
155     {
156       os << "Fields: ";
157       for (index=0; index<size; index++) 
158         os << fields_[index] << " ";
159       os << endl;
160     }
161   }
162 #endif
163
164 $ignore
165 };
166
167 $remote
168 class mdl_icode {
169   mdl_expr *if_expr_;
170   mdl_expr *expr_;
171
172 $ignore
173 public:
174   mdl_icode(mdl_expr *if_expr, mdl_expr *expr);
175   ~mdl_icode();
176   bool apply(AstNode *&mn, bool mn_initialized);
177 $ignore
178 };
179
180 $remote
181 abstract class mdl_stmt {
182 $ignore
183 public:
184   virtual ~mdl_stmt() { }
185   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags) = 0;
186   virtual bool mk_list(vector<string> &funcs) = 0;
187 #ifdef NO_MDL_PRINT
188   virtual void print(ostream& os) = 0;
189 #endif
190 $ignore
191 };
192
193 $remote
194 class mdl_list_stmt : mdl_stmt {
195   u_int type_;
196   string id_;
197   vector<string> *elements_;
198   bool is_lib_;
199   vector<string> *flavor_;
200
201 $ignore
202 public:
203   mdl_list_stmt(u_int type, string ident, vector<string> *elems,
204                 bool is_lib, vector<string> *flavor);
205   virtual ~mdl_list_stmt();
206   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
207   virtual bool mk_list(vector<string> &funcs);
208 #ifdef NO_MDL_PRINT
209   virtual void print(ostream&) { }
210 #endif
211
212 $ignore
213 };
214
215 $remote
216 class mdl_for_stmt : mdl_stmt {
217   mdl_stmt *for_body_;
218   string index_name_;
219   mdl_expr *list_expr_;
220
221 $ignore
222 public:
223   mdl_for_stmt(string index_name, mdl_expr *list_exp, mdl_stmt *body);
224   virtual ~mdl_for_stmt();
225   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
226   virtual bool mk_list(vector<string> &funcs);
227 #ifdef NO_MDL_PRINT
228   virtual void print(ostream&) { }
229 #endif
230
231 $ignore
232 };
233
234 $remote
235 class mdl_if_stmt : mdl_stmt {
236   mdl_expr *expr_;
237   mdl_stmt *body_;
238
239 $ignore
240 public:
241   mdl_if_stmt(mdl_expr *expr, mdl_stmt *body);
242   virtual ~mdl_if_stmt();
243   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
244   virtual bool mk_list(vector<string> &funcs);
245 #ifdef NO_MDL_PRINT
246   virtual void print(ostream&) { }
247 #endif
248
249 $ignore
250 };
251
252 $remote
253 class mdl_seq_stmt : mdl_stmt {
254   vector<mdl_stmt*> *stmts_;
255
256 $ignore
257 public:
258   mdl_seq_stmt(vector<mdl_stmt*> *stmts);
259   virtual ~mdl_seq_stmt();
260   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
261   virtual bool mk_list(vector<string> &funcs);
262 #ifdef NO_MDL_PRINT
263   virtual void print(ostream&) { }
264 #endif
265
266 $ignore
267 };
268
269 $remote
270 class mdl_instr_stmt : mdl_stmt {
271   u_int position_; // append or prepend
272   mdl_expr *point_expr_; // e.g. $start.entry.  Can be a fn entry, exit, or call site.
273   vector<mdl_icode*> *icode_reqs_; // the instrumentation code itself
274   u_int where_instr_; // preInsn or postInsn
275   bool constrained_; // if not true, no constraints will be applied
276
277 $ignore
278 public:
279   mdl_instr_stmt(u_int pos, mdl_expr *point_expr, vector<mdl_icode*> *i_reqs,
280                  unsigned where_instr, bool constrained);
281   virtual ~mdl_instr_stmt();
282   virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
283   virtual bool mk_list(vector<string> &funcs);
284 #ifdef NO_MDL_PRINT
285   virtual void print(ostream& os) {
286     os << "MDL_INSTR_STMT: constrained=" << constrained_ << " ";
287     point_expr_->print(os);
288   }
289 #endif
290
291 $ignore
292 };
293
294 $remote 
295 class mdl_constraint {
296   string id_;
297   vector<string> *match_path_;
298   vector<mdl_stmt*> *stmts_;
299   bool replace_;
300   u_int data_type_; // type of this constraint: counter, timer, etc.
301   u_int hierarchy_;
302   u_int type_; // type of things constrained: module, procedure, int, etc.
303
304 $ignore
305 public:
306   mdl_constraint(string id, vector<string> *match_path,
307                  vector<mdl_stmt*> *stmts, bool replace, u_int d_type,
308                  bool& error);
309   ~mdl_constraint();
310   bool apply(metricDefinitionNode *mn, dataReqNode *&flag,
311              vector<string>& resource, process *proc, bool computingCost);
312   bool mk_list(vector<string> &funcs);
313
314 #ifdef NO_MDL_PRINT
315    friend ostream& operator<< (ostream& os, const mdl_constraint& cons) {
316      os << "\nConstraint: " << cons.id_ << " ";
317      unsigned size, index;
318      if (cons.match_path_) {
319        size = cons.match_path_->size();
320        for (index=0; index<size; index++) os << (*cons.match_path_)[index] << "/";
321        os << endl;
322      }
323      os << "Replace=" << cons.replace_ << " Data_type=" << cons.data_type_ << " Hierarchy=" 
324        << cons.hierarchy_ << " Type=" << cons.type_ << endl;
325     if (cons.stmts_) {
326       size = cons.stmts_->size();
327       os << "Statements\n";
328       for (index=0; index<size; index++) {
329         (*cons.stmts_)[index]->print(os);
330         os << " ";
331       }
332     }
333     return os;
334    }
335 #endif
336
337 $ignore
338 };
339
340 $remote
341 class mdl_metric {
342   string id_;
343   string name_;
344   string units_;
345   u_int agg_op_; // avg, sum, min, or max
346   u_int style_;  // currently, always EventCounter
347   u_int type_;   // counter, processTimer, or wallTimer
348   vector<mdl_stmt*> *stmts_; // for "base is <type_> { ... }
349   vector<string> *flavors_; // which flavors this metric is valid for
350   vector<mdl_constraint*> *constraints_;
351   vector<string> *temp_ctr_; // temporary counters
352   bool developerMode_;
353   int unitstype_; // normalized, unnormalized, or sampled
354
355 $ignore
356 public:
357   mdl_metric(string id, string name, string units,
358              u_int agg, u_int style, u_int type,
359              vector<mdl_stmt*> *mv, vector<string> *flavs, 
360              vector<mdl_constraint*> *cons,
361              vector<string> *temp_c, bool developerMode,int unitstype);
362   ~mdl_metric();
363 #ifdef NO_MDL_PRINT
364   friend ostream& operator<< (ostream &os, const mdl_metric& met) {
365     os << "\nMetric: " << met.id_ << " " << met.name_ << " agg_op=" << met.agg_op_ << " style=" 
366       << met.style_ << " type=" << met.type_ << endl;
367     unsigned size, index;
368     if (met.stmts_) {
369       size = met.stmts_->size();
370       os << "Statements\n";
371       for (index=0; index<size; index++) {
372         (*met.stmts_)[index]->print(os);
373          os << " ";
374       }
375     }
376     if (met.constraints_) {
377       size = met.constraints_->size();
378       os << "Constraints\n";
379       for (index=0; index<size; index++) {
380         os << *((*met.constraints_)[index]) << " ";
381       }
382     }
383     return os;
384   }
385 #endif
386   metricDefinitionNode *apply(vector< vector<string> >&focus, 
387                               string& flat_name,
388                               vector<process *> procs,
389                               bool replace_components_if_present,
390                               bool computingCost);
391 $ignore
392 };
393
394 /* descriptive information about a metric */
395 $remote struct metricInfo { 
396     string name;
397     int style;
398     int aggregate;
399     string units;
400     bool developerMode;
401     int unitstype;
402     u_int handle;  // this is currently ignored by the daemons 
403 };
404
405 $remote struct focusStruct {
406   vector<u_int> focus;
407 };
408
409 $remote struct resourceInfoCallbackStruct {
410    u_int temporaryId;
411    vector<string> resource_name;
412    string abstraction;
413    u_int type;
414 };
415
416 /*
417  * Create a paradynd process.
418  *
419  */
420 int createDaemon(string machine,
421                  string login,
422                  string name,
423                  vector<string> argv);
424
425
426 $remote dynRPC {
427     $base 4000;
428     $version 55;
429
430     //
431     // Define a program to run. 
432     // argv: the command and arguments
433     // dir: working directory where program will run.
434     int addExecutable(vector<string> argv, string dir);
435
436     //
437     // Connect up with a running program (not possible on all platforms).
438     // 'path' gives the full path name to the executable, used only to read
439     // the symbol table.
440     // values for 'afterAttach': 1 --> pause, 2 --> run, 0 --> leave as is
441     //
442     bool attach(string path, int pid, int afterAttach);
443
444     //
445     // Start an application running (This starts the actual execution).
446     //
447     bool startProgram(int program);
448
449     //
450     //   Stop a process
451     //
452     bool pauseProgram(int program);
453
454     //
455     //   Stop all processes associted with the application.
456     //
457     bool pauseApplication();
458
459     //
460     // Continue a paused process
461     //
462     void continueProgram(int program);
463
464     //
465     // Continue all of the processes
466     //
467     void continueApplication();
468
469     //
470     // Disconnect the tool from the process.
471     //    pause - leave the process in a stopped state.
472     //
473     //
474     bool detachProgram(int program, bool pause);
475
476     //
477     // Called by paradynd when a new process starts up.  Specifically, paradynd
478     // calls it when it detects that the new program has finished running
479     // its DYNINST().
480     //
481     // If the state of the appl as a whole is 'running' then we (paradyn) will
482     // issue an igen call to continue this new process; otherwise, we'll leave it
483     // paused.
484     //
485     $upcall $async void newProgramCallbackFunc( int pid, 
486                                                 vector<string> argv, 
487                                                 string machine,
488                                                 bool calledFromExec,
489                                                 bool wantToInitiallyRun);
490     //
491     // Message display with "error" visual characteristics
492     // and lookup in error database for explanation. This function
493     // calls showError function in UIM class
494     //
495     $upcall $async void showErrorCallback (int errCode,
496                                            string errString,
497                                            string hostName);
498
499    // batch the samples (paradynd-->paradyn) to get better performance
500    // the functionality is essentially the same as the 
501    // sampleDataCallbackFunc, which is now obsolete
502
503    $virtual $upcall $async
504    void batchSampleDataCallbackFunc(int program,
505                                     vector<batch_buffer_entry> theBatchBuffer);
506
507    // batch the traces (paradynd-->paradyn) to get better performance
508    // the functionality is essentially the same as the 
509    // batchSampleDataCallbackFunc, which is now obsolete
510
511    $virtual $upcall $async
512    void batchTraceDataCallbackFunc(int program,
513                                     vector<trace_batch_buffer_entry> theTraceBatchBuffer);
514
515    //
516    // XXXX - Hack this should be generalized into a vector.
517    //
518    $virtual $upcall $async void cpDataCallbackFunc(int program,
519                                                       double timeStamp,
520                                                       int context,
521                                                       double total,
522                                                       double share);
523
524    // 
525    // Handler that reports the initial time for which a daemon reports a sample
526    // The earliest (absolute) initial time will become the base time (0)
527    //
528    $virtual $upcall $async void firstSampleCallback(int program,
529                                                     double time);
530
531     //
532     // Handler that gets called when a new resource is defined.
533     //
534     // temporaryId      - daemon generated resource id (it will become the 
535     //                          permanent id, unless there are conflicts
536     //                          with id's generated by another daemon)
537     // resource_name    - name of resource, divided into parts
538     // abstraction      - abstraction to which it belongs     
539     // type             - the MDL type for this resource (MDL_T_STRING, etc.)
540     // 
541     $virtual $upcall $async void resourceInfoCallback(u_int temporaryId, 
542                                              vector<string> resource_name,
543                                              string abstraction, u_int type);
544
545     $virtual $upcall $async void severalResourceInfoCallback(vector<resourceInfoCallbackStruct>);
546         
547     //
548     // Handlers that gets called in paradynd when a new call graph relationship
549     //  is defined....
550     // Names post-fixed w/ Callback to preserve convention that functions
551     //  names *Callback represent callbacks from paradynd TO paradyn....
552     //
553     $virtual $upcall $async void AddCallGraphNodeCallback(int program, string resource);
554     $virtual $upcall $async void 
555         AddCallGraphStaticChildrenCallback(int program, string resource, 
556         vector<string> children);
557     $virtual $upcall $async void CallGraphSetEntryFuncCallback(int program, string entry_func);
558     $virtual $upcall $async void CallGraphFillDone(int program);
559     // Handler that gets called when a new memory is defined.
560     //
561     // data_structure   - name of memory chunk, divided into blks
562     // virtual_address  - start address of the memory chunk
563     // memory_size      - size of the memory chunk
564     // blk_size         - block size
565     $upcall $async void memoryInfoCallback(int program,
566                                            string data_structure,
567                                            int virtual_address,
568                                            u_int memory_size,
569                                            u_int blk_size) ;
570
571     // In case there are conflicts between the resource Id's generated by
572     // the daemons, paradyn generates a new Id and report it to the daemon.
573     $async void resourceInfoResponse(vector<u_int> temporaryIds,
574                                      vector<u_int>resourceIds);
575
576
577     // The ids that will be used to represent memory resources
578     // see memoryInfoCallback
579     $async void memoryInfoResponse(string data_structure,
580                                    int virtual_address,
581                                    u_int memory_size,
582                                    u_int blk_size,
583                                    vector<u_int> resource_ids) ;
584
585     $async void memoryRangeSelected(string flat, int min, int max) ;
586
587     $virtual $upcall $async void resourceBatchMode(bool);
588
589     //
590     // Handler that gets called when new mapping data is collected.
591     //
592     $upcall $async void mappingInfoCallback(int program, 
593                                             string abstraction, 
594                                             string type, 
595                                             string key,
596                                             string value);
597
598     // Upcall for a new metric being defined.
599     //
600     $upcall $async void newMetricCallback(metricInfo info); 
601
602     $async void setSampleRate(double sampleInterval);
603
604     //
605     // tell dyninst to ignore this resource for instrumentation.
606     //    Currently this only applies to programs, modules, and procedures.
607     //    False - suppress
608     //    True - enable
609     //
610     bool setTracking(u_int resource_id, bool);
611
612     //
613     // Routines to control data collection on a performanceStream.
614     //
615     // resourceList     - a list of resources
616     // metric   - what metric to collect data for
617     //
618     $async void enableDataCollection(vector<focusStruct> focus, 
619                                       vector<string> metric,
620                                       vector<u_int> mi_ids, 
621                                       u_int daemon_id,
622                                       u_int request_id);
623     //
624     // synchronous enable call, for propogating metrics
625     //
626     int enableDataCollection2(vector<u_int> focus, string metric, int id);
627
628     //
629     // Upcall to tell paradyn that all daemons are ready after a metric 
630     // enable request
631     //
632     $upcall $async void enableDataCallback(u_int daemon_id, 
633                                            vector<int> return_id,
634                                            vector<u_int> mi_ids,
635                                            u_int request_id);
636     //
637     // Upcall to tell paradyn that all daemons are ready after computing 
638     // the value for predicted data cost
639     //    id: an identifier for the request
640     //  client_id: an id passed by calling thread
641     //
642     $upcall $async void getPredictedDataCostCallback(u_int id,
643                                                      u_int req_id,
644                                                      float val,
645                                                      u_int clientID);
646
647     //
648     // stop collecting data for the named mi.
649     //     mi           - a metricInstance returned by enableDataCollection.
650     //
651     $async void disableDataCollection(int mi);
652
653     // 
654     // called by a daemon when there is no more data to be sent for a metric
655     // instance, because all processes have exited.
656     $virtual $upcall $async void endOfDataCollection(int mi);
657
658     //
659     // Return the expected cost of collecting performance data for a single
660     //    metric at a given focus.  The value returned is the fraction of
661     //    perturbation expected (i.e. 0.10 == 10% slow down expected).
662     //    id: an identifier for the request
663     //  client_id: an id passed by calling thread
664     //
665     $async void getPredictedDataCost(u_int id,
666                                      u_int req_id,
667                                      vector<u_int> focus, 
668                                      string metric,
669                                      u_int clientID);
670
671     //
672     // Get the static configuration information.
673     //
674     vector<metricInfo> getAvailableMetrics();
675
676     //
677     // Create a new resource.
678     //
679     void addResource(u_int parent, u_int id, string name, u_int type);
680
681     //
682     // stdio or stderr from an application.
683     //
684     $upcall $async void applicationIO(int pid, int len, string line);
685
686     //
687     // stdio or stderr from an application.
688     //
689     $virtual $upcall $async void reportStatus(string line);
690
691     //
692     // Debugger style calls.
693     //
694     //
695     string getStatus(int pid);
696     void coreProcess(int pid);
697
698     //
699     // For paradynd's that may get started, but not by paradyn
700     // This allows them to report system information
701     // flavor = programming environment {"pvm", "cm5", ... }
702     $virtual $upcall $async void reportSelf(string machine, 
703                                             string program, 
704                                             int pid,
705                                             string flavor);
706
707     //
708     // this call is used by paradynd to inform paradyn of a change in
709     // the status of a process -- the process stops (due to a signal), 
710     // or the process exits
711     //
712     $virtual $upcall $async void processStatus(int pid, u_int procstat);
713
714     //
715     // For timing and other measurements of paradynd
716     //
717     void printStats();
718
719     // MDL methods
720     $async void send_metrics(vector<mdl_metric*> *);
721     $async void send_constraints(vector<mdl_constraint*>*);
722     $async void send_stmts(vector<mdl_stmt*> *);
723     $async void send_libs(vector<string>*);
724     $async void send_no_libs();
725
726     // get the current wall clock time of the daemon to adjust for clock differences
727     double getTime();
728
729 };