1/* Copyright (C) 2021 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21/* This file describes the data structures used to control
22 * data collection; it is used by various commands in the MPMT
23 * tree, and is also shared with dbx.  Care should be taken
24 * to ensure that both the mpmt and dbx builds continue.
25
26 * To remove any APIs or change any enum cases:
27 *
28 * 1.  Make the changes in mpmt, and preserve the old APIs
29 *	as scaffolding and any old enum values as #defines.
30 *
31 * 2.  Add the new APIs and new cases to dbx, remove the
32 *	old ones.
33 *
34 * 3.  Remove the old API scaffolding and enum values here
35 *
36 */
37
38#ifndef	_COLLCTRL_H
39#define	_COLLCTRL_H
40
41#include "hwcentry.h"
42#include "cc_libcollector.h"
43
44/*---------------------------------------------------------------------------*/
45
46/* class */
47
48typedef struct {
49    int min;
50    int res;
51    int max;
52    int hival;
53    int normval;
54    int lowval;
55} clk_params_t;
56
57#define PROFINT_HIGH 997
58#define PROFINT_NORM 10007
59#define PROFINT_LOW 100003
60
61#define PROFINT_MIN 500
62#define PROFINT_MAX 1000000
63
64class Coll_Ctrl {
65public:
66
67  /* _interactive is 1 for dbx, 0 for collect */
68  Coll_Ctrl(int _interactive = 0, bool _defHWC = false, bool _kernelHWC = false);
69  ~Coll_Ctrl();
70
71  Coll_Ctrl(Coll_Ctrl *cc);       /* constructor for duplicate */
72  char *check_expt(char **);      /* check the experiment directory */
73  char *setup_experiment();       /* set up the experiment directory, etc. */
74  void close_expt();
75  void interrupt();               /* the user interrupts experiment */
76  void delete_expt();
77
78  /* enable/disable the experiment */
79  char *enable_expt();
80  void disable_expt()     { enabled = 0; };
81  int isenabled()         { return enabled; };
82
83  /* check for active experiment */
84  int isopened()          { return opened; };
85
86  /* set the parameters for clock-profiling */
87  void set_clk_params(int min, int res, int max, int hi, int norm, int lo);
88  char *set_clkprof(const char *valptr, char **warn);
89  char *reset_clkprof(int val); /* called if profiler must reset value */
90  int get_sys_period()    { return clk_params.min; };
91  int get_clk_min()       { return clk_params.min; };
92  int get_clk_max()       { return clk_params.max; };
93  int get_clk_res()       { return clk_params.res; };
94  int get_clkprof_mode()  { return clkprof_enabled; };
95  int get_clkprof_timer() { return clkprof_timer; };
96
97  /* set the parameters for synchronization tracing */
98  char *set_synctrace(const char *valptr);
99  int get_synctrace_mode()    { return synctrace_enabled; };
100  int get_synctrace_thresh()  { return synctrace_thresh; };
101  int get_synctrace_scope()   { return synctrace_scope; };
102
103  /* set the parameters for heap tracing */
104  char *set_heaptrace(const char *);
105  int get_heaptrace_mode()    { return heaptrace_enabled; };
106  int get_heaptrace_checkmode() { return heaptrace_checkenabled; };
107
108  /* set the parameters for I/O tracing */
109  char *set_iotrace(const char *);
110  int get_iotrace_mode()      { return iotrace_enabled; };
111
112  /* set the parameters for HW counting */
113  void setup_hwc();
114  char *set_hwcstring(const char *str, char **warn);
115  char *add_hwcstring(const char *str, char **warn);
116  char *add_default_hwcstring(const char *str, char **warn, bool add, bool forKernel = false);
117  void set_hwcdefault();
118  void disable_hwc();
119  int get_hwc_cnt()       { return hwcprof_enabled_cnt; };
120  int get_hwc_mode()      { return hwcprof_enabled_cnt ? 1 : 0; };
121  char *get_hwc_string()  { return hwc_string; };
122
123  Hwcentry *
124  get_hwc_entry (int n)
125  {
126    if (n < 0 || n >= hwcprof_enabled_cnt)
127      return 0;
128    return &hwctr[n];
129  };
130
131  void hwcentry_dup (Hwcentry *, Hwcentry *);
132  char *get_hwc_counter (int n) { return get_hwc_entry (n)->name; };
133
134  /* set the parameters for count data */
135  char *set_count (const char *);
136  int get_count ()              { return count_enabled; };
137  void set_Iflag ()             { Iflag = 1; };
138  void set_Nflag ()             { Nflag = 1; };
139
140  /* set time interval for attach with dbx timed collection */
141  /* also used for er_kernel */
142  char *set_time_run (const char *);
143  int get_time_run (void)       { return time_run; };
144  int get_start_delay (void)    { return start_delay; };
145
146  /* set pid for attach with dbx to collect data */
147  char *set_attach_pid (char *);
148  int get_attach_pid (void)     { return attach_pid; };
149
150  /* set java mode, "on" = yes; "off" = no; anthing else implies
151   *	yes, and is the path to the java to use
152   *	java_mode is returned as zero for off, one for on
153   *	java_default is returned as zero for explicitly set, one for defaulted on
154   */
155  char *set_java_mode (const char *);
156  int get_java_mode ()          { return java_mode; };
157  int get_java_default ()       { return java_default; };
158
159  /* setting Java path explicitly */
160  char *set_java_path (const char *);
161  char *get_java_path ()        { return java_path; };
162
163  /* set additional arguments for Java invocation */
164  char *set_java_args (char *);
165  char *get_java_args ()        { return java_args; };
166  int get_java_arg_cnt ()       { return njava_args; };
167
168  /* set load-object archive mode, 0 = no; other = yes */
169  char *set_archive_mode (const char *);
170  char *get_archive_mode ()     { return archive_mode; };
171
172  /* set follow-descendants mode, 0 = no; other = yes */
173  char *set_follow_mode (const char *);
174  Follow_type get_follow_mode () { return follow_mode; };
175  int get_follow_default ()     { return follow_default; };
176  char *get_follow_usr_spec ()  { return follow_spec_usr; };
177  char *get_follow_cmp_spec ()  { return follow_spec_cmp; };
178
179  /* set profile idle cpus mode, 1 = no; 0 = yes */
180  char *set_prof_idle (const char *);
181  int get_prof_idle ()          { return prof_idle; };
182
183  /* set debug more, 1 = yes; other = no */
184  /* if set, target will be set to halt at exit from exec */
185  char *set_debug_mode (int);
186  int get_debug_mode ()         { return debug_mode; };
187
188  /* find a signal from a string */
189  int find_sig (const char *);
190  /* find a signal name from a signal value */
191  char *find_signal_name (int signal);
192
193  /* set the pauseresume (delayed initialization) signal */
194  char *set_pauseresume_signal (int, int);
195  int get_pauseresume_signal () { return pauseresume_sig; };
196  int get_pauseresume_pause ()  { return pauseresume_pause; };
197
198  /* set the sample signal */
199  char *set_sample_signal (int);
200  int get_sample_signal ()      { return sample_sig; };
201
202  /* set the periodic sampling */
203  char *set_sample_period (const char *);
204  int get_sample_period (void)  { return sample_period; };
205
206  /* set experiment size limit */
207  char *set_size_limit (const char *);
208  int get_size_limit (void)     { return size_limit; };
209
210  /* naming methods */
211  /* set the target executable name */
212  int set_target (char *);
213  char *get_target ()           { return target_name; };
214
215  /* set the experiment name */
216  void set_default_stem (const char *);
217  char *set_expt (const char *, char **, bool);
218  char *get_expt ()             { return expt_name; };
219
220  /* set the experiment directory */
221  char *set_directory (char *, char **);
222
223  char *get_directory ()        { return udir_name ? udir_name : store_dir; };
224
225  /* return the real experiment ptr file name */
226  char *get_experiment ()       { return store_ptr; };
227  char *update_expt_name (bool verbose = true, bool ckonly = false, bool newname = false);
228
229  /* remove the experiment */
230  void remove_exp_dir ();
231
232  /* return the data descriptor */
233  char *
234  get_data_desc ()
235  {
236    return data_desc;
237  };
238
239  /* set the experiment group */
240  char *set_group (char *);
241  char *get_group ()            { return expt_group; };
242
243  /* return the experiment settings as a string */
244  char *show (int); /* full show */
245  char *show_expt (); /* short form */
246
247  /* return an argv array to compose a "collect" command from settings */
248  char **get_collect_args ();
249
250  /* determine characteristics of system */
251  char *get_node_name ()        { return node_name; };
252  long get_ncpus ()             { return ncpus; };
253  int get_cpu_clk_freq ()       { return cpu_clk_freq; };
254  int get_cpc_cpuver ()         { return cpc_cpuver; };
255
256    /* disable warning about non-local filesystems */
257  void set_nofswarn ()          { nofswarn = 1; };
258
259  //========== Special functions to communicate with the Collector GUI ==========//
260  char *get (char *);   /* get control's value */
261  char *set (char *, const char *); /* set control's value */
262  char *unset (char *); /* reset control's value to its default */
263  void set_project_home (char *);
264
265private:
266  int interactive;      /* 1 - dbx, 0 - collect */
267  bool defHWC;          /* true if default HWC experiment should be run */
268  bool kernelHWC;       /* T if default HWC counters are for kernel profiling */
269  int opened;           /* T if an experiment is opened */
270  int enabled;          /* T if an experiment is enabled */
271  volatile int uinterrupt; /* set if interrupt from user */
272
273  /* experiment/machine characteristics */
274  char *node_name;      /* name of machine on which experiment is run */
275  long ncpus;           /* number of online CPUs */
276  int cpu_clk_freq;     /* chip clock (MHz.), as reported from processor_info */
277  int cpc_cpuver;       /* chip version, as reported from libcpc */
278  long sys_resolution;  /* system clock resolution */
279  int sys_period;       /* profiling clock resolution on the system */
280  int sample_period;    /* period for sampling, seconds */
281  int sample_default;    /* if period for sampling set by default */
282  int size_limit;       /* experiment size limit, MB */
283  long npages;          /* number of pages configured */
284  long page_size;       /* size of system page */
285  clk_params_t clk_params;
286
287  /* user specification of name */
288  /*  user may specify both uexpt_name and udir_name
289   *	if uexpt_name is absolute path, udir_name is ignored, with warning
290   *	otherwise, udir_name is prepended to uexpt_name
291   *
292   *	if uexpt_name is of the form: <dir>/zzzz.nnn.er, where nnn is numeric,
293   *	nnn will be reset to one greater than the the highest experiment
294   *	  with a name of the same form.
295   */
296  char *default_stem;   /* default stem for experiment name */
297  char *uexpt_name;     /* suggested experiment name */
298  char *expt_name;      /* experiment name, after defaulting */
299  char *expt_dir;       /* directory part of suggested experiment name */
300  char *base_name;      /* basename of suggested experiment name */
301  char *udir_name;      /* user name of directory for data */
302
303  char *store_dir;      /* directory to contain experiment dir. */
304  char *prev_store_dir; /* previously set store directory */
305  char *store_ptr;      /* experiment pointer file */
306  char *expt_group;     /* name of experiment group, if any */
307  char *project_home;   /* argv[0] */
308
309  char *target_name;    /* target executable name */
310  char *data_desc;      /* string describing the data to be collected */
311  char *lockname;       /* name of directory lock file */
312  int lockfd;           /* fd of open lock file */
313
314  int nofswarn;         /* if 1, don't warn of filesystem */
315  int expno;            /* number in <stem>.<expno>.er */
316
317  /* T if an target is to be left for debugger attach */
318  int debug_mode;
319
320  /* clock-profiling controls */
321  /* T if clock-based profiling */
322  int clkprof_enabled;
323
324  /* T if on by default, rather than explicit setting */
325  int clkprof_default;
326
327  /* value for timer, microseconds. */
328  int clkprof_timer; // adjusted clock profiling interval
329  int clkprof_timer_target; // desired clock profiling interval
330
331  /* HW counter-profiling controls */
332  /* >0 if HW counter-based profiling */
333  int hwcprof_default;
334  int hwcprof_enabled_cnt;
335  char *hwc_string;
336  Hwcentry hwctr[MAX_PICS];
337
338  int synctrace_enabled;    /* T if synchronization tracing */
339  /*  sync trace threshold value, microsec. */
340  /* if 0, record all */
341  /* if <0, calibrate */
342  int synctrace_thresh;
343
344  /* sync trace scope -- a bit mask */
345  /* 	definitions in data_pckts.h */
346  int synctrace_scope;
347
348  int heaptrace_enabled;    /* T if heap tracing */
349  /* if 0 no checking;
350   * if 1, check for over- and under-write
351   * if 2, also set patterns in malloc'd and free'd areas
352   */
353  int heaptrace_checkenabled;
354  int iotrace_enabled;  /* T if I/O tracing */
355
356  /* count controls */
357  /* 1 if counting is enabled; -1 if count static is enabled */
358  int count_enabled;
359  int Iflag;    /* specify bit output directory -- only with count_enabled */
360  int Nflag;    /* specify bit library to ignore -- only with count_enabled */
361
362  /* pid, if -P <pid> is invoked for attach with dbx */
363  int attach_pid;
364
365  /* time_run -- non-zero if timed execution request (dbx/er_kernel) */
366  int time_run;
367  int start_delay;
368
369  /* T if Java profiling is requested */
370  int java_mode;
371  int java_default;
372  char *java_path;
373  char *java_args;
374  int njava_args;
375
376  /* whether/how following-descendants is requested */
377  Follow_type follow_mode;
378  int follow_default;
379  char *follow_spec_usr;    // user's selective follow spec
380  char *follow_spec_cmp;    // compiled selective follow spec
381  int prof_idle;            // whether profiling idle cpus is requested
382  char *archive_mode;       // how load-objects archiving is requested
383
384  // signals to control pause-resume (delayed initialization) and samples
385  int pauseresume_sig;      // for pause-resume signal -- delayed initialization
386  int pauseresume_pause;    // 1 if pauseresume and start paused; 0 if not
387  int sample_sig;           // to trigger sample
388  char *report_signal_conflict (int);
389  char *check_consistency ();   // check the experiment settings for consistency
390  void determine_profile_params ();
391  char *preprocess_names ();
392  char *get_exp_name (const char *);
393  char *create_exp_dir ();
394  void build_data_desc ();
395  char *check_group ();
396  char *join_group ();
397  void free_hwc_fields (Hwcentry *tmpctr);
398
399  // propagates clkprof_timer change to Hwcentry hwctr[]
400  void set_clkprof_timer_target (int microseconds);
401  void adjust_clkprof_timer (int microseconds);
402  hrtime_t clkprof_timer_2_hwcentry_min_time (int clkprof_microseconds);
403};
404
405#endif /* !_COLLCTRL_H */
406