2 * Copyright (c) 1996 Barton P. Miller
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.
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.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
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.
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.
43 #define MetStyleEventCounter 0
44 #define MetStyleSampledFunction 1
46 #include "util/h/Types.h"
47 #include "util/h/aggregation.h"
48 #include "paradyn/src/met/mdl.h"
51 struct batch_buffer_entry {
53 double startTimeStamp;
60 batch_buffer_entry &operator=(const batch_buffer_entry &src) {
62 startTimeStamp = src.startTimeStamp;
63 endTimeStamp = src.endTimeStamp;
66 internal_met = src.internal_met;
74 struct trace_batch_buffer_entry {
77 byteArray traceRecord;
80 trace_batch_buffer_entry &operator=(const trace_batch_buffer_entry &src) {
83 traceRecord = src.traceRecord;
89 /* used by paradynd to inform a change in the status of an application. */
90 // typedef enum { procPaused, procExited } processStatus_t;
93 typedef u_int processStatus_t;
96 abstract class mdl_expr {
100 virtual bool apply(mdl_var &ret) = 0;
101 virtual bool mk_list(vector<string> &funcs) = 0;
103 virtual void print(ostream& os) = 0;
109 class mdl_v_expr : mdl_expr {
111 vector<string> fields_;
112 vector<mdl_expr*> *args_;
118 vector<u_int> type_walk;
125 mdl_v_expr(string var, vector<string> fields);
126 mdl_v_expr(string func_name, vector<mdl_expr*> *args);
127 mdl_v_expr(int int_literal);
128 mdl_v_expr(string string_lit);
129 mdl_v_expr(u_int bin_op, mdl_expr *left, mdl_expr *right);
130 mdl_v_expr(string var, u_int array_index);
132 bool apply(mdl_var &ret);
133 bool mk_list(vector<string> &funcs);
135 virtual void print(ostream& os) {
136 os << "MDL_V_EXPR: var=" << var_ << " res_type=" << res_type_ << " do_type_walk="
138 unsigned size = fields_.size(), index;
141 for (index=0; index<size; index++) {
142 os << fields_[index] << " ";
153 abstract class mdl_rand {
156 virtual ~mdl_rand() {}
157 virtual bool apply(AstNode *&) = 0;
162 class mdl_instr_rand: mdl_rand {
166 vector<mdl_rand *> args_;
169 mdl_instr_rand(u_int type);
170 mdl_instr_rand(u_int type, u_int val);
171 mdl_instr_rand(u_int type, string name);
172 mdl_instr_rand(u_int type, string name, vector<mdl_instr_rand *>args);
174 virtual bool apply(AstNode *&);
179 class mdl_instr_req {
181 mdl_instr_rand *rand_;
182 string timer_counter_name_;
186 // start and stop timers, read symbol
187 mdl_instr_req(u_int type, string name);
190 mdl_instr_req(mdl_instr_rand *arg, u_int type, string obj_name);
193 mdl_instr_req(u_int type, mdl_instr_rand *rand);
197 bool apply(AstNode *&mn, AstNode *pred, bool mn_initialized);
203 mdl_instr_rand *if_op1_;
204 mdl_instr_rand *if_op2_;
211 mdl_icode(mdl_instr_rand *iop1, mdl_instr_rand *iop2,
212 u_int bop, bool use, mdl_instr_req *r);
214 bool apply(AstNode *&mn, bool mn_initialized);
219 abstract class mdl_stmt {
222 virtual ~mdl_stmt() { }
223 virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags) = 0;
224 virtual bool mk_list(vector<string> &funcs) = 0;
226 virtual void print(ostream& os) = 0;
232 class mdl_list_stmt : mdl_stmt {
235 vector<string> *elements_;
237 vector<string> *flavor_;
241 mdl_list_stmt(u_int type, string ident, vector<string> *elems,
242 bool is_lib, vector<string> *flavor);
243 virtual ~mdl_list_stmt();
244 virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
245 virtual bool mk_list(vector<string> &funcs);
247 virtual void print(ostream&) { }
254 class mdl_for_stmt : mdl_stmt {
257 mdl_expr *list_expr_;
261 mdl_for_stmt(string index_name, mdl_expr *list_exp, mdl_stmt *body);
262 virtual ~mdl_for_stmt();
263 virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
264 virtual bool mk_list(vector<string> &funcs);
266 virtual void print(ostream&) { }
273 class mdl_if_stmt : mdl_stmt {
279 mdl_if_stmt(mdl_expr *expr, mdl_stmt *body);
280 virtual ~mdl_if_stmt();
281 virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
282 virtual bool mk_list(vector<string> &funcs);
284 virtual void print(ostream&) { }
291 class mdl_seq_stmt : mdl_stmt {
292 vector<mdl_stmt*> *stmts_;
296 mdl_seq_stmt(vector<mdl_stmt*> *stmts);
297 virtual ~mdl_seq_stmt();
298 virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
299 virtual bool mk_list(vector<string> &funcs);
301 virtual void print(ostream&) { }
308 class mdl_instr_stmt : mdl_stmt {
309 u_int position_; // append or prepend
310 mdl_expr *point_expr_; // e.g. $start.entry. Can be a fn entry, exit, or call site.
311 vector<mdl_icode*> *icode_reqs_; // the instrumentation code itself
312 u_int where_instr_; // preInsn or postInsn
313 bool constrained_; // if not true, no constraints will be applied
317 mdl_instr_stmt(u_int pos, mdl_expr *point_expr, vector<mdl_icode*> *i_reqs,
318 unsigned where_instr, bool constrained);
319 virtual ~mdl_instr_stmt();
320 virtual bool apply(metricDefinitionNode *mn, vector<dataReqNode*>& flags);
321 virtual bool mk_list(vector<string> &funcs);
323 virtual void print(ostream& os) {
324 os << "MDL_INSTR_STMT: constrained=" << constrained_ << " ";
325 point_expr_->print(os);
333 class mdl_constraint {
335 vector<string> *match_path_;
336 vector<mdl_stmt*> *stmts_;
344 mdl_constraint(string id, vector<string> *match_path,
345 vector<mdl_stmt*> *stmts, bool replace, u_int d_type,
348 bool apply(metricDefinitionNode *mn, dataReqNode *&flag,
349 vector<string>& resource, process *proc, bool computingCost);
350 bool mk_list(vector<string> &funcs);
353 friend ostream& operator<< (ostream& os, const mdl_constraint& cons) {
354 os << "\nConstraint: " << cons.id_ << " ";
355 unsigned size, index;
356 if (cons.match_path_) {
357 size = cons.match_path_->size();
358 for (index=0; index<size; index++) os << (*cons.match_path_)[index] << "/";
361 os << "Replace=" << cons.replace_ << " Data_type=" << cons.data_type_ << " Hierarchy="
362 << cons.hierarchy_ << " Type=" << cons.type_ << endl;
364 size = cons.stmts_->size();
365 os << "Statements\n";
366 for (index=0; index<size; index++) {
367 (*cons.stmts_)[index]->print(os);
383 u_int agg_op_; // avg, sum, min, or max
384 u_int style_; // currently, always EventCounter
385 u_int type_; // counter, processTimer, or wallTimer
386 vector<mdl_stmt*> *stmts_; // for "base is <type_> { ... } (is this correct?)
387 vector<string> *flavors_; // which flavors this metric is valid for
388 vector<mdl_constraint*> *constraints_;
389 vector<string> *temp_ctr_; // temporary counters
391 int unitstype_; // normalized, unnormalized, or sampled
395 mdl_metric(string id, string name, string units,
396 u_int agg, u_int style, u_int type,
397 vector<mdl_stmt*> *mv, vector<string> *flavs,
398 vector<mdl_constraint*> *cons,
399 vector<string> *temp_c, bool developerMode,int unitstype);
402 friend ostream& operator<< (ostream &os, const mdl_metric& met) {
403 os << "\nMetric: " << met.id_ << " " << met.name_ << " agg_op=" << met.agg_op_ << " style="
404 << met.style_ << " type=" << met.type_ << endl;
405 unsigned size, index;
407 size = met.stmts_->size();
408 os << "Statements\n";
409 for (index=0; index<size; index++) {
410 (*met.stmts_)[index]->print(os);
414 if (met.constraints_) {
415 size = met.constraints_->size();
416 os << "Constraints\n";
417 for (index=0; index<size; index++) {
418 os << *((*met.constraints_)[index]) << " ";
424 metricDefinitionNode *apply(vector< vector<string> >&focus,
426 vector<process *> procs,
427 bool replace_components_if_present,
432 /* descriptive information about a metric */
433 $remote struct metricInfo {
440 u_int handle; // this is currently ignored by the daemons
443 $remote struct focusStruct {
447 $remote struct resourceInfoCallbackStruct {
449 vector<string> resource_name;
455 * Create a paradynd process.
458 int createDaemon(string machine,
461 vector<string> argv);
469 // Define a program to run.
470 // argv: the command and arguments
471 // dir: working directory where program will run.
472 int addExecutable(vector<string> argv, string dir);
475 // Connect up with a running program (not possible on all platforms).
476 // 'path' gives the full path name to the executable, used only to read
478 // values for 'afterAttach': 1 --> pause, 2 --> run, 0 --> leave as is
480 bool attach(string path, int pid, int afterAttach);
483 // Start an application running (This starts the actual execution).
485 bool startProgram(int program);
490 bool pauseProgram(int program);
493 // Stop all processes associted with the application.
495 bool pauseApplication();
498 // Continue a paused process
500 void continueProgram(int program);
503 // Continue all of the processes
505 void continueApplication();
508 // Disconnect the tool from the process.
509 // pause - leave the process in a stopped state.
512 bool detachProgram(int program, bool pause);
515 // Called by paradynd when a new process starts up. Specifically, paradynd
516 // calls it when it detects that the new program has finished running
519 // If the state of the appl as a whole is 'running' then we (paradyn) will
520 // issue an igen call to continue this new process; otherwise, we'll leave it
523 $upcall $async void newProgramCallbackFunc( int pid,
527 bool wantToInitiallyRun);
529 // Message display with "error" visual characteristics
530 // and lookup in error database for explanation. This function
531 // calls showError function in UIM class
533 $upcall $async void showErrorCallback (int errCode,
537 // batch the samples (paradynd-->paradyn) to get better performance
538 // the functionality is essentially the same as the
539 // sampleDataCallbackFunc, which is now obsolete
541 $virtual $upcall $async
542 void batchSampleDataCallbackFunc(int program,
543 vector<batch_buffer_entry> theBatchBuffer);
545 // batch the traces (paradynd-->paradyn) to get better performance
546 // the functionality is essentially the same as the
547 // batchSampleDataCallbackFunc, which is now obsolete
549 $virtual $upcall $async
550 void batchTraceDataCallbackFunc(int program,
551 vector<trace_batch_buffer_entry> theTraceBatchBuffer);
554 // XXXX - Hack this should be generalized into a vector.
556 $virtual $upcall $async void cpDataCallbackFunc(int program,
563 // Handler that reports the initial time for which a daemon reports a sample
564 // The earliest (absolute) initial time will become the base time (0)
566 $virtual $upcall $async void firstSampleCallback(int program,
570 // Handler that gets called when a new resource is defined.
572 // temporaryId - daemon generated resource id (it will become the
573 // permanent id, unless there are conflicts
574 // with id's generated by another daemon)
575 // resource_name - name of resource, divided into parts
576 // abstraction - abstraction to which it belongs
577 // type - the MDL type for this resource (MDL_T_STRING, etc.)
579 $virtual $upcall $async void resourceInfoCallback(u_int temporaryId,
580 vector<string> resource_name,
581 string abstraction, u_int type);
583 $virtual $upcall $async void severalResourceInfoCallback(vector<resourceInfoCallbackStruct>);
586 // Handler that gets called when a new memory is defined.
588 // data_structure - name of memory chunk, divided into blks
589 // virtual_address - start address of the memory chunk
590 // memory_size - size of the memory chunk
591 // blk_size - block size
592 $upcall $async void memoryInfoCallback(int program,
593 string data_structure,
598 // In case there are conflicts between the resource Id's generated by
599 // the daemons, paradyn generates a new Id and report it to the daemon.
600 $async void resourceInfoResponse(vector<u_int> temporaryIds,
601 vector<u_int>resourceIds);
604 // The ids that will be used to represent memory resources
605 // see memoryInfoCallback
606 $async void memoryInfoResponse(string data_structure,
610 vector<u_int> resource_ids) ;
612 $async void memoryRangeSelected(string flat, int min, int max) ;
614 $virtual $upcall $async void resourceBatchMode(bool);
617 // Handler that gets called when new mapping data is collected.
619 $upcall $async void mappingInfoCallback(int program,
625 // Upcall for a new metric being defined.
627 $upcall $async void newMetricCallback(metricInfo info);
629 void setSampleRate(double sampleInterval);
632 // tell dyninst to ignore this resource for instrumentation.
633 // Currently this only applies to programs, modules, and procedures.
637 bool setTracking(u_int resource_id, bool);
640 // Routines to control data collection on a performanceStream.
642 // resourceList - a list of resources
643 // metric - what metric to collect data for
645 $async void enableDataCollection(vector<focusStruct> focus,
646 vector<string> metric,
647 vector<u_int> mi_ids,
651 // synchronous enable call, for propogating metrics
653 int enableDataCollection2(vector<u_int> focus, string metric, int id);
656 // Upcall to tell paradyn that all daemons are ready after a metric
659 $upcall $async void enableDataCallback(u_int daemon_id,
660 vector<int> return_id,
661 vector<u_int> mi_ids,
664 // Upcall to tell paradyn that all daemons are ready after computing
665 // the value for predicted data cost
666 // id: an identifier for the request
667 // client_id: an id passed by calling thread
669 $upcall $async void getPredictedDataCostCallback(u_int id,
675 // stop collecting data for the named mi.
676 // mi - a metricInstance returned by enableDataCollection.
678 $async void disableDataCollection(int mi);
681 // called by a daemon when there is no more data to be sent for a metric
682 // instance, because all processes have exited.
683 $virtual $upcall $async void endOfDataCollection(int mi);
686 // Return the expected cost of collecting performance data for a single
687 // metric at a given focus. The value returned is the fraction of
688 // perturbation expected (i.e. 0.10 == 10% slow down expected).
689 // id: an identifier for the request
690 // client_id: an id passed by calling thread
692 $async void getPredictedDataCost(u_int id,
699 // Get the static configuration information.
701 vector<metricInfo> getAvailableMetrics();
704 // Create a new resource.
706 void addResource(u_int parent, u_int id, string name, u_int type);
709 // stdio or stderr from an application.
711 $upcall $async void applicationIO(int pid, int len, string line);
714 // stdio or stderr from an application.
716 $virtual $upcall $async void reportStatus(string line);
719 // Debugger style calls.
722 string getStatus(int pid);
723 void coreProcess(int pid);
726 // For paradynd's that may get started, but not by paradyn
727 // This allows them to report system information
728 // flavor = programming environment {"pvm", "cm5", ... }
729 $virtual $upcall $async void reportSelf(string machine,
735 // this call is used by paradynd to inform paradyn of a change in
736 // the status of a process -- the process stops (due to a signal),
737 // or the process exits
739 $virtual $upcall $async void processStatus(int pid, u_int procstat);
742 // For timing and other measurements of paradynd
747 $async void send_metrics(vector<mdl_metric*> *);
748 $async void send_constraints(vector<mdl_constraint*>*);
749 $async void send_stmts(vector<mdl_stmt*> *);
750 $async void send_libs(vector<string>*);
751 $async void send_no_libs();
753 // get the current wall clock time of the daemon to adjust for clock differences