Module: xenomai-3 Branch: wip/prioceil Commit: ec0776f69aa3d3f4fadf3e31dc43b9c8779400da URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=ec0776f69aa3d3f4fadf3e31dc43b9c8779400da
Author: Philippe Gerum <r...@xenomai.org> Date: Fri Feb 26 11:44:16 2016 +0100 testsuite/smokey: add test checking Cobalt's cpu affinity control --- configure.ac | 1 + testsuite/smokey/Makefile.am | 1 + testsuite/smokey/cpu-affinity/Makefile.am | 9 ++ testsuite/smokey/cpu-affinity/cpu-affinity.c | 180 ++++++++++++++++++++++++++ 4 files changed, 191 insertions(+) diff --git a/configure.ac b/configure.ac index 7aaedc2..578327e 100644 --- a/configure.ac +++ b/configure.ac @@ -902,6 +902,7 @@ AC_CONFIG_FILES([ \ testsuite/smokey/net_packet_dgram/Makefile \ testsuite/smokey/net_packet_raw/Makefile \ testsuite/smokey/net_common/Makefile \ + testsuite/smokey/cpu-affinity/Makefile \ testsuite/clocktest/Makefile \ testsuite/xeno-test/Makefile \ utils/Makefile \ diff --git a/testsuite/smokey/Makefile.am b/testsuite/smokey/Makefile.am index e9a0fd2..5ade58b 100644 --- a/testsuite/smokey/Makefile.am +++ b/testsuite/smokey/Makefile.am @@ -8,6 +8,7 @@ smokey_SOURCES = main.c COBALT_SUBDIRS = \ arith \ bufp \ + cpu-affinity \ iddp \ leaks \ net_packet_dgram\ diff --git a/testsuite/smokey/cpu-affinity/Makefile.am b/testsuite/smokey/cpu-affinity/Makefile.am new file mode 100644 index 0000000..0d2e4e6 --- /dev/null +++ b/testsuite/smokey/cpu-affinity/Makefile.am @@ -0,0 +1,9 @@ + +noinst_LIBRARIES = libcpu-affinity.a + +libcpu_affinity_a_SOURCES = cpu-affinity.c + +libcpu_affinity_a_CPPFLAGS = \ + @XENO_USER_CFLAGS@ \ + -I$(top_srcdir) \ + -I$(top_srcdir)/include diff --git a/testsuite/smokey/cpu-affinity/cpu-affinity.c b/testsuite/smokey/cpu-affinity/cpu-affinity.c new file mode 100644 index 0000000..edb285e --- /dev/null +++ b/testsuite/smokey/cpu-affinity/cpu-affinity.c @@ -0,0 +1,180 @@ +/* + * Test CPU affinity control mechanisms. + * + * Copyright (C) Philippe Gerum <r...@xenomai.org> + * + * Released under the terms of GPLv2. + */ +#include <pthread.h> +#include <sched.h> +#include <stdio.h> +#include <stdlib.h> +#include <semaphore.h> +#include <smokey/smokey.h> + +smokey_test_plugin(cpu_affinity, + SMOKEY_NOARGS, + "Check CPU affinity control." +); + +static cpu_set_t cpu_realtime_set, cpu_online_set; + +struct test_context { + sem_t done; + int status; +}; + +static void *test_thread(void *arg) +{ + int cpu, cpu_in_rt_set, status = 0, ncpu, ret; + struct test_context *p = arg; + cpu_set_t set; + + cpu = get_current_cpu(); + if (!__Fassert(cpu < 0)) { + status = cpu; + goto out; + } + + smokey_trace(".. child thread starts on CPU%d", cpu); + + /* + * When emerging, we should be running on a member of the + * real-time CPU set. + */ + cpu_in_rt_set = CPU_ISSET(cpu, &cpu_realtime_set); + if (!__Tassert(cpu_in_rt_set)) { + status = -EINVAL; + goto out; + } + + for (ncpu = 0; ncpu < CPU_SETSIZE; ncpu++) { + if (ncpu == cpu || !CPU_ISSET(ncpu, &cpu_realtime_set)) + continue; + smokey_trace(".. child moving to CPU%d", ncpu); + CPU_ZERO(&set); + CPU_SET(ncpu, &set); + if (!__Terrno(ret, sched_setaffinity(0, sizeof(set), &set))) { + status = ret; + goto out; + } + } +out: + p->status = status; + __STD(sem_post(&p->done)); + + return NULL; +} + +static void *__run_cpu_affinity(void *arg) +{ + struct test_context context; + struct sched_param param; + struct timespec ts, now; + pthread_attr_t thattr; + cpu_set_t set; + pthread_t tid; + int cpu, ret; + + cpu = *(int *)arg; + smokey_trace(".. parent binding to non-RT CPU%d", cpu); + + context.status = 0; + __STD(sem_init(&context.done, 0, 0)); + + /* + * Make the child thread inherit a CPU affinity outside of the + * valid RT set from us. Cobalt should migrate the spawned + * thread to a CPU from the RT set automatically. + */ + CPU_ZERO(&set); + CPU_SET(cpu, &set); + if (!__Terrno(ret, sched_setaffinity(0, sizeof(set), &set))) { + context.status = ret; + goto out; + } + + pthread_attr_init(&thattr); + param.sched_priority = 1; + pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED); + pthread_attr_setschedpolicy(&thattr, SCHED_FIFO); + pthread_attr_setschedparam(&thattr, ¶m); + pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED); + + if (!__T(ret, pthread_create(&tid, &thattr, test_thread, &context))) { + context.status = ret; + goto out; + } + + __STD(clock_gettime(CLOCK_REALTIME, &now)); + timespec_adds(&ts, &now, 100000000); /* 100ms from now */ + + if (!__Terrno(ret, __STD(sem_timedwait(&context.done, &ts)))) + context.status = ret; +out: + __STD(sem_destroy(&context.done)); + + return (void *)(long)context.status; +} + +static int run_cpu_affinity(struct smokey_test *t, + int argc, char *const argv[]) +{ + struct sched_param param; + pthread_attr_t thattr; + pthread_t tid; + void *status; + int cpu, ret; + + ret = get_realtime_cpu_set(&cpu_realtime_set); + if (ret) + return -ENOSYS; + + ret = get_online_cpu_set(&cpu_online_set); + if (ret) + return -ENOSYS; + + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + if (CPU_ISSET(cpu, &cpu_online_set)) + smokey_trace(".. CPU%d is %s", cpu, + CPU_ISSET(cpu, &cpu_realtime_set) ? + "available" : "online, non-RT"); + } + + /* Find a non-RT CPU in the online set. */ + for (cpu = CPU_SETSIZE - 1; cpu >= 0; cpu--) { + if (CPU_ISSET(cpu, &cpu_online_set) && + !CPU_ISSET(cpu, &cpu_realtime_set)) + break; + } + + /* + * If there is no CPU restriction on the bootargs + * (i.e. xenomai.supported_cpus is absent or does not exclude + * any online CPU), pretend that we have no kernel support for + * running this test. + */ + if (cpu < 0) { + smokey_trace("no CPU restriction with xenomai.supported_cpus"); + return -ENOSYS; + } + + pthread_attr_init(&thattr); + param.sched_priority = 0; + pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE); + pthread_attr_setschedpolicy(&thattr, SCHED_OTHER); + pthread_attr_setschedparam(&thattr, ¶m); + pthread_attr_setinheritsched(&thattr, PTHREAD_EXPLICIT_SCHED); + + /* + * Start a regular pthread for running the tests, to bypass + * sanity checks Cobalt does on CPU affinity. + */ + if (!__T(ret, __STD(pthread_create(&tid, &thattr, __run_cpu_affinity, &cpu)))) + return ret; + + if (!__T(ret, pthread_join(tid, &status))) + return ret; + + return (long)status; +} _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git