diff --git a/configure.in b/configure.in index d65c17eaa..75eef279b 100644 --- a/configure.in +++ b/configure.in @@ -577,6 +577,17 @@ dnl Checks for precise integer types AC_CHECK_HEADERS([stdint.h signal.h inttypes.h sys/int_types.h]) AC_CHECK_TYPES([uint64_t, uint128_t]) +dnl =========================================================================== +dnl check for CPU affinity support +AC_CHECK_HEADERS([sched.h], [ + AC_CHECK_FUNCS([sched_getaffinity], [ + AC_DEFINE([HAVE_SCHED_GETAFFINITY], [1], + [Define to 1 if you have Linux compatible sched_getaffinity]) + ]) +]) + +dnl =========================================================================== +dnl check compiler flags AC_DEFUN([CAIRO_CC_TRY_FLAG], [ AC_MSG_CHECKING([whether $CC supports $1]) diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index 49f4b5990..44e842b34 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -27,12 +27,17 @@ */ #include "cairo-perf.h" +#include "config.h" /* For getopt */ #include /* For basename */ #include +#ifdef HAVE_SCHED_H +#include +#endif + #define CAIRO_PERF_ITERATIONS_DEFAULT 100 #define CAIRO_PERF_LOW_STD_DEV 0.03 #define CAIRO_PERF_STABLE_STD_DEV_COUNT 5 @@ -259,6 +264,40 @@ parse_options (cairo_perf_t *perf, int argc, char *argv[]) } } +static int +check_cpu_affinity(void) +{ +#ifdef HAVE_SCHED_GETAFFINITY + + cpu_set_t affinity; + int i, cpu_count; + + if (sched_getaffinity(0, sizeof(affinity), &affinity)) { + perror("sched_getaffinity"); + return -1; + } + + for(i = 0, cpu_count = 0; i < CPU_SETSIZE; ++i) { + if (CPU_ISSET(i, &affinity)) + ++cpu_count; + } + + if (cpu_count > 1) { + fputs( + "WARNING: cairo-perf has not been bound to a single CPU.\n", + stderr); + return -1; + } + + return 0; +#else + fputs( + "WARNING: Cannot check CPU affinity for this platform.\n", + stderr); + return -1; +#endif +} + int main (int argc, char *argv[]) { @@ -271,6 +310,19 @@ main (int argc, char *argv[]) parse_options (&perf, argc, argv); + if (check_cpu_affinity()) { + fputs( + "NOTICE: cairo-perf and the X server should be bound to CPUs (either the same\n" + "or separate) on SMP systems. Not doing so causes random results when the X\n" + "server is moved to or from cairo-perf's CPU during the benchmarks:\n" + "\n" + " $ sudo taskset -cp 0 $(pidof X)\n" + " $ taskset -cp 1 $$\n" + "\n" + "See taskset(1) for information about changing CPU affinity.\n", + stderr); + } + for (i = 0; targets[i].name; i++) { perf.target = target = &targets[i]; perf.test_number = 0;