From 40a1faf3322bf9cff2d52405647c60eca112158f Mon Sep 17 00:00:00 2001 From: "Bruce A. Mah" Date: Mon, 14 Apr 2014 10:45:46 -0700 Subject: [PATCH] Improve detection of CPU affinity support (for FreeBSD and Linux). As with several other recent commits, don't check explicitly for an OS platform, but rather detect the various API bits that are used to implement CPU affinity setting. --- configure.ac | 9 +++++++++ src/iperf.h | 8 ++++---- src/iperf_api.c | 42 +++++++++++++++++++++--------------------- src/locale.c | 4 ++-- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/configure.ac b/configure.ac index c516c74..5695c30 100644 --- a/configure.ac +++ b/configure.ac @@ -75,4 +75,13 @@ if test "x$iperf3_cv_header_flowlabel" = "xyes"; then AC_DEFINE([HAVE_FLOWLABEL], [1], [Have IPv6 flowlabel support.]) fi +# Check for CPU affinity support. FreeBSD and Linux do this differently +# unfortunately so we have to check separately for each of them. +# FreeBSD uses cpuset_setaffinity while Linux uses sched_setaffinity. +# Define HAVE_CPU_AFFINITY to indicate the CPU affinity setting as a +# generic concept is available. +AC_CHECK_FUNCS([cpuset_setaffinity sched_setaffinity], + AC_DEFINE([HAVE_CPU_AFFINITY], [1], + [Have CPU affinity support.])) + AC_OUTPUT([Makefile src/Makefile examples/Makefile]) diff --git a/src/iperf.h b/src/iperf.h index dd59483..74ff86d 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -16,10 +16,10 @@ #include #include -#if defined(__FreeBSD__) +#if defined(HAVE_CPUSET_SETAFFINITY) #include #include -#endif +#endif /* HAVE_CPUSET_SETAFFINITY */ #include "timer.h" #include "queue.h" @@ -167,9 +167,9 @@ struct iperf_test int duration; /* total duration of test (-t flag) */ char *diskfile_name; /* -F option */ int affinity, server_affinity; /* -A option */ -#if (__FreeBSD__) +#if defined(HAVE_CPUSET_SETAFFINITY) cpuset_t cpumask; -#endif +#endif /* HAVE_CPUSET_SETAFFINITY */ char *title; /* -T option */ char *congestion; /* -C option */ char *pidfile; /* -P option */ diff --git a/src/iperf_api.c b/src/iperf_api.c index e06620c..b06f74d 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -35,10 +35,10 @@ #include #include -#if defined(__FreeBSD__) +#if defined(HAVE_CPUSET_SETAFFINITY) #include #include -#endif +#endif /* HAVE_CPUSET_SETAFFINITY */ #include "config.h" #include "net.h" @@ -568,9 +568,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"zerocopy", no_argument, NULL, 'Z'}, {"omit", required_argument, NULL, 'O'}, {"file", required_argument, NULL, 'F'}, -#if defined(linux) || defined(__FreeBSD__) +#if defined(HAVE_CPU_AFFINITY) {"affinity", required_argument, NULL, 'A'}, -#endif +#endif /* HAVE_CPU_AFFINITY */ {"title", required_argument, NULL, 'T'}, #if defined(HAVE_TCP_CONGESTION) {"linux-congestion", required_argument, NULL, 'C'}, @@ -587,9 +587,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) int flag; int blksize; int server_flag, client_flag, rate_flag, duration_flag; -#if defined(linux) || defined(__FreeBSD__) +#if defined(HAVE_CPU_AFFINITY) char* comma; -#endif +#endif /* HAVE_CPU_AFFINITY */ char* slash; blksize = 0; @@ -769,7 +769,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) test->diskfile_name = optarg; break; case 'A': -#if defined(linux) || defined(__FreeBSD__) +#if defined(HAVE_CPU_AFFINITY) test->affinity = atoi(optarg); if (test->affinity < 0 || test->affinity > 1024) { i_errno = IEAFFINITY; @@ -784,10 +784,10 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) } client_flag = 1; } -#else +#else /* HAVE_CPU_AFFINITY */ i_errno = IEUNIMP; return -1; -#endif +#endif /* HAVE_CPU_AFFINITY */ break; case 'T': test->title = strdup(optarg); @@ -1570,9 +1570,9 @@ iperf_defaults(struct iperf_test *testp) testp->diskfile_name = (char*) 0; testp->affinity = -1; testp->server_affinity = -1; -#if defined(__FreeBSD__) +#if defined(HAVE_CPUSET_SETAFFINITY) CPU_ZERO(&testp->cpumask); -#endif +#endif /* HAVE_CPUSET_SETAFFINITY */ testp->title = NULL; testp->congestion = NULL; testp->server_port = PORT; @@ -1754,9 +1754,9 @@ iperf_reset_test(struct iperf_test *test) test->omit = OMIT; test->duration = DURATION; test->server_affinity = -1; -#if defined(__FreeBSD__) +#if defined(HAVE_CPUSET_SETAFFINITY) CPU_ZERO(&test->cpumask); -#endif +#endif /* HAVE_CPUSET_SETAFFINITY */ test->state = 0; if(test->title) { @@ -2578,7 +2578,7 @@ iperf_json_finish(struct iperf_test *test) int iperf_setaffinity(struct iperf_test *test, int affinity) { -#ifdef linux +#if defined(HAVE_SCHED_SETAFFINITY) cpu_set_t cpu_set; CPU_ZERO(&cpu_set); @@ -2588,7 +2588,7 @@ iperf_setaffinity(struct iperf_test *test, int affinity) return -1; } return 0; -#elif (__FreeBSD__) +#elif defined(HAVE_CPUSET_SETAFFINITY) cpuset_t cpumask; if(cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, @@ -2606,16 +2606,16 @@ iperf_setaffinity(struct iperf_test *test, int affinity) return -1; } return 0; -#else /* Linux or FreeBSD */ +#else /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY */ i_errno = IEAFFINITY; return -1; -#endif /* Linux or FreeBSD*/ +#endif /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY */ } int iperf_clearaffinity(struct iperf_test *test) { -#ifdef linux +#if defined(HAVE_SCHED_SETAFFINITY) cpu_set_t cpu_set; int i; @@ -2627,17 +2627,17 @@ iperf_clearaffinity(struct iperf_test *test) return -1; } return 0; -#elif (__FreeBSD__) +#elif defined(HAVE_CPUSET_SETAFFINITY) if(cpuset_setaffinity(CPU_LEVEL_WHICH,CPU_WHICH_PID, -1, sizeof(cpuset_t), &test->cpumask) != 0) { i_errno = IEAFFINITY; return -1; } return 0; -#else /* Linux or FreeBSD */ +#else /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY */ i_errno = IEAFFINITY; return -1; -#endif /* Linux or FreeBSD */ +#endif /* neither HAVE_SCHED_SETAFFINITY nor HAVE_CPUSET_SETAFFINITY */ } int diff --git a/src/locale.c b/src/locale.c index 6aae6b5..b08aa96 100644 --- a/src/locale.c +++ b/src/locale.c @@ -75,9 +75,9 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n" " -f, --format [kmgKMG] format to report: Kbits, Mbits, KBytes, MBytes\n" " -i, --interval # seconds between periodic bandwidth reports\n" " -F, --file name xmit/recv the specified file\n" -#if defined(linux) || defined(__FreeBSD__) +#if defined(HAVE_CPU_AFFINITY) " -A, --affinity n/n,m set CPU affinity\n" -#endif +#endif /* HAVE_CPU_AFFINITY */ " -V, --verbose more detailed output\n" " -J, --json output in JSON format\n" " --logfile f send output to a log file\n"