[cairo-commit] perf/cairo-perf.h perf/cairo-perf-trace.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Jun 11 05:01:38 PDT 2009


 perf/cairo-perf-trace.c |  135 +++++++++++++++++++++++++++++++++++++++++++++---
 perf/cairo-perf.h       |    2 
 2 files changed, 130 insertions(+), 7 deletions(-)

New commits:
commit 42c0aee1d9ff5e0182c41ed505a2b0f56e564cbb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Jun 11 12:58:05 2009 +0100

    [perf] Add a -x to exclude traces from a benchmark.
    
    Read names of traces to exclude from a file specified using -x on the
    commandline, i.e.
    $ ./cairo-perf-trace -x cairo-traces/tiny.exclude
    
    This is a convenient method for me to exclude certain traces for
    particular machines. For example tiny cannot run
    firefox-36-20090609.trace as that has a greater working set than the
    available RAM on tiny.

diff --git a/perf/cairo-perf-trace.c b/perf/cairo-perf-trace.c
index 5e35cf6..790e836 100644
--- a/perf/cairo-perf-trace.c
+++ b/perf/cairo-perf-trace.c
@@ -28,7 +28,7 @@
  *          Chris Wilson <chris at chris-wilson.co.uk>
  */
 
-#define _GNU_SOURCE 1	/* for sched_getaffinity() */
+#define _GNU_SOURCE 1	/* for sched_getaffinity() and getline() */
 
 #include "cairo-perf.h"
 #include "cairo-stats.h"
@@ -40,6 +40,7 @@
 #ifdef HAVE_LIBGEN_H
 #include <libgen.h>
 #endif
+#include <ctype.h> /* isspace() */
 
 #include <sys/types.h>
 #include <dirent.h>
@@ -114,8 +115,9 @@ cairo_perf_can_run (cairo_perf_t	*perf,
 {
     unsigned int i;
     char *copy, *dot;
+    cairo_bool_t ret;
 
-    if (perf->num_names == 0)
+    if (perf->num_names == 0 && perf->num_exclude_names == 0)
 	return TRUE;
 
     copy = xstrdup (name);
@@ -123,13 +125,31 @@ cairo_perf_can_run (cairo_perf_t	*perf,
     if (dot != NULL)
 	*dot = '\0';
 
-    for (i = 0; i < perf->num_names; i++)
-	if (strstr (copy, perf->names[i]))
-	    break;
+    if (perf->num_names) {
+	ret = TRUE;
+	for (i = 0; i < perf->num_names; i++)
+	    if (strstr (copy, perf->names[i]))
+		goto check_exclude;
+
+	ret = FALSE;
+	goto done;
+    }
 
+check_exclude:
+    if (perf->num_exclude_names) {
+	ret = FALSE;
+	for (i = 0; i < perf->num_exclude_names; i++)
+	    if (strstr (copy, perf->exclude_names[i]))
+		goto done;
+
+	ret = TRUE;
+	goto done;
+    }
+
+done:
     free (copy);
 
-    return i != perf->num_names;
+    return ret;
 }
 
 static void
@@ -317,6 +337,7 @@ usage (const char *argv0)
 "  -r	raw; display each time measurement instead of summary statistics\n"
 "  -v	verbose; in raw mode also show the summaries\n"
 "  -i	iterations; specify the number of iterations per test case\n"
+"  -x   exclude; specify a file to read a list of traces to exclude\n"
 "  -l	list only; just list selected test case names without executing\n"
 "\n"
 "If test names are given they are used as sub-string matches so a command\n"
@@ -325,6 +346,97 @@ usage (const char *argv0)
 	     argv0, argv0);
 }
 
+#ifndef __USE_GNU
+#define POORMANS_GETLINE_BUFFER_SIZE (65536)
+static ssize_t
+getline (char **lineptr, size_t *n, FILE *stream)
+{
+    if (!*lineptr)
+    {
+        *n = POORMANS_GETLINE_BUFFER_SIZE;
+        *lineptr = (char *) malloc (*n);
+    }
+
+    if (!fgets (*lineptr, *n, stream))
+        return -1;
+
+    if (!feof (stream) && !strchr (*lineptr, '\n'))
+    {
+        fprintf (stderr, "The poor man's implementation of getline in "
+                          __FILE__ " needs a bigger buffer. Perhaps it's "
+                         "time for a complete implementation of getline.\n");
+        exit (0);
+    }
+
+    return strlen (*lineptr);
+}
+#undef POORMANS_GETLINE_BUFFER_SIZE
+
+static char *
+strndup (const char *s, size_t n)
+{
+    size_t len;
+    char *sdup;
+
+    if (!s)
+        return NULL;
+
+    len = strlen (s);
+    len = (n < len ? n : len);
+    sdup = (char *) malloc (len + 1);
+    if (sdup)
+    {
+        memcpy (sdup, s, len);
+        sdup[len] = '\0';
+    }
+
+    return sdup;
+}
+#endif /* ifndef __USE_GNU */
+
+static cairo_bool_t
+read_excludes (cairo_perf_t *perf, const char *filename)
+{
+    FILE *file;
+    char *line = NULL;
+    size_t line_size = 0;
+    char *s, *t;
+
+    file = fopen (filename, "r");
+    if (file == NULL)
+	return FALSE;
+
+    while (getline (&line, &line_size, file) != -1) {
+	/* terminate the line at a comment marker '#' */
+	s = strchr (line, '#');
+	if (s)
+	    *s = '\0';
+
+	/* whitespace delimits */
+	s = line;
+	while (*s != '\0' && isspace (*s))
+	    s++;
+
+	t = s;
+	while (*t != '\0' && ! isspace (*t))
+	    t++;
+
+	if (s != t) {
+	    int i = perf->num_exclude_names;
+	    perf->exclude_names = xrealloc (perf->exclude_names,
+					    sizeof (char *) * (i+1));
+	    perf->exclude_names[i] = strndup (s, t-s);
+	    perf->num_exclude_names++;
+	}
+    }
+    if (line != NULL)
+	free (line);
+
+    fclose (file);
+
+    return TRUE;
+}
+
 static void
 parse_options (cairo_perf_t *perf, int argc, char *argv[])
 {
@@ -345,9 +457,11 @@ parse_options (cairo_perf_t *perf, int argc, char *argv[])
     perf->num_names = 0;
     perf->summary = stdout;
     perf->summary_continuous = FALSE;
+    perf->exclude_names = NULL;
+    perf->num_exclude_names = 0;
 
     while (1) {
-	c = _cairo_getopt (argc, argv, "i:lrv");
+	c = _cairo_getopt (argc, argv, "ix:lrv");
 	if (c == -1)
 	    break;
 
@@ -371,6 +485,13 @@ parse_options (cairo_perf_t *perf, int argc, char *argv[])
 	case 'v':
 	    verbose = 1;
 	    break;
+	case 'x':
+	    if (! read_excludes (perf, optarg)) {
+		fprintf (stderr, "Invalid argument for -x (not readable file): %s\n",
+			 optarg);
+		exit (1);
+	    }
+	    break;
 	default:
 	    fprintf (stderr, "Internal error: unhandled option: %c\n", c);
 	    /* fall-through */
diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h
index 3ff3d7f..fbb1500 100644
--- a/perf/cairo-perf.h
+++ b/perf/cairo-perf.h
@@ -79,6 +79,8 @@ typedef struct _cairo_perf {
     cairo_bool_t list_only;
     char **names;
     unsigned int num_names;
+    char **exclude_names;
+    unsigned int num_exclude_names;
 
     /* Stuff used internally */
     cairo_perf_ticks_t *times;


More information about the cairo-commit mailing list