| /* Copyright (C) 2021-2024 Free Software Foundation, Inc. |
| Contributed by Oracle. |
| |
| This file is part of GNU Binutils. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3, or (at your option) |
| any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, 51 Franklin Street - Fifth Floor, Boston, |
| MA 02110-1301, USA. */ |
| |
| /* This file describes the data structures used to control |
| * data collection; it is used by various commands in the MPMT |
| * tree, and is also shared with dbx. Care should be taken |
| * to ensure that both the mpmt and dbx builds continue. |
| |
| * To remove any APIs or change any enum cases: |
| * |
| * 1. Make the changes in mpmt, and preserve the old APIs |
| * as scaffolding and any old enum values as #defines. |
| * |
| * 2. Add the new APIs and new cases to dbx, remove the |
| * old ones. |
| * |
| * 3. Remove the old API scaffolding and enum values here |
| * |
| */ |
| |
| #ifndef _COLLCTRL_H |
| #define _COLLCTRL_H |
| |
| #include "hwcentry.h" |
| #include "cc_libcollector.h" |
| |
| /*---------------------------------------------------------------------------*/ |
| |
| /* class */ |
| |
| typedef struct { |
| int min; |
| int res; |
| int max; |
| int hival; |
| int normval; |
| int lowval; |
| } clk_params_t; |
| |
| #define PROFINT_HIGH 997 |
| #define PROFINT_NORM 10007 |
| #define PROFINT_LOW 100003 |
| |
| #define PROFINT_MIN 500 |
| #define PROFINT_MAX 1000000 |
| |
| class Coll_Ctrl { |
| public: |
| |
| /* _interactive is 1 for dbx, 0 for collect */ |
| Coll_Ctrl(int _interactive = 0, bool _defHWC = false, bool _kernelHWC = false); |
| ~Coll_Ctrl(); |
| |
| Coll_Ctrl(Coll_Ctrl *cc); /* constructor for duplicate */ |
| char *check_expt(char **); /* check the experiment directory */ |
| char *setup_experiment(); /* set up the experiment directory, etc. */ |
| void close_expt(); |
| void interrupt(); /* the user interrupts experiment */ |
| void delete_expt(); |
| |
| /* enable/disable the experiment */ |
| char *enable_expt(); |
| void disable_expt() { enabled = 0; }; |
| int isenabled() { return enabled; }; |
| |
| /* check for active experiment */ |
| int isopened() { return opened; }; |
| |
| /* set the parameters for clock-profiling */ |
| void set_clk_params(int min, int res, int max, int hi, int norm, int lo); |
| char *set_clkprof(const char *valptr, char **warn); |
| char *reset_clkprof(int val); /* called if profiler must reset value */ |
| int get_clk_min() { return clk_params.min; }; |
| int get_clk_max() { return clk_params.max; }; |
| int get_clk_res() { return clk_params.res; }; |
| int get_clkprof_mode() { return clkprof_enabled; }; |
| int get_clkprof_timer() { return clkprof_timer; }; |
| |
| /* set the parameters for synchronization tracing */ |
| char *set_synctrace(const char *valptr); |
| int get_synctrace_mode() { return synctrace_enabled; }; |
| int get_synctrace_thresh() { return synctrace_thresh; }; |
| int get_synctrace_scope() { return synctrace_scope; }; |
| |
| /* set the parameters for heap tracing */ |
| char *set_heaptrace(const char *); |
| char *get_heaptrace_mode() { return heaptrace_mode; }; |
| |
| /* set the parameters for I/O tracing */ |
| char *set_iotrace(const char *); |
| int get_iotrace_mode() { return iotrace_enabled; }; |
| |
| /* set the parameters for HW counting */ |
| void setup_hwc(); |
| char *set_hwcstring(const char *str, char **warn); |
| char *add_hwcstring(const char *str, char **warn); |
| char *add_default_hwcstring(const char *str, char **warn, bool add, bool forKernel = false); |
| void set_hwcdefault(); |
| void disable_hwc(); |
| int get_hwc_cnt() { return hwcprof_enabled_cnt; }; |
| int get_hwc_mode() { return hwcprof_enabled_cnt ? 1 : 0; }; |
| char *get_hwc_string() { return hwc_string; }; |
| |
| Hwcentry * |
| get_hwc_entry (int n) |
| { |
| if (n < 0 || n >= hwcprof_enabled_cnt) |
| return 0; |
| return &hwctr[n]; |
| }; |
| |
| void hwcentry_dup (Hwcentry *, Hwcentry *); |
| char *get_hwc_counter (int n) { return get_hwc_entry (n)->name; }; |
| |
| /* set the parameters for count data */ |
| char *set_count (const char *); |
| int get_count () { return count_enabled; }; |
| void set_Iflag () { Iflag = 1; }; |
| void set_Nflag () { Nflag = 1; }; |
| |
| /* set time interval for attach with dbx timed collection */ |
| /* also used for er_kernel */ |
| char *set_time_run (const char *); |
| int get_time_run (void) { return time_run; }; |
| int get_start_delay (void) { return start_delay; }; |
| |
| /* set pid for attach with dbx to collect data */ |
| char *set_attach_pid (char *); |
| int get_attach_pid (void) { return attach_pid; }; |
| |
| /* set java mode, "on" = yes; "off" = no; anthing else implies |
| * yes, and is the path to the java to use |
| * java_mode is returned as zero for off, one for on |
| * java_default is returned as zero for explicitly set, one for defaulted on |
| */ |
| char *set_java_mode (const char *); |
| int get_java_mode () { return java_mode; }; |
| int get_java_default () { return java_default; }; |
| |
| /* setting Java path explicitly */ |
| char *set_java_path (const char *); |
| char *get_java_path () { return java_path; }; |
| |
| /* set additional arguments for Java invocation */ |
| char *set_java_args (char *); |
| char *get_java_args () { return java_args; }; |
| int get_java_arg_cnt () { return njava_args; }; |
| |
| /* set load-object archive mode, 0 = no; other = yes */ |
| char *set_archive_mode (const char *); |
| char *get_archive_mode () { return archive_mode; }; |
| |
| /* set follow-descendants mode, 0 = no; other = yes */ |
| char *set_follow_mode (const char *); |
| Follow_type get_follow_mode () { return follow_mode; }; |
| int get_follow_default () { return follow_default; }; |
| char *get_follow_usr_spec () { return follow_spec_usr; }; |
| char *get_follow_cmp_spec () { return follow_spec_cmp; }; |
| |
| /* set profile idle cpus mode, 1 = no; 0 = yes */ |
| char *set_prof_idle (const char *); |
| int get_prof_idle () { return prof_idle; }; |
| |
| /* set debug more, 1 = yes; other = no */ |
| /* if set, target will be set to halt at exit from exec */ |
| char *set_debug_mode (int); |
| int get_debug_mode () { return debug_mode; }; |
| |
| /* find a signal from a string */ |
| int find_sig (const char *); |
| /* find a signal name from a signal value */ |
| char *find_signal_name (int signal); |
| |
| /* set the pauseresume (delayed initialization) signal */ |
| char *set_pauseresume_signal (int, int); |
| int get_pauseresume_signal () { return pauseresume_sig; }; |
| int get_pauseresume_pause () { return pauseresume_pause; }; |
| |
| /* set the sample signal */ |
| char *set_sample_signal (int); |
| int get_sample_signal () { return sample_sig; }; |
| |
| /* set the periodic sampling */ |
| char *set_sample_period (const char *); |
| int get_sample_period (void) { return sample_period; }; |
| |
| /* set experiment size limit */ |
| char *set_size_limit (const char *); |
| int get_size_limit (void) { return size_limit; }; |
| |
| /* naming methods */ |
| /* set the target executable name */ |
| int set_target (char *); |
| char *get_target () { return target_name; }; |
| |
| /* set the experiment name */ |
| void set_default_stem (const char *); |
| char *set_expt (const char *, char **, bool); |
| char *get_expt () { return expt_name; }; |
| |
| /* set the experiment directory */ |
| char *set_directory (char *, char **); |
| |
| char *get_directory () { return udir_name ? udir_name : store_dir; }; |
| |
| /* return the real experiment ptr file name */ |
| char *get_experiment () { return store_ptr; }; |
| char *update_expt_name (bool verbose = true, bool ckonly = false, bool newname = false); |
| |
| /* remove the experiment */ |
| void remove_exp_dir (); |
| |
| /* return the data descriptor */ |
| char * |
| get_data_desc () |
| { |
| return data_desc; |
| }; |
| |
| /* set the experiment group */ |
| char *set_group (char *); |
| char *get_group () { return expt_group; }; |
| |
| /* return the experiment settings as a string */ |
| char *show (int); /* full show */ |
| char *show_expt (); /* short form */ |
| |
| /* return an argv array to compose a "collect" command from settings */ |
| char **get_collect_args (); |
| |
| /* determine characteristics of system */ |
| char *get_node_name () { return node_name; }; |
| long get_ncpus () { return ncpus; }; |
| int get_cpu_clk_freq () { return cpu_clk_freq; }; |
| |
| /* disable warning about non-local filesystems */ |
| void set_nofswarn () { nofswarn = 1; }; |
| |
| //========== Special functions to communicate with the Collector GUI ==========// |
| char *get (char *); /* get control's value */ |
| char *set (char *, const char *); /* set control's value */ |
| char *unset (char *); /* reset control's value to its default */ |
| void set_project_home (char *); |
| |
| private: |
| int interactive; /* 1 - dbx, 0 - collect */ |
| bool defHWC; /* true if default HWC experiment should be run */ |
| bool kernelHWC; /* T if default HWC counters are for kernel profiling */ |
| int opened; /* T if an experiment is opened */ |
| int enabled; /* T if an experiment is enabled */ |
| volatile int uinterrupt; /* set if interrupt from user */ |
| |
| /* experiment/machine characteristics */ |
| char *node_name; /* name of machine on which experiment is run */ |
| long ncpus; /* number of online CPUs */ |
| int cpu_clk_freq; /* chip clock (MHz.), as reported from processor_info */ |
| long sys_resolution; /* system clock resolution */ |
| int sample_period; /* period for sampling, seconds */ |
| int sample_default; /* if period for sampling set by default */ |
| int size_limit; /* experiment size limit, MB */ |
| long npages; /* number of pages configured */ |
| long page_size; /* size of system page */ |
| clk_params_t clk_params; |
| |
| /* user specification of name */ |
| /* user may specify both uexpt_name and udir_name |
| * if uexpt_name is absolute path, udir_name is ignored, with warning |
| * otherwise, udir_name is prepended to uexpt_name |
| * |
| * if uexpt_name is of the form: <dir>/zzzz.nnn.er, where nnn is numeric, |
| * nnn will be reset to one greater than the the highest experiment |
| * with a name of the same form. |
| */ |
| char *default_stem; /* default stem for experiment name */ |
| char *uexpt_name; /* suggested experiment name */ |
| char *expt_name; /* experiment name, after defaulting */ |
| char *expt_dir; /* directory part of suggested experiment name */ |
| char *base_name; /* basename of suggested experiment name */ |
| char *udir_name; /* user name of directory for data */ |
| |
| char *store_dir; /* directory to contain experiment dir. */ |
| char *prev_store_dir; /* previously set store directory */ |
| char *store_ptr; /* experiment pointer file */ |
| char *expt_group; /* name of experiment group, if any */ |
| char *project_home; /* argv[0] */ |
| |
| char *target_name; /* target executable name */ |
| char *data_desc; /* string describing the data to be collected */ |
| char *lockname; /* name of directory lock file */ |
| int lockfd; /* fd of open lock file */ |
| |
| int nofswarn; /* if 1, don't warn of filesystem */ |
| int expno; /* number in <stem>.<expno>.er */ |
| |
| /* T if an target is to be left for debugger attach */ |
| int debug_mode; |
| |
| /* clock-profiling controls */ |
| /* T if clock-based profiling */ |
| int clkprof_enabled; |
| |
| /* T if on by default, rather than explicit setting */ |
| int clkprof_default; |
| |
| /* value for timer, microseconds. */ |
| int clkprof_timer; // adjusted clock profiling interval |
| int clkprof_timer_target; // desired clock profiling interval |
| |
| /* HW counter-profiling controls */ |
| /* >0 if HW counter-based profiling */ |
| int hwcprof_default; |
| int hwcprof_enabled_cnt; |
| char *hwc_string; |
| Hwcentry hwctr[MAX_PICS]; |
| |
| int synctrace_enabled; /* T if synchronization tracing */ |
| /* sync trace threshold value, microsec. */ |
| /* if 0, record all */ |
| /* if <0, calibrate */ |
| int synctrace_thresh; |
| |
| /* sync trace scope -- a bit mask */ |
| /* definitions in data_pckts.h */ |
| int synctrace_scope; |
| |
| char *heaptrace_mode; /* NULL, or on, or off, or range */ |
| int iotrace_enabled; /* T if I/O tracing */ |
| |
| /* count controls */ |
| /* 1 if counting is enabled; -1 if count static is enabled */ |
| int count_enabled; |
| int Iflag; /* specify bit output directory -- only with count_enabled */ |
| int Nflag; /* specify bit library to ignore -- only with count_enabled */ |
| |
| /* pid, if -P <pid> is invoked for attach with dbx */ |
| int attach_pid; |
| |
| /* time_run -- non-zero if timed execution request (dbx/er_kernel) */ |
| int time_run; |
| int start_delay; |
| |
| /* T if Java profiling is requested */ |
| int java_mode; |
| int java_default; |
| char *java_path; |
| char *java_args; |
| int njava_args; |
| |
| /* whether/how following-descendants is requested */ |
| Follow_type follow_mode; |
| int follow_default; |
| char *follow_spec_usr; // user's selective follow spec |
| char *follow_spec_cmp; // compiled selective follow spec |
| int prof_idle; // whether profiling idle cpus is requested |
| char *archive_mode; // how load-objects archiving is requested |
| |
| // signals to control pause-resume (delayed initialization) and samples |
| int pauseresume_sig; // for pause-resume signal -- delayed initialization |
| int pauseresume_pause; // 1 if pauseresume and start paused; 0 if not |
| int sample_sig; // to trigger sample |
| char *report_signal_conflict (int); |
| char *check_consistency (); // check the experiment settings for consistency |
| void determine_profile_params (); |
| char *preprocess_names (); |
| char *get_exp_name (const char *); |
| char *create_exp_dir (); |
| void build_data_desc (); |
| char *check_group (); |
| char *join_group (); |
| void free_hwc_fields (Hwcentry *tmpctr); |
| |
| // propagates clkprof_timer change to Hwcentry hwctr[] |
| void set_clkprof_timer_target (int microseconds); |
| void adjust_clkprof_timer (int microseconds); |
| hrtime_t clkprof_timer_2_hwcentry_min_time (int clkprof_microseconds); |
| }; |
| |
| #endif /* !_COLLCTRL_H */ |