Wolfgang Thallergcc16 merge934c3885 months agoHistory
3031 lines · 82.1 KB · C++
RawDownload
/* Copyright (C) 2021-2026 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.  */ #include "config.h"#include <unistd.h>#include <strings.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/statvfs.h>#include <sys/param.h>#include <signal.h>#include <fcntl.h>#include <errno.h>#include <ctype.h>#include <dirent.h>#include <libgen.h>#include <assert.h>#include <regex.h>  /* regcomp() */ #include "util.h"#include "libiberty.h"#include "collctrl.h"#include "hwcdrv.h"#include "StringBuilder.h" #define SP_GROUP_HEADER     "#analyzer experiment group" /* If the system doesn't provide strsignal, we get it defined in   libiberty but no declaration is supplied.   */#if !defined (HAVE_STRSIGNAL) && !defined (strsignal)extern const char *strsignal (int);#endif static const char *get_fstype (char *);static cpu_info_t cpu_info; static voidread_str (char *from, char **to){  if (*to != NULL)    return;  for (char *s = from; *s; s++)    if (*s != ':' && *s != '\t' && *s != ' ')      {	for (int i = ((int) strlen (s)) - 1; i >= 0; i--)	  {	    if (s[i] != '\n' && s[i] != ' ' && s[i] != '\t')	      {		*to = xstrndup (s, i + 1);		return;	      }	  }	return; // string is empty      }} static intread_int (char *from){  char *val = strchr (from, ':');  if (val)    return (int) strtol (val + 1, NULL, 0);  return 0;} cpu_info_t *read_cpuinfo (){  static int inited = 0;  if (inited)    return &cpu_info;  inited = 1; #if defined(__aarch64__)  asm volatile("mrs %0, cntfrq_el0" : "=r" (cpu_info.cpu_clk_freq));#elif defined(__riscv)  // Set 1000 MHz for minimal support RISC-V, will fix with a better method to get cpu clock frequency.  cpu_info.cpu_clk_freq = 1000;#endif   // Read /proc/cpuinfo to get CPU info and clock rate  FILE *procf = fopen ("/proc/cpuinfo", "r");  if (procf != NULL)    {      char temp[1024];      while (fgets (temp, (int) sizeof (temp), procf) != NULL)	{	  if (strncmp (temp, "processor", 9) == 0)	    cpu_info.cpu_cnt++;	  else if (strncmp (temp, "cpu MHz", 7) == 0)	    cpu_info.cpu_clk_freq = read_int (temp + 9);	  else if (strncmp (temp, "cpu family", 10) == 0)	    cpu_info.cpu_family = read_int (temp + 10);	  else if (strncmp (temp, "vendor_id", 9) == 0		   || strncmp (temp, "mvendorid", 9) == 0)	    {	      if (cpu_info.cpu_vendorstr == NULL)		read_str (temp + 9, &cpu_info.cpu_vendorstr);	    }	  else if (strncmp (temp, "model name", 10) == 0)	    {	      if (cpu_info.cpu_modelstr == NULL)		read_str (temp + 10, &cpu_info.cpu_modelstr);	    }	  else if (strncmp (temp, "model", 5) == 0)	    cpu_info.cpu_model = read_int (temp + 5);	  else if (strncmp (temp, "CPU implementer", 15) == 0)	    cpu_info.cpu_family = read_int (temp + 15);	  else if (strncmp (temp, "CPU architecture", 16) == 0)	    cpu_info.cpu_model = read_int (temp + 16);	}      fclose (procf);    }  if (cpu_info.cpu_vendorstr == NULL)#if defined(__aarch64__)    cpu_info.cpu_vendorstr = xstrdup (AARCH64_VENDORSTR_ARM);#else    cpu_info.cpu_vendorstr = GTXT ("Unknown processor");#endif  if (cpu_info.cpu_modelstr == NULL)    cpu_info.cpu_modelstr = GTXT ("Unknown cpu model");  return &cpu_info;} Coll_Ctrl::Coll_Ctrl (int _interactive, bool _defHWC, bool _kernelHWC){  char hostname[MAXPATHLEN];  interactive = _interactive;  defHWC = _defHWC;  kernelHWC = _kernelHWC;   /* set this host's parameters */  gethostname (hostname, 1023);  node_name = xstrdup (hostname);  char *p = strchr (node_name, (int) '.');  if (p != NULL)    *p = 0;  default_stem = xstrdup ("test");   cpu_info_t *cpu_p = read_cpuinfo ();  ncpus = cpu_p->cpu_cnt;  cpu_clk_freq = cpu_p->cpu_clk_freq;   /* check resolution of system clock */  sys_resolution = sysconf (_SC_CLK_TCK);   /* determine memory page size and number of pages */  npages = sysconf (_SC_PHYS_PAGES);  page_size = sysconf (_SC_PAGE_SIZE);   /* set default clock parameters */  hwcprof_enabled_cnt = 0; // must be set before calling determine_profile_params();  determine_profile_params (); // inits clk_params which is used by clock profiling AND HWCs   /* set default control values */  debug_mode = 0;#if defined(GPROFNG_JAVA_PROFILING)  java_mode = 1;#else  java_mode = 0;#endif  java_default = 1;  java_path = NULL;  java_args = NULL;  njava_args = 0;  follow_mode = FOLLOW_ON;  follow_default = 1;  follow_spec_usr = NULL;  follow_spec_cmp = NULL;  prof_idle = 1;  archive_mode = xstrdup ("on");  pauseresume_sig = 0;  sample_sig = 0;  uinterrupt = 0;  attach_pid = 0;  time_run = 0;  start_delay = 0;   /* clear the string pointers */  uexpt_name = NULL;  expt_name = NULL;  expt_dir = NULL;  base_name = NULL;  udir_name = NULL;  store_dir = NULL;  prev_store_dir = xstrdup ("");  store_ptr = NULL;  expt_group = NULL;  target_name = NULL;  data_desc = NULL;  lockname = NULL;  hwc_string = NULL;  project_home = NULL;  lockfd = -1;   /* set default data collection values */  enabled = 0;  opened = 0;  clkprof_enabled = 1;  clkprof_default = 1;  for (unsigned ii = 0; ii < MAX_PICS; ii++)    {      memset (&hwctr[ii], 0, sizeof (Hwcentry));      hwctr[ii].reg_num = -1;    }  hwcprof_default = 0;  if (defHWC == true)    {      setup_hwc ();      hwcprof_default = 1;    }  else // disable the default, and reset the counters    hwcprof_enabled_cnt = 0;  synctrace_enabled = 0;  synctrace_thresh = -1;  synctrace_scope = 0;  heaptrace_mode = NULL;  iotrace_enabled = 0;  count_enabled = 0;  Iflag = 0;  Nflag = 0;  sample_period = 1;  sample_default = 1;  size_limit = 0;  nofswarn = 0;  expno = 1;   // ensure that the default name is updated  // but don't print any message  (void) preprocess_names ();  (void) update_expt_name (false, false);} /* Copy constructor */Coll_Ctrl::Coll_Ctrl (Coll_Ctrl * cc){  uinterrupt = 0;  interactive = cc->interactive;  defHWC = cc->defHWC;  kernelHWC = cc->kernelHWC;  node_name = xstrdup (cc->node_name);  default_stem = xstrdup (cc->default_stem);  ncpus = cc->ncpus;  cpu_clk_freq = cc->cpu_clk_freq;  npages = cc->npages;  page_size = cc->page_size;  debug_mode = cc->debug_mode;  java_mode = cc->java_mode;  java_default = cc->java_default;  java_path = NULL;  java_args = NULL;  njava_args = 0;  follow_mode = cc->follow_mode;  follow_default = cc->follow_default;  if (cc->follow_spec_usr)    {      follow_spec_usr = xstrdup (cc->follow_spec_usr);      follow_spec_cmp = xstrdup (cc->follow_spec_cmp);    }  else    {      follow_spec_usr = NULL;      follow_spec_cmp = NULL;    }  archive_mode = xstrdup (cc->archive_mode);  pauseresume_sig = cc->pauseresume_sig;  sample_sig = cc->sample_sig;  time_run = cc->time_run;  start_delay = cc->start_delay;  clk_params = cc->clk_params;  clkprof_enabled = cc->clkprof_enabled;  clkprof_default = cc->clkprof_default;  clkprof_timer = cc->clkprof_timer;  clkprof_timer_target = cc->clkprof_timer_target;   // copy HW counter information  hwcprof_default = cc->hwcprof_default;  hwcprof_enabled_cnt = cc->hwcprof_enabled_cnt;  if (cc->hwc_string != NULL)    hwc_string = xstrdup (cc->hwc_string);  else    hwc_string = NULL;  for (int i = 0; i < hwcprof_enabled_cnt; i++)    hwcentry_dup (&hwctr[i], &(cc->hwctr[i]));  project_home = cc->project_home ? xstrdup (cc->project_home) : NULL;  synctrace_enabled = cc->synctrace_enabled;  synctrace_thresh = cc->synctrace_thresh;  synctrace_scope = cc->synctrace_scope;  heaptrace_mode = dbe_strdup(cc->heaptrace_mode);  iotrace_enabled = cc->iotrace_enabled;  count_enabled = cc->count_enabled;  Iflag = cc->Iflag;  Nflag = cc->Nflag;  sample_period = cc->sample_period;  sample_default = cc->sample_default;  size_limit = cc->size_limit;  nofswarn = cc->nofswarn;   // these will get reset during preprocess_names()  expt_name = NULL;  expt_dir = NULL;  store_dir = NULL;  base_name = NULL;  expno = 1;   // these represent user settings  expt_group = NULL;  if (cc->expt_group != NULL)    expt_group = xstrdup (cc->expt_group);  uexpt_name = NULL;  if (cc->uexpt_name != NULL)    uexpt_name = xstrdup (cc->uexpt_name);  udir_name = NULL;  if (cc->udir_name != NULL)    udir_name = xstrdup (cc->udir_name);   /* clear the string pointers */  prev_store_dir = xstrdup ("");  store_ptr = NULL;  target_name = NULL;  data_desc = NULL;  lockname = NULL;  lockfd = -1;   /* set default data collection values */  enabled = cc->enabled;  opened = 0;  nofswarn = cc->nofswarn;  sys_resolution = cc->sys_resolution;   // ensure that the default name is updated  (void) preprocess_names ();  (void) update_expt_name (false, false);  build_data_desc ();} Coll_Ctrl::~Coll_Ctrl (){  free (node_name);  free (expt_name);  free (expt_dir);  free (base_name);  free (udir_name);  free (store_dir);  free (store_ptr);  free (expt_group);  free (target_name);  free (data_desc);  free (lockname);  free (hwc_string);  free (project_home);  free (java_path);  free (heaptrace_mode);  hwcprof_enabled_cnt = 0;} /* set up the experiment */char *Coll_Ctrl::setup_experiment (){  char *ret;  if (enabled == 0)    return NULL;  build_data_desc ();   /* create the experiment directory */  ret = create_exp_dir ();  if (ret != NULL)    return ret;   /* if an experiment-group, join it */  ret = join_group ();  if (ret != NULL)    {      remove_exp_dir ();      return ret;    }  /* all is OK, return 0 */  opened = 1;  return NULL;} voidColl_Ctrl::interrupt (){  uinterrupt = 1;} char *Coll_Ctrl::enable_expt (){  if (opened == 1)    return xstrdup (GTXT ("Experiment is active; command ignored.\n"));  if (cpu_clk_freq == 0)    return xstrdup (GTXT ("Can not determine CPU clock frequency.\n"));  if (sys_resolution == 0)    return xstrdup (GTXT ("System clock profile resolution can not be determined.\n"));  enabled = 1;  return NULL;} /* close the experiment */voidColl_Ctrl::close_expt (){  opened = 0;  (void) update_expt_name (false, false);} /* close and delete the experiment */voidColl_Ctrl::delete_expt (){  if (opened == 0)    return;  remove_exp_dir ();   /* The order of removing the directory and closing   * the experiment may seem unnatural, but it's not.   * We do need to update names when we close the experiment   * (actually Coll_Ctrl object) and we can't remove anything   * after that.   */  close_expt ();} // Check the experiment settings for consistency.  Returns NULL if OK,//	or an error message if there are invalid combinations of settings char *Coll_Ctrl::check_consistency (){  /* check for Java arguments, but not Java profiling */  if (java_args != NULL && java_mode == 0)    return xstrdup (GTXT ("Java arguments can not be set if Java profiling is not enabled.\n"));   /* if count data, no other data is allowed */  if (count_enabled != 0      && ((clkprof_default != 1 && clkprof_enabled != 0)	  || hwcprof_enabled_cnt != 0 || synctrace_enabled != 0	  || heaptrace_mode != NULL || iotrace_enabled != 0))    return xstrdup (GTXT ("Count data cannot be collected along with any other data.\n"));   /* if count data, various other options are not allowed */  if (count_enabled != 0      && ((java_mode != 0 && java_default != 1)	  || java_args != NULL || debug_mode != 0	  || (follow_mode != 0 && follow_default != 1)	  || pauseresume_sig != 0 || sample_sig != 0	  || (sample_default != 1 && sample_period != 0) || time_run != 0))    return xstrdup (GTXT ("Count data cannot be collected with any of -F -S -y -l -j -J -x -t .\n"));  /* if not count data, I and N options are not allowed */  if (count_enabled == 0 && (Iflag != 0 || Nflag != 0))    return xstrdup (GTXT ("-I or -N can only be specified with count data.\n"));  return NULL;} char *Coll_Ctrl::check_expt (char **warn){  char *ret;  *warn = NULL;  ret = check_consistency ();  if (ret != NULL) /* something is wrong, return the error */    return ret;  /* check for heaptrace and java -- warn that it covers native allocations only */  if (heaptrace_mode != NULL && java_mode == 1 && java_default == 0)    *warn = xstrdup (GTXT ("Note: Heap profiling will only trace native allocations, not Java allocations.\n"));   /* if no profiling data selected, warn the user */  if (clkprof_enabled == 0 && hwcprof_enabled_cnt == 0 && synctrace_enabled == 0      && heaptrace_mode == NULL && iotrace_enabled == 0 && count_enabled == 0)    *warn = xstrdup (GTXT ("Warning: No function level data requested; only statistics will be collected.\n\n"));  build_data_desc ();   /* verify that the directory exists */  struct stat statbuf;  if (stat (store_dir, &statbuf) != 0)    return dbe_sprintf (GTXT ("Store directory %s is not accessible: %s\n"),			store_dir, strerror (errno));  if (access (store_dir, W_OK) != 0)    return dbe_sprintf (GTXT ("Store directory %s is not writeable: %s\n"),

Lines 1–500 of 3031.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t