Author: sebor
Date: Fri Sep 15 12:02:55 2006
New Revision: 446689
URL: http://svn.apache.org/viewvc?view=rev&rev=446689
Log:
2006-09-15 Andrew Black <[EMAIL PROTECTED]>
* display.h (unistd.h) [!_WIN32 && !_WIN64]: Include.
(sys/time.h) [_XOPEN_UNIX]: Include.
(rw_time_t, rw_suseconds_t, struct rw_timeval) [!_XOPEN_UNIX]: Define
placeholder structures.
(rw_timeval): Define abstraction typedef.
(struct target_status): Add run, user, sys elements.
* display.cpp (unistd.h) [!_WIN32 && !_WIN64]: Include.
print_header_plain: Alter cols for process times.
print_target_plain: Partition output column printing by section, add
timing output.
* exec.h (exec_file): Alter signature to accept target_status rather
than char**.
* exec.cpp (display.h): Include.
(calculate_usage) [!_WIN32 && !_WIN64]: Define function to populate
user and sys fields of provided target_status struct (if _XOPEN_UNIX
is defined).
(exec_file): Alter to accept target_status rather than char**, use
argv element in place of old char** argument.
(exec_file) [!_WIN32 && !_WIN64]: call calculate_usage after
wait_for_child.
* runall.cpp (run_target): Pass target_status struct rather than argv
element.
Modified:
incubator/stdcxx/trunk/util/display.cpp
incubator/stdcxx/trunk/util/display.h
incubator/stdcxx/trunk/util/exec.cpp
incubator/stdcxx/trunk/util/exec.h
incubator/stdcxx/trunk/util/runall.cpp
Modified: incubator/stdcxx/trunk/util/display.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/display.cpp?view=diff&rev=446689&r1=446688&r2=446689
==============================================================================
--- incubator/stdcxx/trunk/util/display.cpp (original)
+++ incubator/stdcxx/trunk/util/display.cpp Fri Sep 15 12:02:55 2006
@@ -26,6 +26,9 @@
#include <assert.h>
#include <stdio.h> /* for fflush(), printf(), puts(), ... */
+#if !defined (_WIN32) && !defined (_WIN64)
+# include <unistd.h> /* for _XOPEN_UNIX */
+#endif
#include "cmdopt.h" /* for target_name -should this be moved? */
#include "exec.h" /* for get_signame */
@@ -34,7 +37,8 @@
void print_header_plain ()
{
- puts ("NAME STATUS ASSERTS FAILED PERCNT");
+ puts ("NAME STATUS ASSERTS FAILED PERCNT USER "
+ "SYS");
}
void print_target_plain (const struct target_status*)
@@ -45,23 +49,38 @@
void print_status_plain (const struct target_status* status)
{
+ unsigned valid_timing;
+ assert (0 != status);
assert (ST_OK <= status->status && ST_LAST > status->status);
+ valid_timing = status->run && ST_NOT_KILLED != status->status;
+
if (status->status) /* if status is set, print it */
- printf ("%6s\n", short_st_name [status->status]);
+ printf ("%6s", short_st_name [status->status]);
else if (status->exit) /* if exit code is non-zero, print it */
- printf ("%6d\n", status->exit);
+ printf ("%6d", status->exit);
else if (status->signal) /* if exit signal is non-zero, print it */
- printf ("%6s\n", get_signame (status->signal));
- else if (!status->assert) /* if the assertion count is 0, it's an example
*/
- puts (" 0");
+ printf ("%6s", get_signame (status->signal));
+ else
+ printf (" 0");
+
+ /* Print assetions, if any registered */
+ if (status->assert) {
+ printf (" %7u %6u %5d%%", status->assert, status->failed,
+ 100 * (status->assert - status->failed) / status->assert);
+ }
+ else if (valid_timing)
+ printf (" ");
+
+ /* Print timings, if available */
+ if (valid_timing)
+ printf (" %3ld.%03ld %3ld.%03ld\n", status->user.tv_sec,
+ status->user.tv_usec/1000, status->sys.tv_sec,
+ status->sys.tv_usec/1000);
else {
- unsigned pcnt = 0;
- if (status->assert) {
- pcnt = 100 * (status->assert - status->failed) / status->assert;
- }
- printf (" 0 %7u %6u %5d%%\n", status->assert, status->failed,
pcnt);
+ puts ("");
}
+
}
void print_footer_plain () {}
Modified: incubator/stdcxx/trunk/util/display.h
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/display.h?view=diff&rev=446689&r1=446688&r2=446689
==============================================================================
--- incubator/stdcxx/trunk/util/display.h (original)
+++ incubator/stdcxx/trunk/util/display.h Fri Sep 15 12:02:55 2006
@@ -27,6 +27,38 @@
#ifndef RW_DISPLAY_H
#define RW_DISPLAY_H
+#if !defined (_WIN32) && !defined (_WIN64)
+# include <unistd.h> /* for _XOPEN_UNIX */
+#endif
+
+#ifdef _XOPEN_UNIX
+# include <sys/time.h> /* for struct timeval */
+/**
+ Abstraction typedef for struct timeval using real struct
+*/
+typedef struct timeval rw_timeval;
+#else
+/**
+ Placeholder time_t for use in rw_timeval
+*/
+typedef long rw_time_t;
+/**
+ Placeholder suseconds_t for use in rw_timeval
+*/
+typedef long rw_suseconds_t;
+/**
+ Placeholder struct timeval to use if _XOPEN_UNIX isn't defined
+*/
+struct rw_timeval {
+ rw_time_t tv_sec;
+ rw_suseconds_t tv_usec;
+};
+/**
+ Abstraction typedef for struct timeval using placeholder struct
+*/
+typedef struct rw_timeval rw_timeval;
+#endif
+
/**
Output format mode enumeration.
@@ -74,7 +106,10 @@
char** argv; /**< Target argv array. */
int exit; /**< exit code for process. */
int signal; /**< Termination signal for process. */
+ int run; /**< Flag indicating if the process executed. */
enum ProcessStatus status; /**< Textual process status. */
+ rw_timeval user; /**< Elapsed user time spent in execution. */
+ rw_timeval sys; /**< Elapsed system time spent in execution. */
unsigned warn; /**< Number of (test) warnings. */
unsigned assert; /**< Number of (test) assertions. */
unsigned failed; /**< Number of failed (test) assertions. */
Modified: incubator/stdcxx/trunk/util/exec.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/exec.cpp?view=diff&rev=446689&r1=446688&r2=446689
==============================================================================
--- incubator/stdcxx/trunk/util/exec.cpp (original)
+++ incubator/stdcxx/trunk/util/exec.cpp Fri Sep 15 12:02:55 2006
@@ -51,6 +51,7 @@
#include <sys/types.h>
#include "cmdopt.h"
+#include "display.h" /* for struct target_status */
#include "util.h"
#include "exec.h"
@@ -697,6 +698,62 @@
#endif /* _XOPEN_UNIX */
/**
+ Calculates the amount of resources used by the child processes.
+
+ This method uses the getrusage() system call to calculate the resources
+ used by the child process. However, getrusage() only is able to calcualte
+ agragate usage by all child processes, not usage by a specific child
process.
+ Therefore, we must keep a running tally of how many resources had been used
+ the previous time we calculated the usage. This difference is the resources
+ that were used by the process that just completed.
+
+ @param result target_status structure to populate with process usage.
+*/
+static void
+calculate_usage (struct target_status* result)
+{
+#ifdef _XOPEN_UNIX
+ static bool init = 0;
+ static struct rusage history;
+ struct rusage now;
+
+ assert (0 != result);
+
+ if (!init) {
+ memset (&history, 0, sizeof history);
+ init = 1;
+ }
+
+ if (0 != getrusage (RUSAGE_CHILDREN, &now)) {
+ warn ("Failed to retrieve child resource usage: %s", strerror (errno));
+ return;
+ }
+
+ /* time calculations */
+ result->user.tv_sec = now.ru_utime.tv_sec - history.ru_utime.tv_sec;
+ result->user.tv_usec = now.ru_utime.tv_usec - history.ru_utime.tv_usec;
+ result->sys.tv_sec = now.ru_stime.tv_sec - history.ru_stime.tv_sec;
+ result->sys.tv_usec = now.ru_stime.tv_usec - history.ru_stime.tv_usec;
+
+ /* Adjust seconds/microseconds */
+ if (now.ru_utime.tv_usec < history.ru_utime.tv_usec) {
+ --result->user.tv_sec;
+ result->user.tv_usec += 1000000;
+ }
+ if (now.ru_stime.tv_usec < history.ru_stime.tv_usec) {
+ --result->sys.tv_sec;
+ result->sys.tv_usec += 1000000;
+ }
+
+ /* Tag result as having run */
+ result->run = 1;
+
+ /* Cache the values retrieved */
+ memcpy (&history, &now, sizeof (struct rusage));
+#endif /* _XOPEN_UNIX */
+}
+
+/**
Entry point to the child process (watchdog) subsystem.
This method fork ()s, creating a child process. This child process becomes
@@ -712,15 +769,17 @@
@see wait_for_child ()
*/
struct exec_attrs
-exec_file (char** argv)
+exec_file (struct target_status* result)
{
const pid_t child_pid = fork ();
+ assert (0 != result);
+ assert (0 != result->argv);
+ assert (0 != result->argv [0]);
+
if (0 == child_pid) { /* child */
FILE* error_file;
- assert (0 != argv);
- assert (0 != argv [0]);
assert (0 != target_name);
/* Set process group ID (so entire group can be killed)*/
@@ -752,7 +811,7 @@
/* Redirect stdout */
{
- char* const tmp_name = output_name (argv [0]);
+ char* const tmp_name = output_name (result->argv [0]);
int intermit;
intermit = open (tmp_name, O_WRONLY | O_CREAT | O_TRUNC,
@@ -776,10 +835,10 @@
limit_process ();
#endif /* _XOPEN_UNIX */
- execv (argv [0], argv);
+ execv (result->argv [0], result->argv);
fprintf (error_file, "%s (%s): execv (\"%s\", ...) error: %s\n",
- exe_name, target_name, argv [0], strerror (errno));
+ exe_name, target_name, result->argv [0], strerror (errno));
exit (1);
}
@@ -787,13 +846,15 @@
if (-1 == child_pid) {
/* Fake a failue to execute status return structure */
struct exec_attrs state = {127, -1};
- warn ("Unable to create child process for %s: %s\n", argv [0],
+ warn ("Unable to create child process for %s: %s\n", result->argv [0],
strerror (errno));
return state;
+ } else {
+ /* parent */
+ struct exec_attrs state = wait_for_child (child_pid);
+ calculate_usage (result);
+ return state;
}
-
- /* parent */
- return wait_for_child (child_pid);
}
#else /* _WIN{32,64} */
/**
@@ -950,7 +1011,7 @@
@see wait_for_child ()
*/
struct exec_attrs
-exec_file (char** argv)
+exec_file (struct target_status* result)
{
char* merged;
PROCESS_INFORMATION child;
@@ -962,7 +1023,9 @@
const DWORD real_timeout = (timeout > 0) ? timeout * 1000 : INFINITE;
DWORD wait_code;
- assert (0 != argv);
+ assert (0 != result);
+ assert (0 != result->argv);
+ assert (0 != result->argv [0]);
memset (&status, 0, sizeof status);
@@ -979,7 +1042,7 @@
/* Create I/O handles */
{
/* Output redirection */
- char* const tmp_name = output_name (argv [0]);
+ char* const tmp_name = output_name (result->argv [0]);
context.hStdOutput = CreateFile (tmp_name, GENERIC_WRITE,
FILE_SHARE_WRITE, &child_sa, CREATE_ALWAYS,
@@ -1003,7 +1066,7 @@
}
}
- merged = merge_argv (argv);
+ merged = merge_argv (result->argv);
/* set appropriate error mode (the child process inherits this
error mode) to disable displaying the critical-error-handler
@@ -1011,7 +1074,7 @@
UINT old_mode = SetErrorMode (SEM_FAILCRITICALERRORS
| SEM_NOGPFAULTERRORBOX);
/* Create the child process */
- if (0 == CreateProcess (argv [0], merged, 0, 0, 1,
+ if (0 == CreateProcess (result->argv [0], merged, 0, 0, 1,
CREATE_NEW_PROCESS_GROUP, 0, 0, &context, &child)) {
/* record the status if we failed to create the process */
status.status = -1;
Modified: incubator/stdcxx/trunk/util/exec.h
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/exec.h?view=diff&rev=446689&r1=446688&r2=446689
==============================================================================
--- incubator/stdcxx/trunk/util/exec.h (original)
+++ incubator/stdcxx/trunk/util/exec.h Fri Sep 15 12:02:55 2006
@@ -42,6 +42,6 @@
const char* get_signame (int signo);
-struct exec_attrs exec_file (char** argv);
+struct exec_attrs exec_file (struct target_status* result);
#endif // RW_EXEC_H
Modified: incubator/stdcxx/trunk/util/runall.cpp
URL:
http://svn.apache.org/viewvc/incubator/stdcxx/trunk/util/runall.cpp?view=diff&rev=446689&r1=446688&r2=446689
==============================================================================
--- incubator/stdcxx/trunk/util/runall.cpp (original)
+++ incubator/stdcxx/trunk/util/runall.cpp Fri Sep 15 12:02:55 2006
@@ -415,7 +415,7 @@
print_target (&results);
if (check_target_ok (&results)) {
- struct exec_attrs status = exec_file (results.argv);
+ struct exec_attrs status = exec_file (&results);
process_results (&status, &results);
}