This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: time usage for subprocesses [NEW PATCH]


Jeffrey A Law wrote:
> 
>   In message <199908070639.XAA08070@zack.bitmover.com>you write:
>   > Jeffrey A Law wrote:
>   > > But it's trivial to get deltas given the rusage stats as you wait on
>   > > each process in succession.
>   > 
>   > My impression was that times() and getrusage(RUSAGE_CHILDREN, ...)
>   > would give me cumulative execution times for all the children up to
>   > the moment I made the call.  Is that not the case?
> Right, but all that means is you have to subtract the last sample from the
> new sample to get the run time for whatever pass you just ran.

I get it now... and doing it this way, I don't have to modify
libiberty.  On the other hand, I have to turn off -pipe, but that's
OK.  New patch follows.

zw

1999-08-12 19:50 -0700  Zack Weinberg  <zack@bitmover.com>

	* gcc.c (report_times): New flag.
	(execute): If HAVE_GETRUSAGE, and report_times is set, then
	call getrusage for each child process in turn, and print the
	user and system time consumed.
	(process_command): If -time is given, then set report_times
	flag and turn off -pipe.
	(option_map): Map --time to -time.
	(display_help): Document -time option.

	* configure.in: Check for getrusage.
	* acconfig.h: Add NEED_DECLARATION_GETRUSAGE.

Index: gcc.c
===================================================================
RCS file: /cvs/egcs/egcs/gcc/gcc.c,v
retrieving revision 1.107
diff -u -r1.107 gcc.c
--- gcc.c	1999/08/05 09:16:26	1.107
+++ gcc.c	1999/08/13 02:57:46
@@ -43,6 +43,13 @@
 #define exit __posix_exit
 #endif
 
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef NEED_DECLARATION_GETRUSAGE
+extern int getrusage(int, struct rusage *);
+#endif
+
 /* By default there is no special suffix for executables.  */
 #ifdef EXECUTABLE_SUFFIX
 #define HAVE_EXECUTABLE_SUFFIX
@@ -125,6 +132,11 @@
 
 static int verbose_flag;
 
+/* Flag indicating whether we should report subprocess execution times
+   (if this is supported by the system - see pexecute.c).  */
+
+static int report_times;
+
 /* Nonzero means write "temp" files in source directory
    and use the source file's name in them, and don't delete them.  */
 
@@ -166,6 +178,12 @@
 
 static struct obstack collect_obstack;
 
+/* These structs are used to collect resource usage information for
+   subprocesses.  */
+#ifdef HAVE_GETRUSAGE
+static struct rusage rus, prus;
+#endif
+
 extern char *version_string;
 
 /* Forward declaration for prototypes.  */
@@ -875,6 +893,7 @@
    {"--std", "-std=", "aj"},
    {"--symbolic", "-symbolic", 0},
    {"--target", "-b", "a"},
+   {"--time", "-time", 0},
    {"--trace-includes", "-H", 0},
    {"--traditional", "-traditional", 0},
    {"--traditional-cpp", "-traditional-cpp", 0},
@@ -2336,6 +2355,10 @@
 
   {
     int ret_code = 0;
+#ifdef HAVE_GETRUSAGE
+    struct timeval d;
+    double ut, st;
+#endif
 
     for (i = 0; i < n_commands; )
       {
@@ -2347,6 +2370,25 @@
 	if (pid < 0)
 	  abort ();
 
+#ifdef HAVE_GETRUSAGE
+	if (report_times)
+	  {
+	    /* getrusage returns the total resource usage of all children
+	       up to now.  Copy the previous values into prus, get the
+	       current statistics, then take the difference.  */
+
+	    prus = rus;
+	    getrusage (RUSAGE_CHILDREN, &rus);
+	    d.tv_sec = rus.ru_utime.tv_sec - prus.ru_utime.tv_sec;
+	    d.tv_usec = rus.ru_utime.tv_usec - prus.ru_utime.tv_usec;
+	    ut = (double)d.tv_sec + (double)d.tv_usec / 1.0e6;
+	    
+	    d.tv_sec = rus.ru_stime.tv_sec - prus.ru_stime.tv_sec;
+	    d.tv_usec = rus.ru_stime.tv_usec - prus.ru_utime.tv_usec;
+	    st = (double)d.tv_sec + (double)d.tv_usec / 1.0e6;
+	  }
+#endif
+
 	for (j = 0; j < n_commands; j++)
 	  if (commands[j].pid == pid)
 	    {
@@ -2364,6 +2406,10 @@
 			   && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
 		    ret_code = -1;
 		}
+#ifdef HAVE_GETRUSAGE
+	      if (report_times && ut + st != 0)
+		notice ("# %s %.2f %.2f\n", commands[j].prog, ut, st);
+#endif
 	      break;
 	    }
       }
@@ -2504,6 +2550,7 @@
   printf ("  -Xlinker <arg>           Pass <arg> on to the linker\n");
   printf ("  -save-temps              Do not delete intermediate files\n");
   printf ("  -pipe                    Use pipes rather than intermediate files\n");
+  printf ("  -time                    Time the execution of each subprocess\n");
   printf ("  -specs=<file>            Override builtin specs with the contents of <file>\n");
   printf ("  -std=<standard>          Assume that the input sources are for <standard>\n");
   printf ("  -B <directory>           Add <directory> to the compiler's search paths\n");
@@ -2888,6 +2935,8 @@
 	    user_specs_head = user;
 	  user_specs_tail = user;
 	}
+      else if (strcmp (argv[i], "-time") == 0)
+	report_times = 1;
       else if (argv[i][0] == '-' && argv[i][1] != 0)
 	{
 	  register char *p = &argv[i][1];
@@ -3227,10 +3276,20 @@
       else if (strcmp (argv[i], "-specs") == 0)
 	i++;
       else if (strncmp (argv[i], "-specs=", 7) == 0)
+	;
+      else if (strcmp (argv[i], "-time") == 0)
 	;
-      /* -save-temps overrides -pipe, so that temp files are produced */
-      else if (save_temps_flag && strcmp (argv[i], "-pipe") == 0)
-	error ("Warning: -pipe ignored since -save-temps specified");
+      else if ((save_temps_flag || report_times)
+	       && strcmp (argv[i], "-pipe") == 0)
+	{
+	  /* -save-temps overrides -pipe, so that temp files are produced */
+	  if (save_temps_flag)
+	    error ("Warning: -pipe ignored since -save-temps specified");
+          /* -time overrides -pipe because we can't get correct stats when
+	     multiple children are running at once.  */
+	  else if (report_times)
+	    error ("Warning: -pipe ignored since -time specified");
+	}
       else if (argv[i][0] == '-' && argv[i][1] != 0)
 	{
 	  register char *p = &argv[i][1];
Index: configure.in
===================================================================
RCS file: /cvs/egcs/egcs/gcc/configure.in,v
retrieving revision 1.274
diff -u -r1.274 configure.in
--- configure.in	1999/08/12 22:31:16	1.274
+++ configure.in	1999/08/13 02:57:46
@@ -339,7 +339,9 @@
 AC_HEADER_TIME
 GCC_HEADER_STRING
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unistd.h stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h sys/stat.h direct.h)
+AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h \
+		 fcntl.h unistd.h stab.h sys/file.h sys/time.h \
+		 sys/resource.h sys/param.h sys/times.h sys/stat.h direct.h)
 
 # Check for thread headers.
 AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
@@ -379,7 +381,7 @@
 AC_CHECK_FUNCS(strtoul bsearch strerror putenv popen bcopy bzero bcmp \
 	index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \
 	sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
-	fputs_unlocked)
+	fputs_unlocked getrusage)
 
 # Make sure wchar_t is available
 #AC_CHECK_TYPE(wchar_t, unsigned int)
@@ -401,7 +403,7 @@
 	index rindex getenv atol sbrk abort atof strerror getcwd getwd \
 	strsignal putc_unlocked fputs_unlocked strstr)
 
-GCC_NEED_DECLARATIONS(getrlimit setrlimit, [
+GCC_NEED_DECLARATIONS(getrlimit setrlimit getrusage, [
 #include <sys/types.h>
 #ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
Index: acconfig.h
===================================================================
RCS file: /cvs/egcs/egcs/gcc/acconfig.h,v
retrieving revision 1.34
diff -u -r1.34 acconfig.h
--- acconfig.h	1999/08/02 22:57:49	1.34
+++ acconfig.h	1999/08/13 02:57:46
@@ -114,6 +114,9 @@
 /* Whether setrlimit must be declared even if <sys/resource.h> is included.  */
 #undef NEED_DECLARATION_SETRLIMIT
 
+/* Whether getrusage must be declared even if <sys/resource.h> is included.  */
+#undef NEED_DECLARATION_GETRUSAGE
+
 /* Whether putc_unlocked must be declared even if <stdio.h> is included.  */
 #undef NEED_DECLARATION_PUTC_UNLOCKED
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]